From 89be710ab3c1d48a7d4a50ad8b13625fbe7a8479 Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Tue, 17 Feb 2026 10:54:55 +0500 Subject: [PATCH 1/3] fix: fixtures for zk circuits --- crates/events/src/enclave_event/proof.rs | 42 ++-- .../events/src/enclave_event/signed_proof.rs | 40 ++- .../src/circuits/dkg/share_decryption.rs | 17 +- .../src/circuits/dkg/share_encryption.rs | 17 +- .../threshold/decrypted_shares_aggregation.rs | 9 +- crates/zk-prover/src/circuits/utils.rs | 10 + .../fixtures/decrypted_shares_aggregation.vk | Bin 3680 -> 0 bytes .../decrypted_shares_aggregation_bn.json | 140 +++++++++++ .../decrypted_shares_aggregation_bn.vk | Bin 0 -> 1888 bytes ... => decrypted_shares_aggregation_mod.json} | 10 +- .../decrypted_shares_aggregation_mod.vk | Bin 0 -> 1888 bytes .../fixtures/dkg_e_sm_share_decryption.json | 61 ----- .../fixtures/dkg_e_sm_share_decryption.vk | Bin 3680 -> 0 bytes .../fixtures/dkg_sk_share_decryption.json | 61 ----- .../tests/fixtures/dkg_sk_share_decryption.vk | Bin 3680 -> 0 bytes .../fixtures/e_sm_share_computation.json | 18 +- .../tests/fixtures/e_sm_share_computation.vk | Bin 3680 -> 1888 bytes .../tests/fixtures/e_sm_share_encryption.vk | Bin 3680 -> 0 bytes .../tests/fixtures/pk_aggregation.json | 16 +- .../tests/fixtures/pk_aggregation.vk | Bin 3680 -> 1888 bytes .../tests/fixtures/pk_generation.json | 14 +- .../zk-prover/tests/fixtures/pk_generation.vk | Bin 3680 -> 1888 bytes .../tests/fixtures/share_decryption.json | 145 +++++++++++ .../tests/fixtures/share_decryption.vk | Bin 0 -> 1888 bytes ..._encryption.json => share_encryption.json} | 22 +- .../tests/fixtures/share_encryption.vk | Bin 0 -> 1888 bytes .../tests/fixtures/sk_share_computation.json | 18 +- .../tests/fixtures/sk_share_computation.vk | Bin 3680 -> 1888 bytes .../tests/fixtures/sk_share_encryption.json | 228 ------------------ .../tests/fixtures/sk_share_encryption.vk | Bin 3680 -> 0 bytes .../fixtures/threshold_share_decryption.json | 145 ----------- .../fixtures/threshold_share_decryption.vk | Bin 3680 -> 0 bytes .../tests/fixtures/user_data_encryption.json | 214 ++++++++++++++++ .../tests/fixtures/user_data_encryption.vk | Bin 0 -> 1888 bytes crates/zk-prover/tests/local_e2e_tests.rs | 155 ++---------- 35 files changed, 621 insertions(+), 761 deletions(-) delete mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation.vk create mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.json create mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk rename crates/zk-prover/tests/fixtures/{decrypted_shares_aggregation.json => decrypted_shares_aggregation_mod.json} (99%) create mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk delete mode 100644 crates/zk-prover/tests/fixtures/dkg_e_sm_share_decryption.json delete mode 100644 crates/zk-prover/tests/fixtures/dkg_e_sm_share_decryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.json delete mode 100644 crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/e_sm_share_encryption.vk create mode 100644 crates/zk-prover/tests/fixtures/share_decryption.json create mode 100644 crates/zk-prover/tests/fixtures/share_decryption.vk rename crates/zk-prover/tests/fixtures/{e_sm_share_encryption.json => share_encryption.json} (84%) create mode 100644 crates/zk-prover/tests/fixtures/share_encryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/sk_share_encryption.json delete mode 100644 crates/zk-prover/tests/fixtures/sk_share_encryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/threshold_share_decryption.json delete mode 100644 crates/zk-prover/tests/fixtures/threshold_share_decryption.vk create mode 100644 crates/zk-prover/tests/fixtures/user_data_encryption.json create mode 100644 crates/zk-prover/tests/fixtures/user_data_encryption.vk diff --git a/crates/events/src/enclave_event/proof.rs b/crates/events/src/enclave_event/proof.rs index 48cc967cee..625cd09a38 100644 --- a/crates/events/src/enclave_event/proof.rs +++ b/crates/events/src/enclave_event/proof.rs @@ -44,20 +44,20 @@ pub enum CircuitName { SkShareComputation, /// E_SM share computation proof (C2b). ESmShareComputation, - /// Encrypted sk share proof (C3a). - SkShareEncryption, - /// Encrypted E_SM share proof (C3b). - ESmShareEncryption, - /// Sk share decryption proof (C4a). - DkgSkShareDecryption, - /// E_SM share decryption proof (C4b). - DkgESmShareDecryption, + /// Share encryption proof (C3). + ShareEncryption, + /// DKG share decryption proof (C4). + DkgShareDecryption, /// Public key aggregation proof (C5). PkAggregation, /// Decryption share proof (C6). ThresholdShareDecryption, - /// Decrypted shares aggregation proof (C7). - DecryptedSharesAggregation, + /// Decrypted shares aggregation proof — BigNum variant (C7a). + DecryptedSharesAggregationBn, + /// Decrypted shares aggregation proof — Modular variant (C7b). + DecryptedSharesAggregationMod, + /// User data encryption proof. + UserDataEncryption, } impl CircuitName { @@ -67,13 +67,13 @@ impl CircuitName { CircuitName::PkGeneration => "pk_generation", CircuitName::SkShareComputation => "sk_share_computation", CircuitName::ESmShareComputation => "e_sm_share_computation", - CircuitName::SkShareEncryption => "sk_share_encryption", - CircuitName::ESmShareEncryption => "e_sm_share_encryption", - CircuitName::DkgSkShareDecryption => "dkg_sk_share_decryption", - CircuitName::DkgESmShareDecryption => "dkg_e_sm_share_decryption", + CircuitName::ShareEncryption => "share_encryption", + CircuitName::DkgShareDecryption => "share_decryption", CircuitName::PkAggregation => "pk_aggregation", - CircuitName::ThresholdShareDecryption => "threshold_share_decryption", - CircuitName::DecryptedSharesAggregation => "decrypted_shares_aggregation", + CircuitName::ThresholdShareDecryption => "share_decryption", + CircuitName::DecryptedSharesAggregationBn => "decrypted_shares_aggregation_bn", + CircuitName::DecryptedSharesAggregationMod => "decrypted_shares_aggregation_mod", + CircuitName::UserDataEncryption => "user_data_encryption", } } @@ -82,14 +82,14 @@ impl CircuitName { CircuitName::PkBfv => "dkg", CircuitName::SkShareComputation => "dkg", CircuitName::ESmShareComputation => "dkg", - CircuitName::SkShareEncryption => "dkg", - CircuitName::ESmShareEncryption => "dkg", - CircuitName::DkgSkShareDecryption => "dkg", - CircuitName::DkgESmShareDecryption => "dkg", + CircuitName::ShareEncryption => "dkg", + CircuitName::DkgShareDecryption => "dkg", CircuitName::PkGeneration => "threshold", CircuitName::ThresholdShareDecryption => "threshold", CircuitName::PkAggregation => "threshold", - CircuitName::DecryptedSharesAggregation => "threshold", + CircuitName::DecryptedSharesAggregationBn => "threshold", + CircuitName::DecryptedSharesAggregationMod => "threshold", + CircuitName::UserDataEncryption => "threshold", } } diff --git a/crates/events/src/enclave_event/signed_proof.rs b/crates/events/src/enclave_event/signed_proof.rs index 554b98e0cd..6748429bac 100644 --- a/crates/events/src/enclave_event/signed_proof.rs +++ b/crates/events/src/enclave_event/signed_proof.rs @@ -37,18 +37,14 @@ pub enum ProofType { T1SkShareComputation = 2, /// T1 — Smudging noise share computation proof (Proof 2b). T1ESmShareComputation = 3, - /// T1 — Secret key share encryption proof (Proof 3a). - T1SkShareEncryption = 4, - /// T1 — Smudging noise share encryption proof (Proof 3b). - T1ESmShareEncryption = 5, - /// T2 — Secret key share decryption proof (Proof 4a). - T2SkShareDecryption = 6, - /// T2 — Smudging noise share decryption proof (Proof 4b). - T2ESmShareDecryption = 7, - /// T5 — Share decryption proof (Proof 6). - T5ShareDecryption = 8, + /// T1 — Share encryption proof (Proof 3). + T1ShareEncryption = 4, + /// T2 — DKG share decryption proof (Proof 4). + T2DkgShareDecryption = 5, + /// T5 — Threshold share decryption proof (Proof 6). + T5ShareDecryption = 6, /// T6 — Decrypted shares aggregation proof (Proof 7). - T6DecryptedSharesAggregation = 9, + T6DecryptedSharesAggregation = 7, } impl ProofType { @@ -59,12 +55,10 @@ impl ProofType { ProofType::T1PkGeneration => CircuitName::PkGeneration, ProofType::T1SkShareComputation => CircuitName::SkShareComputation, ProofType::T1ESmShareComputation => CircuitName::ESmShareComputation, - ProofType::T1SkShareEncryption => CircuitName::SkShareEncryption, - ProofType::T1ESmShareEncryption => CircuitName::ESmShareEncryption, - ProofType::T2SkShareDecryption => CircuitName::DkgSkShareDecryption, - ProofType::T2ESmShareDecryption => CircuitName::DkgESmShareDecryption, + ProofType::T1ShareEncryption => CircuitName::ShareEncryption, + ProofType::T2DkgShareDecryption => CircuitName::DkgShareDecryption, ProofType::T5ShareDecryption => CircuitName::ThresholdShareDecryption, - ProofType::T6DecryptedSharesAggregation => CircuitName::DecryptedSharesAggregation, + ProofType::T6DecryptedSharesAggregation => CircuitName::DecryptedSharesAggregationBn, } } @@ -75,10 +69,8 @@ impl ProofType { | ProofType::T1PkGeneration | ProofType::T1SkShareComputation | ProofType::T1ESmShareComputation - | ProofType::T1SkShareEncryption - | ProofType::T1ESmShareEncryption - | ProofType::T2SkShareDecryption - | ProofType::T2ESmShareDecryption => "E3_BAD_DKG_PROOF", + | ProofType::T1ShareEncryption + | ProofType::T2DkgShareDecryption => "E3_BAD_DKG_PROOF", ProofType::T5ShareDecryption => "E3_BAD_DECRYPTION_PROOF", ProofType::T6DecryptedSharesAggregation => "E3_BAD_AGGREGATION_PROOF", } @@ -307,12 +299,12 @@ mod tests { CircuitName::PkGeneration ); assert_eq!( - ProofType::T1SkShareEncryption.circuit_name(), - CircuitName::SkShareEncryption + ProofType::T1ShareEncryption.circuit_name(), + CircuitName::ShareEncryption ); assert_eq!( - ProofType::T2SkShareDecryption.circuit_name(), - CircuitName::DkgSkShareDecryption + ProofType::T2DkgShareDecryption.circuit_name(), + CircuitName::DkgShareDecryption ); assert_eq!( ProofType::T5ShareDecryption.circuit_name(), diff --git a/crates/zk-prover/src/circuits/dkg/share_decryption.rs b/crates/zk-prover/src/circuits/dkg/share_decryption.rs index 3778385085..8641aa9147 100644 --- a/crates/zk-prover/src/circuits/dkg/share_decryption.rs +++ b/crates/zk-prover/src/circuits/dkg/share_decryption.rs @@ -7,7 +7,6 @@ use crate::traits::Provable; use e3_events::CircuitName; use e3_fhe_params::BfvPreset; -use e3_zk_helpers::computation::DkgInputType; use e3_zk_helpers::dkg::share_decryption::{ Inputs, ShareDecryptionCircuit, ShareDecryptionCircuitData, }; @@ -17,21 +16,7 @@ impl Provable for ShareDecryptionCircuit { type Input = ShareDecryptionCircuitData; type Inputs = Inputs; - fn resolve_circuit_name(&self, input: &Self::Input) -> CircuitName { - match input.dkg_input_type { - DkgInputType::SecretKey => CircuitName::DkgSkShareDecryption, - DkgInputType::SmudgingNoise => CircuitName::DkgESmShareDecryption, - } - } - - fn valid_circuits(&self) -> Vec { - vec![ - CircuitName::DkgSkShareDecryption, - CircuitName::DkgESmShareDecryption, - ] - } - fn circuit(&self) -> CircuitName { - CircuitName::DkgSkShareDecryption + CircuitName::DkgShareDecryption } } diff --git a/crates/zk-prover/src/circuits/dkg/share_encryption.rs b/crates/zk-prover/src/circuits/dkg/share_encryption.rs index 1608a9d4df..ad206b8d87 100644 --- a/crates/zk-prover/src/circuits/dkg/share_encryption.rs +++ b/crates/zk-prover/src/circuits/dkg/share_encryption.rs @@ -7,7 +7,6 @@ use crate::traits::Provable; use e3_events::CircuitName; use e3_fhe_params::BfvPreset; -use e3_zk_helpers::computation::DkgInputType; use e3_zk_helpers::dkg::share_encryption::{ Inputs, ShareEncryptionCircuit, ShareEncryptionCircuitData, }; @@ -17,21 +16,7 @@ impl Provable for ShareEncryptionCircuit { type Input = ShareEncryptionCircuitData; type Inputs = Inputs; - fn resolve_circuit_name(&self, _input: &Self::Input) -> CircuitName { - match _input.dkg_input_type { - DkgInputType::SecretKey => CircuitName::SkShareEncryption, - DkgInputType::SmudgingNoise => CircuitName::ESmShareEncryption, - } - } - - fn valid_circuits(&self) -> Vec { - vec![ - CircuitName::SkShareEncryption, - CircuitName::ESmShareEncryption, - ] - } - fn circuit(&self) -> CircuitName { - CircuitName::SkShareEncryption + CircuitName::ShareEncryption } } diff --git a/crates/zk-prover/src/circuits/threshold/decrypted_shares_aggregation.rs b/crates/zk-prover/src/circuits/threshold/decrypted_shares_aggregation.rs index 6cf3e3d2f8..189d3baa6c 100644 --- a/crates/zk-prover/src/circuits/threshold/decrypted_shares_aggregation.rs +++ b/crates/zk-prover/src/circuits/threshold/decrypted_shares_aggregation.rs @@ -18,6 +18,13 @@ impl Provable for DecryptedSharesAggregationCircuit { type Inputs = Inputs; fn circuit(&self) -> CircuitName { - CircuitName::DecryptedSharesAggregation + CircuitName::DecryptedSharesAggregationBn + } + + fn valid_circuits(&self) -> Vec { + vec![ + CircuitName::DecryptedSharesAggregationBn, + CircuitName::DecryptedSharesAggregationMod, + ] } } diff --git a/crates/zk-prover/src/circuits/utils.rs b/crates/zk-prover/src/circuits/utils.rs index 2464a52cc1..e19828d95c 100644 --- a/crates/zk-prover/src/circuits/utils.rs +++ b/crates/zk-prover/src/circuits/utils.rs @@ -32,6 +32,16 @@ fn json_value_to_input_value(v: &serde_json::Value) -> Result9|!PfESaIPjhSmrc7{T^vS(@JQlez55u+rRl(Ah!Ws4|c#zkn-q9|Tt zrYy<5SF($lqE&AAT}zf0y67i&?w@_<_3EDg&UrtdbI$8I=lP!RLFl`i+;za(r@o&~hzsgp{^7M$grDb$TlfF`PF<0iWbw3qKrp%~a~F4L8Ut zj9dy_uq)QOJR7PiL3ud$Y)wHRaEYkipqv$#_EvI`c9~hUcQ|l_4`tg1j$Zb?elBJaxNB+qu1V#lt4}u^ zSy)WDtGpXHLO70(Sd^(xviH>JJaxzexP;we@)yx9A^yImPt9)SYaarRkW})B%0fWC zZ*fKU8L{bWz%MyRTxrukIO*1B?|j{{E=m_TLL&CZ@cg->y-s0jPjJJhfMX`!dQ(*k z_441~#PmMO(29X0wBFCu$gspwc|~UCgeOS{`1yc&`K}7lY1z`(^aNsWvjK2~jP5pz zow^{U*)T!Hw9MB4Z=r=$UJ&oFsmnTNtQnh$$cY|8`t1&x;6LRJ-gK$)NLDRBO~ zQ;jyLKI>RJ<;v`TM=|j^CX_c;Z!F9;Z*`ryhwFc0rV2bZyCZ)7B;GKMwqPA1_wa{y z;0O`zto(yKOz4OAy)3O?JpsJ6s@-ClL2b;W*5ZS6WRHmfM@VO|YUiqb9-n&d{N5*r zB!DLmZK|DkCUWm6YoT+Y>bKqdfFq;1<{@ElD`}M_e*ke)%GN9UHi6m}gRf zd6$UVI?I&)6zc=<{DSL0usHu|w}xFmuaX)0;WWr=efh&+@}k^qt zx#t7Rj7O6e0=FkW^GX9=-pnzyY#KRJD6_APgz|fgfD6`tfp%%z&C9C{x^$n!C28Qk zs_up}50xajr49>ppGlH7aD=3%l*kmc&Y6Tn{8vS}HYUp-rV_wsIw3DL+ zaD*g|q<3`Dm&0!FA+X;wxWFTLpL9Q*IG9|Sn&KxG$;;Ub93dH^ed0;UkI&T$9>pX^ zrUTzEZDStOl}NJ*%nnSf9?0kfE~q~;p^n5FG}iftFoSBfj9 zk|Krjdb%FGZf8T$>T&ko?ye%>buW9DsY5k6T`oL=1h;TD7|gC6ASClICbmPU;6RI_jGl) zZq(8W#|q^oxg*%)G}`H^rc&vQ{CePKwDp!=HW#UrH}miN{k)|IejgChwqI99z0as z$jW)oojHJ6DlZ3~(5hfJYVV*qx?|pt5N{%y3|z2&QyL!pSu*VVcwo&ogC$4c$M;5D zC9reuam`2yvgG&YgzGO#PGe4Blx#bF+1!M*9*~zA&P-nD4*pZ&;qSrizAINJOW}Lyk*5OrBq@~Jdu75i$wL%wxOEzS8__GEX7_ zzW+Bca$I|RDZ{QUBW!Fyo@<;?p5UEieR2O8jMYn`*3Z}bfWKS`?wZPVb8?T)`IYb{ z`{6U-g8t2guanuJj?Zz9uJPIS2DttVuVO4b6<@;GI!xKEdhjuD!S93Z8f${&Fo*6~ zL+K~_1J5^MlE-)W*pkv;bh{$Dg%@yybcvd+*nE?NVXFo7AO=IozdZo|kG|Fa-V^!n zA>WKRePety>q@;thP;Mo9B)UkaQ~&!HA8)Wi&e~#+J`lkTmMZOp-mTRr&zh(ZT$-- cHEtq0Bt_r|=?_j1=zZ [T; N] {\n /// Returns the length of this array.\n ///\n /// ```noir\n /// fn len(self) -> Field\n /// ```\n ///\n /// example\n ///\n /// ```noir\n /// fn main() {\n /// let array = [42, 42];\n /// assert(array.len() == 2);\n /// }\n /// ```\n #[builtin(array_len)]\n pub fn len(self) -> u32 {}\n\n /// Returns this array as a slice.\n ///\n /// ```noir\n /// let array = [1, 2];\n /// let slice = array.as_slice();\n /// assert_eq(slice, &[1, 2]);\n /// ```\n #[builtin(as_slice)]\n pub fn as_slice(self) -> [T] {}\n\n /// Applies a function to each element of this array, returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.map(|a| a * 2);\n /// assert_eq(b, [2, 4, 6]);\n /// ```\n pub fn map(self, f: fn[Env](T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array along with its index,\n /// returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.mapi(|i, a| i + a * 2);\n /// assert_eq(b, [2, 5, 8]);\n /// ```\n pub fn mapi(self, f: fn[Env](u32, T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(i, self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// let mut i = 0;\n /// a.for_each(|x| {\n /// b[i] = x;\n /// i += 1;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_each(self, f: fn[Env](T) -> ()) {\n for i in 0..self.len() {\n f(self[i]);\n }\n }\n\n /// Applies a function to each element of this array along with its index.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// a.for_eachi(|i, x| {\n /// b[i] = x;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_eachi(self, f: fn[Env](u32, T) -> ()) {\n for i in 0..self.len() {\n f(i, self[i]);\n }\n }\n\n /// Applies a function to each element of the array, returning the final accumulated value. The first\n /// parameter is the initial value.\n ///\n /// This is a left fold, so the given function will be applied to the accumulator and first element of\n /// the array, then the second, and so on. For a given call the expected result would be equivalent to:\n ///\n /// ```rust\n /// let a1 = [1];\n /// let a2 = [1, 2];\n /// let a3 = [1, 2, 3];\n ///\n /// let f = |a, b| a - b;\n /// a1.fold(10, f); //=> f(10, 1)\n /// a2.fold(10, f); //=> f(f(10, 1), 2)\n /// a3.fold(10, f); //=> f(f(f(10, 1), 2), 3)\n ///\n /// assert_eq(a3.fold(10, f), 10 - 1 - 2 - 3);\n /// ```\n pub fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U {\n for elem in self {\n accumulator = f(accumulator, elem);\n }\n accumulator\n }\n\n /// Same as fold, but uses the first element as the starting element.\n ///\n /// Requires the input array to be non-empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [1, 2, 3, 4];\n /// let reduced = arr.reduce(|a, b| a + b);\n /// assert(reduced == 10);\n /// }\n /// ```\n pub fn reduce(self, f: fn[Env](T, T) -> T) -> T {\n let mut accumulator = self[0];\n for i in 1..self.len() {\n accumulator = f(accumulator, self[i]);\n }\n accumulator\n }\n\n /// Returns true if all the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 2];\n /// let all = arr.all(|a| a == 2);\n /// assert(all);\n /// }\n /// ```\n pub fn all(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = true;\n for elem in self {\n ret &= predicate(elem);\n }\n ret\n }\n\n /// Returns true if any of the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 5];\n /// let any = arr.any(|a| a == 5);\n /// assert(any);\n /// }\n /// ```\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n for elem in self {\n ret |= predicate(elem);\n }\n ret\n }\n\n /// Concatenates this array with another array.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr1 = [1, 2, 3, 4];\n /// let arr2 = [6, 7, 8, 9, 10, 11];\n /// let concatenated_arr = arr1.concat(arr2);\n /// assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n /// }\n /// ```\n pub fn concat(self, array2: [T; M]) -> [T; N + M] {\n let mut result = [crate::mem::zeroed(); N + M];\n for i in 0..N {\n result[i] = self[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n }\n}\n\nimpl [T; N]\nwhere\n T: Ord + Eq,\n{\n /// Returns a new sorted array. The original array remains untouched. Notice that this function will\n /// only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting\n /// logic it uses internally is optimized specifically for these values. If you need a sort function to\n /// sort any type, you should use the `sort_via` function.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32];\n /// let sorted = arr.sort();\n /// assert(sorted == [32, 42]);\n /// }\n /// ```\n pub fn sort(self) -> Self {\n self.sort_via(|a, b| a <= b)\n }\n}\n\nimpl [T; N]\nwhere\n T: Eq,\n{\n /// Returns a new sorted array by sorting it with a custom comparison function.\n /// The original array remains untouched.\n /// The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument.\n ///\n /// Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32]\n /// let sorted_ascending = arr.sort_via(|a, b| a <= b);\n /// assert(sorted_ascending == [32, 42]); // verifies\n ///\n /// let sorted_descending = arr.sort_via(|a, b| a >= b);\n /// assert(sorted_descending == [32, 42]); // does not verify\n /// }\n /// ```\n pub fn sort_via(self, ordering: fn[Env](T, T) -> bool) -> Self {\n // Safety: `sorted` array is checked to be:\n // a. a permutation of `input`'s elements\n // b. satisfying the predicate `ordering`\n let sorted = unsafe { quicksort::quicksort(self, ordering) };\n\n if !is_unconstrained() {\n for i in 0..N - 1 {\n assert(\n ordering(sorted[i], sorted[i + 1]),\n \"Array has not been sorted correctly according to `ordering`.\",\n );\n }\n check_shuffle::check_shuffle(self, sorted);\n }\n sorted\n }\n}\n\nimpl [u8; N] {\n /// Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation -\n /// the given array is interpreted as-is as a string.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let hi = [104, 105].as_str_unchecked();\n /// assert_eq(hi, \"hi\");\n /// }\n /// ```\n #[builtin(array_as_str_unchecked)]\n pub fn as_str_unchecked(self) -> str {}\n}\n\nimpl From> for [u8; N] {\n /// Returns an array of the string bytes.\n fn from(s: str) -> Self {\n s.as_bytes()\n }\n}\n\nmod test {\n #[test]\n fn map_empty() {\n assert_eq([].map(|x| x + 1), []);\n }\n\n global arr_with_100_values: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2, 54,\n 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41, 19, 98,\n 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21, 43, 86, 35,\n 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15, 127, 81, 30, 8,\n 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n global expected_with_100_values: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30, 32,\n 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58, 61, 62,\n 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82, 84, 84, 86,\n 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114, 114, 116, 118,\n 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n fn sort_u32(a: u32, b: u32) -> bool {\n a <= b\n }\n\n #[test]\n fn test_sort() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort();\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort();\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values_comptime() {\n let sorted = arr_with_100_values.sort();\n assert(sorted == expected_with_100_values);\n }\n\n #[test]\n fn test_sort_via() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_via_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn mapi_empty() {\n assert_eq([].mapi(|i, x| i * x + 1), []);\n }\n\n #[test]\n fn for_each_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_each(|_x| assert(false));\n }\n\n #[test]\n fn for_eachi_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_eachi(|_i, _x| assert(false));\n }\n\n #[test]\n fn map_example() {\n let a = [1, 2, 3];\n let b = a.map(|a| a * 2);\n assert_eq(b, [2, 4, 6]);\n }\n\n #[test]\n fn mapi_example() {\n let a = [1, 2, 3];\n let b = a.mapi(|i, a| i + a * 2);\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn for_each_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n let mut i = 0;\n let i_ref = &mut i;\n a.for_each(|x| {\n b_ref[*i_ref] = x * 2;\n *i_ref += 1;\n });\n assert_eq(b, [2, 4, 6]);\n assert_eq(i, 3);\n }\n\n #[test]\n fn for_eachi_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n a.for_eachi(|i, a| { b_ref[i] = i + a * 2; });\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn concat() {\n let arr1 = [1, 2, 3, 4];\n let arr2 = [6, 7, 8, 9, 10, 11];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n }\n\n #[test]\n fn concat_zero_length_with_something() {\n let arr1 = [];\n let arr2 = [1];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_something_with_zero_length() {\n let arr1 = [1];\n let arr2 = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_zero_lengths() {\n let arr1: [Field; 0] = [];\n let arr2: [Field; 0] = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, []);\n }\n}\n", + "path": "std/array/mod.nr" + }, + "5": { + "source": "use crate::meta::derive_via;\n\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for u1 {\n fn eq(self, other: u1) -> bool {\n self == other\n }\n}\n\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl Eq for str {\n fn eq(self, other: str) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\nimpl Eq for (A, B)\nwhere\n A: Eq,\n B: Eq,\n{\n fn eq(self, other: (A, B)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1)\n }\n}\n\nimpl Eq for (A, B, C)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n{\n fn eq(self, other: (A, B, C)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2)\n }\n}\n\nimpl Eq for (A, B, C, D)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n D: Eq,\n{\n fn eq(self, other: (A, B, C, D)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2) & self.3.eq(other.3)\n }\n}\n\nimpl Eq for (A, B, C, D, E)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n D: Eq,\n E: Eq,\n{\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n self.0.eq(other.0)\n & self.1.eq(other.1)\n & self.2.eq(other.2)\n & self.3.eq(other.3)\n & self.4.eq(other.4)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\nimpl Ord for (A, B)\nwhere\n A: Ord,\n B: Ord,\n{\n fn cmp(self, other: (A, B)) -> Ordering {\n let result = self.0.cmp(other.0);\n\n if result != Ordering::equal() {\n result\n } else {\n self.1.cmp(other.1)\n }\n }\n}\n\nimpl Ord for (A, B, C)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n{\n fn cmp(self, other: (A, B, C)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n result\n }\n}\n\nimpl Ord for (A, B, C, D)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n D: Ord,\n{\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n if result == Ordering::equal() {\n result = self.3.cmp(other.3);\n }\n\n result\n }\n}\n\nimpl Ord for (A, B, C, D, E)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n D: Ord,\n E: Ord,\n{\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n if result == Ordering::equal() {\n result = self.3.cmp(other.3);\n }\n\n if result == Ordering::equal() {\n result = self.4.cmp(other.4);\n }\n\n result\n }\n}\n\n// Compares and returns the maximum of two values.\n//\n// Returns the second argument if the comparison determines them to be equal.\n//\n// # Examples\n//\n// ```\n// use std::cmp;\n//\n// assert_eq(cmp::max(1, 2), 2);\n// assert_eq(cmp::max(2, 2), 2);\n// ```\npub fn max(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n// Compares and returns the minimum of two values.\n//\n// Returns the first argument if the comparison determines them to be equal.\n//\n// # Examples\n//\n// ```\n// use std::cmp;\n//\n// assert_eq(cmp::min(1, 2), 1);\n// assert_eq(cmp::min(2, 2), 2);\n// ```\npub fn min(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use super::{Eq, max, min, Ord};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_slices() {\n let slice_1 = &[0, 1, 2, 3];\n let slice_2 = &[0, 1, 2];\n assert(!slice_1.eq(slice_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_slices() {\n assert(&[2_u32].cmp(&[1_u32, 1_u32, 1_u32]) == super::Ordering::greater());\n assert(&[1_u32, 2_u32].cmp(&[1_u32, 2_u32, 3_u32]) == super::Ordering::less());\n }\n}\n", + "path": "std/cmp.nr" + }, + "17": { + "source": "use crate::field::field_less_than;\nuse crate::runtime::is_unconstrained;\n\n// The low and high decomposition of the field modulus\nglobal PLO: Field = 53438638232309528389504892708671455233;\nglobal PHI: Field = 64323764613183177041862057485226039389;\n\npub(crate) global TWO_POW_128: Field = 0x100000000000000000000000000000000;\n\n// Decomposes a single field into two 16 byte fields.\nfn compute_decomposition(x: Field) -> (Field, Field) {\n // Here's we're taking advantage of truncating 128 bit limbs from the input field\n // and then subtracting them from the input such the field division is equivalent to integer division.\n let low = (x as u128) as Field;\n let high = (x - low) / TWO_POW_128;\n\n (low, high)\n}\n\npub(crate) unconstrained fn decompose_hint(x: Field) -> (Field, Field) {\n compute_decomposition(x)\n}\n\nunconstrained fn lte_hint(x: Field, y: Field) -> bool {\n if x == y {\n true\n } else {\n field_less_than(x, y)\n }\n}\n\n// Assert that (alo > blo && ahi >= bhi) || (alo <= blo && ahi > bhi)\nfn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) {\n let (alo, ahi) = a;\n let (blo, bhi) = b;\n // Safety: borrow is enforced to be boolean due to its type.\n // if borrow is 0, it asserts that (alo > blo && ahi >= bhi)\n // if borrow is 1, it asserts that (alo <= blo && ahi > bhi)\n unsafe {\n let borrow = lte_hint(alo, blo);\n\n let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128;\n let rhi = ahi - bhi - (borrow as Field);\n\n rlo.assert_max_bit_size::<128>();\n rhi.assert_max_bit_size::<128>();\n }\n}\n\n/// Decompose a single field into two 16 byte fields.\npub fn decompose(x: Field) -> (Field, Field) {\n if is_unconstrained() {\n compute_decomposition(x)\n } else {\n // Safety: decomposition is properly checked below\n unsafe {\n // Take hints of the decomposition\n let (xlo, xhi) = decompose_hint(x);\n\n // Range check the limbs\n xlo.assert_max_bit_size::<128>();\n xhi.assert_max_bit_size::<128>();\n\n // Check that the decomposition is correct\n assert_eq(x, xlo + TWO_POW_128 * xhi);\n\n // Assert that the decomposition of P is greater than the decomposition of x\n assert_gt_limbs((PLO, PHI), (xlo, xhi));\n (xlo, xhi)\n }\n }\n}\n\npub fn assert_gt(a: Field, b: Field) {\n if is_unconstrained() {\n assert(\n // Safety: already unconstrained\n unsafe { field_less_than(b, a) },\n );\n } else {\n // Decompose a and b\n let a_limbs = decompose(a);\n let b_limbs = decompose(b);\n\n // Assert that a_limbs is greater than b_limbs\n assert_gt_limbs(a_limbs, b_limbs)\n }\n}\n\npub fn assert_lt(a: Field, b: Field) {\n assert_gt(b, a);\n}\n\npub fn gt(a: Field, b: Field) -> bool {\n if is_unconstrained() {\n // Safety: unsafe in unconstrained\n unsafe {\n field_less_than(b, a)\n }\n } else if a == b {\n false\n } else {\n // Safety: Take a hint of the comparison and verify it\n unsafe {\n if field_less_than(a, b) {\n assert_gt(b, a);\n false\n } else {\n assert_gt(a, b);\n true\n }\n }\n }\n}\n\npub fn lt(a: Field, b: Field) -> bool {\n gt(b, a)\n}\n\nmod tests {\n // TODO: Allow imports from \"super\"\n use crate::field::bn254::{assert_gt, decompose, gt, lt, lte_hint, PHI, PLO, TWO_POW_128};\n\n #[test]\n fn check_decompose() {\n assert_eq(decompose(TWO_POW_128), (0, 1));\n assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1));\n assert_eq(decompose(0x1234567890), (0x1234567890, 0));\n }\n\n #[test]\n unconstrained fn check_lte_hint() {\n assert(lte_hint(0, 1));\n assert(lte_hint(0, 0x100));\n assert(lte_hint(0x100, TWO_POW_128 - 1));\n assert(!lte_hint(0 - 1, 0));\n\n assert(lte_hint(0, 0));\n assert(lte_hint(0x100, 0x100));\n assert(lte_hint(0 - 1, 0 - 1));\n }\n\n #[test]\n fn check_gt() {\n assert(gt(1, 0));\n assert(gt(0x100, 0));\n assert(gt((0 - 1), (0 - 2)));\n assert(gt(TWO_POW_128, 0));\n assert(!gt(0, 0));\n assert(!gt(0, 0x100));\n assert(gt(0 - 1, 0 - 2));\n assert(!gt(0 - 2, 0 - 1));\n assert_gt(0 - 1, 0);\n }\n\n #[test]\n fn check_plo_phi() {\n assert_eq(PLO + PHI * TWO_POW_128, 0);\n let p_bytes = crate::field::modulus_le_bytes();\n let mut p_low: Field = 0;\n let mut p_high: Field = 0;\n\n let mut offset = 1;\n for i in 0..16 {\n p_low += (p_bytes[i] as Field) * offset;\n p_high += (p_bytes[i + 16] as Field) * offset;\n offset *= 256;\n }\n assert_eq(p_low, PLO);\n assert_eq(p_high, PHI);\n }\n\n #[test]\n fn check_decompose_edge_cases() {\n assert_eq(decompose(0), (0, 0));\n assert_eq(decompose(TWO_POW_128 - 1), (TWO_POW_128 - 1, 0));\n assert_eq(decompose(TWO_POW_128 + 1), (1, 1));\n assert_eq(decompose(TWO_POW_128 * 2), (0, 2));\n assert_eq(decompose(TWO_POW_128 * 2 + 0x1234567890), (0x1234567890, 2));\n }\n\n #[test]\n fn check_decompose_large_values() {\n let large_field = 0xffffffffffffffff;\n let (lo, hi) = decompose(large_field);\n assert_eq(large_field, lo + TWO_POW_128 * hi);\n\n let large_value = large_field - TWO_POW_128;\n let (lo2, hi2) = decompose(large_value);\n assert_eq(large_value, lo2 + TWO_POW_128 * hi2);\n }\n\n #[test]\n fn check_lt_comprehensive() {\n assert(lt(0, 1));\n assert(!lt(1, 0));\n assert(!lt(0, 0));\n assert(!lt(42, 42));\n\n assert(lt(TWO_POW_128 - 1, TWO_POW_128));\n assert(!lt(TWO_POW_128, TWO_POW_128 - 1));\n }\n}\n", + "path": "std/field/bn254.nr" + }, + "18": { + "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", + "path": "std/field/mod.nr" + }, + "39": { + "source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for u1 {\n fn add(self, other: u1) -> u1 {\n self + other\n }\n}\n\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for u1 {\n fn sub(self, other: u1) -> u1 {\n self - other\n }\n}\n\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for u1 {\n fn mul(self, other: u1) -> u1 {\n self * other\n }\n}\n\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for u1 {\n fn div(self, other: u1) -> u1 {\n self / other\n }\n}\n\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for u1 {\n fn rem(self, other: u1) -> u1 {\n self % other\n }\n}\n\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u1 {\n fn wrapping_add(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u1 {\n fn wrapping_sub(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u1 {\n fn wrapping_mul(self: u1, y: u1) -> u1 {\n self & y\n }\n}\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp(x: T, y: T) -> T\nwhere\n T: AsPrimitive,\n Field: AsPrimitive,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp(x: T, y: T) -> Field\nwhere\n T: AsPrimitive,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp(x: T, y: T) -> T\nwhere\n T: AsPrimitive,\n Field: AsPrimitive,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem\n assert_eq(17.rem(5), 2);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder\n assert_eq(42.rem(42), 0);\n assert_eq(0.rem(42), 0);\n assert_eq(1.rem(42), 1);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n #[test]\n fn test_u1_behavior() {\n // u1 wrapping add is XOR\n assert_eq(0u1.wrapping_add(0u1), 0u1);\n assert_eq(0u1.wrapping_add(1u1), 1u1);\n assert_eq(1u1.wrapping_add(0u1), 1u1);\n assert_eq(1u1.wrapping_add(1u1), 0u1);\n\n // u1 wrapping sub is XOR\n assert_eq(0u1.wrapping_sub(0u1), 0u1);\n assert_eq(0u1.wrapping_sub(1u1), 1u1);\n assert_eq(1u1.wrapping_sub(0u1), 1u1);\n assert_eq(1u1.wrapping_sub(1u1), 0u1);\n\n // u1 wrapping mul is AND\n assert_eq(0u1.wrapping_mul(0u1), 0u1);\n assert_eq(0u1.wrapping_mul(1u1), 0u1);\n assert_eq(1u1.wrapping_mul(0u1), 0u1);\n assert_eq(1u1.wrapping_mul(1u1), 1u1);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n}\n", + "path": "std/ops/arith.nr" + }, + "50": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::{MAX_MSG_NON_ZERO_COEFFS, T};\nuse lib::configs::default::threshold::{\n DECRYPTED_SHARES_AGGREGATION_BIT_NOISE, DECRYPTED_SHARES_AGGREGATION_CONFIGS, L,\n};\nuse lib::core::threshold::decrypted_shares_aggregation::DecryptedSharesAggregationBigNum;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n decryption_shares: pub [[Polynomial; L]; T + 1],\n party_ids: pub [Field; T + 1],\n message: pub Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n) {\n let decrypted_shares_aggregation: DecryptedSharesAggregationBigNum = DecryptedSharesAggregationBigNum::new(\n DECRYPTED_SHARES_AGGREGATION_CONFIGS,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n );\n\n decrypted_shares_aggregation.execute();\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/decrypted_shares_aggregation_bn/src/main.nr" + }, + "67": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\nuse dep::bignum::BigNum;\nuse dep::bignum::bignum::to_field;\nuse dep::bignum::SecureThreshold8192;\n\n/// Cryptographic parameters for decryption share aggregation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Plaintext modulus (typically denoted as `t`)\n pub plaintext_modulus: Field,\n /// Precomputed value: `-Q^(-1) mod t` where Q is the product of all CRT moduli\n pub q_inverse_mod_t: Field,\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], plaintext_modulus: Field, q_inverse_mod_t: Field) -> Self {\n Configs { qis, plaintext_modulus, q_inverse_mod_t }\n }\n}\n\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using BigNum\n/// for large Q values.\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationBigNum {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using modular arithmetic\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationModular {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n\nimpl DecryptedSharesAggregationBigNum {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationBigNum {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Verifies decoding using BigNum for large Q values\n fn verify_decoding(self) {\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1 as Field;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_bn = SecureThreshold8192::from(q_modulus);\n\n let q_half_bn = q_bn.udiv(SecureThreshold8192::from(2));\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let u_bn = SecureThreshold8192::from(self.u_global.coefficients[coeff_idx]);\n let t_bn = SecureThreshold8192::from(self.configs.plaintext_modulus);\n let u_bn_mod_q = u_bn.umod(q_bn);\n let t_bn_mod_q = t_bn.umod(q_bn);\n let t_times_u_bn_q = (t_bn_mod_q * u_bn_mod_q).umod(q_bn);\n\n let m = ModU128::new(self.configs.plaintext_modulus);\n\n // Check if centering is needed\n let needs_centering = t_times_u_bn_q > q_half_bn;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_bn - t_times_u_bn_q;\n let centered_positive_mod_t = centered_positive.umod(t_bn);\n let centered_field = to_field(centered_positive_mod_t);\n m.mul_mod(self.configs.q_inverse_mod_t, centered_field)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_bn_t = t_times_u_bn_q.umod(t_bn);\n let t_times_u_field = to_field(t_times_u_bn_t);\n let product = m.mul_mod(self.configs.q_inverse_mod_t, t_times_u_field);\n if product == 0 {\n 0\n } else {\n self.configs.plaintext_modulus - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\nimpl DecryptedSharesAggregationModular {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationModular {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Alternative verification function using efficient modular arithmetic without BigNum.\n ///\n /// Uses `ModU128` for decoding verification instead of BigNum. More efficient when\n /// Q (the product of all CRT moduli) fits within u128 (e.g., 72 bits for insecure parameter sets).\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Alternative decoding verification using the formula:\n /// message = -Q^{-1} * (t * u_global)_Q mod t\n fn verify_decoding(self) {\n let t: Field = self.configs.plaintext_modulus;\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_half = q_modulus as u128 / 2;\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let q_mod = ModU128::new(q_modulus);\n let t_mod = ModU128::new(t);\n\n // Compute (t * u_global) mod Q using modular arithmetic functions\n let t_times_u_mod_q = q_mod.mul_mod(t, self.u_global.coefficients[coeff_idx]);\n let needs_centering = (t_times_u_mod_q as u128) > q_half;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_modulus - t_times_u_mod_q;\n let centered_positive_mod_t = t_mod.reduce_mod(centered_positive);\n\n t_mod.mul_mod(self.configs.q_inverse_mod_t, centered_positive_mod_t)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_mod_t = t_mod.reduce_mod(t_times_u_mod_q);\n let product = t_mod.mul_mod(self.configs.q_inverse_mod_t, t_times_u_mod_t);\n if product == 0 {\n 0\n } else {\n t - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\n/// Computes all Lagrange coefficients using optimized modular arithmetic\npub fn compute_all_lagrange_coeffs(\n qis: [Field; L],\n party_ids: [Field; T + 1],\n) -> [[Field; T + 1]; L] {\n let mut lagrange_coeffs = [[0 as Field; T + 1]; L];\n\n // Step 1: Cache |x_i - x_j| factors for all party pairs\n let mut diffs = [[0 as Field; T + 1]; T + 1];\n for i in 0..(T + 1) {\n for j in (i + 1)..(T + 1) {\n let diff = party_ids[j] - party_ids[i];\n diffs[i][j] = diff;\n diffs[j][i] = diff;\n }\n }\n\n // Step 2: Determine signs (same for all parties within a basis)\n let numerator_sign_negative = (T % 2) == 1;\n\n // Step 3: For each CRT basis, compute Lagrange coefficients\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n\n // Compute product of all party IDs: PRODUCT(j=0..T) x_j mod q_l\n let mut product_x = 1 as Field;\n for j in 0..(T + 1) {\n product_x = m.mul_mod(product_x, party_ids[j]);\n }\n\n // For each party i, compute L_i(0) mod q_l\n for party_idx in 0..(T + 1) {\n // Numerator (absolute value): PRODUCT(j!=party_idx) x_j\n let numerator_abs = m.div_mod(product_x, party_ids[party_idx]);\n\n // Denominator (absolute value): PRODUCT(j!=party_idx) |x_party_idx - x_j|\n let mut denominator_abs = 1 as Field;\n for j in 0..(T + 1) {\n if j != party_idx {\n denominator_abs = m.mul_mod(denominator_abs, diffs[party_idx][j]);\n }\n }\n\n // Determine denominator sign\n let num_greater = T - party_idx;\n let denom_sign_negative = (num_greater % 2) == 1;\n\n // Compute unsigned result: |numerator| / |denominator| mod q_l\n let result_abs = m.div_mod(numerator_abs, denominator_abs);\n\n // Apply combined sign\n let should_negate = numerator_sign_negative != denom_sign_negative;\n let result = if should_negate {\n m.reduce_mod(q_l - result_abs)\n } else {\n result_abs\n };\n\n lagrange_coeffs[basis_idx][party_idx] = result;\n }\n }\n\n lagrange_coeffs\n}\n\n/// Computes u^{(l)} for each CRT basis via Lagrange interpolation\npub fn compute_crt_components(\n qis: [Field; L],\n decryption_shares: [[Polynomial; L]; T + 1],\n lagrange_coeffs: [[Field; T + 1]; L],\n) -> [Polynomial; L] {\n let mut u_crts: [Polynomial; L] =\n [Polynomial::new([0; MAX_MSG_NON_ZERO_COEFFS]); L];\n\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n let mut u_coeffs = [0 as Field; MAX_MSG_NON_ZERO_COEFFS];\n\n // For each coefficient position\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n let mut u_coeff = 0 as Field;\n\n // Sum all contributions: u = SUM(i=0..T) [d_i * L_i(0)] mod q_l\n for party_idx in 0..(T + 1) {\n let d_coeff = decryption_shares[party_idx][basis_idx].coefficients[coeff_idx];\n let l_i_0 = lagrange_coeffs[basis_idx][party_idx];\n\n let term = m.mul_mod(d_coeff, l_i_0);\n u_coeff = m.reduce_mod(u_coeff + term);\n }\n\n u_coeffs[coeff_idx] = u_coeff;\n }\n\n u_crts[basis_idx] = Polynomial::new(u_coeffs);\n }\n\n u_crts\n}\n\n/// Verifies CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global for all bases l\npub fn verify_crt_reconstruction(\n qis: [Field; L],\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n u_crts: [Polynomial; L],\n) {\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n\n // Compute r^{(l)} * q_l\n let r_times_q = crt_quotients[basis_idx].mul_scalar(q_l);\n\n // Compute u^{(l)} + r^{(l)} * q_l\n let reconstructed = u_crts[basis_idx].add(r_times_q);\n\n // Verify: u^{(l)} + r^{(l)} * q_l = u_global\n // Must hold for every coefficient\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n assert(\n reconstructed.coefficients[coeff_idx] == u_global.coefficients[coeff_idx],\n \"CRT reconstruction verification failed\",\n );\n }\n }\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/decrypted_shares_aggregation.nr" + }, + "77": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" + }, + "79": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + }, + "84": { + "source": "use crate::fns::constrained_ops::limbs_to_field;\nuse crate::params::BigNumParams;\nuse std::ops::{Add, Div, Mul, Neg, Sub};\n\npub trait BigNum: Neg + Add + Sub + Mul + Div + Eq {\n let N: u32;\n let MOD_BITS: u32;\n\n fn params() -> BigNumParams;\n fn modulus_bits(_: Self) -> u32;\n fn num_limbs(_: Self) -> u32;\n fn modulus() -> Self;\n\n fn new() -> Self;\n fn zero() -> Self;\n fn one() -> Self;\n fn from_limbs(limbs: [u128; N]) -> Self;\n fn get_limbs(self) -> [u128; N];\n fn set_limb(self: &mut Self, idx: u32, value: u128);\n fn derive_from_seed(seed: [u8; SeedBytes]) -> Self;\n unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self;\n fn from_be_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self;\n fn to_be_bytes(self) -> [u8; (MOD_BITS + 7) / 8];\n fn from_le_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self;\n fn to_le_bytes(self) -> [u8; (MOD_BITS + 7) / 8];\n\n fn get_limb(self: Self, idx: u32) -> u128 {\n self.get_limbs()[idx]\n }\n\n unconstrained fn __eq(self: Self, other: Self) -> bool;\n\n unconstrained fn __is_zero(self: Self) -> bool;\n\n unconstrained fn __neg(self) -> Self;\n unconstrained fn __add(self, other: Self) -> Self;\n unconstrained fn __sub(self, other: Self) -> Self;\n unconstrained fn __mul(self, other: Self) -> Self;\n unconstrained fn __sqr(self) -> Self;\n unconstrained fn __div(self, other: Self) -> Self;\n unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self);\n unconstrained fn __invmod(self) -> Self;\n unconstrained fn __pow(self, exponent: Self) -> Self;\n\n unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option;\n unconstrained fn __sqrt(self) -> std::option::Option;\n\n fn assert_is_not_equal(self: Self, other: Self);\n\n fn validate_in_range(self);\n fn validate_in_field(self);\n\n fn sqr(self) -> Self;\n\n fn udiv_mod(self, divisor: Self) -> (Self, Self);\n fn udiv(self, divisor: Self) -> Self;\n fn umod(self, divisor: Self) -> Self;\n\n fn is_zero(self) -> bool;\n fn is_zero_integer(self) -> bool;\n fn assert_is_not_zero(self);\n fn assert_is_not_zero_integer(self);\n}\n\n// we need macros that implement the BigNum, Default, From, Neg, Add, Sub, Mul, Div, Eq, Ord traits for each bignum type\npub comptime fn derive_bignum(\n strukt: TypeDefinition,\n N: u32,\n MOD_BITS: u32,\n params: Quoted,\n) -> Quoted {\n let constrained_ops = quote { $crate::fns::constrained_ops };\n let unconstrained_ops = quote { $crate::fns::unconstrained_ops };\n let typ = strukt.as_type();\n let serialization = quote { $crate::fns::serialization };\n quote {\n\n // implement BigNum for BigNum \n impl $crate::BigNum for $typ {\n let N: u32 = $N; \n let MOD_BITS: u32 = $MOD_BITS;\n \n fn modulus_bits(_: Self) -> u32 {\n $MOD_BITS\n }\n \n fn num_limbs(_: Self) -> u32 {\n $N\n }\n\n fn modulus() -> Self {\n Self { limbs: Self::params().modulus }\n }\n\n fn new() -> Self {\n Self {limbs: [0; $N]}\n }\n\n fn params() -> $crate::params::BigNumParams<$N, $MOD_BITS> {\n $params\n }\n\n fn from_limbs(limbs: [u128; $N]) -> Self {\n Self { limbs }\n }\n\n fn get_limbs(self: Self) -> [u128; $N] {\n self.limbs\n }\n\n fn set_limb(self: &mut Self, idx: u32, value: u128) {\n self.limbs[idx] = value;\n }\n\n fn zero() -> Self {\n Self { limbs: [0; $N] }\n }\n\n fn one() -> Self {\n let mut limbs = [0; $N];\n limbs[0] = 1;\n Self { limbs }\n }\n\n fn derive_from_seed(seed: [u8; SeedBytes]) -> Self {\n let params = Self::params();\n $typ::from_limbs($constrained_ops::derive_from_seed::<_, $MOD_BITS, _>(params, seed))\n }\n\n unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self {\n let params = Self::params();\n Self { limbs: $unconstrained_ops::__derive_from_seed::<_, $MOD_BITS, _>(params, seed) }\n }\n\n fn from_be_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self {\n Self { limbs: $serialization::from_be_bytes::<_, $MOD_BITS>(x) }\n }\n \n fn to_be_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] {\n $serialization::to_be_bytes::<_, $MOD_BITS>(self.limbs)\n }\n\n fn from_le_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self {\n Self { limbs: $serialization::from_le_bytes::<_, $MOD_BITS>(x) }\n }\n\n fn to_le_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] {\n $serialization::to_le_bytes::<_, $MOD_BITS>(self.limbs)\n }\n\n unconstrained fn __eq(self: Self, other: Self) -> bool {\n $crate::fns::unconstrained_ops::__eq(self.get_limbs(), other.get_limbs())\n }\n\n unconstrained fn __is_zero(self: Self) -> bool {\n $crate::fns::unconstrained_ops::__is_zero(self.get_limbs())\n }\n\n unconstrained fn __neg(self: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__neg(params.modulus, self.get_limbs())}\n }\n\n unconstrained fn __add(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__add(params.modulus, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __sub(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__sub(params.modulus, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __mul(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__mul(params, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __sqr(self: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__sqr(params, self.get_limbs()) }\n }\n\n unconstrained fn __div(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__div(params, self.get_limbs(), divisor.get_limbs())}\n }\n\n unconstrained fn __udiv_mod(self: Self, divisor: Self) -> (Self, Self) {\n let (q, r) = $unconstrained_ops::__udiv_mod(self.get_limbs(), divisor.get_limbs());\n (Self{limbs: q}, Self{limbs: r})\n }\n\n unconstrained fn __invmod(self: Self) -> Self {\n let params = Self::params();\n assert(params.has_multiplicative_inverse);\n Self {limbs: $unconstrained_ops::__invmod(params, self.get_limbs())}\n }\n\n unconstrained fn __pow(self: Self, exponent: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__pow(params, self.get_limbs(), exponent.get_limbs())}\n }\n\n #[deprecated(\"use __sqrt\")]\n unconstrained fn __tonelli_shanks_sqrt(self: Self) -> std::option::Option {\n let params = Self::params();\n let maybe_limbs = $unconstrained_ops::__sqrt(params, self.get_limbs());\n maybe_limbs.map(|limbs| Self {limbs: limbs})\n }\n\n unconstrained fn __sqrt(self: Self) -> std::option::Option {\n let params = Self::params();\n let maybe_limbs = $unconstrained_ops::__sqrt(params, self.get_limbs());\n maybe_limbs.map(|limbs| Self {limbs: limbs })\n }\n\n fn assert_is_not_equal(self: Self, other: Self) {\n let params = Self::params();\n $crate::fns::constrained_ops::assert_is_not_equal(\n params,\n self.get_limbs(),\n other.get_limbs(),\n );\n }\n\n fn validate_in_field(self: Self) {\n let params = Self::params();\n $constrained_ops::validate_in_field::<_, $MOD_BITS>(params, self.get_limbs());\n }\n\n fn validate_in_range(self: Self) {\n $constrained_ops::validate_in_range::<_, _, $MOD_BITS>(self.get_limbs());\n }\n\n fn sqr(self: Self) -> Self {\n let params = Self::params();\n Self { limbs: $constrained_ops::sqr::<$N, $MOD_BITS>(params, self.get_limbs()) }\n }\n\n fn udiv_mod(self: Self, divisor: Self) -> (Self, Self) {\n let (q, r) = $constrained_ops::udiv_mod::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs());\n (Self {limbs: q}, Self {limbs: r})\n }\n\n fn udiv(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $constrained_ops::udiv::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs())}\n }\n\n fn umod(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $constrained_ops::umod::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs())}\n }\n\n fn is_zero(self: Self) -> bool {\n let params = Self::params();\n $constrained_ops::is_zero::<$N, $MOD_BITS>(params, self.get_limbs())\n }\n\n fn is_zero_integer(self: Self) -> bool {\n $constrained_ops::is_zero_integer(self.get_limbs())\n }\n\n fn assert_is_not_zero(self: Self) {\n let params = Self::params();\n $constrained_ops::assert_is_not_zero::<$N, $MOD_BITS>(params, self.get_limbs());\n }\n\n fn assert_is_not_zero_integer(self: Self) {\n $constrained_ops::assert_is_not_zero_integer(self.get_limbs());\n }\n }\n\n // implement Default for BigNum\n impl Default for $typ {\n fn default() -> Self {\n $typ::from_limbs([0; $N])\n }\n }\n\n impl std::convert::From for $typ {\n fn from(input: Field) -> Self {\n $typ { limbs: $constrained_ops::from_field::<$N, $MOD_BITS>($params, input) }\n }\n }\n\n impl std::ops::Neg for $typ {\n fn neg(self) -> Self {\n $typ { limbs: $constrained_ops::neg::<$N, $MOD_BITS>($params, self.limbs) }\n }\n }\n\n impl std::ops::Add for $typ {\n fn add(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::add::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Sub for $typ {\n fn sub(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::sub::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Mul for $typ {\n fn mul(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::mul::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Div for $typ {\n fn div(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::div::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::cmp::Eq for $typ {\n fn eq(self, other: Self) -> bool {\n $constrained_ops::eq::<$N, $MOD_BITS>($params, self.limbs, other.limbs)\n }\n }\n\n impl std::cmp::Ord for $typ {\n fn cmp(self, other: Self) -> std::cmp::Ordering {\n $constrained_ops::cmp::<$N, $MOD_BITS>(self.limbs, other.limbs)\n }\n }\n\n }\n}\n\npub fn conditional_select(lhs: T, rhs: T, predicate: bool) -> T {\n if predicate {\n lhs\n } else {\n rhs\n }\n}\n\npub unconstrained fn compute_quadratic_expression(\n lhs_terms: [[T; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[T; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [T; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> (T, T) {\n let params = T::params();\n let (q_limbs, r_limbs) = crate::fns::expressions::__compute_quadratic_expression(\n params,\n crate::utils::map::map(\n lhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n lhs_flags,\n crate::utils::map::map(\n rhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n rhs_flags,\n crate::utils::map::map(linear_terms, |bn: T| bn.get_limbs()),\n linear_flags,\n );\n (T::from_limbs(q_limbs), T::from_limbs(r_limbs))\n}\n\npub fn evaluate_quadratic_expression(\n lhs_terms: [[T; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[T; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [T; ADD_N],\n linear_flags: [bool; ADD_N],\n) {\n let params = T::params();\n crate::fns::expressions::evaluate_quadratic_expression(\n params,\n crate::utils::map::map(\n lhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n lhs_flags,\n crate::utils::map::map(\n rhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n rhs_flags,\n crate::utils::map::map(linear_terms, |bn: T| bn.get_limbs()),\n linear_flags,\n )\n}\n\npub unconstrained fn batch_invert(x: [T; M]) -> [T; M] {\n let params = T::params();\n assert(params.has_multiplicative_inverse);\n crate::fns::unconstrained_ops::batch_invert(params, x.map(|bn: T| bn.get_limbs())).map(|limbs| {\n T::from_limbs(limbs)\n })\n}\n\npub unconstrained fn batch_invert_slice(x: [T]) -> [T] {\n let params = T::params();\n assert(params.has_multiplicative_inverse);\n crate::fns::unconstrained_ops::batch_invert_slice(params, x.map(|bn: T| bn.get_limbs()))\n .map(|limbs| T::from_limbs(limbs))\n}\n\npub fn to_field(bn: T) -> Field {\n let params = T::params();\n limbs_to_field(params, bn.get_limbs())\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/bignum.nr" + }, + "120": { + "source": "use crate::constants::{GRUMPKIN_MODULUS, TWO_POW_120, TWO_POW_240};\n\nuse crate::fns::{\n expressions::{evaluate_quadratic_expression, validate_udiv_mod_expression},\n unconstrained_helpers::{\n __add_with_flags, __from_field, __neg_with_flags, __sub_with_flags,\n __validate_gte_with_flags, __validate_in_field_compute_borrow_flags,\n },\n unconstrained_ops::{__add, __div, __mul, __neg, __sqr, __sub, __udiv_mod},\n};\n\nuse crate::params::BigNumParams;\n\nuse std::cmp::Ordering;\n\n/// Lift the limbs of a `BigNum` value onto the circuit `Field`\n///\n/// Descent the `BigNum` value back into the `Field` and\n/// - check that it's a proper `BigNum` value\n/// - validate the limbs sum up to a `Field` value\npub(crate) fn limbs_to_field(\n _params: BigNumParams,\n limbs: [u128; N],\n) -> Field {\n validate_in_range::(limbs);\n if N > 2 {\n // validate that the `BigNum` is less than the Grumpkin modulus\n let mut grumpkin_modulus: [u128; N] = [0; N];\n grumpkin_modulus[0] = GRUMPKIN_MODULUS[0];\n grumpkin_modulus[1] = GRUMPKIN_MODULUS[1];\n grumpkin_modulus[2] = GRUMPKIN_MODULUS[2];\n validate_gt::(grumpkin_modulus, limbs);\n }\n\n if N < 2 {\n limbs[0] as Field\n } else if N == 2 {\n (limbs[0] as Field) + (limbs[1] as Field) * (TWO_POW_120 as Field)\n } else {\n (limbs[0] as Field)\n + (limbs[1] as Field) * (TWO_POW_120 as Field)\n + (limbs[2] as Field) * TWO_POW_240\n }\n}\n\n/// Construct a `BigNum` value from a native `Field`\n///\n/// Decomposes the `Field` value into 120-bit limbs\n/// then we have three cases:\n/// - MOD_BITS < 253 (grumpkin_mod_bits - 1): it is enough to call for `validate_in_field`, which is basically `val <= MOD`\n/// - MOD_BITS > 253: we need to verify that the obtained `BigNum` `val < GRUMPKIN_MODULUS`\n/// - MOD_BITS = 253: verify that `val < min(MOD, GRUMPKIN_MODULUS)`\n/// Next we verify that all the limbs are properly ranged\n/// and that the accumulated limbs are equal to the input `Field` value\npub(crate) fn from_field(\n _params: BigNumParams,\n val: Field,\n) -> [u128; N] {\n // Safety: we check that the resulting limbs represent the intended field element\n // we check the bit length, the limbs being max 120 bits, and the value in total is less than the field modulus\n let result: [u128; N] = unsafe { __from_field::(val) };\n\n if !std::runtime::is_unconstrained() {\n // validate the limbs are in range and the value in total is less than 2^254\n if MOD_BITS < 253 {\n // this means that the field modulus is smaller than grumpkin modulus so we have to check if the element fields in the field size\n validate_in_field(_params, result);\n } else {\n let mut grumpkin_modulus: [u128; N] = [0; N];\n grumpkin_modulus[0] = GRUMPKIN_MODULUS[0];\n grumpkin_modulus[1] = GRUMPKIN_MODULUS[1];\n grumpkin_modulus[2] = GRUMPKIN_MODULUS[2];\n\n if MOD_BITS > 253 {\n // this means that the field modulus is larger than grumpkin modulus so we have to check if the element fields in the field size are less than the grumpkin modulus.\n // also for correct params N is always larger than 3 here\n validate_gt::(grumpkin_modulus, result);\n } else {\n // this is the tricky part, when MOD_BITS = 253, we have to compare the limbs of the modulus to the grumpkin modulus limbs\n // any `BigNum` with 253 bits will have 3 limbs\n\n // if MOD is less than grumpkin modulus, this will be true\n let mut mod_lt_grumpkin: bool = false;\n for i in 0..3 {\n if !mod_lt_grumpkin & (_params.modulus[2 - i] < grumpkin_modulus[2 - i]) {\n mod_lt_grumpkin = true;\n }\n }\n let min_modulus: [u128; N] = if mod_lt_grumpkin {\n _params.modulus\n } else {\n grumpkin_modulus\n };\n validate_gt::(min_modulus, result);\n }\n }\n validate_in_range::(result);\n\n // validate the limbs sum up to the field value\n let field_val: Field = if N < 2 {\n result[0] as Field\n } else if N == 2 {\n (result[0] as Field) + (result[1] as Field) * (TWO_POW_120 as Field)\n } else {\n (result[0] as Field)\n + (result[1] as Field) * (TWO_POW_120 as Field)\n + (result[2] as Field) * TWO_POW_240\n };\n assert_eq(field_val, val);\n }\n\n result\n}\n\n/// Given an input seed, generate a pseudorandom `BigNum` value\n///\n/// This function *should* produce a uniformly randomly distributed value modulo `MOD`\n///\n/// First we take the seed and pack it's 31-byte chunks into `Field`s\n/// We use a hash function that can be modelled as a random oracle\n/// We hash the packed seed using Poseidon2 to produce `MOD_BITS * 2` bits of entropy\n///\n/// From these bits we construct 4(in case N = 2) or 3(N > 2) `BigNum` values:\n/// - We fill first `N - 1` limbs and leave the top limb empty\n///\n/// Then we accumulate the resulting BigNum values using:\n/// B = 2^{120 * (N - 1)}\n/// res = x3 + B * x2 + B^2 * x1 + B^3 * x0\n///\n/// ## Note\n/// This function will always produce an `x3` `BigNum`\n/// If `MOD = 2^{120 * (N - 1)}`\n/// It will use only `MOD_BITS - 1` bits of entropy\npub(crate) fn derive_from_seed(\n params: BigNumParams,\n seed: [u8; SeedBytes],\n) -> [u128; N] {\n // Pack seed bytes into Fields.\n // For the seed of length M, we construct a rolling_hash_field of size ceil(M / 31).\n // i.e. 31 bytes per Field\n // NOTE: the Fields produced are 248 bits in size\n let mut rolling_hash_fields: [Field; (SeedBytes + 30) / 31] = [0; (SeedBytes + 30) / 31];\n let mut seed_ptr: u32 = 0;\n for i in 0..(SeedBytes + 30) / 31 {\n let mut packed: Field = 0;\n for _ in 0..31 {\n if (seed_ptr < SeedBytes) {\n packed *= 256;\n packed += seed[seed_ptr] as Field;\n seed_ptr += 1;\n }\n }\n rolling_hash_fields[i] = packed;\n }\n\n let compressed: Field =\n poseidon::poseidon2::Poseidon2::hash(rolling_hash_fields, (SeedBytes + 30) / 31);\n let mut rolling_hash: [Field; 2] = [compressed, 0];\n\n // 120 bit limb has 15 bytes in it\n // we buffer (N * 15) * 2 bytes for 2N limbs\n let mut hash_buffer: [u8; N * 15 * 2] = [0; N * 15 * 2];\n\n // We produce 32 bytes (254 bits) per hash iteration\n // We take only 30 bytes, so we need ceil(N * 2 * 15 / 30) hashes to fill them up\n for i in 0..N {\n let hash: Field = poseidon::poseidon2::Poseidon2::hash(rolling_hash, 2);\n let hash: [u8; 32] = hash.to_le_bytes();\n for j in 0..30 {\n hash_buffer[i * 30 + j] = hash[j];\n }\n rolling_hash[1] += 1;\n }\n\n let num_bits: u32 = MOD_BITS * 2;\n let num_bytes: u32 = (num_bits + 7) / 8;\n\n // Truncate the final byte that will be used in `BigNum` creation\n let bits_in_last_byte: u8 = (num_bits as u8) % 8;\n if bits_in_last_byte != 0 {\n let last_byte_mask: u8 = ((1 as u8) << bits_in_last_byte) - 1;\n hash_buffer[num_bytes - 1] &= last_byte_mask;\n }\n\n let num_bigfield_chunks: u32 = if N == 2 { 4 } else { 3 };\n let mut byte_ptr: u32 = 0;\n\n // We want to convert our hash_buffer into bigfield chunks, with each `BigNum` having at most N - 1 limbs filled\n // We sample only N - 1 limbs mostly because we do not wont to deal with accidental overflows in the top limb\n // In any case the security is preserved\n //\n // For all integer values N > 1, the number of chunks is either 4(for N = 2) or 3(for N > 2) (ceil(2*N / (N - 1)))\n //\n // To determine the exact number of chunks, we need the `!=` or `>` operator which is not available when defining array sizes\n // so we overestimate at 4\n // e.g. if N = 20, then we have 40 limbs we want to reduce, but each bigfield chunk is 19 limbs, so we need 3\n // if N = 2, we have 4 limbs we want to reduce but each bigfield chunk is only 1 limb, so we need 4\n let mut bigfield_chunks: [[u128; N]; 4] = [[0; N]; 4];\n\n for k in 0..num_bigfield_chunks {\n let mut bigfield_limbs: [u128; N] = [0; N];\n\n // Before the current limb, we filled out (N - 1) limbs, k times\n // 15 bytes per limb\n // resulting in total of 15 * k * (N - 1)\n let mut num_filled_bytes: u32 = 15 * k * (N - 1);\n if num_bytes > num_filled_bytes {\n // Static assert for completeness\n assert(num_filled_bytes == byte_ptr);\n\n let mut num_remaining_bytes_to_sample: u32 = num_bytes - num_filled_bytes;\n let mut num_remaining_limbs_to_sample: u32 = (num_remaining_bytes_to_sample + 14) / 15;\n\n // Sample at most (N - 1) limbs from hash_buffer\n let mut num_limbs_to_sample: u32 = if num_remaining_limbs_to_sample > (N - 1) {\n N - 1\n } else {\n num_remaining_limbs_to_sample\n };\n\n for j in 0..num_limbs_to_sample {\n let mut limb: Field = 0;\n // Construct a 120 bit limb\n for _ in 0..15 {\n if byte_ptr < num_bytes {\n let mut byte: u8 = hash_buffer[byte_ptr];\n limb *= 256;\n limb += byte as Field;\n byte_ptr += 1;\n }\n }\n // crucial for performance\n limb.assert_max_bit_size::<120>();\n // Accumulate limbs from top to bottom\n bigfield_limbs[num_limbs_to_sample - 1 - j] = limb as u128;\n }\n // Accumulate `BigNum` values from top to bottom\n bigfield_chunks[num_bigfield_chunks - 1 - k] = bigfield_limbs;\n }\n }\n\n // B = 2^{120 * (N - 1)}, we know it is \\leq `MOD`, since the top limb\n // have to be at least one\n let mut bigfield_rhs_limbs: [u128; N] = [0; N];\n bigfield_rhs_limbs[N - 1] = 1;\n\n let mut result: [u128; N] = bigfield_chunks[0];\n\n for i in 1..num_bigfield_chunks {\n result = mul(params, result, bigfield_rhs_limbs);\n result = add(params, result, bigfield_chunks[i]);\n }\n\n result\n}\n\n// ------------------------------ COMPARISON FUNCTIONS ------------------------------\n\n/// Validate lhs != rhs\n///\n/// We compare `A` and `B` via their encodings in the circuit `Field`\n///\n/// Under our range assumptions, equality in `Field` implies equality of the underlying\n/// `BigNum` values, hence equality (mod `MOD`)\n///\n/// In this library it is possible that A or B is a little bit greater than `MOD`\n/// So A == B (mod `MOD`) implies that A == B, A == B + MOD or A == B - MOD over the integers\n/// Hence we can compute everything (mod p) and constrain that\n/// (A - B) * (A - B + MOD) * (A - B - MOD) != 0 (mod p)\n///\n/// ## Soundness\n/// This method is *sound* for checking `A != B (mod MOD)`\n///\n/// If `A == B (mod MOD)`, then `A - B` is in `{0, +-MOD}` as an integer,\n/// so one of the factors `A-B`, `A-B+MOD`, `A-B-MOD` is zero in `Field`, and the product is zero\n/// Therefore, whenever the assertion `target != 0` holds, we must have `A != B (mod MOD)`\n/// under our range assumptions\n///\n/// ## Completeness\n/// In general, this method is not *complete*: if the admissible range of `A` and `B`\n/// is large enough relative to the circuit `Field` prime `p`, an honest prover with\n/// `A != B (mod MOD)` can still hit an alias where\n/// (A - B) * (A - B + MOD) * (A - B - MOD) == 0 (mod p),\n/// i.e.\n/// - A = B (mod p), or\n/// - A = B + MOD (mod p), or\n/// - A = B - MOD (mod p).\n///\n/// For random `A, B` in such a wide range, the probability of this collision is\n/// roughly 3/p.\n///\n/// In case `MOD` < `p` this function becomes *complete*\npub(crate) fn assert_is_not_equal(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) {\n let mut l: Field = 0;\n let mut r: Field = 0;\n let mut modulus_mod_p: Field = 0;\n for i in 0..N {\n l *= TWO_POW_120 as Field;\n r *= TWO_POW_120 as Field;\n modulus_mod_p *= TWO_POW_120 as Field;\n\n l += lhs[N - i - 1] as Field;\n r += rhs[N - i - 1] as Field;\n modulus_mod_p += params.modulus[N - i - 1] as Field;\n }\n\n let diff: Field = l - r;\n let target: Field = diff * (diff + modulus_mod_p) * (diff - modulus_mod_p);\n assert(target != 0, \"assert_is_not_equal fail\");\n}\n\n/// Compute equality flag\n///\n/// A == B (mod MOD)\n/// We compute A - B and check whether it is `0` or `MOD`\n/// This is due to subtract constrains the diff value to be < 2^MOD_BITS, not < `MOD`\n///\n/// ## Soundness\n/// This function is conditionally *sound*. See `sub` for details\n///\n/// ## Completeness\n/// This function is *complete*. An honest prover will always be able to execute it.\n///\n/// ## TODO\n/// can do this more efficiently via witngen in unconstrained functions?\npub(crate) fn eq(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> bool {\n let diff: [u128; N] = sub::(params, lhs, rhs);\n is_zero::(params, diff)\n}\n\n/// Validate that `val` is not equal to zero when interpreted as an integer.\n///\n/// This enforces that at least one limb of `val` is non-zero.\n/// It does *not* check \"BigNum zero\" in the modular sense (e.g. it\n/// treats `MOD` as non-zero).\n///\n/// ## Assumptions\n/// * Each limb of `val` is range-constrained to be a 120-bit value:\n/// `0 <= val[i] < 2^120`.\n/// * For our concrete fields and limb counts we have `N * 2^120 < p`,\n/// so the sum of all limbs fits strictly inside the field modulus.\n///\n/// ## Completeness\n/// If `val` is non-zero as an integer, then at least one limb is non-zero,\n/// so the integer sum of the limbs satisfies `0 < limb_sum < p`. In this\n/// case `limb_sum != 0` in the `Field`, and the assertion passes.\n///\n/// ## Soundness\n/// If all limbs of `val` are zero, then `limb_sum` is zero as an integer\n/// and as a field element, so the assertion fails. A witness representing\n/// the zero integer can never satisfy this check.\n///\n/// ## Note\n/// This is slightly cheaper than doing `val != [0; N]`, as we avoid\n/// creating per-limb boolean equalities and chaining them with `and`s.\npub(crate) fn assert_is_not_zero_integer(val: [u128; N]) {\n let mut limb_sum: Field = 0;\n for i in 0..N {\n limb_sum += val[i] as Field;\n }\n assert(limb_sum != 0, \"assert_is_not_zero_integer fail\");\n}\n\n/// Check whether `val` is the zero `BigNum` in the integer sense.\n///\n/// This returns `true` iff all limbs of `val` are zero. It does *not*\n/// treat `MOD` as zero; for modular `BigNum` zero use `is_zero`.\n///\n/// See `assert_is_not_zero_integer` for the underlying assumptions.\n///\n/// ## Note\n/// This is slightly cheaper than testing `val == [0; N]`, as we avoid\n/// creating per-limb boolean equalities and chaining them with `and`s.\npub(crate) fn is_zero_integer(val: [u128; N]) -> bool {\n let mut limb_sum: Field = 0;\n for i in 0..N {\n limb_sum += val[i] as Field;\n }\n limb_sum == 0\n}\n\n/// Validate that a `BigNum` value is not zero modulo `MOD`.\n///\n/// Convenience wrapper around `assert_is_not_equal`.\npub(crate) fn assert_is_not_zero(\n params: BigNumParams,\n val: [u128; N],\n) {\n assert_is_not_equal::(params, val, [0; N]);\n}\n\n/// Check whether a `BigNum` value is zero modulo `MOD`.\n///\n/// This treats both the all-zero limb vector and `params.modulus` as\n/// representing zero. It assumes that all valid `BigNum` values are\n/// range-constrained so that no other representatives of `0 (mod MOD)`\n/// can appear.\n///\n/// ## Note\n/// This is cheaper than calling `eq(val, [0; N])`\npub(crate) fn is_zero(\n params: BigNumParams,\n val: [u128; N],\n) -> bool {\n is_zero_integer(val) | (val == params.modulus)\n}\n\n/// Validate a `BigNum` instance is correctly range constrained to contain no more than `MOD_BITS` bits\n///\n/// Constrain the `BigNum` instance to be < 2^MOD_BITS by:\n/// - Constraining each limb(0..N-2) to be 120-bit limb\n/// - Constraining the last limb to be `MOD_BITS - 120 * (N - 1)`\n///\n/// ## Note\n/// This can be a very expensive function, when the `TOP_LIMB_BITS` is uncommon\n///\n/// For example: BLS12_377Fr, with `TOP_LIMB_BITS`=13\n/// It creates a new 13-bit range table, which consists of roughly 3k variables\n/// And ~2k circuit gates\n///\n/// Compare this to BLS12_377Fq, with `TOP_LIMB_BITS`=17\n/// It is nicely decomposed into\n/// 14-bit range check and 3-bit range check - much much cheaper, since 14-bit range checks\n/// are already pretty common for 120-bit range checks\npub(crate) fn validate_in_range(limbs: [T; N])\nwhere\n T: Into,\n{\n for i in 0..(N - 1) {\n limbs[i].into().assert_max_bit_size::<120>();\n }\n\n limbs[N - 1].into().assert_max_bit_size::();\n}\n\n/// Validate quotient produced from `evaluate_quadratic_expression` is well-formed\n///\n/// Because the inputs into `evaluate_quadratic_expression` may cause the quotient to extend beyond `Params::modulus_bits`.\n/// We allow the quotient to extend `6` bits beyond `Params::modulus_bits()`\n/// Why is this?\n/// several factors: 1. quotient * modulus , limbs cannot overflow `Field` boundary (254 bits)\n/// 2. in `evaluate_quadratic_expression`, we require that for `expression - quotient * modulus`,\n/// limbs cannot exceed `246` bits (246 magic number due to a higher number adding extra range check gates)\n/// because of factor 2 and the fact that modulus limbs are 120 bits, quotient limbs cannot be > 126 bits\npub(crate) fn validate_quotient_in_range(limbs: [u128; N]) {\n for i in 0..(N - 1) {\n (limbs[i] as Field).assert_max_bit_size::<120>();\n }\n (limbs[N - 1] as Field).assert_max_bit_size::();\n}\n\n/// Validate that `lhs - rhs` does not underflow i.e. that lhs > rhs over the integers\n///\n/// Compute `result = lhs - rhs` along with `borrow_flags`,\n/// then constrain `result` to be a valid `BigNum` value.\n///\n/// ## Completeness\n/// This function is complete and will work only if `lhs > rhs` over the integers.\n///\n/// ## Soundness\n/// This function is sound:\n/// result[0] = lhs[0] - rhs[0] + bf[0] * 2^{120} < 2^{120}\n/// result[i] = lhs[i] - rhs[i] + bf[i] * 2^{120} - bf[i - 1] < 2^{120}, i = 1..N-2\n/// result[N - 1] = lhs[N - 1] - rhs[N - 1] - bf[N - 2] < 2^{TOP_LIMB_BITS}\n/// result != 0\n///\n/// If `lhs < rhs`, then some limb of `result` would have to borrow from a higher limb,\n/// which is impossible because the top limb cannot borrow\n/// Without the extra borrow, the resulting difference will be wrapped around the `Field` modulus\n/// And won't satisfy the range constraint, since all the limbs are < 2^120\n///\n/// ## Note\n/// `assert_is_not_zero_integer(result)` is crucial. Without it, we could always provide\n/// two identical inputs `x`, `x` and set `borrow_flags = [false; N]`,\n/// which would satisfy the limb constraints.\n///\n/// Also note that `underflow` is not properly constrained, so it just hangs there for\n/// completeness\npub(crate) fn validate_gt(lhs: [u128; N], rhs: [u128; N]) {\n // Safety: compute borrow flags out-of-circuit\n let (underflow, result, borrow_flags): (bool, [u128; N], [bool; N - 1]) =\n unsafe { __validate_gte_with_flags(lhs, rhs) };\n\n // Completeness: require that no underflow occurred\n assert(!underflow, \"validate_gt fail\");\n\n // Constrain the `result` to be a valid `BigNum` value\n validate_in_range::(result);\n // Constrain it to be strict inequality\n assert_is_not_zero_integer(result);\n\n // Constrain `result` and `borrow_flags` to match the expected arithmetic\n check_gte_with_flags(lhs, rhs, result, borrow_flags);\n}\n\n/// Constraining function for the results of `__validate_gte_with_flags`,\n/// used by both `cmp` and `validate gt`\n///\n/// This function checks the relations between `lhs`, `rhs`, `result` adn `borrow_flags`:\n/// lhs[0] - rhs[0] - result[0] + bf[0] * 2^{120} = 0\n/// lhs[i] - rhs[i] - result[i] + bf[i] * 2^{120} - bf[i - 1] = 0, i = 1..N-2\n/// lhs[N - 1] - rhs[N - 1] - result[N - 1] - bf[N - 2] = 0\npub(crate) fn check_gte_with_flags(\n lhs: [u128; N],\n rhs: [u128; N],\n result: [u128; N],\n borrow_flags: [bool; N - 1],\n) {\n let result_limb: Field = (lhs[0] as Field) - (rhs[0] as Field) - (result[0] as Field)\n + (borrow_flags[0] as Field) * TWO_POW_120 as Field;\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) - (rhs[i] as Field) - (result[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n\n let result_limb: Field = (lhs[N - 1] as Field)\n - (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n - (borrow_flags[N - 2] as Field);\n assert(result_limb == 0);\n}\n\n/// Validate that `val` <= `MOD`\n///\n/// Compute `result = MOD - val` along with `borrow_flags`,\n/// then constrain `result` to be a valid `BigNum` value.\n///\n/// Basically the same as `validate_gt` but we compute the result on the fly\n/// It is just a bit more optimized as we expect each `BigNum` value to be \\leq `MOD`\n///\n/// ## Note\n/// In contrast to `validate_gt`, we allow the value to be `MOD`\n/// Since it is consistent with the rest of the library\npub(crate) fn validate_in_field(\n params: BigNumParams,\n val: [u128; N],\n) {\n let modulus: [u128; N] = params.modulus;\n\n // Safety: compute borrow flags out-of-circuit\n let borrow_flags: [bool; (N - 1)] =\n unsafe { __validate_in_field_compute_borrow_flags(params, val) };\n\n let mut p_minus_self: [Field; N] = [0; N];\n p_minus_self[0] = (modulus[0] as Field) - (val[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field);\n for i in 1..N - 1 {\n p_minus_self[i] = (modulus[i] as Field) - (val[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n }\n p_minus_self[N - 1] =\n (modulus[N - 1] as Field) - (val[N - 1] as Field) - (borrow_flags[N - 2] as Field);\n validate_in_range::(p_minus_self);\n}\n\n/// Compare two `BigNum` values\n///\n/// Returns `lhs > rhs`\n///\n/// ## Note\n/// This is a strict value comparison over the integers,\n/// the values do not have to be reduced modulo `MOD`.\npub(crate) fn cmp(lhs: [u128; N], rhs: [u128; N]) -> Ordering {\n // Safety: we constrain:\n // - `result` and `borrow_flags` with `check_gte_with_flags`\n // - `borrow_flags` are also booleans\n // - `underflow` with the following swap and (bool)\n let (underflow, result, borrow_flags): (bool, [u128; N], [bool; N - 1]) =\n unsafe { __validate_gte_with_flags(lhs, rhs) };\n\n // if underflow is true, swap lhs and rhs\n let (lhs, rhs): ([u128; N], [u128; N]) = if underflow { (rhs, lhs) } else { (lhs, rhs) };\n\n // Constrain the `result` to be a valid `BigNum` value\n validate_in_range::(result);\n\n // Constrain subtraction: result = lhs - rhs with borrow_flags\n check_gte_with_flags(lhs, rhs, result, borrow_flags);\n\n if lhs == rhs {\n Ordering::equal()\n } else if underflow {\n Ordering::less()\n } else {\n Ordering::greater()\n }\n}\n\n// ------------------------------ ARITHMETIC FUNCTIONS ------------------------------\n\n/// Negate a `BigNum` value\n///\n/// Computes `result = MOD - val` using limb-wise subtraction with borrow flags,\n/// then constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the subtraction relation with the borrow flags\n///\n/// ## Assumptions\n/// - `val` is a valid `BigNum` in the range `0 <= val <= MOD`.\n///\n/// ## Soundness\n/// This function constrains the following relations:\n/// result[0] = MOD[0] - val[0] + bf[0] * 2^{120} < 2^{120}\n/// result[i] = MOD[i] - val[i] + bf[i] * 2^{120} - bf[i - 1] < 2^{120}, i = 1..N-2\n/// result[N - 1] = MOD[N - 1] - val[N - 1] - bf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// If all `MOD` and `val` limbs are valid `BigNum` limbs, these constraints\n/// ensure that:\n/// - the borrow flags `bf[i]` form a valid limb-wise subtraction chain, and\n/// - no underflow can occur in the subtraction `MOD - val`.\n///\n/// ## Completeness\n/// This function is complete for inputs in the range `0 <= val <= MOD`.\n/// If a value `val > MOD` is passed in (while still `< 2^{MOD_BITS}`), the\n/// constraints above will fail, since there is no valid borrow chain making\n/// `MOD - val` a well-formed `BigNum`.\n///\n/// In practice, honest provers should not hit this case: all functions in this\n/// module are expected to return values `< MOD`.\n///\n/// ## Note\n/// This function returns `MOD` when `val` is zero.\npub(crate) fn neg(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in an unconstrained runtime\n unsafe {\n __neg(params.modulus, val)\n }\n } else {\n // Safety: compute borrow flags out-of-circuit\n let (result, borrow_flags): ([u128; N], [bool; N - 1]) =\n unsafe { __neg_with_flags(params.modulus, val) };\n validate_in_range::(result);\n\n let result_limb: Field = (params.modulus[0] as Field)\n - (val[0] as Field)\n - (result[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (params.modulus[i] as Field)\n - (val[i] as Field)\n - (result[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n\n let result_limb: Field = (params.modulus[N - 1] as Field)\n - (val[N - 1] as Field)\n - (result[N - 1] as Field)\n - (borrow_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Add two `BigNum` values\n///\n/// Computes `result = lhs + rhs` using limb-wise addition with carry flags,\n/// and an optional subtraction of `MOD` using borrow flags. The function then\n/// constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the addition/subtraction relation with the carry/borrow flags and the\n/// `overflow_modulus` bit.\n///\n/// ## Assumptions\n/// - All limbs of `lhs`, `rhs` and `MOD` are valid `BigNum` limbs\n/// (120-bit for non-top limbs, `TOP_LIMB_BITS` for the top limb).\n/// - Semantically, we intend to use this only with `0 <= lhs, rhs < MOD`,\n/// even though the limb/range constraints allow values up to `< 2^{MOD_BITS}`.\n///\n/// ## Soundness (intended relation)\n/// This function constrains the following equations:\n///\n/// result[0] = lhs[0] + rhs[0]\n/// - sub[0]\n/// + bf[0] * 2^{120}\n/// - cf[0] < 2^{120}\n///\n/// result[i] = lhs[i] + rhs[i]\n/// - sub[i]\n/// + bf[i] * 2^{120} - bf[i - 1]\n/// - cf[i] * 2^{120} + cf[i - 1] < 2^{120},\n/// for i = 1..N-2\n///\n/// result[N - 1] = lhs[N - 1] + rhs[N - 1]\n/// - sub[N - 1]\n/// - bf[N - 2]\n/// + cf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// where:\n/// - `bf[i]` are the borrow flags of the optional subtraction,\n/// - `cf[i]` are the carry flags of the addition, and\n/// - `sub` is either the zero vector or `MOD`, depending on the\n/// `overflow_modulus` flag:\n/// * `overflow_modulus = 0` => `sub = 0`\n/// * `overflow_modulus = 1` => `sub = MOD`\n///\n/// If `lhs`, `rhs` and `MOD` are valid `BigNum` limbs and the witness for\n/// `(bf, cf, overflow_modulus)` is the honest one produced by `__add_with_flags`,\n/// these constraints enforce:\n/// - a valid limb-wise carry chain for `lhs + rhs`, and\n/// - a valid limb-wise subtraction chain for either `lhs + rhs` or\n/// `lhs + rhs - MOD`, with no underflow in any limb.\n///\n/// Under these assumptions the constrained result equals:\n///\n/// result = lhs + rhs (mod MOD)\n///\n/// in the intended arithmetic.\n///\n/// ## Limitations / extra satisfying witnesses\n///\n/// The constraint system itself does **not** uniquely determine the carry/borrow\n/// flags nor the `overflow_modulus` bit:\n///\n/// - For each limb `i`, `bf[i]` and `cf[i]` only appear in the combination\n/// `bf[i] * 2^{120} - cf[i] * 2^{120}`. This means that both\n///\n/// (bf[i], cf[i]) = (0, 0) and (bf[i], cf[i]) = (1, 1)\n///\n/// give the same contribution to the equation. As a result, there are multiple\n/// valid flag assignments for the *same* `lhs`, `rhs`, `sub` and `result`.\n///\n/// - More importantly, if `lhs + rhs` is greater than `MOD` but still strictly\n/// less than `2^{MOD_BITS}`, there exist *spurious* witnesses where:\n/// * `overflow_modulus` is set inconsistently with the true arithmetic\n/// overflow, and\n/// * the `(bf, cf)` flags are adjusted accordingly,\n///\n/// such that all equations above still hold and all `result` limbs remain\n/// within range. In particular, when\n///\n/// lhs + rhs + MOD < 2^{MOD_BITS},\n///\n/// a malicious prover can \"hide\" an extra `MOD` inside the choice of\n/// `overflow_modulus`, `bf` and `cf`, so that the circuit is satisfied by a\n/// witness\n///\n/// Consequently, this function is only *conditionally* sound: we rely on the\n/// out-of-circuit implementation of `__add_with_flags` to provide the honest\n/// `(borrow_flags, carry_flags, overflow_modulus)` witness. Under that\n/// assumption, the constrained `result` matches `lhs + rhs (mod MOD)`.\n///\n/// ## Completeness\n///\n/// For inputs in the range `0 <= lhs, rhs < MOD` and honest flags from\n/// `__add_with_flags`, the constraints are complete: every valid `BigNum` sum\n/// `lhs + rhs (mod MOD)` admits a satisfying assignment.\n///\n/// Inputs with `lhs` or `rhs` in `[MOD, 2^{MOD_BITS})` are still representable\n/// as limb arrays and may admit satisfying witnesses, but then the operation\n/// no longer corresponds to a unique, well-defined addition in the field\n/// `Z / MOD Z`. Such uses are outside the intended semantics of this function.\npub(crate) fn add(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in unconstrained runtime\n unsafe {\n __add(params.modulus, lhs, rhs)\n }\n } else {\n // Safety: compute borrow/carry flags out-of-circuit\n let (result, carry_flags, borrow_flags, overflow_modulus): ([u128; N], [bool; N - 1], [bool; N - 1], bool) =\n unsafe { __add_with_flags(params.modulus, lhs, rhs) };\n validate_in_range::(result);\n\n let mut subtrahend: [u128; N] = if overflow_modulus {\n params.modulus\n } else {\n [0; N]\n };\n\n let result_limb: Field = (lhs[0] as Field) + (rhs[0] as Field)\n - (result[0] as Field)\n - (subtrahend[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) + (rhs[i] as Field)\n - (result[i] as Field)\n - (subtrahend[i] as Field)\n - (borrow_flags[i - 1] as Field)\n + (carry_flags[i - 1] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[i] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n }\n let result_limb: Field = (lhs[N - 1] as Field) + (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n - (subtrahend[N - 1] as Field)\n - (borrow_flags[N - 2] as Field)\n + (carry_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Subtract two `BigNum` values\n///\n/// Computes `result = lhs - rhs` using limb-wise subtraction with borrow flags,\n/// and an optional addition of `MOD` using carry flags. The function then\n/// constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the subtraction/addition relation with the carry/borrow flags and the\n/// `underflow_modulus` bit.\n///\n/// ## Assumptions\n/// - All limbs of `lhs`, `rhs` and `MOD` are valid `BigNum` limbs\n/// (120-bit for non-top limbs, `TOP_LIMB_BITS` for the top limb).\n/// - Semantically, we intend to use this only with `0 <= lhs, rhs < MOD`,\n/// even though the limb/range constraints allow values up to `< 2^{MOD_BITS}`.\n///\n/// ## Soundness (intended relation)\n/// This function constrains the following equations:\n///\n/// result[0] = lhs[0] - rhs[0]\n/// + add[0]\n/// + bf[0] * 2^{120}\n/// - cf[0] < 2^{120}\n///\n/// result[i] = lhs[i] - rhs[i]\n/// + add[i]\n/// + bf[i] * 2^{120} - bf[i - 1]\n/// - cf[i] * 2^{120} + cf[i - 1] < 2^{120},\n/// for i = 1..N-2\n///\n/// result[N - 1] = lhs[N - 1] - rhs[N - 1]\n/// + add[N - 1]\n/// - bf[N - 2]\n/// + cf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// where:\n/// - `bf[i]` are the borrow flags of the subtraction,\n/// - `cf[i]` are the carry flags of the optional addition, and\n/// - `add` is either the zero vector or `MOD`, depending on the\n/// `underflow_modulus` flag:\n/// * `underflow_modulus = 0` => `add = 0`\n/// * `underflow_modulus = 1` => `add = MOD`\n///\n/// If `lhs`, `rhs` and `MOD` are valid `BigNum` limbs and the witness for\n/// `(bf, cf, underflow_modulus)` is the honest one produced by `__sub_with_flags`,\n/// these constraints enforce:\n/// - a valid limb-wise borrow chain for `lhs - rhs`, and\n/// - a valid limb-wise addition chain for either `lhs - rhs` or\n/// `lhs - rhs + MOD`, with no underflow in any limb.\n///\n/// Under these assumptions the constrained result equals:\n///\n/// result = lhs - rhs (mod MOD)\n///\n/// in the intended arithmetic.\n///\n/// ## Limitations / extra satisfying witnesses\n///\n/// The constraint system itself does **not** uniquely determine the carry/borrow\n/// flags nor the `underflow_modulus` bit:\n///\n/// - For each limb `i`, `bf[i]` and `cf[i]` only appear in the combination\n/// `bf[i] * 2^{120} - cf[i] * 2^{120}`. This means that both\n///\n/// (bf[i], cf[i]) = (0, 0) and (bf[i], cf[i]) = (1, 1)\n///\n/// give the same contribution to the equation. As a result, there are multiple\n/// valid flag assignments for the *same* `lhs`, `rhs`, `add` and `result`.\n///\n/// - More importantly, when `lhs < rhs`, the true field result is\n///\n/// lhs - rhs + MOD,\n///\n/// and as long as\n///\n/// lhs - rhs + MOD < 2^{MOD_BITS},\n///\n/// a malicious prover can:\n/// * set `underflow_modulus` inconsistently with the true underflow, and\n/// * adjust the `(bf, cf)` flags accordingly,\n///\n/// such that all equations above still hold and all `result` limbs remain\n/// within range. In other words, the circuit can be satisfied by a witness\n/// that does **not** correspond to the unique intended subtraction modulo\n/// `MOD` for some inputs with `lhs < rhs`.\n///\n/// Consequently, this function is only *conditionally* sound: we rely on the\n/// out-of-circuit implementation of `__sub_with_flags` to provide the honest\n/// `(borrow_flags, carry_flags, underflow_modulus)` witness. Under that\n/// assumption, the constrained `result` matches `lhs - rhs (mod MOD)`.\n///\n/// ## Completeness\n///\n/// For inputs in the range `0 <= lhs, rhs < MOD` and honest flags from\n/// `__sub_with_flags`, the constraints are complete: every valid `BigNum`\n/// difference `lhs - rhs (mod MOD)` admits a satisfying assignment.\n///\n/// Inputs with `lhs` or `rhs` in `[MOD, 2^{MOD_BITS})` are still representable\n/// as limb arrays and may admit satisfying witnesses, but then the operation\n/// no longer corresponds to a unique, well-defined subtraction in the field\n/// `Z / MOD Z`. Such uses are outside the intended semantics of this function.\npub(crate) fn sub(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in unconstrained runtime\n unsafe {\n __sub(params.modulus, lhs, rhs)\n }\n } else {\n // Safety: we constrain carry, borrow, underflow and result immediately\n let (result, carry_flags, borrow_flags, underflow_modulus): ([u128; N], [bool; N - 1], [bool; N - 1], bool) =\n unsafe { __sub_with_flags(params.modulus, lhs, rhs) };\n validate_in_range::(result);\n\n let mut addend: [u128; N] = if underflow_modulus {\n params.modulus\n } else {\n [0; N]\n };\n\n let result_limb: Field = (lhs[0] as Field) - (rhs[0] as Field) - (result[0] as Field)\n + (addend[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) - (rhs[i] as Field) - (result[i] as Field)\n + (addend[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field)\n + (carry_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n let result_limb: Field = (lhs[N - 1] as Field)\n - (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n + (addend[N - 1] as Field)\n - (borrow_flags[N - 2] as Field)\n + (carry_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Compute the `BigNum` multiplication\n///\n/// Computes `result = lhs * rhs (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__mul`.\n/// 2. Constraining the quadratic relation `lhs * rhs - result = 0` with\n/// `evaluate_quadratic_expression`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `lhs * rhs - result = 0`\n///\n/// ## Note\n/// When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `mul`\npub(crate) fn mul(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n // Safety: we constrain the multiplication result immediately after\n let result: [u128; N] = unsafe { __mul::(params, lhs, rhs) };\n if !std::runtime::is_unconstrained() {\n // lhs * rhs - result = 0\n evaluate_quadratic_expression(\n params,\n [[lhs]],\n [[false]],\n [[rhs]],\n [[false]],\n [result],\n [true],\n );\n }\n result\n}\n\n/// Compute the `BigNum` squaring\n///\n/// Computes `result = val * val (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__sqr`.\n/// 2. Constraining the quadratic relation `val * val - result = 0` with\n/// `evaluate_quadratic_expression`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `val * val - result = 0`\n///\n/// ## Note\n/// When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `sqr`\npub(crate) fn sqr(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n // Safety: we constrain the multiplication result immediately after\n let result: [u128; N] = unsafe { __sqr::<_, MOD_BITS>(params, val) };\n if !std::runtime::is_unconstrained() {\n // val * val - result = 0\n evaluate_quadratic_expression(\n params,\n [[val]],\n [[false]],\n [[val]],\n [[false]],\n [result],\n [true],\n );\n }\n result\n}\n\n/// Compute the `BigNum` division\n///\n/// Computes `result = lhs * rhs^{-1} (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__div`.\n/// 2. Constraining the quadratic relation `result * rhs - lhs = 0` with\n/// `evaluate_quadratic_expression`.\n/// 3. Enforcing `rhs != 0 (mod MOD)`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `result * rhs - lhs = 0`, together with the non-zero check on `rhs` and the\n/// assumption that `MOD` has multiplicative inverses for all non-zero elements\n/// (`params.has_multiplicative_inverse = true`).\n///\n/// ## Note\n/// - This is **expensive** in witness time due to modular inversion.\n/// - When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `div`.\n/// - In the unconstrained runtime, the behavior of `__div` on zero divisors is\n/// not constrained by this function.\npub(crate) fn div(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n assert(\n params.has_multiplicative_inverse,\n \"BigNum has no multiplicative inverse. Use udiv for unsigned integer division\",\n );\n // Safety: We constrain the result of division immediately after\n let result: [u128; N] = unsafe { __div::<_, MOD_BITS>(params, lhs, rhs) };\n if !std::runtime::is_unconstrained() {\n // result * rhs - lhs = 0\n evaluate_quadratic_expression(\n params,\n [[result]],\n [[false]],\n [[rhs]],\n [[false]],\n [lhs],\n [true],\n );\n assert_is_not_zero(params, rhs);\n }\n result\n}\n\n/// Compute the `BigNum` integer division with remainder\n///\n/// Computes `quotient = floor(numerator / divisor)` and\n/// `remainder = numerator % divisor` by:\n/// 1. Computing `(quotient, remainder)` out of circuit via `__udiv_mod`.\n/// 2. Constraining the quadratic relation\n/// quotient * divisor + remainder - numerator = 0\n/// with `validate_udiv_mod_expression`.\n/// 3. Enforcing `remainder < divisor`.\n///\n/// ## Soundness\n/// Soundness reduces to `validate_udiv_mod_expression` for the relation\n/// quotient * divisor + remainder - numerator = 0,\n/// together with `remainder < divisor` check enforced via `validate_gt`.\n///\n/// Under these checks, any satisfying assignment corresponds to a valid\n/// integer division `numerator = quotient * divisor + remainder` with\n/// `0 <= remainder < divisor`\n///\n/// ## Note\n/// Enforcing `divisor != 0` is not necessary. `remainder < divisor`\n/// Already enforces this.\npub(crate) fn udiv_mod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> ([u128; N], [u128; N]) {\n // Safety: We constrain the result of __udiv_mod immediately after\n let (quotient, remainder): ([u128; N], [u128; N]) = unsafe { __udiv_mod(numerator, divisor) };\n if !std::runtime::is_unconstrained() {\n // quotient * divisor + remainder - numerator = 0\n validate_udiv_mod_expression::(numerator, divisor, quotient, remainder);\n // remainder < divisor\n validate_gt::(divisor, remainder);\n }\n (quotient, remainder)\n}\n\n/// Compute the `BigNum` integer division\n///\n/// Returns `floor(numerator / divisor)`.\n/// All constraints and soundness details are handled inside `udiv_mod`.\npub(crate) fn udiv(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n udiv_mod::(numerator, divisor).0\n}\n\n/// Compute the `BigNum` remainder\n///\n/// Returns `numerator % divisor`.\n/// All constraints and soundness details are handled inside `udiv_mod`.\npub(crate) fn umod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n udiv_mod::(numerator, divisor).1\n}", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/constrained_ops.nr" + }, + "121": { + "source": "use crate::utils::split_bits;\n\nuse crate::constants::{TWO_POW_120, TWO_POW_126, TWO_POW_246};\n\nuse crate::fns::constrained_ops::{validate_in_range, validate_quotient_in_range};\nuse crate::fns::unconstrained_helpers::__barrett_reduction;\nuse crate::fns::unconstrained_ops::__is_zero;\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ UNCONSTRAINED EXPRESSIONS ------------------------------\n\n/// Compute the result of a linear combination of (possibly negative) `BigNum` values (unconstrained)\n///\n/// ## Note\n/// 1. `modulus2` is structured such that all limbs will be greater than `0`, even when subtracting.\n/// To do this, when computing `p - x`, we ensure that each limb in `p` is greater than each limb in `x`.\n/// We know that, for a valid bignum element, the limbs in `x` will be < 2^{120}\n/// Therefore each of the limbs in `p` (except the most significant) will borrow 2^{120} from the more significant limb.\n/// Finally, to ensure we do not underflow in the most significant limb, we use `2p` instead of `p`\n///\n/// 2. Returns the `Field` values that are not normalized to be 120-bit\nunconstrained fn __add_linear_expression(\n params: BigNumParams,\n vals: [[u128; N]; M],\n flags: [bool; M],\n) -> ([Field; N]) {\n let mut sum: [Field; N] = [0; N];\n let modulus2: [u128; N] = params.double_modulus;\n for i in 0..M {\n if (flags[i]) {\n for j in 0..N {\n sum[j] = sum[j] + (modulus2[j] as Field) - (vals[i][j] as Field);\n }\n } else {\n for j in 0..N {\n sum[j] = sum[j] + (vals[i][j] as Field);\n }\n }\n }\n sum\n}\n\n/// Compute the limb products of a quadratic expression (unconstrained)\n///\n/// See `__compute_quadratic_expression_with_borrow_flags` for full description\n///\n/// ## Note\n/// Returns the `Field` values that are not normalized to be 120-bit\nunconstrained fn __compute_quadratic_expression_product(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> [Field; 2 * N] {\n let mut lhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n let mut rhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n\n for i in 0..NUM_PRODUCTS {\n lhs[i] = __add_linear_expression(params, lhs_terms[i], lhs_flags[i]);\n rhs[i] = __add_linear_expression(params, rhs_terms[i], rhs_flags[i]);\n }\n let add: [Field; N] = __add_linear_expression(params, linear_terms, linear_flags);\n\n let mut mulout: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n for k in 0..NUM_PRODUCTS {\n mulout[i + j] += lhs[k][i] * rhs[k][j];\n }\n }\n mulout[i] += add[i];\n }\n mulout\n}\n\n/// Compute the borrow flags for a limb-wise subtraction `lhs - rhs` (unconstrained).\n///\n/// This helper operates on `N`-limb values where each limb is interpreted as a\n/// 120-bit chunk (base `B = 2^{120}`), but where intermediate limbs may exceed\n/// `2^{120}` due to sums of products.\n///\n/// Conceptually, we want to model the integer subtraction\n///\n/// lhs - rhs\n///\n/// as a base-`B` subtraction with borrows, without allowing any intermediate\n/// values to go negative in the circuit field. We achieve this by:\n///\n/// 1. Working with widened 246-bit ranges per limb.\n/// 2. Encoding a borrow from limb `i+1` into limb `i` by:\n/// - adding `2^{246}` into limb `i`,\n/// - subtracting `2^{126}` (= 2^{246 - 120}) from limb `i+1` after\n/// scaling by `2^{-120}`.\n///\n/// The returned `borrow_flags[i]` indicate whether the canonical integer\n/// subtraction would borrow from limb `i+1` into limb `i`. These flags are\n/// later re-applied in-circuit via `apply_borrow_flags`, and the resulting\n/// limbs are checked by `validate_expression_is_zero`.\nunconstrained fn __compute_borrow_flags(\n mut lhs_limbs: [Field; N],\n rhs_limbs: [Field; N],\n) -> [bool; N - 1] {\n // compute borrow flags from mulout_p and mulout_n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let borrow_shift: Field = TWO_POW_246; // 2^{246}\n let borrow_carry: Field = TWO_POW_126; // 2^{126} = 2^{246 - 120}\n let downshift_120: Field = 1 / (TWO_POW_120 as Field);\n\n // determine whether we need to borrow from more significant limbs.\n // initial limb is \"simple\" comparison operation\n borrow_flags[0] = lhs_limbs[0].lt(rhs_limbs[0]);\n\n // we have N - 1 borrow flags. The number of limbs is N\n // and there is nothing to borrow against for the final limb.\n let mut hi_bits: Field =\n (lhs_limbs[0] - rhs_limbs[0] + ((borrow_flags[0] as Field) * borrow_shift)) * downshift_120;\n\n for i in 1..(N - 1) {\n // compute the contribution from limb `i-1` that gets added into limb `i`, and add into limb `i`\n lhs_limbs[i] += hi_bits;\n\n let subtrahend: Field = rhs_limbs[i] + (borrow_flags[i - 1] as Field) * borrow_carry;\n\n // determine whether negative limb values are greater than positive limb values\n borrow_flags[i] = lhs_limbs[i].lt(subtrahend);\n let minuend: Field = lhs_limbs[i] + (borrow_flags[i] as Field) * borrow_shift;\n\n hi_bits = (minuend - subtrahend) * downshift_120;\n }\n borrow_flags\n}\n\n/// Given a degree-2 `BigNum` expression that is equal to `0 mod MOD`, compute\n/// the quotient and the borrow flags (unconstrained).\n///\n/// The expression has the form:\n///\n/// sum_{k=0}^{NUM_PRODUCTS-1} (L_k * R_k) + sum_{i=0}^{ADD_N-1} A_i = quotient * MOD\n///\n/// where each `L_k`, `R_k`, `A_i` is an `N`-limb `BigNum` assembled from the\n/// `(terms, flags)` arrays.\n///\n/// This helper:\n/// 1. Evaluates the quadratic expression into `mulout_p` as a `2N`-limb\n/// non-normalized value.\n/// 2. Normalizes `mulout_p` into 120-bit limbs and applies Barrett\n/// reduction to obtain `(quotient, remainder)`.\n/// 3. Asserts that the integer remainder is zero (debugging aid; range\n/// checks enforce this later).\n/// 4. Reconstructs `mulout_n = quotient * MOD`.\n/// 5. Computes `borrow_flags` for the limb-wise subtraction\n/// `mulout_p - mulout_n`,\n/// using the 2^{246}/2^{126} encoding described in\n/// `evaluate_quadratic_expression`.\n///\n/// The returned `quotient` and `borrow_flags` are later constrained\n/// in-circuit by `compute_quadratic_expression_with_modulus` and\n/// `evaluate_quadratic_expression`.\nunconstrained fn __compute_quadratic_expression_with_borrow_flags(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([u128; N], [bool; 2 * N - 2]) {\n let mulout_p: [Field; 2 * N] = __compute_quadratic_expression_product(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n\n // `__normalize_limbs` will validate that we do not overflow 2N, normally we should not overflow 2N-1\n let mut relation_result: [u128; 2 * N] = split_bits::__normalize_limbs(mulout_p);\n let (quotient, remainder): ([u128; N], [u128; N]) =\n __barrett_reduction(relation_result, params.redc_param, MOD_BITS, params.modulus);\n\n // This is verified later by the range checks but left for debugging purposes\n assert(__is_zero(remainder));\n\n // We do not normalize `mulout_n` so we won't fill the `2 * N - 1`\n let mut mulout_n: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n mulout_n[i + j] += (quotient[i] as Field) * (params.modulus[j] as Field);\n }\n }\n\n let borrow_flags: [bool; 2 * N - 1] = __compute_borrow_flags(mulout_p, mulout_n);\n\n // We have to copy it because we know that borrow_flags[2 * N - 1] is always 0\n // But we also have to provide 2 * N limbs to `__barrett_reduction`.\n // And keep `__compute_borrow_flags` generic enough\n let mut borrow_flags_real: [bool; 2 * N - 2] = [false; 2 * N - 2];\n for i in 0..2 * N - 2 {\n borrow_flags_real[i] = borrow_flags[i];\n }\n\n (quotient, borrow_flags_real)\n}\n\n/// Computes the quotient/remainder of a quadratic expression (unconstrained)\n///\n/// See `__compute_quadratic_expression_with_borrow_flags` for full description\npub(crate) unconstrained fn __compute_quadratic_expression(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([u128; N], [u128; N]) {\n let mulout: [Field; 2 * N] = __compute_quadratic_expression_product(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n // __normalize_limbs will validate that we do not overflow 2N, normally we should not overflow 2N-1\n let mut relation_result: [u128; 2 * N] = split_bits::__normalize_limbs(mulout);\n\n let (quotient, remainder): ([u128; N], [u128; N]) =\n __barrett_reduction(relation_result, params.redc_param, MOD_BITS, params.modulus);\n\n (quotient, remainder)\n}\n\n// ------------------------------ CONSTRAINED EXPRESSIONS ------------------------------\n\n/// Constrained version of `__add_linear_expression`\n///\n/// Computes all the linear parts of an expression in-circuit\n///\n/// ## Note\n/// 1. Negative terms are implemented by adding `double_modulus`\n/// `double_modulus` is chosen so that all limbs except the top one\n/// are > 2^{120}, which prevents underflows in intermediate computations.\n///\n/// 2. For the most significant limb we slightly reduce the padding (to keep the\n/// overall value equal to `2 * MOD`), so in principle there is a narrow edge\n/// case where that limb could underflow if enough negative contributions are\n/// accumulated and the top limb of `MOD` is very small. In practice, the\n/// global `BigNum` range and operand-count assumptions in\n/// `evaluate_quadratic_expression` rule out such patterns.\nfn compute_linear_expressions(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([[Field; N]; NUM_PRODUCTS], [[Field; N]; NUM_PRODUCTS], [Field; N]) {\n // lhs linear terms\n let mut lhs_linear: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n // rhs linear terms\n let mut rhs_linear: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n // linear terms\n let mut lin_expr: [Field; N] = [0; N];\n\n for k in 0..NUM_PRODUCTS {\n for i in 0..N {\n for j in 0..LHS_N {\n // Note: if lhs_flags[k][j] - `is_negative` is not known at comptime this is very expensive\n if (lhs_flags[k][j]) {\n lhs_linear[k][i] -= lhs_terms[k][j][i] as Field;\n lhs_linear[k][i] += params.double_modulus[i] as Field;\n } else {\n lhs_linear[k][i] += lhs_terms[k][j][i] as Field;\n }\n }\n for j in 0..RHS_N {\n // Note: if rhs_flags[k][j] - `is_negative` is not known at comptime this is very expensive\n if (rhs_flags[k][j]) {\n rhs_linear[k][i] -= rhs_terms[k][j][i] as Field;\n rhs_linear[k][i] += params.double_modulus[i] as Field;\n } else {\n rhs_linear[k][i] += rhs_terms[k][j][i] as Field;\n }\n }\n }\n }\n\n for i in 0..N {\n for j in 0..ADD_N {\n // Note: if linear_flags[j] - `is_negative` is not known at comptime this is very expensive\n if (linear_flags[j]) {\n lin_expr[i] -= linear_terms[j][i] as Field;\n lin_expr[i] += params.double_modulus[i] as Field;\n } else {\n lin_expr[i] += linear_terms[j][i] as Field;\n }\n }\n }\n\n (lhs_linear, rhs_linear, lin_expr)\n}\n\n/// Constrained version of `__compute_quadratic_expression_product`\n///\n/// Computes the following expression in-circuit:\n/// \\sum (L_i * R_i) + \\sum (A_i) - QUOTIENT * MOD\n///\n/// Because of the subtraction of `QUOTIENT * MODULUS`, the resulting limbs may\n/// underflow and represent *negative* values. To account for this, we allow the\n/// prover to choose a sequence of borrow flags and interpret the limbs with\n/// additional terms:\n///\n/// - for each limb `i` we may add `2^{246}` (via a flag at position `i`);\n/// - for each limb `i` we may subtract `2^{126 = 246 - 120}` (via the flag\n/// at position `i - 1`).\n///\n/// This corresponds to borrowing `2^{126}` from limb `i + 1` and adding\n/// `2^{246}` into limb `i`. After this adjustment, an honest prover can ensure\n/// that every limb lies in `[0, 2^{246})` and that the adjusted limbs encode\n/// the correct integer value.\n///\n/// Additionally, we constrain the quotient limbs via `validate_quotient_in_range`:\n/// - limbs `0..N-2` of `quotient` are < 2^{120};\n/// - the top limb is < 2^{TOP_LIMB_BITS + 6}.\n/// Which validates `quotient < 2^{MOD_BITS + 6}`\n///\n/// ## TODO\n/// Apply static or runtime checks in this method to validate that the effective\n/// `twiddle_factor` does not exceed 6 under the chosen parameters.\nfn compute_quadratic_expression_with_modulus(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> [Field; 2 * N - 1] {\n // Safety: use an unconstrained function to compute the value of the quotient and borrow_flags out-of-circuit\n let (quotient, borrow_flags): ([u128; N], [bool; 2 * N - 2]) = unsafe {\n __compute_quadratic_expression_with_borrow_flags::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n )\n };\n\n // Constrain the `quotient < 2^{MOD_BITS + 6}`\n // By constraining limbs(0..N-2) to be < 2^120 and the the top limb < 2^{TOP_LIMB_BITS + 6}\n validate_quotient_in_range::(quotient);\n\n // Compute the linear sums that represent L_i, R_i, A\n let (lhs_linear, rhs_linear, lin_expr): ([[Field; N]; NUM_PRODUCTS], [[Field; N]; NUM_PRODUCTS], [Field; N]) = compute_linear_expressions::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n\n // We want to evaluate that L * R + A - Quotient * MOD = 0, evaluated over the integers\n // For this we need to be able to borrow values from more-significant limbs into less-significant limbs,\n // so that we can ensure that no limbs will underflow\n let mut expression_limbs: [Field; 2 * N - 1] = [0; 2 * N - 1];\n\n // Compute the product t0 * t1 + t4 - Quotient * MOD\n // TODO: this is super nasty as it requires a multiplication\n for i in 0..N {\n for j in 0..N {\n for k in 0..NUM_PRODUCTS {\n if k == 0 {\n let new_term: Field = lhs_linear[k][i] * rhs_linear[k][j]\n - (quotient[i] as Field) * (params.modulus[j] as Field);\n // width-4 optimization\n std::as_witness(new_term);\n expression_limbs[i + j] += new_term;\n } else {\n expression_limbs[i + j] += lhs_linear[k][i] * rhs_linear[k][j];\n }\n }\n // This is the fallback for pure linear expression\n if (NUM_PRODUCTS == 0) {\n expression_limbs[i + j] -= (quotient[i] as Field) * (params.modulus[j] as Field);\n }\n }\n expression_limbs[i] += lin_expr[i];\n }\n\n apply_borrow_flags(expression_limbs, borrow_flags)\n}\n\n/// Apply a precomputed borrow chain to a limb array.\n///\n/// Given:\n///\n/// - `expression_limbs`: an `N`-limb array of `Field` values representing a\n/// (possibly non-normalized) degree-2-style expression, and\n/// - `borrow_flags[i]` indicating that we \"borrow\" from limb `i+1` into limb `i`,\n///\n/// this function applies the same 2^{246}/2^{126} encoding used in\n/// `__compute_borrow_flags` to produce an adjusted limb array\n///\n/// This matches the behavior of `__compute_borrow_flags`, which conceptually:\n///\n/// 1. Adds `2^{246}` into a limb when a borrow is taken at that limb;\n/// 2. After scaling by `2^{-120}`, contributes `2^{126}` into the next limb.\n///\n/// The resulting `expression_limbs` can then be passed to\n/// `validate_expression_is_zero`, which:\n///\n/// - right-shifts by 120 bits per limb,\n/// - enforces a 126-bit bound,\n/// - and propagates carries forward, finally checking that the most\n/// significant limb is zero.\n///\n/// ## Assumptions\n///\n/// - `borrow_flags` was computed consistently with the original construction\n/// of `expression_limbs` (e.g. via `__compute_borrow_flags` on the\n/// corresponding unconstrained expression).\n/// - The caller has ensured that each adjusted limb remains < 2^{246} for\n/// honest witnesses (e.g. via `NUM_PRODUCTS < 64`).\n///\n/// ## Note\n///\n/// This function does not itself enforce any bit-size bounds; it only applies\n/// the borrow encoding. The actual range checks happen later in\n/// `validate_expression_is_zero`.\n///\n/// ## TODO\n/// define trade-offs regarding the value of borrow_shift\n/// (the larger the value, the greater the range check that is required on product_limbs)\n/// (126-bit range check is a sweet spot for the barretenberg backend as it decomposes into 9 14-bit range checks)\n/// (the barretenberg backend can evaluate these in 5.25 gates. 127 bits costs 6.5 gates)\nfn apply_borrow_flags(\n mut expression_limbs: [Field; N],\n borrow_flags: [bool; N - 1],\n) -> [Field; N] {\n let borrow_shift: Field = TWO_POW_246; // 2^{246}\n let borrow_carry: Field = TWO_POW_126; // 2^{246 - 120} = 2^{126}\n\n // Get the product_limbs into the form where each entry is a 246-bit value\n expression_limbs[0] += (borrow_flags[0] as Field) * borrow_shift;\n for i in 1..(N - 1) {\n expression_limbs[i] += (borrow_flags[i] as Field) * borrow_shift\n - (borrow_flags[i - 1] as Field) * borrow_carry;\n }\n expression_limbs[N - 1] -= (borrow_flags[N - 2] as Field) * borrow_carry;\n expression_limbs\n}\n\n/// Validate that `limbs` represent the integer value `0`\n///\n/// ## Assumptions\n/// - `limbs` is an array of `Field` values that was derived arithmetically as\n/// a degree-2 expression\n/// - each limb satisfies `limbs[i] < 2^{246}`, as ensured by\n/// `compute_quadratic_expression_with_modulus` under its parameter bounds.\n///\n/// ## Details\n/// Each element `i` in `limbs` overlaps in bit-range with element `i+1`, EXCEPT for the low 120 bits\n/// i.e. we need to do the following for each limb `i`:\n/// 1. validate the limb's low-120 bits equals zero\n/// 2. compute the limb \"carry\" by right-shifting by 2^{120}\n/// 3. propagate the \"carry\" into limb `i+1`\n/// We can efficiently do all of the above by multiplying the limb by 2^{-120} and constraining the result to be <2^{126}\n///\n/// If the low 120 bits are nonzero, there is no value in `[0, 2^{126})` that\n/// could have produced this limb after multiplying by `2^{120}`. Since\n/// multiplication by `2^{120}` is a bijection on the Field, any limb with\n/// non-zero low 120 bits must map outside the `[0, 2^{126})` range after\n/// scaling by `2^{-120}`.\n///\n/// The most significant limb has no limb to \"carry\" values into - the entire limb must equal zero\n///\n/// ## Note\n/// The constant 126 is not arbitrary. We use 120-bit limbs and allow up to 64\n/// products per limb, which contributes at most `log2(64) = 6` bits of headroom.\n/// After scaling by `2^{-120}`, honest witnesses fit in 126 bits. We could in\n/// principle go higher (up to roughly `CircuitModulusBits - 121`), but 126 is\n/// the minimal bound consistent with `NUM_PRODUCTS < 64` and is significantly\n/// cheaper than larger bounds for the barretenberg backend.\nfn validate_expression_is_zero(mut limbs: [Field; N]) {\n let hi_shift: Field = TWO_POW_120 as Field;\n let hi_downshift: Field = 1 / hi_shift;\n for i in 0..N - 1 {\n limbs[i] *= hi_downshift;\n std::as_witness(limbs[i]);\n limbs[i].assert_max_bit_size::<126>(); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb\n limbs[i + 1] += limbs[i];\n }\n assert(limbs[N - 1] == 0);\n}\n\n/// Constrain a degree-2 `BigNum` expression to be equal to 0 (mod `MOD`)\n///\n//\n/// This method is intended for relations where the remainder term of the\n/// degree-2 expression is exactly zero as an integer relation. In other words,\n/// we use it only when we expect:\n///\n/// \\sum (L_i * R_i) + \\sum (A_i) - QUOTIENT * MOD = 0\n///\n/// as integers, not just modulo the circuit field or `BigNum` field.\n///\n/// ## Details\n///\n/// The constrained expression, viewed over the integers, is:\n///\n/// \\sum_{i=0}^{NUM_PRODUCTS-1} (L_i * R_i)\n/// + \\sum_{i=0}^{ADD_N-1} (A_i)\n/// - QUOTIENT * MOD\n/// = 0\n///\n/// Each `L_i`, `R_i`, `A_i` is an `N`-limb `BigNum` assembled from the\n/// `(terms, flags)` arrays. For example, for `i = 0`:\n///\n/// L_0 = \\sum_{j=0}^{LHS_N-1} lhs[0][j] as a `BigNum`\n/// R_0 = \\sum_{j=0}^{RHS_N-1} rhs[0][j] as a `BigNum`\n///\n/// The intent is to capture a generic degree-2 expression within Noir's\n/// limitations (no efficient dynamically sized vectors).\n///\n/// The expensive parts of this algorithm are:\n/// 1. evaluating the limb products required to compute the `L_i * R_i` values;\n/// 2. applying range constraints to validate that the result encodes 0.\n///\n/// ## Note\n/// When the expression is evaluated over `N`-limb `BigNum` values, the product\n/// has up to `2N - 1` significant limbs. Each limb is a sum of at most\n/// `NUM_PRODUCTS` products of `linear` 120-bit limbs and `quadratic` 240-bit-ish limbs\n///\n/// Note that:\n/// * limb-wise multiplication is not uniform across indices. For example:\n///\n/// [x0, x1, x2] * [y0, y1, y2] =\n/// [\n/// x0*y0, // 1 term\n/// x0*y1 + x1*y0, // 2 terms\n/// x0*y2 + x1*y1 + x2*y0, // 3 terms\n/// x1*y2 + x2*y1, // 2 terms\n/// x2*y2 // 1 term\n/// ]\n/// The number of partial products per limb grows linearly from 1 to N,\n/// then decreases linearly back to 1.\n///\n/// * we also allow linear combinations inside the products, which further increases the bound\n/// on a `quadratic` limb\n///\n/// * finally, when `is_negative` flag is set, we effectively add 2 * MOD to each limb, where\n/// 2 * MOD limbs are structured in such a way that they all are > 2**120\n///\n/// We allow `NUM_PRODUCTS < 64` completeness-wise, but it certainly can overflow the 2^{240 + `twiddle_factor=6`} bound\n/// in edge cases. See completeness section for an example.\n///\n/// ## Assumptions\n///\n/// Each `BigNum` value used in this gadget is already range constrained:\n/// - limbs `0..N-2` satisfy `limb_i < 2^{120}`\n/// - limb `N-1` satisfies `limb_{N-1} < 2^{TOP_LIMB_BITS}`\n///\n/// ## Completeness\n/// If an honest prover supplies inputs that satisfy the assumptions above,\n/// it can always find a `quotient` and `borrow_flags` such that the integer\n/// relation holds and all constraints are satisfied.\n///\n/// The only possibility to break completeness is by providing too many inputs, for example:\n///\n/// (a0 + a1 + a2) * (b0 + b1 + b2) + ... (60 times), with each a_i having its limbs at maximum value of 2^{120} - 1\n/// The middle limb will contain a value that will definitely overflow the 2^{246} bound.\n///\n/// ## Soundness\n/// This function is conditionally sound: it enforces that the degree-2 relation\n/// holds modulo `MOD`, but it does not, by itself, enforce that any particular\n/// term (for example a result `z`) is a *canonical* representative in\n/// `[0, MOD)`.\n///\n/// In other words, if the surrounding relation is invariant under adding a\n/// multiple of `MOD` to one of its terms, then a dishonest prover can exploit\n/// this. For example, consider a multiplication relation:\n///\n/// x * y - z = 0 (mod MOD)\n///\n/// Internally we encode this as:\n///\n/// x * y + 2 * MOD - z - quotient * MOD = 0\n///\n/// which is equivalent to:\n///\n/// x * y - z = (quotient - 2) * MOD\n///\n/// Suppose the honest witness uses some `z` satisfying\n/// `0 <= z < MOD` and some `quotient`. If the `BigNum` encoding allows\n/// `z' = z + MOD` (i.e. `z' < 2^{MOD_BITS}` still holds), then a dishonest\n/// prover can instead provide:\n///\n/// z' = z + MOD\n/// quotient' = quotient - 1\n///\n/// and still satisfy:\n///\n/// x * y + 2 * MOD - z' - quotient' * MOD = 0\n///\n/// even though `z'` is no longer the canonical representative of `x * y mod MOD`.\n///\n/// The same consideration applies to almost every constrained `BigNum` relation:\n/// whenever a value participates *only* through a modular equality, and no\n/// separate range constraint is imposed on that value, the prover is free to\n/// shift it by an extra `MOD` as long as the resulting limb\n/// encoding still satisfies its bit-bounds. This is inherent in working with\n/// modular constraints; the responsibility for enforcing canonical\n/// representatives lies with the caller when it is required.\n///\n/// This is the same \"extra modulus\" phenomenon as in the `add`/`sub` functions:\n/// the constraints are sound for modular arithmetic, but any caller that\n/// requires canonical outputs in `[0, MOD)` must additionally enforce a\n/// range check (for example via `validate_in_field`) on the relevant terms.\npub(crate) fn evaluate_quadratic_expression(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) {\n assert(NUM_PRODUCTS < 64, f\"evaluate_quadratic_expression overflow in operands count\");\n // NUM_PRODUCTS < 64 is a light bound that tries to ensure each limb sum < 2^{246} so that the 126-bit bound is valid.\n\n lhs_terms.for_each(|lhs_limbs: [[u128; N]; LHS_N]| {\n lhs_limbs.for_each(|term: [u128; N]| validate_in_range::(term))\n });\n rhs_terms.for_each(|rhs_limbs: [[u128; N]; RHS_N]| {\n rhs_limbs.for_each(|term: [u128; N]| validate_in_range::(term))\n });\n linear_terms.for_each(|term: [u128; N]| validate_in_range::(term));\n\n let expression_limbs: [Field; 2 * N - 1] = compute_quadratic_expression_with_modulus::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n validate_expression_is_zero(expression_limbs);\n}\n\n// ------------------------------ UDIV MOD EXPRESSION ------------------------------\n\n/// Given a `udiv_mod` `BigNum` expression that is equal to `0` over integers, compute the borrow flags (unconstrained)\n///\n/// Mirror function of `__compute_quadratic_expression_with_borrow_flags` optimized to compute borrow flags of an expression:\n/// divisor * quotient + remainder - numerator = 0\n/// see `__compute_quadratic_expression_with_borrow_flags` for details\n///\n/// The main differences from it are:\n/// 1. `product_limbs` stores only the least-significant `N` limbs of\n/// `quotient * divisor + remainder`. This is sufficient to compute the\n/// borrow flags for the first `N` limbs of\n/// quotient * divisor + remainder - numerator.\n///\n/// For an honest `udiv_mod` relation we also have\n/// quotient * divisor <= numerator < B^N,\n/// so the true product fits into `N` limbs as an integer.\n/// 2. Instead of subtracting `quotient * MOD` we subtract `numerator`. This is due to the fact that\n/// we no longer work over `MOD`, and we can't really do subtractions as we did previously: `double_modulus - x`\n///\n/// ## Note\n/// We leave the borrow values at 2^{246}, even though we should never reach this bound with just 3 terms\n/// The cases where it can happen are: N >= 64 (middle limb will have 64 additions). And it is a pure completeness issue\n/// But the rest of the library will probably not work with that massive number anyway\nunconstrained fn __compute_udiv_mod_expression_with_borrow_flags(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) -> [bool; N - 1] {\n let mut product_limbs: [Field; N] = [0; N];\n let mut numerator_field: [Field; N] = [0; N];\n for i in 0..N {\n for j in 0..N - i {\n product_limbs[i + j] += (quotient[i] as Field) * (divisor[j] as Field);\n }\n product_limbs[i] += (remainder[i] as Field);\n\n numerator_field[i] = numerator[i] as Field;\n }\n\n __compute_borrow_flags(product_limbs, numerator_field)\n}\n\n/// Constrained version of `__compute_udiv_mod_expression_with_borrow_flags`\n///\n/// Computes the following expression in-circuit:\n/// quotient * divisor + remainder - numerator = 0\n///\n/// Mirror function of `compute_quadratic_expression_with_modulus`. See it for details.\n///\n/// ## Soundness note\n/// We compute the full convolution `quotient * divisor` into `2N - 1` limbs\n/// and then constrain all limbs with index `i >= N` to be zero. For `i >= N`\n/// the value `expression_limbs_full[i]` is a sum of products\n/// sum_{j+k=i} quotient[j] * divisor[k]\n/// with no contribution from `numerator` or `remainder`.\n///\n/// Every limb of `quotient` and `divisor` is range-constrained to be a 120-bit\n/// integer, so each product term is < 2^{240} and each coefficient of the\n/// convolution is strictly smaller than the field modulus. In this regime,\n/// the constraint `expression_limbs_full[i] == 0` in `Field` coincides with\n/// the same equality over the integers.\n///\n/// Vanishing of all high limbs `i >= N` is therefore an integer statement that\n/// the product has degree < N, i.e.\n/// quotient * divisor < 2^{120 * N},\n/// so `quotient * divisor` fits into `N` 120-bit limbs and does not overflow.\nfn compute_udiv_mod_expression(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) -> [Field; N] {\n // Safety: use an unconstrained function to compute the value of the quotient and borrow_flags out-of-circuit\n let borrow_flags: [bool; N - 1] = unsafe {\n __compute_udiv_mod_expression_with_borrow_flags::(\n numerator,\n divisor,\n quotient,\n remainder,\n )\n };\n\n let mut expression_limbs_full: [Field; 2 * N - 1] = [0; 2 * N - 1];\n for i in 0..N {\n for j in 0..N {\n expression_limbs_full[i + j] += (quotient[i] as Field) * (divisor[j] as Field);\n }\n expression_limbs_full[i] += (remainder[i] as Field) - (numerator[i] as Field);\n }\n\n let mut expression_limbs: [Field; N] = [0; N];\n for i in 0..N {\n expression_limbs[i] = expression_limbs_full[i];\n }\n for i in N..2 * N - 1 {\n assert(expression_limbs_full[i] == 0);\n }\n\n apply_borrow_flags(expression_limbs, borrow_flags)\n}\n\n/// Constrain a `udiv_mod` `BigNum` expression to be equal to 0\n///\n/// Mirror function of `evaluate_quadratic_expression`\n///\n/// ## Details\n///\n/// The constrained expression, viewed over the integers, is:\n///\n/// quotient * divisor + remainder - numerator = 0\n///\n/// ## Completeness\n/// If an honest prover supplies valid `BigNum` inputs that satisfy the equation,\n/// it can always find `borrow_flags` such that the integer\n/// relation holds and all constraints are satisfied.\n///\n/// The only possibility to break completeness is by providing a `BigNum` with `N >= 64`\n/// See `__compute_udiv_mod_expression_with_borrow_flags` for details\n///\n/// ## Soundness\n/// This function is conditionally sound: it enforces that the degree-2 relation\n/// holds over the integers, but it does not, by itself, enforce that\n/// this relation is unique for given `numerator` and `divisor`\n///\n/// For example, if the true relation is\n/// quotient * divisor + remainder - numerator = 0\n///\n/// then we can set quotient' = quotient - 1, remainder' = remainder + divisor\npub(crate) fn validate_udiv_mod_expression(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) {\n validate_in_range::(numerator);\n validate_in_range::(divisor);\n validate_in_range::(quotient);\n validate_in_range::(remainder);\n\n let expression_limbs: [Field; N] =\n compute_udiv_mod_expression::(numerator, divisor, quotient, remainder);\n validate_expression_is_zero(expression_limbs);\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/expressions.nr" + }, + "124": { + "source": "// This file contains the unconstrained helpers that are mostly used by unconstrained ops\n\nuse crate::constants::TWO_POW_120;\n\nuse crate::fns::unconstrained_ops::{__add, __eq, __gte, __mul, __neg, __pow, __sqr};\n\nuse crate::utils::msb::get_msb;\nuse crate::utils::split_bits::{__normalize_limbs, __split_120_bits};\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ DERIVATION HELPER FUNCTIONS ------------------------------\n\n/// Construct a `1` BigNum value (unconstrained)\npub(crate) unconstrained fn __one() -> [u128; N] {\n let mut limbs: [u128; N] = [0; N];\n limbs[0] = 1;\n limbs\n}\n\n/// Construct a BigNum value from Field (unconstrained)\n///\n/// Split the native `Field` value into `N` 120-bit limbs\npub(crate) unconstrained fn __from_field(val: Field) -> [u128; N] {\n let mut x: Field = val;\n let mut result: [u128; N] = [0; N];\n\n if (N == 1) {\n let (first_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n }\n\n if (N == 2) {\n let (first_limb, x): (u128, Field) = __split_120_bits(x);\n let (second_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n result[1] = second_limb;\n }\n\n if (N > 2) {\n let (first_limb, x): (u128, Field) = __split_120_bits(x);\n let (second_limb, x): (u128, Field) = __split_120_bits(x);\n let (third_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n result[1] = second_limb;\n result[2] = third_limb;\n }\n result\n}\n\n// ------------------------------ ARITHMETIC WITH FLAGS HELPER FUNCTIONS ------------------------------\n// These are the functions that compute modular operations results as well as borrow and carry flags for constraints\n\n/// Compute the `MOD - val` and the corresponding borrow flags (unconstrained)\n///\n/// Negate the value and compute the flags indicating whether we need\n/// to borrow a `bit` from the upper limb when subtracting the value from modulus\n///\n/// ## Note\n/// The `borrow_in` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __neg_with_flags(\n modulus: [u128; N],\n val: [u128; N],\n) -> ([u128; N], [bool; N - 1]) {\n let mut result: [u128; N] = [0; N];\n let mut borrow_in: u128 = 0;\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n for i in 0..N {\n let sub_term: u128 = val[i] + borrow_in;\n borrow_in = (sub_term > modulus[i]) as u128;\n result[i] = borrow_in * TWO_POW_120 + modulus[i] - sub_term;\n if (i < N - 1) {\n borrow_flags[i] = (borrow_in != 0);\n }\n }\n (result, borrow_flags)\n}\n\n/// Compute modular addition and the corresponding borrow and carry flags (unconstrained)\n///\n/// Given `x, y, MOD` compute x + y or x + y - MOD in case it overflows\n/// Additionally compute all the carries from addition (x + y)\n/// and borrows from subtraction (- MOD)\n///\n/// ## Note\n/// The `borrow` must be equal to `carry` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __add_with_flags(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [bool; N - 1], [bool; N - 1], bool) {\n let mask: u128 = TWO_POW_120 - 1;\n\n let add_res: [u128; N] = __helper_add(lhs, rhs);\n let overflow: bool = __gte(add_res, modulus);\n\n let mut subtrahend: [u128; N] = if overflow { modulus } else { [0; N] };\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let mut carry_flags: [bool; N - 1] = [false; N - 1];\n\n let mut carry: u128 = 0;\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = lhs[i] + rhs[i] + carry;\n carry = add_term >> 120;\n add_term &= mask;\n\n let sub_term: u128 = subtrahend[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n // Only set `borrow` and `carry` if they differ\n // And if it's not the last limb\n if (carry != borrow) & (i < N - 1) {\n carry_flags[i] = carry != 0;\n borrow_flags[i] = borrow != 0;\n }\n }\n (result, carry_flags, borrow_flags, overflow)\n}\n\n/// Compute modular subtraction and the corresponding borrow and carry flags (unconstrained)\n///\n/// Given `x, y, MOD` compute x - y or x - y + MOD in case it overflows\n/// Additionally compute all the carries from addition (x + MOD)\n/// and borrows from subtraction (- y)\n///\n/// ## Note\n/// The `borrow` must be equal to `carry` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __sub_with_flags(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [bool; N - 1], [bool; N - 1], bool) {\n let mask: u128 = TWO_POW_120 - 1;\n\n let underflow: bool = !__gte(lhs, rhs);\n\n let addend: [u128; N] = if underflow { modulus } else { [0; N] };\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let mut carry_flags: [bool; N - 1] = [false; N - 1];\n\n let mut carry: u128 = 0;\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = lhs[i] + addend[i] + carry;\n carry = add_term >> 120;\n add_term &= mask;\n\n let sub_term: u128 = rhs[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n // Only set `borrow` and `carry` if they differ\n // And if it's not the last limb\n if (carry != borrow) & (i < N - 1) {\n carry_flags[i] = carry != 0;\n borrow_flags[i] = borrow != 0;\n }\n }\n (result, carry_flags, borrow_flags, underflow)\n}\n\n/// Validate that lhs - rhs does not underflow (unconstrained)\n///\n/// Same as `__validate_gte_with_flags`, but we don't compute the\n/// result of a subtraction\npub(crate) unconstrained fn __validate_in_field_compute_borrow_flags(\n params: BigNumParams,\n val: [u128; N],\n) -> [bool; N - 1] {\n let modulus: [u128; N] = params.modulus;\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n borrow_flags[0] = modulus[0] < val[0];\n for i in 1..N - 1 {\n borrow_flags[i] = modulus[i] < val[i] + (borrow_flags[i - 1] as u128);\n }\n borrow_flags\n}\n\n/// Validate that lhs - rhs does not underflow (unconstrained)\n///\n/// Compute underflow flag (lhs < rhs)\n/// then perform subtraction with borrow flags\n///\n/// ## Note\n/// The `borrow` must be equal to 0 at the end of the loop.\n/// And it can't be nonzero, since we swap the terms at the beginning\npub(crate) unconstrained fn __validate_gte_with_flags(\n lhs: [u128; N],\n rhs: [u128; N],\n) -> (bool, [u128; N], [bool; N - 1]) {\n let mut a: [u128; N] = lhs;\n let mut b: [u128; N] = rhs;\n\n let underflow: bool = !__gte(lhs, rhs);\n // swap a and b if there's an underflow\n let (a, b): ([u128; N], [u128; N]) = if underflow { (b, a) } else { (a, b) };\n\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = a[i];\n\n let sub_term: u128 = b[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n if (i < N - 1) {\n borrow_flags[i] = borrow != 0;\n }\n }\n (underflow, result, borrow_flags)\n}\n\n// ------------------------------ BARRETT REDUCTION ------------------------------\n\n/// `BARRETT_REDUCTION_OVERFLOW_BITS` defines how large an input to barrett reduction can be\n///\n/// maximum value = modulus^2 << BARRETT_REDUCTION_OVERFLOW_BITS\n/// see __barrett_reduction for more details\ncomptime global BARRETT_REDUCTION_OVERFLOW_BITS: u32 = 4;\n\n/// Optimized modular multiplication (unconstrained)\n///\n/// The trick is to approximate 1/p with m/2**r, because division by 2**r is much cheaper\n/// In our case m = redc_param = floor(2^{MOD_BITS * 2 + BARRET_REDUCTION_OVERFLOW_BITS} / p)\n/// r = MOD_BITS * 2 + BARRET_REDUCTION_OVERFLOW_BITS\n///\n/// When we apply the barrett reduction, the maximum value of the output will be <= p * (1 + x/2^{2k})\n/// where p = modulus,\n/// x = reduction input\n///\n/// If x > p * p, we need k to be larger than modulus_bits()\n/// We hardcode k = 4, which means that the maximum value of x is approx. 16 * p * p\n/// This should be larger than most values put into `evaluate_quadratic_expression`\n///\n/// ## TODO\n/// Detect cases where x might be too large at comptime\n///\n/// ## Note\n/// very niche edge case error that we need to be aware of:\n/// N must be large enough to cover the modulus *plus* BARRETT_REDUCTION_OVERFLOW_BITS\n/// i.e. a 359-bit prime needs (I think) 4 limbs to represent or we may overflow\n/// when calling __barrett_reduction\n///\n/// ## Note on final reduction\n///\n/// Assumptions:\n/// - k = ceil(log2 p), so p <= 2^k\n/// - s = 4, m = redc_param = floor(2^{2*k + s}/p)\n/// - x < 16 * p^2 (x < 2^{2 * k + s})\n///\n/// Let m' = 2^{2*k + s} / p, and write m = m' - \\epsilon, \\epsilon \\in [0, 1)\n//\n/// quo = floor(x * m / 2^{2 * k + s}) = floor(x * m' / 2^{2 * k + s} - x * \\epsilon / 2^{2 * k + s}) =\n/// floor(x / p - x * \\epsilon / 2^{2 * k + s})\n///\n/// Bounds:\n/// quo <= floor(x / p)\n///\n/// floor(a - b) >= floor(a) - ceil(b) (known identity) =>\n/// quo >= floor(x / p) - ceil(x * \\epsilon / 2^{2 * k + s})\n/// >= floor(x / p) - ceil(x / 2^{2 * k + s}) (epsilon < 1)\n///\n/// x / 2^{2 * k + s} < C * p^2 / 2^{2 * k + s} <= C * 2^{2 * k} / 2^{2 * k + s} = C / 2^s\n///\n/// When the assumption holds (C = 16), ceil(x / 2^{2 * k + s}) = 1, for x > 0\n/// Therefore quo = {floor(x/p), floor(x/p) - 1}\n///\n/// In first case: rem = x - quo * p = x - floor(x/p) * p < p\n/// In second case: rem = x - (floor(x/p) - 1) * p = (x - floor(x/p) * p) + p -> need 1 subtraction\n///\n/// ### Note\n/// We allow 64 products to be summed inside the `evaluate_quadratic_expression`\n/// In that case x / 2^{2 * k + s} < 64 / 2^4 = 4 => hence we need to subtract modulus at most 4 times\n/// We can leave it 2 for now as it is unlikely to reach beyond 32 * p^2\n///\n/// In the worst case though, we will have the input > 64 * p^2\n/// (for example (a1 + b1) * (c1 + d1) + ... 64 times)\n/// This is highly unlikely though.\n///\n/// ### TODO:\n/// Possibly change the `BARRETT_REDUCTION_OVERFLOW_BITS` to 6, so that we need only 1 reduction here\n/// However we will have to recompute all the fields `redc_param`s and fix paramgen\npub(crate) unconstrained fn __barrett_reduction(\n x: [u128; 2 * N],\n redc_param: [u128; N],\n k: u32,\n modulus: [u128; N],\n) -> ([u128; N], [u128; N]) {\n // TODO: switch to __helper_mul, once the compiler is smart enough to handle this\n let mut mulout_field: [Field; 3 * N] = [0; 3 * N];\n for i in 0..(2 * N) {\n for j in 0..N {\n mulout_field[i + j] += (x[i] as Field) * (redc_param[j] as Field);\n }\n }\n let mulout: [u128; 3 * N] = __normalize_limbs(mulout_field);\n\n let quotient: [u128; 3 * N] = __shr(mulout, (k + k + BARRETT_REDUCTION_OVERFLOW_BITS));\n\n // Remove a bunch of zeros from the end\n let mut smaller_quotient: [u128; N] = [0; N];\n for i in 0..N {\n smaller_quotient[i] = quotient[i] as u128;\n }\n\n // long_quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array\n let long_quotient_mul_modulus: [u128; 2 * N] = __helper_mul(smaller_quotient, modulus);\n let long_remainder: [u128; 2 * N] = __helper_sub(x, long_quotient_mul_modulus);\n\n // Remove a bunch of zeros from the end\n let mut remainder: [u128; N] = [0; N];\n for i in 0..N {\n remainder[i] = long_remainder[i];\n }\n\n for _ in 0..2 {\n if (__gte(remainder, modulus)) {\n remainder = __helper_sub(remainder, modulus);\n smaller_quotient = __increment(smaller_quotient);\n }\n }\n\n (smaller_quotient, remainder)\n}\n\n// ------------------------------ ARITHMETIC HELPER FUNCTIONS ------------------------------\n// These are the functions that operate on limbs as if they were just big integers\n\n/// Adds `1` to the BigNum value without modular reduction (unconstrained)\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __increment(val: [u128; N]) -> [u128; N] {\n let mask: u128 = TWO_POW_120 - 1;\n\n let mut result: [u128; N] = [0; N];\n let mut carry: u128 = 1;\n for i in 0..N {\n let add_term: u128 = val[i] + carry;\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n result\n}\n\n/// Adds two `BigNum` values without modular reduction (unconstrained).\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __helper_add(lhs: [u128; N], rhs: [u128; N]) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let mut carry: u128 = 0;\n let mask: u128 = TWO_POW_120 - 1;\n\n for i in 0..N {\n let add_term: u128 = lhs[i] + rhs[i] + carry;\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n result\n}\n\n/// Subtracts two `BigNum` values without modular reduction (unconstrained).\n///\n/// ## Note\n/// The `borrow` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __helper_sub(lhs: [u128; N], rhs: [u128; N]) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let mut borrow: u128 = 0;\n for i in 0..N {\n let subtrahend: u128 = rhs[i] + borrow;\n borrow = (subtrahend > lhs[i]) as u128;\n result[i] = (borrow << 120) + lhs[i] - subtrahend;\n }\n result\n}\n\n/// Multiplies two `BigNum` values without modular reduction (unconstrained).\n///\n/// Computes the full schoolbook product of two N-limb little-endian arrays\n///\n/// ## Note\n/// The mathematical product fits in `2 * N - 1` limbs, but we keep `2 * N`\n/// limbs intentionally as the extra high limb safely absorbs a possible single limb overflow\n/// for moduli close to `120 * N` bits.\npub(crate) unconstrained fn __helper_mul(\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; 2 * N] {\n let mut result: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n result[i + j] += (lhs[i] as Field) * (rhs[j] as Field);\n }\n }\n __normalize_limbs(result)\n}\n\n// ------------------------------ LOGIC HELPER FUNCTIONS ------------------------------\n// These are the functions that operate on limbs as if they were just big integers\n\n/// Left-shifts a `BigNum` value by `shift` bits (unconstrained).\n///\n/// Performs a bitwise left shift across limbs.\n///\n/// ## Note\n/// The most significant limb is truncated to 120 bits after the shift.\n///\n/// No bounds check is performed on `num_shifted_limbs`.\n/// However, we use it only in `__udiv_mod`, where it is not possible to reach\n/// `num_shifted_limbs` > `N`\npub(crate) unconstrained fn __shl(input: [u128; N], shift: u32) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let num_shifted_limbs: u32 = shift / 120;\n let limb_shift: u128 = (shift % 120) as u128;\n let remainder_shift: u128 = 120 - limb_shift;\n\n let mask: u128 = TWO_POW_120 - 1;\n let mut remainder: u128 = input[0] >> remainder_shift;\n\n result[num_shifted_limbs] = (input[0] << limb_shift) & mask;\n\n for i in 1..(N - num_shifted_limbs) {\n let value: u128 = input[i];\n let upshift: u128 = ((value << limb_shift) | remainder) & mask;\n result[i + num_shifted_limbs] = upshift;\n remainder = value >> remainder_shift;\n }\n result\n}\n\n/// Right-shifts a `BigNum` value by `shift` bits (unconstrained).\n///\n/// Performs a bitwise right shift across limbs.\n///\n/// # Note\n/// No bounds check is performed on `num_shifted_limbs`.\n/// However, we use it only in `__tonelli_shanks_sqrt`, where it is not possible to reach\n/// `num_shifted_limbs` > `N`\npub(crate) unconstrained fn __shr(input: [u128; N], shift: u32) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let num_shifted_limbs: u32 = shift / 120;\n let limb_shift: u128 = (shift % 120) as u128;\n\n let remainder_shift: u128 = 120 - limb_shift;\n let low_mask: u128 = (1 as u128 << limb_shift) - 1;\n\n result[0] = input[num_shifted_limbs] >> limb_shift;\n for i in 1..(N - num_shifted_limbs) {\n let value: u128 = input[i + num_shifted_limbs];\n\n let carry: u128 = (value & low_mask) << remainder_shift;\n result[i - 1] |= carry;\n\n result[i] = value >> limb_shift;\n }\n result\n}\n\n/// Right-shifts a `BigNum` value by `1` bit (unconstrained)\n///\n/// # Note\n/// All the operations on limbs are executed in place\n/// to save opcodes\npub(crate) unconstrained fn __shr1(mut input: [u128; N]) -> [u128; N] {\n let value: u128 = input[N - 1];\n let mut remainder: u128 = (value & 1) << 119;\n input[N - 1] >>= 1;\n\n for i in 1..N {\n let value: u128 = input[N - 1 - i];\n input[N - 1 - i] = (value >> 1) | remainder;\n remainder = (value & 1) << 119;\n }\n input\n}\n\n/// Returns the index of the most significant set bit in a `BigNum` value (unconstrained).\npub(crate) unconstrained fn __get_msb(val: [u128; N]) -> u32 {\n let mut count: u32 = 0;\n for i in 0..N {\n let idx: u32 = N - 1 - i;\n let v: u128 = val[idx];\n if (v > 0) {\n count = 120 * idx + get_msb(v);\n break;\n }\n }\n count\n}\n\n/// Returns `true` if the bit at position `bit` is set in the `BigNum` (unconstrained).\n///\n/// ## Note\n/// No bounds check is performed on `bit`\npub(crate) fn __get_bit(input: [u128; N], bit: u32) -> bool {\n let segment_index: u32 = bit / 120;\n let uint_index: u128 = (bit % 120) as u128;\n\n let limb: u128 = input[segment_index];\n let value: u128 = (limb >> uint_index) & 1;\n value == 1\n}\n\n// ------------------------------ SQRT HELPER FUNCTIONS ------------------------------\n// These are the functions that are used during taking a square root\n\n/// Compute the maximal power of 2 that divides the group order (unconstrained)\n///\n/// Find the maximum value s such that `MOD = 2^s * q + 1`, where `q` is odd\n/// This is needed for our Tonelli-Shanks sqrt algorithm\npub(crate) unconstrained fn __primitive_root_log_size(\n params: BigNumParams,\n) -> u32 {\n let mut target: [u128; N] = __helper_sub(params.modulus, __one());\n let mut result: u32 = 0;\n while !__get_bit(target, result) {\n result += 1;\n }\n result\n}\n\n/// Find a quadratic non-residue `g` where `g` is the smallest such value (unconstrained)\n/// i.e. smallest `g` such that `g^{(p - 1)/2} = -1 (mod MOD)`\n/// or smallest `g`, such that `x^2 - g = 0 (mod MOD)` has no solutions\n///\n/// ## Note\n/// WARNING If the field is not prime, this function will enter an infinite loop!\npub(crate) unconstrained fn __quadratic_non_residue(\n params: BigNumParams,\n) -> [u128; N] {\n let one: [u128; N] = __one();\n let neg_one: [u128; N] = __neg(params.modulus, one);\n\n let p_minus_one_over_two: [u128; N] = __shr1(__helper_sub(params.modulus, __one()));\n\n // We start with 2\n let mut target: [u128; N] = __increment(one);\n let mut expd: [u128; N] = __pow(params, target, p_minus_one_over_two);\n while !__eq(expd, neg_one) {\n target = __increment(target);\n expd = __pow(params, target, p_minus_one_over_two);\n }\n target\n}\n\n/// Compute the smallest `i`, such that `t^{2^i} = 1, t^{2^{i-1}} = -1 (mod MOD)` (unconstrained)\n///\n/// ## Note\n/// Multiplicative order of t must divide 2^v2(MOD-1), otherwise you'll end up in an infinite loop!\npub(crate) unconstrained fn __tonelli_shanks_sqrt_find_i(\n params: BigNumParams,\n t: [u128; N],\n) -> u32 {\n let one: [u128; N] = __one();\n let mut c: [u128; N] = t;\n\n let mut i: u32 = 0;\n // Compute t^{2^k} until it hits 1 for the first time\n while !__eq(c, one) {\n c = __sqr::(params, c);\n i += 1;\n }\n i\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/unconstrained_helpers.nr" + }, + "125": { + "source": "// This file contains the unconstrained operations that are used directly by BigNum class\n\nuse crate::fns::constrained_ops::derive_from_seed;\n\nuse crate::fns::unconstrained_helpers::{\n __barrett_reduction, __get_bit, __get_msb, __helper_add, __helper_mul, __helper_sub,\n __increment, __one, __primitive_root_log_size, __quadratic_non_residue, __shl, __shr, __shr1,\n __tonelli_shanks_sqrt_find_i,\n};\n\nuse crate::constants::TWO_POW_120;\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ DERIVATION FUNCTIONS ------------------------------\n\n/// Deterministically derives a `BigNum` from a seed value (unconstrained)\n///\n/// Takes a seed byte array and generates a `BigNum` in the range [0, modulus-1].\n///\n/// See more information in `constrained_ops.nr`: `derive_from_seed`\npub(crate) unconstrained fn __derive_from_seed(\n params: BigNumParams,\n seed: [u8; SeedBytes],\n) -> [u128; N] {\n derive_from_seed::(params, seed)\n}\n\n// ------------------------------ COMPARISON FUNCTIONS ------------------------------\n\n/// Compare two limb arrays for equality (unconstrained)\npub(crate) unconstrained fn __eq(lhs: [u128; N], rhs: [u128; N]) -> bool {\n lhs == rhs\n}\n\n/// Compare a limb array to a zero array (unconstrained)\npub(crate) unconstrained fn __is_zero(limbs: [u128; N]) -> bool {\n limbs == [0; N]\n}\n\n/// Compare two little-endian limb arrays for `lhs >= rhs` over integers (unconstrained)\n///\n/// Starts from the most significant limb (`N - 1`) and returns true\n/// if `lhs` is greater or equal to `rhs`\npub(crate) unconstrained fn __gte(lhs: [u128; N], rhs: [u128; N]) -> bool {\n let mut result: bool = true;\n for i in 0..N {\n let idx: u32 = N - 1 - i;\n if (lhs[idx] != rhs[idx]) {\n result = lhs[idx] > rhs[idx];\n break;\n }\n }\n result\n}\n\n// ------------------------------ ARITHMETIC FUNCTIONS ------------------------------\n\n/// Negates a `BigNum` value, returning `m - x` (unconstrained)\n///\n/// ## Note\n/// The input is assumed to be less than modulus\npub(crate) unconstrained fn __neg(modulus: [u128; N], limbs: [u128; N]) -> [u128; N] {\n __helper_sub(modulus, limbs)\n}\n\n/// Adds two `BigNum` values with modular reduction (unconstrained)\n///\n/// Sums the limbs one by one, keeping the carry.\n/// In case the result overflows the modulus, the modulus is subtracted once\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __add(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n let mut carry: u128 = 0;\n let mask: u128 = TWO_POW_120 - 1;\n\n for i in 0..N {\n let add_term: u128 = (lhs[i] + rhs[i] + carry);\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n\n // check if the result is greater than the modulus\n if __gte(result, modulus) {\n __helper_sub(result, modulus)\n } else {\n result\n }\n}\n\n/// Subtracts two `BigNum` values with modular reduction (unconstrained).\n///\n/// Computes `x + (m - y)` (mod m)\npub(crate) unconstrained fn __sub(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n __add(modulus, lhs, __neg(modulus, rhs))\n}\n\n/// Multiply `x` and `y` and reduce via Barrett, returning (Q, R) (unconstrained).\n///\n/// For `BigNum` values `x` and `y` compute (`Q`, `R`) such that:\n/// x * y = R + Q * m, 0 <= R < m\n/// See `__barrett_reduction` for details.\npub(crate) unconstrained fn __mul_with_quotient(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [u128; N]) {\n let to_reduce: [u128; N * 2] = __helper_mul(lhs, rhs);\n let (q, r): ([u128; N], [u128; N]) =\n __barrett_reduction(to_reduce, params.redc_param, MOD_BITS, params.modulus);\n (q, r)\n}\n\n/// Multiplies two `BigNum` values with modular reduction (unconstrained).\npub(crate) unconstrained fn __mul(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n __mul_with_quotient::(params, lhs, rhs).1\n}\n\n/// Squares a `BigNum` value with modular reduction (unconstrained).\npub(crate) unconstrained fn __sqr(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n __mul_with_quotient::(params, val, val).1\n}\n\n/// Modular exponentiation via square-and-multiply. LSB-first (unconstrained).\n///\n/// Computes `x^e mod m`\n///\n/// ## Note\n/// For the loop, we are using `MOD_BITS` instead of `__get_msb`\n/// because it is much much cheaper\npub(crate) unconstrained fn __pow(\n params: BigNumParams,\n val: [u128; N],\n exponent: [u128; N],\n) -> [u128; N] {\n let mut accumulator: [u128; N] = __one();\n let mut x: [u128; N] = val;\n let num_bits: u32 = MOD_BITS + 1;\n\n for i in 0..num_bits {\n if __get_bit(exponent, i) {\n accumulator = __mul::(params, accumulator, x);\n }\n x = __sqr::(params, x);\n }\n accumulator\n}\n\n/// Given a `BigNum` value `x` compute x^{-1} (mod m) (unconstrained)\n///\n/// x^{p-1} = 1 (mod p) (Fermat's little theorem)\n/// x^{p-2} = x^{-1} (mod p)\n///\n/// ## Note\n/// The input value must be nonzero and modulus has to be prime\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __invmod(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n let one: [u128; N] = __one();\n let exp: [u128; N] = __helper_sub(params.modulus, __helper_add(one, one));\n __pow::(params, val, exp)\n}\n\n/// Divides two `BigNum` values with modular reduction (unconstrained).\n///\n/// Computes `x * y^{-1}` (mod m)\n///\n/// ## Note\n/// The divisor must be nonzero\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __div(\n params: BigNumParams,\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n let inv_divisor: [u128; N] = __invmod::(params, divisor);\n __mul::(params, numerator, inv_divisor)\n}\n\n/// Given the `BigNum` inputs `x, y`, compute integer division x / y (unconstrained)\n///\n/// This function implements binary long division and outputs (`quotient`, `remainder`) such that:\n/// 1. floor(numerator / divisor) = quotient\n/// 2. numerator % divisor = remainder\n/// 3. divisor * quotient + remainder = numerator\n///\n/// ## Note\n/// The divisor must be nonzero\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __udiv_mod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> ([u128; N], [u128; N]) {\n let mut quotient: [u128; N] = [0; N];\n let mut remainder: [u128; N] = numerator;\n let b: [u128; N] = divisor;\n\n let numerator_msb: u32 = __get_msb(numerator);\n let divisor_msb: u32 = __get_msb(divisor);\n if divisor_msb > numerator_msb {\n ([0; N], numerator)\n } else {\n let mut bit_difference: u32 = __get_msb(remainder) - __get_msb(divisor);\n let mut divisor: [u128; N] = __shl(divisor, bit_difference);\n let mut accumulator: [u128; N] = __shl(__one(), bit_difference);\n\n // The same as divisor > remainder\n if (__gte(divisor, __increment(remainder))) {\n divisor = __shr1(divisor);\n accumulator = __shr1(accumulator);\n }\n\n for _ in 0..(N * 120) {\n if (__gte(remainder, b) == false) {\n break;\n }\n // we've shunted 'divisor' up to have the same bit length as our remainder.\n // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b\n if (__gte(remainder, divisor)) {\n remainder = __helper_sub(remainder, divisor);\n // we can use OR here instead of +, as\n // accumulator is always a nice power of two\n quotient = __helper_add(quotient, accumulator);\n }\n divisor = __shr1(divisor);\n accumulator = __shr1(accumulator);\n }\n\n (quotient, remainder)\n }\n}\n\n/// Batch modular inversion of `BigNum` values in an array (unconstrained)\n///\n/// Given values v[0..M), returns inv[0...M) with inv[i] = v[i]^{-1} (mod m)\n///\n/// We use the Montgomery trick:\n/// First we compute the partial products:\n/// T0 = 1\n/// T1 = v1,\n/// T2 = v1 * v2,\n/// ...\n/// T_{m - 1} = T_{m - 2} * v_{m - 1} = v1 * ... * v_{m - 1}\n///\n/// P = T_{m-1} * v_m = v1 * v2 * ... * v_m\n///\n/// Then we calculate a single inverse P^-1 = v1^-1 * v2^-1 * ... * v_m^-1\n/// Finally we compute\n/// v_m^-1 = (P^-1 * T_{m-1})\n/// v_{m - 1}^-1 = (P^-1 * v_m * T_{m - 2})\n/// ....\n/// v_2^-1 = (P^-1 * v_m * ... * v_3 * T_1)\n/// v_1^-1 = (P^-1 * v_m * ... * v_2 * T_0)\n///\n/// ## Note\n/// Zero elements are allowed and are left unchanged in the resulting array\n///\n/// This interacts poorly with `neg(zero)`:\n/// Calling `neg` on `zero` yields `modulus` rather than `0`.\n/// A value in this form will **not** satisfy\n/// the `__is_zero` check and will lead to incorrect results.\n///\n/// This edge case should be rare, but it's worth keeping in mind when\n/// composing operations or debugging unexpected behavior\npub(crate) unconstrained fn batch_invert(\n params: BigNumParams,\n vals: [[u128; N]; M],\n) -> [[u128; N]; M] {\n let mut accumulator: [u128; N] = __one();\n let mut temporaries: [[u128; N]; M] = [[0; N]; M];\n\n for i in 0..M {\n temporaries[i] = accumulator;\n if (!__is_zero(vals[i])) {\n accumulator = __mul::(params, accumulator, vals[i]);\n }\n }\n\n let mut result: [[u128; N]; M] = [[0; N]; M];\n accumulator = __invmod::(params, accumulator);\n for i in 0..M {\n let idx: u32 = M - 1 - i;\n if (!__is_zero(vals[idx])) {\n let T0: [u128; N] = __mul::(params, accumulator, temporaries[idx]);\n accumulator = __mul::(params, accumulator, vals[idx]);\n result[idx] = T0;\n }\n }\n result\n}\n\n/// Batch modular inversion of `BigNum` values in a slice (unconstrained)\n///\n/// See `batch_invert` for details\npub(crate) unconstrained fn batch_invert_slice(\n params: BigNumParams,\n vals: [[u128; N]],\n) -> [[u128; N]] {\n let mut accumulator: [u128; N] = __one();\n let mut temporaries: [[u128; N]] = &[];\n\n let M: u32 = vals.len();\n\n for i in 0..M {\n temporaries = temporaries.push_back(accumulator);\n if (!__is_zero(vals[i])) {\n accumulator = __mul::(params, accumulator, vals[i]);\n }\n }\n\n let mut result: [[u128; N]] = [];\n accumulator = __invmod::(params, accumulator);\n for i in 0..M {\n let idx: u32 = M - 1 - i;\n if (!__is_zero(vals[idx])) {\n let T0: [u128; N] = __mul::(params, accumulator, temporaries[idx]);\n accumulator = __mul::(params, accumulator, vals[idx]);\n result = result.push_front(T0);\n } else {\n result = result.push_front([0; N]);\n }\n }\n\n result\n}\n\n/// Compute a modular square root in a prime field (unconstrained)\npub(crate) unconstrained fn __sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n assert(\n params.has_multiplicative_inverse,\n \"BigNum::__sqrt: Must be a field to take square roots\",\n );\n\n if (__is_zero(input)) {\n Option::some(input)\n } else if (params.modulus[0] % 4 == 3) {\n __easy_sqrt(params, input)\n } else {\n __tonelli_shanks_sqrt(params, input)\n }\n}\n\n/// Compute a modular square root using the Tonelli-Shanks algorithm (unconstrained)\n///\n/// Solves `x^2 = a (mod MOD)` for odd prime MOD\n///\n/// ## Algorithm\n///\n/// Here p = MOD\n///\n/// Tonelli-Shanks setup\n///\n/// Write `p - 1 = 2^s * Q`, `Q` - odd\n/// Define:\n/// `R = a^{(Q+1)/2}`\n/// `t = a^Q`\n///\n/// so that `R^2 = a^{Q + 1} = a * a^Q = a * t`\n/// If t = 1, we are done\n///\n/// By Euler's criterion, `a` is a quadratic reside iff `a^{(p - 1)/2} = 1`\n/// Since `t = a^Q` and `(p - 1) / 2 = Q * 2^{s-1}` we have:\n/// `t^{2^{s-1}} = a^{Q * 2^{s-1}} = a^{(p-1)/2} = 1`, assuming `a` is a q.r.\n///\n/// To proceed with computing our square root, we want to transfer `t` into a smaller subgroup,\n/// specifically, the `2^(s-2)`'th roots of unity or lower.\n///\n/// We do this by finding some value `b`, such that\n/// `(t * b^2)^{2^{s-2}} = 1` and `R' = R * b`\n/// Finding such a `b` is trivial, because from Euler's criterion, we know that,\n/// for any quadratic non-residue `z`, `z^{(p - 1) / 2} = -1`\n/// i.e. `z^{Q * 2^{s-1}} = -1`\n/// => `z^Q` is a `2^{s-1}`'th root of `-1`\n/// => `z^{2 * Q}` is a `2^{s-2}`'th root of `-1`\n///\n/// Since `t^{2^{s-1}} = 1`, we know that for some `i`, `i <= s - 2: t^{2^{i-1}} = -1`\n/// => `t * z^{2 * Q}` is a `2^{s - 2}`'th root of unity.\n/// We can iteratively transform `t` into ever smaller subgroups, until `t = 1`.\n/// At each iteration, we need to find a new value for `b`, which we can obtain\n/// by repeatedly squaring `z^Q`\n///\n/// ## Note\n/// Only use for prime fields! Function may infinite loop if used for non-prime fields\n///\n/// The input is assumed to be a nonzero value\npub(crate) unconstrained fn __tonelli_shanks_sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n let mut result: Option<[u128; N]> = Option::none();\n\n let one: [u128; N] = __one();\n let s: u32 = __primitive_root_log_size::(params); // p - 1 = 2^s * Q, where Q is odd\n let Q: [u128; N] = __shr(__helper_sub(params.modulus, one), s);\n let Q_minus_one_over_two: [u128; N] = __shr1(__helper_sub(Q, one)); // (Q - 1) / 2\n\n let z: [u128; N] = __quadratic_non_residue::(params);\n\n // Initialize:\n // b = a^{(Q - 1)/2}\n // R = a * b = a^{(Q + 1) / 2} => R^2 = a * a^Q\n // t = R * b = a^Q\n let mut b: [u128; N] = __pow::<_, MOD_BITS>(params, input, Q_minus_one_over_two);\n let mut r: [u128; N] = __mul::<_, MOD_BITS>(params, input, b);\n let mut t: [u128; N] = __mul::<_, MOD_BITS>(params, r, b);\n\n let mut check: [u128; N] = t;\n // Assure t^{2^{s - 1}} = a^{(p -1)/2} = 1, otherwise we have met a non-residue\n for _ in 0..s - 1 {\n check = __sqr::(params, check);\n }\n if (__eq(check, one)) {\n let mut m: u32 = s;\n let mut c: [u128; N] = __pow::(params, z, Q); // z^Q - proper 2^{M}'th root of unity\n\n // Tonelli-Shanks main loop\n\n // At the beginning of each iteration we have:\n // M - current exponent such that t lies in the subgroup of order 2^m\n // t - element, whose order divides 2^m\n // c - the proper 2^M'th root of unity\n // R - accumulator with R^2 = a * t\n\n // If t == 1, we are done and R is a square root\n //\n // Otherwise\n // 1. We compute 1 <= i < M, such that t^{2^i} = 1, t^{2^{i - 1}} = -1\n // 2. Set b = c^{2^{M - i - 1}}, so it becomes a proper 2^(i+1)'th root of unity\n // Then b^2 has order 2^i which matches the order of t\n //\n // 3. Update the state values:\n // R <- R * b\n // t <- t * b^2\n // c <- b^2 = c^{2^{M - i}}\n // M <- i\n // reduces the order of t from 2^i to at most 2^{i - 1} and preserves R^2 = a * t\n //\n // The loop runs at most s times because M strictly decreases\n for _ in 0..s {\n if (__eq(t, one)) {\n result = Option::some(r);\n break;\n }\n let i: u32 = __tonelli_shanks_sqrt_find_i::(params, t);\n let mut j: u32 = m - i - 1;\n b = c;\n for _ in 0..j {\n b = __sqr(params, b);\n }\n\n let b2: [u128; N] = __sqr::(params, b);\n c = b2;\n t = __mul::(params, t, b2);\n r = __mul::(params, r, b);\n m = i;\n }\n }\n result\n}\n\n/// Compute a modular square root for MOD = 3 (mod 4) (unconstrained)\n///\n/// In case MOD = 3 (mod 4), the square root can be computed using the formula:\n/// `R = a^{(MOD + 1) / 4} (mod MOD)`\n///\n/// Then R^2 = a^{(MOD + 1)/ 4 * 2} = a^{(MOD + 1) / 2} = a^{(MOD - 1) / 2 + 1} = a\n///\n/// ## Note\n/// The input is assumed to be a nonzero value\n///\n/// This is much cheaper than `__tonelli_shanks_sqrt`\npub(crate) unconstrained fn __easy_sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n let mut result: Option<[u128; N]> = Option::none();\n\n let one: [u128; N] = __one();\n let p_minus_one_over_two: [u128; N] = __shr1(__helper_sub(params.modulus, one));\n let mut check: [u128; N] = __pow(params, input, p_minus_one_over_two);\n if (__eq(check, one)) {\n // a = (MOD - 1) / 2\n // b = (a + 1) / 2 = ((MOD - 1) / 2 + 1) / 2 = (MOD + 1) / 4\n let p_plus_one_over_four: [u128; N] = __shr1(__increment(p_minus_one_over_two));\n result = Option::some(__pow(params, input, p_plus_one_over_four));\n }\n result\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/unconstrained_ops.nr" + }, + "134": { + "source": "use std::ops::WrappingMul;\n\nglobal MUL_DE_BRUIJN_BIT: [u32; 128] = [\n 1, 14, 2, 15, 26, 20, 3, 16, 68, 80, 27, 21, 56, 50, 4, 17, 65, 96, 69, 81, 105, 99, 28, 22, 86,\n 90, 57, 51, 72, 42, 5, 126, 18, 66, 48, 94, 97, 84, 70, 124, 82, 122, 106, 100, 114, 108, 29,\n 23, 77, 102, 87, 91, 119, 116, 58, 52, 61, 110, 73, 37, 43, 31, 6, 127, 13, 25, 19, 67, 79, 55,\n 49, 64, 95, 104, 98, 85, 89, 71, 41, 125, 47, 93, 83, 123, 121, 113, 107, 76, 101, 118, 115, 60,\n 109, 36, 30, 12, 24, 78, 54, 63, 103, 88, 40, 46, 92, 120, 112, 75, 117, 59, 35, 11, 53, 62, 39,\n 45, 111, 74, 34, 10, 38, 44, 33, 9, 32, 8, 7, 128,\n];\n\n/// Get the most significant bit position of a `val` (unconstrained)\n///\n/// Bit hack that uses De Bruijn sequence to calculate msb position in log(N)\n/// See [IntegerLog2DeBruijn](https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn)\npub(crate) unconstrained fn get_msb(x: u128) -> u32 {\n let result: u32 = if x == 0 {\n 0\n } else {\n let mut v: u128 = x;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v |= v >> 32;\n v |= v >> 64;\n let index: u128 = (v.wrapping_mul(0x1FC10C2FBCF471B913B14CD2595D6D5)) >> 121;\n MUL_DE_BRUIJN_BIT[index as u32]\n };\n result\n}\n\nmod tests {\n use crate::constants::{TWO_POW_120, TWO_POW_60};\n use crate::fns::unconstrained_helpers::__get_msb;\n use super::get_msb as get_msb128;\n use std::ops::WrappingMul;\n\n fn assert_msb_equal(x: u64) {\n // Safety: test code\n let msb64 = unsafe { get_msb64(x) };\n // Safety: test code\n let msb128 = unsafe { get_msb128(x as u128) };\n assert_eq(msb64, msb128);\n }\n\n #[test]\n /// Check that the msb functions are equivalent with de bruijn sequence for 64 bits and 128 bits\n fn test_get_msb() {\n // Test case 1: MSB at position 7\n let x: u64 = 0x80; // binary: 10000000\n assert_msb_equal(x);\n\n // Test case 2: MSB at position 0\n let x: u64 = 0x1; // binary: 00000001\n assert_msb_equal(x);\n\n // Test case 3: MSB at position 63\n let x: u64 = 0x8000000000000000; // binary: 1000...0000 (63 zeros)\n assert_msb_equal(x);\n\n // Test case 4: Zero input\n let x: u64 = 0x0;\n assert_msb_equal(x);\n\n // Test case 5: All bits set\n let x: u64 = 0xFFFFFFFFFFFFFFFF;\n assert_msb_equal(x);\n }\n\n /// Multiple entires in the `MUL_DE_BRUIJN_BIT` list do not map to a valid output of `v * 0x6c04f118e9966f6b`.\n /// This is a dummy value to fill the gaps in the map.\n global n1: u32 = 0xffffffff;\n\n global MUL_DE_BRUIJN_BIT_64: [u32; 128] = [\n 0, // change to 1 if you want bitSize(0) = 1\n 48, n1, n1, 31, n1, 15, 51, n1, 63, 5, n1, n1, n1, 19, n1, 23, 28, n1, n1, n1, 40, 36, 46,\n n1, 13, n1, n1, n1, 34, n1, 58, n1, 60, 2, 43, 55, n1, n1, n1, 50, 62, 4, n1, 18, 27, n1,\n 39, 45, n1, n1, 33, 57, n1, 1, 54, n1, 49, n1, 17, n1, n1, 32, n1, 53, n1, 16, n1, n1, 52,\n n1, n1, n1, 64, 6, 7, 8, n1, 9, n1, n1, n1, 20, 10, n1, n1, 24, n1, 29, n1, n1, 21, n1, 11,\n n1, n1, 41, n1, 25, 37, n1, 47, n1, 30, 14, n1, n1, n1, n1, 22, n1, n1, 35, 12, n1, n1, n1,\n 59, 42, n1, n1, 61, 3, 26, 38, 44, n1, 56,\n ];\n\n pub(crate) unconstrained fn get_msb64(x: u64) -> u32 {\n let mut v: u64 = x;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v |= v >> 32;\n let index: u64 = (v.wrapping_mul(0x6c04f118e9966f6b)) >> 57;\n (index as Field).assert_max_bit_size::<32>();\n MUL_DE_BRUIJN_BIT_64[index as u32]\n }\n\n unconstrained fn __get_msb64(val: [u128; N]) -> u32 {\n let mut count: u32 = 0;\n for i in 0..N {\n let v: u128 = val[((N) - 1 - i)];\n let v_low: u64 = v as u64 % TWO_POW_60 as u64;\n let v_high: u64 = ((v - v_low as u128) / TWO_POW_60) as u64;\n if (v_high > 0) {\n count = 60 * ((2 * N) - 1 - (i * 2)) + get_msb64(v_high);\n break;\n }\n if (v_low > 0) {\n count = 60 * ((2 * N) - 1 - (i * 2 + 1)) + get_msb64(v_low);\n break;\n }\n }\n count\n }\n\n #[test]\n // Check that the msb functions are equivalent with De Bruijn sequence for 64 bits and 128 bits\n unconstrained fn test_get_msb_equivalence() {\n // Test single limb (64-bit number)\n let x: Field = 0x8000000000000000;\n let arr: [u128; 4] = [0, 0, x as u128, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test multiple limbs (120-bit number)\n let x: Field = 0x800000000000000000000000000000; // 120 bits number, 2^119\n let arr: [u128; 4] = [0, 0, x as u128, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test zero\n let arr: [u128; 4] = [0, 0, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test all bits set (120 bits)\n let x: Field = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // 120 bits, 2^120 - 1\n let arr: [u128; 4] = [0, x as u128, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test systematic bit positions\n for i in 0..120 {\n let x: u128 = 1;\n let shifted: u128 = x << i;\n let arr: [u128; 4] = [0, shifted, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n }\n\n // Test random-like patterns (multiple bits set)\n let patterns: [Field; 7] = [\n 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // alternating bits\n 0x555555555555555555555555555555, // alternating bits (opposite)\n 0x1234567890ABCDEF1234567890ABCD, // some pattern\n 0xFEDCBA0987654321FEDCBA09876543, // some pattern\n 0x800000000000000000000000000001, // highest and lowest bits\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, // all bits except lowest\n 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFF, // all bits except highest\n ];\n for i in 0..patterns.len() {\n let arr: [u128; 4] = [0, patterns[i] as u128, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n }\n\n // Test with MSB in different array positions (120 bits)\n let x: Field = 0x800000000000000000000000000000; // 120 bits\n let arr1: [u128; 4] = [x as u128, 0, 0, 0];\n let arr2: [u128; 4] = [0, x as u128, 0, 0];\n let arr3: [u128; 4] = [0, 0, x as u128, 0];\n let arr4: [u128; 4] = [0, 0, 0, x as u128];\n let msb1_1: u32 = __get_msb64(arr1);\n let msb2_1: u32 = __get_msb(arr1);\n assert_eq(msb1_1, msb2_1);\n\n let msb1_2: u32 = __get_msb64(arr2);\n let msb2_2: u32 = __get_msb(arr2);\n assert_eq(msb1_2, msb2_2);\n\n let msb1_3: u32 = __get_msb64(arr3);\n let msb2_3: u32 = __get_msb(arr3);\n assert_eq(msb1_3, msb2_3);\n\n let msb1_4: u32 = __get_msb64(arr4);\n let msb2_4: u32 = __get_msb(arr4);\n assert_eq(msb1_4, msb2_4);\n }\n\n #[test]\n unconstrained fn fuzz_get_msb(seed: [u128; 5]) {\n let mut seed_copy: [u128; 5] = seed;\n for i in 0..5 {\n seed_copy[i] = seed_copy[i] & (TWO_POW_120 - 1);\n }\n let msb1: u32 = __get_msb64(seed_copy);\n let msb2: u32 = __get_msb(seed_copy);\n assert_eq(msb1, msb2);\n }\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/utils/msb.nr" + }, + "135": { + "source": "use crate::constants::TWO_POW_120;\n\n/// Split the Field value into two 120-bit limbs (unconstrained)\n///\n/// Here we're taking advantage of truncating 120 bit limbs from the input field\n/// and then subtracting them from the input such that the field division is equivalent\n/// to integer division.\n///\n/// We return the lower 120-bit limb as a `u128` value,\n/// and the upper limbs as a `Field`, to avoid unnecessary conversions\n/// and potential overflows\npub(crate) unconstrained fn __split_120_bits(mut x: Field) -> (u128, Field) {\n let low: u128 = (x as u128) % TWO_POW_120;\n let high: Field = ((x - low as Field) / TWO_POW_120 as Field);\n (low, high)\n}\n\n/// Normalize an array of Field values into 120-bit limbs (unconstrained)\n///\n/// Each Field element is split into two parts modulo 2^{120}\n/// The overflow from the lower limbs is carried into the higher limbs\npub(crate) unconstrained fn __normalize_limbs(input: [Field; N]) -> [u128; N] {\n let mut normalized: [u128; N] = [0; N];\n let mut next: Field = input[0];\n for i in 0..(N - 1) {\n let (lo, hi): (u128, Field) = __split_120_bits(next);\n normalized[i] = lo;\n next = input[i + 1] + hi;\n }\n let (lo, hi): (u128, Field) = __split_120_bits(next);\n normalized[N - 1] = lo;\n\n // non-zero final carry <=> normalized value overflows the array length\n assert(hi == 0);\n\n normalized\n}\n", + "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/utils/split_bits.nr" + } + }, + "expression_width": { "Bounded": { "width": 4 } } +} diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk new file mode 100644 index 0000000000000000000000000000000000000000..08f48fd083b6b6c83bcd5e870c96cd4108f5f0a0 GIT binary patch literal 1888 zcmajg`9Bkk1Hf@(wlTvn=iD}$^DDXUA=f;v9EEb#_f>Oct{lsgBUg^Ob0df`p_(CGucOJ|i2hl930gAWUJwBsWd?#%x;+4n=|cg73_FC$e)LNKY- zIclkU^04u(MReaE^0__c!zEq z;<`NlirX%`$mx_LEl$xem92*3R}ygCDN?%~^Sx3eEUr4ud(xSuajSJE+tM2iR+p^P zHq*nW+kO>N6>!E%eYsC5%outCjt@$H{2$Jrr0goKd}r5P za>vbvk-CrPD!mP8@H>Rx!e0F0W=R9_N$|i)&4TI*|EQnKMqScqvj-HrIz@4n<2pOY8E1F)JM0#pHnM1fU=0zy( z_%qMyxZWQx?+BR=?Il@r!~nf*&8}!Ns7pMpqrWQrc)Zw@*Z-7XUcHL^6Txd4J!V2Al*=;v4!!`K@gbfaSTLmu69!42Y3A`+F|$K0(dhza^ZX< zxk|O~ zCqvH%(i|T)QI3tbM`SoLL!OXRwE7})MHgzTJ;C^Ha7~l_=qeo=nxTwu8&Vp+X zjELa1`&C#Z)5EP4)X<|kglT?JL~wB^Y?06EL8N+86e^7)q#H=nlM*Z9YJnL(kQj-X z1=AI>8JRSBW_Fkrk2^a;xc!McdhJz5`me!Y+qM^h#T~lG!8l@GsYy8@#AE(kG zoXDH`|MJTi!r}yBJ1aJNF(ai0zR11ytmB!vXuog&)`jFXHR*B?iMs9wAfzPJZ)Dd6 zC0p$Ji;lDsPz+LVmHpz4ZY=8Jh0bUpO+v6nv&vIEXwNalDdd&1=AJHoPAF!=eOtgy zDFWOi%Sml+d5S?551PpVyN-~^R)#vg*&X6~gR8<|vZ{)kb}kA8aK54xP-kczbq1WQ zKxG*Jj!+Pq4beI7A@x98E-@N9zFa4pUR8@}SOA8^kBiHVR-pj!Jta4a>G7klig7=Fa>FH*)N- z4utF?!G%ovG|&iSAjr+4gqxEs8HnpjTVwSr_#{|az6s0H85uBwM##N~kTe4BUKED= z=I4_%3NYX7-Hn7(W`}Iq!gXE$?N9&W>`Leqw|QC3CNsO^=CJVz*iKIv>f8greeX>K pUqbSRf$YAgnR`8jQ>|%vi+7ROaIe@*Qp1JEo_`4XI5_!f(Lb|$Eq(w1 literal 0 HcmV?d00001 diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation.json b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json similarity index 99% rename from crates/zk-prover/tests/fixtures/decrypted_shares_aggregation.json rename to crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json index 00feae8ecb..c2117b26be 100644 --- a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation.json +++ b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json @@ -1,6 +1,6 @@ { "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "7372809025462699427", + "hash": "1413289141083555426", "abi": { "parameters": [ { @@ -65,19 +65,19 @@ "file_map": { "50": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::{MAX_MSG_NON_ZERO_COEFFS, T};\nuse lib::configs::default::threshold::{\n DECRYPTED_SHARES_AGGREGATION_BIT_NOISE, DECRYPTED_SHARES_AGGREGATION_CONFIGS, L,\n};\nuse lib::core::threshold::decrypted_shares_aggregation::DecryptedSharesAggregationModular;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n decryption_shares: pub [[Polynomial; L]; T + 1],\n party_ids: pub [Field; T + 1],\n message: pub Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n) {\n let decrypted_shares_aggregation: DecryptedSharesAggregationModular = DecryptedSharesAggregationModular::new(\n DECRYPTED_SHARES_AGGREGATION_CONFIGS,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n );\n\n decrypted_shares_aggregation.execute();\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/threshold/decrypted_shares_aggregation_mod/src/main.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/decrypted_shares_aggregation_mod/src/main.nr" }, "67": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\nuse dep::bignum::BigNum;\nuse dep::bignum::bignum::to_field;\nuse dep::bignum::SecureThreshold8192;\n\n/// Cryptographic parameters for decryption share aggregation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Plaintext modulus (typically denoted as `t`)\n pub plaintext_modulus: Field,\n /// Precomputed value: `-Q^(-1) mod t` where Q is the product of all CRT moduli\n pub q_inverse_mod_t: Field,\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], plaintext_modulus: Field, q_inverse_mod_t: Field) -> Self {\n Configs { qis, plaintext_modulus, q_inverse_mod_t }\n }\n}\n\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using BigNum\n/// for large Q values.\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationBigNum {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using modular arithmetic\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationModular {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n\nimpl DecryptedSharesAggregationBigNum {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationBigNum {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Verifies decoding using BigNum for large Q values\n fn verify_decoding(self) {\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1 as Field;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_bn = SecureThreshold8192::from(q_modulus);\n\n let q_half_bn = q_bn.udiv(SecureThreshold8192::from(2));\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let u_bn = SecureThreshold8192::from(self.u_global.coefficients[coeff_idx]);\n let t_bn = SecureThreshold8192::from(self.configs.plaintext_modulus);\n let u_bn_mod_q = u_bn.umod(q_bn);\n let t_bn_mod_q = t_bn.umod(q_bn);\n let t_times_u_bn_q = (t_bn_mod_q * u_bn_mod_q).umod(q_bn);\n\n let m = ModU128::new(self.configs.plaintext_modulus);\n\n // Check if centering is needed\n let needs_centering = t_times_u_bn_q > q_half_bn;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_bn - t_times_u_bn_q;\n let centered_positive_mod_t = centered_positive.umod(t_bn);\n let centered_field = to_field(centered_positive_mod_t);\n m.mul_mod(self.configs.q_inverse_mod_t, centered_field)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_bn_t = t_times_u_bn_q.umod(t_bn);\n let t_times_u_field = to_field(t_times_u_bn_t);\n let product = m.mul_mod(self.configs.q_inverse_mod_t, t_times_u_field);\n if product == 0 {\n 0\n } else {\n self.configs.plaintext_modulus - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\nimpl DecryptedSharesAggregationModular {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationModular {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Alternative verification function using efficient modular arithmetic without BigNum.\n ///\n /// Uses `ModU128` for decoding verification instead of BigNum. More efficient when\n /// Q (the product of all CRT moduli) fits within u128 (e.g., 72 bits for insecure parameter sets).\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Alternative decoding verification using the formula:\n /// message = -Q^{-1} * (t * u_global)_Q mod t\n fn verify_decoding(self) {\n let t: Field = self.configs.plaintext_modulus;\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_half = q_modulus as u128 / 2;\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let q_mod = ModU128::new(q_modulus);\n let t_mod = ModU128::new(t);\n\n // Compute (t * u_global) mod Q using modular arithmetic functions\n let t_times_u_mod_q = q_mod.mul_mod(t, self.u_global.coefficients[coeff_idx]);\n let needs_centering = (t_times_u_mod_q as u128) > q_half;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_modulus - t_times_u_mod_q;\n let centered_positive_mod_t = t_mod.reduce_mod(centered_positive);\n\n t_mod.mul_mod(self.configs.q_inverse_mod_t, centered_positive_mod_t)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_mod_t = t_mod.reduce_mod(t_times_u_mod_q);\n let product = t_mod.mul_mod(self.configs.q_inverse_mod_t, t_times_u_mod_t);\n if product == 0 {\n 0\n } else {\n t - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\n/// Computes all Lagrange coefficients using optimized modular arithmetic\npub fn compute_all_lagrange_coeffs(\n qis: [Field; L],\n party_ids: [Field; T + 1],\n) -> [[Field; T + 1]; L] {\n let mut lagrange_coeffs = [[0 as Field; T + 1]; L];\n\n // Step 1: Cache |x_i - x_j| factors for all party pairs\n let mut diffs = [[0 as Field; T + 1]; T + 1];\n for i in 0..(T + 1) {\n for j in (i + 1)..(T + 1) {\n let diff = party_ids[j] - party_ids[i];\n diffs[i][j] = diff;\n diffs[j][i] = diff;\n }\n }\n\n // Step 2: Determine signs (same for all parties within a basis)\n let numerator_sign_negative = (T % 2) == 1;\n\n // Step 3: For each CRT basis, compute Lagrange coefficients\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n\n // Compute product of all party IDs: PRODUCT(j=0..T) x_j mod q_l\n let mut product_x = 1 as Field;\n for j in 0..(T + 1) {\n product_x = m.mul_mod(product_x, party_ids[j]);\n }\n\n // For each party i, compute L_i(0) mod q_l\n for party_idx in 0..(T + 1) {\n // Numerator (absolute value): PRODUCT(j!=party_idx) x_j\n let numerator_abs = m.div_mod(product_x, party_ids[party_idx]);\n\n // Denominator (absolute value): PRODUCT(j!=party_idx) |x_party_idx - x_j|\n let mut denominator_abs = 1 as Field;\n for j in 0..(T + 1) {\n if j != party_idx {\n denominator_abs = m.mul_mod(denominator_abs, diffs[party_idx][j]);\n }\n }\n\n // Determine denominator sign\n let num_greater = T - party_idx;\n let denom_sign_negative = (num_greater % 2) == 1;\n\n // Compute unsigned result: |numerator| / |denominator| mod q_l\n let result_abs = m.div_mod(numerator_abs, denominator_abs);\n\n // Apply combined sign\n let should_negate = numerator_sign_negative != denom_sign_negative;\n let result = if should_negate {\n m.reduce_mod(q_l - result_abs)\n } else {\n result_abs\n };\n\n lagrange_coeffs[basis_idx][party_idx] = result;\n }\n }\n\n lagrange_coeffs\n}\n\n/// Computes u^{(l)} for each CRT basis via Lagrange interpolation\npub fn compute_crt_components(\n qis: [Field; L],\n decryption_shares: [[Polynomial; L]; T + 1],\n lagrange_coeffs: [[Field; T + 1]; L],\n) -> [Polynomial; L] {\n let mut u_crts: [Polynomial; L] =\n [Polynomial::new([0; MAX_MSG_NON_ZERO_COEFFS]); L];\n\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n let mut u_coeffs = [0 as Field; MAX_MSG_NON_ZERO_COEFFS];\n\n // For each coefficient position\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n let mut u_coeff = 0 as Field;\n\n // Sum all contributions: u = SUM(i=0..T) [d_i * L_i(0)] mod q_l\n for party_idx in 0..(T + 1) {\n let d_coeff = decryption_shares[party_idx][basis_idx].coefficients[coeff_idx];\n let l_i_0 = lagrange_coeffs[basis_idx][party_idx];\n\n let term = m.mul_mod(d_coeff, l_i_0);\n u_coeff = m.reduce_mod(u_coeff + term);\n }\n\n u_coeffs[coeff_idx] = u_coeff;\n }\n\n u_crts[basis_idx] = Polynomial::new(u_coeffs);\n }\n\n u_crts\n}\n\n/// Verifies CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global for all bases l\npub fn verify_crt_reconstruction(\n qis: [Field; L],\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n u_crts: [Polynomial; L],\n) {\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n\n // Compute r^{(l)} * q_l\n let r_times_q = crt_quotients[basis_idx].mul_scalar(q_l);\n\n // Compute u^{(l)} + r^{(l)} * q_l\n let reconstructed = u_crts[basis_idx].add(r_times_q);\n\n // Verify: u^{(l)} + r^{(l)} * q_l = u_global\n // Must hold for every coefficient\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n assert(\n reconstructed.coefficients[coeff_idx] == u_global.coefficients[coeff_idx],\n \"CRT reconstruction verification failed\",\n );\n }\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/threshold/decrypted_shares_aggregation.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/decrypted_shares_aggregation.nr" }, "77": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" }, "79": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk new file mode 100644 index 0000000000000000000000000000000000000000..b3b83d01c2855ffba802a461022eb61b41a1156f GIT binary patch literal 1888 zcmajgcRw2l1HkdbOr$|Xa%Sz7Q1c-+(WpZewTTk5j#9CXS}{r~O5#w_6fLFrL}FIm zoh>MdqE+LH=Zsoy#i5US-a+s8@An1#0DvC``=J7OY<}zjpyajQxPx}qxQE0t*;XqS zztu3ek2G7Q+1p@eU(Op}0`Lu;?T5<<;sy^E1j+-pIrWiYiS@dW`)15QlL!1CqgZPv25UxLp*`uEB z_V)VC|2R(ZfEk{AvAUilkDc`+{Iat>b@axzRA1d&t=rs_tPUwx2x(24>tE(o)i9CC zw_7i0aYFjWYZU6^rTf<4MVWF4k5vqmb8u(MCPH==yqf;lHtOk!dhoWxw3Y2MY*(zR zytl3Z%+ee}S~RH&7$fcezEh!CnYJNo(3iy(?UTX^8WQQJfRBQaJ3 z@2)6yiI|L->erBMxafut6c_eyaPBfH3oP7WSb@)PcIiUZI zf=k$Li24S>{Frj@HnI5&KN0`ojjx&=1L4L&p5upAbxs#!HoVF;ze){9UIP~$ZQh|{ zN+V$X?L?{WY1==ZsfND7r8iu62y(W0<&j_KgW6ZFgk)&T^;VP^4%zQ@f@fw8WG1pT zwPY5?F74P;Wa#FMQZm&Nk}-rbjM8?t@EK=Ek~93mPx#RBDIkC&68qN z(CRdMranzipu7~c2iXb1O*IX7YQ%Z3JE5Ajn~>&>Nr9orur2+@wDzkQxt?7JXV21H zySjYR+0WLNhrO+BkY^p>R=jNvqYB?yxtXqzT|ASc#_LMU?nq3VgN8sYLsx(}!+Hl@ zY=MJXMFH}kE{RK|sK**-i|->Z)4!Z9pBLn*$|V5BPxe3dl^H3##ytG$s$en0ZlXkg z&X9?4Nh>#G@yK2_&YHLE_+=W}439Qv-s$v76Z={B~p6EAL;7 zCJi)zWN-hqPu2#a2eVhR1ZoZZnN*1kPnI?@OHEmL`r;z3(ez4OJJq z=^?IsW#7LWR+*msK^Vp#v|QCoD?ViI-2$H0)^bpo91FE8@q{FgHHZGhlgkQOJ+J?& zUiEr2Cva8c6q`IGZn17#WWvjzRy?juMs zT6X3(ZR2?VcP~Yy-aJtZ2Y%9MNE5I1Ifa%Ls^w+y!xlZ>=>vFN=u=Xef67r@(f3#Y z6E(H~A!2UFs^V9lgC`8n)}&mQ_n%V&c*HiP!8N9HG@4M?cL_cqe-DGw@ve*c+?0Pc z1Pv8E5RXy?Ai6m&_=L5|-O434*;_%Q%_Jz@hk(+%Dv}Gmj7pb&6#r8xq{Y184;cyt zj8a7BWrCJe*iATLh{J%`V49A9ekt8<|AXS++ogiZ*>(!nqn|e90Z-=&C*m-2QIc?v zG}A|ZnLv|8gwik1rk?|0Oe-r0nq{;`2l [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{L_THRESHOLD, N, SHARE_DECRYPTION_BIT_MSG};\nuse lib::configs::default::H;\nuse lib::core::dkg::share_decryption::ShareDecryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_commitments: pub [[Field; L_THRESHOLD]; H],\n decrypted_shares: [[Polynomial; L_THRESHOLD]; H],\n) -> pub Field {\n let share_decryption: ShareDecryption =\n ShareDecryption::new(expected_commitments, decrypted_shares);\n\n share_decryption.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/share_decryption/src/main.nr" - }, - "64": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_aggregated_shares_commitment, compute_share_encryption_commitment_from_message,\n};\nuse crate::math::polynomial::Polynomial;\n\n/// Share Decryption Commitment Verification (Circuit 4).\n///\n/// Verifies:\n/// 1. Each decrypted share from H honest parties matches its commitment from Circuit 3\n/// 2. Computes sum of all shares\n/// 3. Returns commitment to aggregated shares\npub struct ShareDecryption {\n /// Expected commitments from Circuit 3 for H honest parties: [party_idx][mod_idx]\n /// (public witness)\n expected_commitments: [[Field; L]; H],\n\n /// Decrypted shares from H honest parties: [party_idx][mod_idx]\n /// (secret witnesses)\n decrypted_shares: [[Polynomial; L]; H],\n}\n\nimpl ShareDecryption {\n pub fn new(\n expected_commitments: [[Field; L]; H],\n decrypted_shares: [[Polynomial; L]; H],\n ) -> Self {\n ShareDecryption { expected_commitments, decrypted_shares }\n }\n\n /// Verifies all decrypted shares match their expected commitments\n fn verify_commitments(self) {\n for party_idx in 0..H {\n for mod_idx in 0..L {\n assert(\n compute_share_encryption_commitment_from_message::(\n self.decrypted_shares[party_idx][mod_idx],\n )\n == self.expected_commitments[party_idx][mod_idx],\n \"Commitment mismatch\",\n );\n }\n }\n }\n\n /// Computes sum of all decrypted shares\n fn compute_aggregated_shares(self) -> [Polynomial; L] {\n let mut sum: [Polynomial; L] = [Polynomial::new([0; N]); L];\n\n for mod_idx in 0..L {\n let mut coeffs = [0 as Field; N];\n for coeff_idx in 0..N {\n let mut total = 0 as Field;\n for party_idx in 0..H {\n total =\n total + self.decrypted_shares[party_idx][mod_idx].coefficients[coeff_idx];\n }\n coeffs[coeff_idx] = total;\n }\n sum[mod_idx] = Polynomial::new(coeffs);\n }\n\n sum\n }\n\n /// Main verification function\n /// Returns commitment to aggregated shares\n pub fn execute(self) -> Field {\n // Step 1: Verify all commitments match\n self.verify_commitments();\n\n // Step 2: Compute aggregated shares\n let aggregated = self.compute_aggregated_shares();\n\n // Step 3: Return commitment to aggregated shares\n compute_aggregated_shares_commitment::(aggregated)\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_decryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/dkg_e_sm_share_decryption.vk b/crates/zk-prover/tests/fixtures/dkg_e_sm_share_decryption.vk deleted file mode 100644 index a9f3fd5ef3426dc772c2c684fd888d24624de5c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3680 zcmajic{o)29|!QSqOnc3CRCV&GV&Wn3X?3Mv80F=Wg7{V;u1yI5{)HG!;B@%)xs1L z^-!`@x|K;NCbA1j$ab^dh~NC%XP)Oa|DEUceV=EZ^ZlInIR~Nt{7L+$BDC>0E&#k@ zk)zVA&4zqJytt?g8!+)6_iJ`htzS z79lBG=3znvj*yn?P~qA&8)>sEb^FsOb-=5Llt#SO_mKV30eJs)9z_`72oXi6hax&p zW}P8#Dd@Pb4m`+qQ|mf-0Jt41n3>Wn zL(-#0p8KL}c2o>FLds#3ZPysegsD5p9rMlUz{iX6cgu>^q#N6dj_0_L9CLvqB=??% z?fo+793|FjdwKd1@Q(Y}j_n=g1}gsiroAyrsICh*LaKt=CSUV$-j{tNny!+AfbZDX z=Tv4al3C|Rp)zcz$fdv$!X~<2l`&k?O0}%DFsRuA{PVy~4Ew});}b!FFYh<}h@1tE z&}u==$;-=3f^ysPQ^v6|;M>!mQt0O<+(o&>-lyFPKN5f=v|;??Q#(Ivmw+k#x!71Z zKXv+Sxd@ZukF_}2SfhG*2A(gE6^zVa&tI5p$#|g~d0Gqj8xglVHrN;o+Ff>TNk$7v z2slE5!xyJ?m4-AwEcI)5-pT+T^$$l)c%+v(qknU7^8{_)3plUQLhYq)yV)svFl-&^ z;o`tINX21%_MiWxm_%O)bO7sNNf!+&SBsmUaubOuJF#wWvVzu zIMr8_0O#%h^1s|%y8*6I(v(+EcPntAa$o)4#Ozba$AwnnIQ)%}>xc?t6koqhiphD$p4@a2^xoM%S& z)#bPa9rqFShy8jz)7}3@!_fZcuW7IHv!5rH^X0dZ1TuSGTyP4{A`yeVnZP3nZ-P?J z)vzVZL?)!047&<G}Natgaej7Vy-G4c%;mhi}^OSd|Nx{%WEE=iR>%rFXNH5_h_k3@>PALe{Nq z55R>DQ?c4TqjDl%ECO7B+IJMTEz;1`$P-SN1Mx&AG?27?y|&GUjUAf ziu;gGVMXX;DkgPhv9kd9EkeD!Gj}p?uC>om`+%u2|NFtl2bO8~*IK>azMW25!u$aF zoP<4zNf%>xH%`*zGV|`{N&!bm;t4stG`J|xC4Tlr1aT0!2$xZBC`@w@%sF%gD}URO z0i1XJR9~J;wLE2L9-L@xQ1u>o)}cRD2fd@i8Xss}uAVo}hyB3o{}zS(^h@sxrs8n5 z{f@dIFKOvN;j7?RJ7o5FY5!4&J9EH!`+q7n(r)YM!Ok{|flK^I|0FW zi8}e5Rj1W}3!kNPKYOfy@0&nL%c^fwR0huLPq&VEqvpv_1zq?0XVhK5eeON0EYMO& zeWc$>?N(T?4zDjl1W8Qz`LBB7il_7TDrDaU`9ncpcG?vkz!|r(qDDklI<5of&0h^x zBId))y<_^R7)xwEaL#U)^c!X(PUy-i-uIysIj-v!?~?*gvcuN|1Uy^Q21jcGmS4V z(Uc#Oj{WwS*3)uSnsf#@^HFO^R;5ue@nj% z1I~N?(J#oRh}}25RaK1W!db}OIZoStwFgabO zH{oR)UtWO1RgJ4q!X{e;mK-tb1-@;(nKgJe8k@~9`ebgu>Et`$y!kg=LzWT!R2pDf zV%~&v0-mbHBz(0wVz{2xQE!C;^c;XAq=r*|C7h~t^7KktfIEY~pMDL%@1tM!_eZOK zzvPz{W1r5|lozn$Zntwi-Lz^s{PU|WzI}d+f7-Pb>6?vc6by+r36<&p2O>yF1^@s6 diff --git a/crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.json b/crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.json deleted file mode 100644 index 0234543f66..0000000000 --- a/crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "9828651845942763134", - "abi": { - "parameters": [ - { - "name": "expected_commitments", - "type": { "kind": "array", "length": 5, "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }, - "visibility": "public" - }, - { - "name": "decrypted_shares", - "type": { - "kind": "array", - "length": 5, - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - } - }, - "visibility": "private" - } - ], - "return_type": { "abi_type": { "kind": "field" }, "visibility": "public" }, - "error_types": { "10481401461242010843": { "error_kind": "string", "string": "Commitment mismatch" } } - }, - "bytecode": "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", - "debug_symbols": "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D2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsMZD2c8nPFwxsNZNSHn2Ygc9qghOTUlp8bk1JycGpRTk3JqVA6dq6a80Tkezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezsywMkOszBQrM8bKzLEyg6yMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezjX/qgZg1QSsGoFVM7BqCFZNwaoxWDUHqwZh1SSsGoVVs7BqGFZNw6pxWDUPqwZi1USsGon1bCZWDcV6NhWLPWouVg3GqslYNRqrZmPVcCw6r/FYNR+rBmTVhKwakVUzsmpIVk3JqjFZNSerBmXVpKwalVWzsmpYVk3LqnFZNS+rBmbVxKwamVUzs2poVk3NqrFZNTerBmfV5KwanVWzs2p4Vk3PqvFZNT+rBmjVBK0aoVUztGqIVk3RqjFaNUerBmnVJK0apVWztGqYVk3TqnFaNU+rBmrh4YyHc83UqqFaNVXrycM9XS2u9v1cuSZr1Witmq1Vw7VqulaN16r5WjVgqyZs1YgtPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDudXkVjrHwxkPZzyc8XDGw7nVFLwag1dz8J4NwmOPGoVXs/BqGF5Nw6txeHSOhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng495rRTOdM+DIjvsyMLzPky0z5MmO+jIczHs54OOPhjIczHs54OOPh3GvuZQ2+rMmXNfry2exL9qjplzX+suZf1gBMOsfDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ/nUdPY6RwPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XAeNem2Rt3WrNsadlvTbp+Nu2WPGnhbE29r5C2d4+GMhzMezng44+GMhzMezng44+HMxDEzcszMHPOTh3u6alz1+7kyHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OOPhjIczHs54OM/6dxfoHA9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDedZs6xpuXdOta7x1zbeuAdfPJlyzR824riHX3M/xcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcMbDGQ9nPJzxcGb+mRmAZiagmRFoZgaaGYJmPJzxcMbDGQ9nPJzxcMbDGQ9nPJxX/QsrdI6HMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyHMx7OeDjj4YyH86pp9jXOvubZ10D7mmhfI+1rpv2zofbsUWPt6RwPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDGwxkPZzyc8XDe9W8p0Tkezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng44+GMhzMezng4M4/NDGQzE9n85OGervKc+tHDPf0TDl87H9fjlblqXHWuBleTq8XV5urk6mvn9xV7LPZY7LHYY7HHYo/FHos9Fnts9tjssdljs8dmj80emz02e2z22Oxx2OOwx2GPwx6HPQ57HPY47HHY42SPRw93X4krc9W46lwNriZXi6vNFXuIPcQeYg+xh9hD7CH2EHuIPcQeZg+zh9nD7GH2MHuYPcweZg+zR2OPxh6NPRp7NPZo7NHYo7FHY4/GHp09Ont09ujs0dmjs0dnj84enT06ewz2GOwx2GOwx2CPwR6DPQZ7DPYY7DHZg84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5SeftSuftSuftSuftSuftSuftSuftSuftSuftSuftuthD7CH2EHuIPcQeYg+xh9hD7CH2MHuYPcweZg+zh9nD7GH2MHuYPRp7NPZo7NHYo7FHY4/GHo09Gns09ujs0dmjs0dnj84enT06e3T26OzR2WOwx2CPwR6DPQZ7DPYY7DHYY7DHYI/JHpM9JntM9pjsMdljssdkj8kekz0Weyz2WOyx2GOxx2KPxR6LPRZ7LPbY7LHZY7PHZo/NHps9Nnts9tjssdnjsfP1ePV1j6//wut/3n/5+P6nTx/+/e5vf3z9F0p///xz/jnSh//52///mv/y05ePnz59/NePv3755ecP//j9y4ev/3Tp43/78+9//hc=", - "file_map": { - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{L_THRESHOLD, N, SHARE_DECRYPTION_BIT_MSG};\nuse lib::configs::default::H;\nuse lib::core::dkg::share_decryption::ShareDecryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_commitments: pub [[Field; L_THRESHOLD]; H],\n decrypted_shares: [[Polynomial; L_THRESHOLD]; H],\n) -> pub Field {\n let share_decryption: ShareDecryption =\n ShareDecryption::new(expected_commitments, decrypted_shares);\n\n share_decryption.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/share_decryption/src/main.nr" - }, - "64": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_aggregated_shares_commitment, compute_share_encryption_commitment_from_message,\n};\nuse crate::math::polynomial::Polynomial;\n\n/// Share Decryption Commitment Verification (Circuit 4).\n///\n/// Verifies:\n/// 1. Each decrypted share from H honest parties matches its commitment from Circuit 3\n/// 2. Computes sum of all shares\n/// 3. Returns commitment to aggregated shares\npub struct ShareDecryption {\n /// Expected commitments from Circuit 3 for H honest parties: [party_idx][mod_idx]\n /// (public witness)\n expected_commitments: [[Field; L]; H],\n\n /// Decrypted shares from H honest parties: [party_idx][mod_idx]\n /// (secret witnesses)\n decrypted_shares: [[Polynomial; L]; H],\n}\n\nimpl ShareDecryption {\n pub fn new(\n expected_commitments: [[Field; L]; H],\n decrypted_shares: [[Polynomial; L]; H],\n ) -> Self {\n ShareDecryption { expected_commitments, decrypted_shares }\n }\n\n /// Verifies all decrypted shares match their expected commitments\n fn verify_commitments(self) {\n for party_idx in 0..H {\n for mod_idx in 0..L {\n assert(\n compute_share_encryption_commitment_from_message::(\n self.decrypted_shares[party_idx][mod_idx],\n )\n == self.expected_commitments[party_idx][mod_idx],\n \"Commitment mismatch\",\n );\n }\n }\n }\n\n /// Computes sum of all decrypted shares\n fn compute_aggregated_shares(self) -> [Polynomial; L] {\n let mut sum: [Polynomial; L] = [Polynomial::new([0; N]); L];\n\n for mod_idx in 0..L {\n let mut coeffs = [0 as Field; N];\n for coeff_idx in 0..N {\n let mut total = 0 as Field;\n for party_idx in 0..H {\n total =\n total + self.decrypted_shares[party_idx][mod_idx].coefficients[coeff_idx];\n }\n coeffs[coeff_idx] = total;\n }\n sum[mod_idx] = Polynomial::new(coeffs);\n }\n\n sum\n }\n\n /// Main verification function\n /// Returns commitment to aggregated shares\n pub fn execute(self) -> Field {\n // Step 1: Verify all commitments match\n self.verify_commitments();\n\n // Step 2: Compute aggregated shares\n let aggregated = self.compute_aggregated_shares();\n\n // Step 3: Return commitment to aggregated shares\n compute_aggregated_shares_commitment::(aggregated)\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_decryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.vk b/crates/zk-prover/tests/fixtures/dkg_sk_share_decryption.vk deleted file mode 100644 index a9f3fd5ef3426dc772c2c684fd888d24624de5c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3680 zcmajic{o)29|!QSqOnc3CRCV&GV&Wn3X?3Mv80F=Wg7{V;u1yI5{)HG!;B@%)xs1L z^-!`@x|K;NCbA1j$ab^dh~NC%XP)Oa|DEUceV=EZ^ZlInIR~Nt{7L+$BDC>0E&#k@ zk)zVA&4zqJytt?g8!+)6_iJ`htzS z79lBG=3znvj*yn?P~qA&8)>sEb^FsOb-=5Llt#SO_mKV30eJs)9z_`72oXi6hax&p zW}P8#Dd@Pb4m`+qQ|mf-0Jt41n3>Wn zL(-#0p8KL}c2o>FLds#3ZPysegsD5p9rMlUz{iX6cgu>^q#N6dj_0_L9CLvqB=??% z?fo+793|FjdwKd1@Q(Y}j_n=g1}gsiroAyrsICh*LaKt=CSUV$-j{tNny!+AfbZDX z=Tv4al3C|Rp)zcz$fdv$!X~<2l`&k?O0}%DFsRuA{PVy~4Ew});}b!FFYh<}h@1tE z&}u==$;-=3f^ysPQ^v6|;M>!mQt0O<+(o&>-lyFPKN5f=v|;??Q#(Ivmw+k#x!71Z zKXv+Sxd@ZukF_}2SfhG*2A(gE6^zVa&tI5p$#|g~d0Gqj8xglVHrN;o+Ff>TNk$7v z2slE5!xyJ?m4-AwEcI)5-pT+T^$$l)c%+v(qknU7^8{_)3plUQLhYq)yV)svFl-&^ z;o`tINX21%_MiWxm_%O)bO7sNNf!+&SBsmUaubOuJF#wWvVzu zIMr8_0O#%h^1s|%y8*6I(v(+EcPntAa$o)4#Ozba$AwnnIQ)%}>xc?t6koqhiphD$p4@a2^xoM%S& z)#bPa9rqFShy8jz)7}3@!_fZcuW7IHv!5rH^X0dZ1TuSGTyP4{A`yeVnZP3nZ-P?J z)vzVZL?)!047&<G}Natgaej7Vy-G4c%;mhi}^OSd|Nx{%WEE=iR>%rFXNH5_h_k3@>PALe{Nq z55R>DQ?c4TqjDl%ECO7B+IJMTEz;1`$P-SN1Mx&AG?27?y|&GUjUAf ziu;gGVMXX;DkgPhv9kd9EkeD!Gj}p?uC>om`+%u2|NFtl2bO8~*IK>azMW25!u$aF zoP<4zNf%>xH%`*zGV|`{N&!bm;t4stG`J|xC4Tlr1aT0!2$xZBC`@w@%sF%gD}URO z0i1XJR9~J;wLE2L9-L@xQ1u>o)}cRD2fd@i8Xss}uAVo}hyB3o{}zS(^h@sxrs8n5 z{f@dIFKOvN;j7?RJ7o5FY5!4&J9EH!`+q7n(r)YM!Ok{|flK^I|0FW zi8}e5Rj1W}3!kNPKYOfy@0&nL%c^fwR0huLPq&VEqvpv_1zq?0XVhK5eeON0EYMO& zeWc$>?N(T?4zDjl1W8Qz`LBB7il_7TDrDaU`9ncpcG?vkz!|r(qDDklI<5of&0h^x zBId))y<_^R7)xwEaL#U)^c!X(PUy-i-uIysIj-v!?~?*gvcuN|1Uy^Q21jcGmS4V z(Uc#Oj{WwS*3)uSnsf#@^HFO^R;5ue@nj% z1I~N?(J#oRh}}25RaK1W!db}OIZoStwFgabO zH{oR)UtWO1RgJ4q!X{e;mK-tb1-@;(nKgJe8k@~9`ebgu>Et`$y!kg=LzWT!R2pDf zV%~&v0-mbHBz(0wVz{2xQE!C;^c;XAq=r*|C7h~t^7KktfIEY~pMDL%@1tM!_eZOK zzvPz{W1r5|lozn$Zntwi-Lz^s{PU|WzI}d+f7-Pb>6?vc6by+r36<&p2O>yF1^@s6 diff --git a/crates/zk-prover/tests/fixtures/e_sm_share_computation.json b/crates/zk-prover/tests/fixtures/e_sm_share_computation.json index e5ed627233..90a82956ec 100644 --- a/crates/zk-prover/tests/fixtures/e_sm_share_computation.json +++ b/crates/zk-prover/tests/fixtures/e_sm_share_computation.json @@ -1,6 +1,6 @@ { "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "12506177918275697276", + "hash": "17372510727995405395", "abi": { "parameters": [ { "name": "expected_secret_commitment", "type": { "kind": "field" }, "visibility": "public" }, @@ -52,35 +52,35 @@ }, "50": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n L_THRESHOLD, N, PARITY_MATRIX, SHARE_COMPUTATION_BIT_SHARE, SHARE_COMPUTATION_E_SM_BIT_SECRET,\n SHARE_COMPUTATION_E_SM_CONFIGS,\n};\nuse lib::configs::default::{N_PARTIES, T};\nuse lib::core::dkg::share_computation::SmudgingNoiseShareComputation;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_secret_commitment: pub Field,\n e_sm_secret: [Polynomial; L_THRESHOLD],\n y: [[[Field; N_PARTIES + 1]; L_THRESHOLD]; N],\n) -> pub [[Field; L_THRESHOLD]; N_PARTIES] {\n let share_computation_e_sm: SmudgingNoiseShareComputation = SmudgingNoiseShareComputation::new(\n SHARE_COMPUTATION_E_SM_CONFIGS,\n expected_secret_commitment,\n e_sm_secret,\n y,\n PARITY_MATRIX,\n );\n\n share_computation_e_sm.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/e_sm_share_computation/src/main.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/e_sm_share_computation/src/main.nr" }, "63": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_share_encryption_commitment_from_shares,\n};\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold secret share verification circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Correct Threshold Secret Key Share Computation (Circuit 2a).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == sk_secret[i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For SK: sk_secret is the trinary coefficients\npub struct SecretKeyShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// (public witness)\n expected_secret_commitment: Field,\n /// Secret key polynomial: Polynomial\n /// trinary coefficients\n /// (secret witness)\n sk_secret: Polynomial,\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = sk_secret[i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n /// (secret witnesses)\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n /// (public constants)\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\n/// Correct Threshold Smudging Noise Share Computation (Circuit 2b).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == e_sm[j][i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For ESM: e_sm[j] is the RNS representation at modulus j\npub struct SmudgingNoiseShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// This is computed from all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n expected_secret_commitment: Field,\n /// Smudging noise polynomial per modulus: [Polynomial; L]\n /// For ESM: each modulus has its own polynomial (RNS representation)\n e_sm_secret: [Polynomial; L],\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = e_sm[j][i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\nimpl SecretKeyShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n sk_secret: Polynomial,\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SecretKeyShareComputation { configs, expected_secret_commitment, sk_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_sk_commitment::(self.sk_secret)\n == self.expected_secret_commitment,\n \"SK commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == sk_secret[i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// sk_secret is the trinary coefficients, so y[i][j][0] is the same for all j.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n let secret_coeff = self.sk_secret.coefficients[coeff_idx];\n\n for mod_idx in 0..L {\n assert(self.y[coeff_idx][mod_idx][0] == secret_coeff);\n }\n }\n }\n}\n\nimpl SmudgingNoiseShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n e_sm_secret: [Polynomial; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SmudgingNoiseShareComputation { configs, expected_secret_commitment, e_sm_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n /// The commitment is computed over all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_e_sm_commitment::(self.e_sm_secret)\n == self.expected_secret_commitment,\n \"ESM commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == e_sm_secret[j][i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// e_sm_secret[j] is the RNS representation at modulus j, so y[i][j][0] varies per modulus.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let secret_coeff = self.e_sm_secret[mod_idx].coefficients[coeff_idx];\n assert(\n self.y[coeff_idx][mod_idx][0] == secret_coeff,\n \"Secret consistency check failed\",\n );\n }\n }\n }\n}\n\n/// Performs range checks on secret key and share values.\n///\n/// This function constrains all values to be within their expected bounds:\n/// - Share values for parties k >= 1 must be in [0, q_j) for each CRT modulus q_j\n///\n/// These bounds are critical for security and correctness of the Threshold scheme.\n///\n/// # Panics\n/// This function will cause the circuit to fail if any value is outside\n/// its expected bounds.\npub fn check_range_bounds(\n qis: [Field; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n // Shares y[i][j][k] for k >= 1 should be in [0, q_j)\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n for coeff_idx in 0..N {\n for party_idx in 1..(N_PARTIES + 1) {\n // Use range_check_standard from Polynomial by creating a single-coefficient polynomial\n Polynomial::new([y[coeff_idx][mod_idx][party_idx]])\n .range_check_standard::(q_j);\n }\n }\n }\n}\n\n/// Verifies Reed-Solomon parity check: `H[j] * y[i][j]^T == 0 mod q_j` for all i, j.\n///\n/// This function verifies that for each coefficient i and CRT basis j, the share\n/// vector `y[i][j]` forms a valid Reed-Solomon codeword by satisfying the parity\n/// check equation with the parity check matrix `H[j]`.\n///\n/// The parity check matrix H[j] has dimensions `(N_PARTIES - T) * (N_PARTIES + 1)`,\n/// and the share vector `y[i][j]` has length `N_PARTIES + 1`. The parity check\n/// ensures that any T+1 shares can correctly reconstruct the secret key via\n/// Lagrange interpolation.\n///\n/// # Panics\n/// The circuit will fail if the parity check doesn't hold for any coefficient,\n/// CRT basis, or parity check row.\npub fn verify_parity_check(\n qis: [Field; L],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n // For each row of H, compute dot product with y and verify == 0\n for row in 0..(N_PARTIES - T) {\n let mut sum: Field = 0;\n\n for col in 0..(N_PARTIES + 1) {\n sum = sum + h[mod_idx][row][col] * y[coeff_idx][mod_idx][col];\n }\n\n // Reduce mod q_j and verify == 0\n let m = ModU128::new(q_j);\n let result = m.reduce_mod(sum);\n assert(result == 0, \"Parity check failed\");\n }\n }\n }\n}\n\n/// Commits to shares for each party and modulus\n/// Returns [[Field; L]; N_PARTIES] where commitments[party_idx][mod_idx]\npub fn commit_to_party_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) -> [[Field; L]; N_PARTIES] {\n let mut commitments: [[Field; L]; N_PARTIES] = [[0; L]; N_PARTIES];\n\n for party_idx in 0..N_PARTIES {\n for mod_idx in 0..L {\n commitments[party_idx][mod_idx] = compute_share_encryption_commitment_from_shares::(\n y,\n party_idx,\n mod_idx,\n );\n }\n }\n\n commitments\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_computation.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_computation.nr" }, "74": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" }, "75": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" }, "77": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" }, "79": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" }, "80": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" }, "81": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/e_sm_share_computation.vk b/crates/zk-prover/tests/fixtures/e_sm_share_computation.vk index c7cdb4eeb7b0d9951f7428b2c6b741a6f7430b70..70efd9e0c24c6f638143cf1acbdbb43c2487db6c 100644 GIT binary patch delta 1747 zcmV;^1}ypD9N-R+V1FsaEjZ!#A+QeC*EXO*837(zc(oy>!JzI}|DbO;0EidZ8ox3H zILQ+Kv!05b#o>|BYCSSuw7eC1CF7g^n{_TCLj{!Tb9Bg;pvD`8U|@azXA{8R#J)5B zv-SOC#NrNo_szJ*4{jq&^OVX=xm)X@j*hRcPKdelTr!lxPJenXclcboU^!)7;<=_P{|KT+HUsw~h_?2;mmGG_x zHtG;*%+4rTO9KLa^RD3IxA$hWSZ3_4`BW%aY;pi9WelfWP4(k$<6G#z$?Oby4;UIX z={L=KODwteoqwoK7VBVQtSo(P?vF6`BPP1%(A!nfDTAX1Gm;U4r8-x631IZX6KtI} zbk6m0zfONSLrPz(BS^V|nE|=x;U`iYFf|`a>Z68wAD;-~;TgGWmX5j@k0~h_fU}nz z4mO;$3A+RBlWAJ=spB^9s9QqvTQzDtdV%gBDxR0G)_-Fcb0q{ZLFc6vXnbve(1km8 z*{zFNL+a9W9{uYv8-oSO+YOChg%dpn)nZA;MmoSFG)LfCv_J`&$#6(wluqzFvji&s zH{2M=x0ghvLt6qdeV2qk3{E)A6;*E2?Z|J4z!sYm@n2V3r>QfPkEswrc-wOMl4s&jKVPi5{nu5-CGblJ_cc=Cv#F>>Lts1mjjLTUk9%hYB$A9~ls54LAQh zPBjuM9WEe7hmLJSrolGM=rf_OWKmZFraC93uYbs3604pgmCeXMk4ND@;3jWS;^+JH zNtaDIS}&JagcHvz`FVRQxQo{NAp{6X&}bP(g#Rt-Y$8WkNCOml2yDBqlPEX0US=)+o7vB!-mWDHcG`Nq#p zFQGsq?6Sumn+F_-e(*fKkSWoJ}w!_=h7vi0R9FN73XblXWKG zb;-O2x-pA`#aeO;bJWuB`pF`|<(;D?{J99WA*lnHqvF#YSUd~Z-Q8K$H_}}sG?^eR z-~i6Nv_TGpy1!agh;x5zDA5YzWPjrB!E1cT74PdV3H}2F(`h7FMTNmvkE)D4qi{^I zAIINXF9JG9A-z~5_>J2utl+_jW?X($T%7^CEn>QR|DC9iN09)VNw?o6Y1FlrVll6u z|MM;E$nwSn2`=_6yP>DM%Y%ED}LG&f~g}SeC*S!G)R604;hUstS+zrb(~Rx!*EKAFKw;% zdye5*#I>(d=1<*ZOAJGS+ka*Yr)G*MXhK>x5(%C=)u5mXxBeIe0R_3Um9^Nnw5B@+ z-(@Qe5bqRiCIA(<(otP@;>_%s+|iU-At|pqV}Dv=Dl$Y5h7BGne;bi?7m^FDJ&V8` zm6Zu9A}ff22;3#nsznY9OTrSvelT8%lCenc+al)ak_UQ(NFhPT>wn}R0HM{4%XBy& zZ5b0*emjv|fdM+&6(eh<&!zzpv_L=$E6O+Gu?Sw0N_PQB(j|$x9}SO2bgx%L-rD_R z%Ic6yLr!#$mlNKM!`B2o20If9-?MWiPBE$%j zFl1`~mUCg0l#?)(Dw8t}9+40ZlYb2$K>{mR9QlgyD@kAfvrfFdJg7bl#L pS6>V{v7|1G#Tv^6H(|kxDldzXU;k36@p~yyZ_Y?sV}Y?@x);g|I>!J2 literal 3680 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 bLw4>; L]; H],\n pk1: [[Polynomial; L]; H],\n pk0_agg: [Polynomial; L],\n pk1_agg: [Polynomial; L],\n) -> pub Field {\n let pk_aggregation: PkAggregation = PkAggregation::new(\n PK_AGGREGATION_CONFIGS,\n expected_threshold_pk_commitments,\n pk0,\n pk1,\n pk0_agg,\n pk1_agg,\n );\n\n pk_aggregation.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/threshold/pk_aggregation/src/main.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/pk_aggregation/src/main.nr" }, "69": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_pk_aggregation_commitment;\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold public key aggregation circuit.\npub struct Configs {\n /// CRT moduli for each basis: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Public Key Aggregation (Circuit 5).\n///\n/// Verifies that for each CRT basis l and each coefficient i:\n/// - pk0_agg[l][i] = sum_h(pk0[h][l][i]) mod q_l\n/// - pk1_agg[l][i] = sum_h(pk1[h][l][i]) mod q_l\npub struct PkAggregation {\n /// Circuit parameters including CRT moduli\n configs: Configs,\n\n /// Expected commitments to threshold public key (from C1)\n /// We need one commitment from each honest party (H).\n /// (public witness)\n expected_threshold_pk_commitments: [Field; H],\n\n /// Individual public keys from H honest parties\n /// pk0[party_idx][basis_idx] - first component of public key for each party and CRT basis\n /// (committed witnesses)\n pk0: [[Polynomial; L]; H],\n /// pk1[party_idx][basis_idx] - second component of public key for each party and CRT basis\n /// (committed witnesses)\n pk1: [[Polynomial; L]; H],\n\n /// Claimed aggregated public key\n /// pk0_agg[basis_idx] - first component of aggregated public key for each CRT basis\n /// (committed witnesses)\n pk0_agg: [Polynomial; L],\n /// pk1_agg[basis_idx] - second component of aggregated public key for each CRT basis\n /// (committed witnesses)\n pk1_agg: [Polynomial; L],\n}\n\nimpl PkAggregation {\n pub fn new(\n configs: Configs,\n expected_threshold_pk_commitments: [Field; H],\n pk0: [[Polynomial; L]; H],\n pk1: [[Polynomial; L]; H],\n pk0_agg: [Polynomial; L],\n pk1_agg: [Polynomial; L],\n ) -> Self {\n PkAggregation { configs, expected_threshold_pk_commitments, pk0, pk1, pk0_agg, pk1_agg }\n }\n\n /// Verifies that pk hashes to each expected_threshold_pk_commitment\n fn verify_pk_commitments(self) {\n for i in 0..H {\n assert(\n compute_pk_aggregation_commitment::(self.pk0[i], self.pk1[i])\n == self.expected_threshold_pk_commitments[i],\n \"PK commitment mismatch\",\n );\n }\n }\n\n fn verify_pk_for_basis(\n self,\n pk: [[Polynomial; L]; H],\n pk_agg: [Polynomial; L],\n basis_idx: u32,\n ) {\n let q_l = self.configs.qis[basis_idx];\n let mod_q_l = ModU128::new(q_l);\n\n for coeff_idx in 0..N {\n // Sum pk coefficients from all honest parties\n let mut sum_pk: Field = 0;\n for party_idx in 0..H {\n sum_pk = sum_pk + pk[party_idx][basis_idx].coefficients[coeff_idx];\n }\n\n // Reduce mod q_l\n let sum_pk_reduced = mod_q_l.reduce_mod(sum_pk);\n\n // Verify equality\n assert(\n sum_pk_reduced == pk_agg[basis_idx].coefficients[coeff_idx],\n \"pk aggregation mismatch\",\n );\n }\n }\n\n /// Main verification function\n /// Returns commitment to aggregated threshold public key\n pub fn execute(self) -> Field {\n // 0. Verify pk commitments\n self.verify_pk_commitments();\n\n // 1. Verify pk0 & pk1 aggregations for each CRT basis\n for basis_idx in 0..L {\n self.verify_pk_for_basis(self.pk0, self.pk0_agg, basis_idx);\n self.verify_pk_for_basis(self.pk1, self.pk1_agg, basis_idx);\n }\n\n // 2. Commit to aggregated threshold public key\n compute_pk_aggregation_commitment::(self.pk0_agg, self.pk1_agg)\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/threshold/pk_aggregation.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/pk_aggregation.nr" }, "74": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" }, "75": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" }, "77": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" }, "79": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" }, "81": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/pk_aggregation.vk b/crates/zk-prover/tests/fixtures/pk_aggregation.vk index e6e87604774c2e1e8c8e44ff6f3eb498ca04eed4..58a10c89eef0602904ff50a5ced0d1cbabd1509e 100644 GIT binary patch delta 1747 zcmV;^1}ypD9N-R+V1E=j;2nN9Jh>XtKLu76`Kr6yt{x>aS{^9CEr zW@rPWVy>MqQW;xB2I1YLoDW<96DLUzH#e1%_nAYeu5?^5KD20Ty%>OKFOtzUHXK+7 zVbp|r{lfqq{4Ve4#Lj){la(CH$hveV9f^KHxhV=D2#Sz!#0dpQhxvI)iP(P6I=!Jh zqJmLi+@C-D+SUY$CfaVGB{6-0w}_m;&?qQ+c3E}dgE}oDDVmB7t~kqs}hR| zLq$QOH|**{cr^@ZS;He5Oa1xDKvezCA)dY6RQk@^57knKP#Mn;Elm)5gXWRnivDv;7`+4OWR^&K_Y(io7S6r`VgW`XJq@ zou@qYLzN(35EblmVt3ic2s!&=v59EJ{tWYkcm>_%bEe=w;8YVC|G< zA8X=rB7b@EmJ1b~pV|xWU0K=`M6lfmO$kG1#UQI8|-#7%Cb*3&?@-pd1AuZjTBLqmgS1xq8D`M)ySON|I|O zHf<_Y;T9KJQ9Wx|;CA=y(PH5oxF8$0 zsH)5&RB&JHJ#k{h6&`ti=hXq7u`ChqP;H18t-bO4BQF6KB8=RT#~a|057;E{HKZ_4 z0Dtq+h%Y-459xVpG{DZ}JvUMpTd;Q#iqV?>a9q z1bTZO3j$?~QG6^HDUtVE_J`$CE~4Cp9e>G+vA7hH(G{eQe*!UO@rGt8!fjES#;$TF zT%>UMk@!`2vboSGAQej`3eKM`u2Hsye~Ix$zjc1JPKw9S)bh*br?Q?zSrrki*3KYi z0&A9e-Szc5`5`uqY0bcJY$e0sThcOH;wPrKT)dJ^FN33bvslqhX)Xu*T22vbcYoUM z0mE^#yCw?}=fxd)zf4Yuh_ASB7An_=CWR!4921WkzL!B9owBg-Oo2VfsXuAm2sGZgAm6j$t@k z1vYTdID}kueApKdbp+A(BsqLN2YTM7*KJx^SSe)g_<_r$`~0w==f0FEdiz*bi8ni( zTdC0!>t}xj@!hAhxi?|{Bweh{{;om*MRKHIWphCgfK-^^CO-s#?%inetAAwJ3T@?_ zu}jVNBYbVhSyLvx7llgH$3EU^|OCDCLF9s{O@ z(r{66-JS^O{nuLT9(T1FyMOWExAu@T3GIy9ZV8?{)u5mXxBeIe0R_3Um9^Nnw5B@+ z-(@Qe5bqRiCIA(<(otP@;>_%s+|iU-At|pqV}Dv=Dl$Y5h7BGne;bi?7m^FDJ&V8` zm6Zu9A}ff22;3#nsznY9OTrSvelT8%lCenc+al)ak_UQ(NFhPT>wn}R0HM{4%XBy& zZ5b0*emjv|fdM+&6(eh<&!zzpv_L=$E6O+Gu?Sw0N_PQB(j|$x9}SO2bgx%L-rD_R z%Ic6yLr!#$mlNKM!`B2o20If9-?MWiPBE$%j zFl1`~mUCg0l#?)(Dw8t}9+40ZlYb2$K>`sOSl6}Mh||B{@=0`LTm{?(*$s_@^${0iGYlOY)hD1xsMRTS4g*RMX~?@ literal 3680 zcmajic{r479|!PzEZLH6hK8~4OGrm1%c+D{h88Jnktj7dLRnrfE%t~R%b_F(Q4v|n zs3gldEh=V87>#i#N*H89qBHNG{pPw(&wuyzdA`?mU-$BReh)(b`pEvPA|(G4#{l=V za1dWy$k7?CeZV~-_odMsI6~Mh!)nH@uOq%&w;k=>;tu?Ses}1_6>Gddd%3X9yj|}i zaD)Ule)(!9HU3@DxWJDxehPTmx;<}H-bhy2VBSXiE$s`S0Y}K#jddW}NVn8{|DE~d z_7A}As^{XB?vn~#W-BN1H~G~Z0glkR%kk7%`Z=r89+L9~<`8hfGXI(@rmlEzyET8a z%8R6YfFrcwnvTEbz5RiMpVufoI~oMs$Mo06px~DEXM#+qbo0#w58w!4`Dhx{$|Yi(D@R0e79xGAJ(Nw z`07yCZ2SegQs4-wiKb_Vb&3i9CuJ#SXIek-f{|z&qe0VVV(e%bO>agFt}jA{!VJ~N z`KH-s#NC+!dhH-@8*RS!xMzo^B57sm={C0&I6s6GUc1j!$zBlKVZXi1VsZlHr8c-o z$DSXfu+vwg<3|eGUI9l)y|{(t_Vp!Gs@FAT5561ty#NOXeJ?cw{Yqb3EMu^U4ICla zAlj|w>Lj;zFQuMzE(tihO+)xoG?z3mAGv|6Y(BsMju0+9uaHAby?%wp)t9{s&&Pmu z!!eP=PoCP$t2I>iU#|JemtUV<@@`q^b~uh9=tBK=0=R!d?gV$|88!Ly(KG2JQ(_Nr z-u|&}T&c9??#NT~mBvj*0RIr!UE?>EdsLM?60Q+5moEXFH~*OwBPW+Sa@_ROMKkR_ z;MElKiq;)VHW675H@{NKA@ZMJ+?A_L3C=-JCf4pYOFbLpw~5t%QavWKvA+UK+#fQ% z-T*j4+VjCA&+hN#J#D!Acc0Dzr;sI@V>>(?7VIXRsATQUA;1w*{8i$~+1V0;uzF~g zxMUe{(Q>S?pCA)c;i(v}g$KaZlWgaYXC8l@oH=}YVUq6uH*kauoa9=zPfFDn zdQl3uDsKYr--%O+Nf__NT&XjX;p_=X1&$DbrlxfF`pxGWZehNYHYb4(Q>6N}IOgT1 zyU}Mxs)>~haNhm9)iS%RX@Zg0$aqV6tOUHIwd}b8)+au*)xAog>0EsqaD=2j#*lw` zG1%#zmA?)gzM-1CFQ-Vap~J6<)`U&G%S_Qmlult zuZn~~V8-4!BL#iR0`R|T!gYPh!+8x8*3^VT$ z;Jmy{^_!P!M+M0FF)S|E3ixqjk!7!4GUO=cG^XQZ!+jm#2&9;OwO0ZGS5#+KI9~LBeoVEmxkc7W!TEtJ) zzNUmPkGLYY6^j#n*ZAJ(tlqc{c#R-Fu9u)+hR<^%p|I#;MC-z}I#tNJ^ zSqH)Ww>FF$_UY_#ATHhrt9R5qcaJZ>cHU*ED$ds(|4yNnk_YPpHRBWQPrUHvupVNf zPh?!b0$*Nkz-esEIka(R?I0t@l?B|((?dUCdhu*m`SQ2hCF2isfg>b+N{GIowI$9* zBzCBx57xH?;aOH?L$k%Xo|KAjfe2x-QJJbCYy zth`7|aj(c_0=KaZWCxaRY~jW-n#B_ZrLO_!)t@BN+Fv$Y>Wmmvyh_fD0nXrPdb6~? zM#~%3$!lrT1H^#y>fgJFzR^qly{_q*>JKmk;FBs*ckuUThnv1+ZxWlzV1@!mNJX$B zi4nH+!t6jpNofu?g#Z4C6gz~@bt*@$-=kvTv#783{%gFzSXARv|lGdYM1SZ=gTWm zPAO0&ZrNOTM99k%gWp$2_3e*8y;DPf^k#HL5>-R+e0kGDY1BH$=|PRLk5rM^MBo(| znZ|9~Bn+QfjMRx9qB=zZM@a5KycNagEXI&x|~o1(T#8ZIyj9^(Hzr&6W{YA4(IaU&mRNu|L8~k`AFdBul(=^ z>yq>5AeFYsSnm2YSC!2KW`5BB4`lEjeRr6tuUgromv7jw0$0b2jwa9PMh!cQG-pY7 ZxH|$zNa*5fZ~4iaGwjZ9;)7dr{sC5EKED6} diff --git a/crates/zk-prover/tests/fixtures/pk_generation.json b/crates/zk-prover/tests/fixtures/pk_generation.json index c1ae8868bf..d0b338cf1e 100644 --- a/crates/zk-prover/tests/fixtures/pk_generation.json +++ b/crates/zk-prover/tests/fixtures/pk_generation.json @@ -1,6 +1,6 @@ { "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "944264242874897871", + "hash": "6089811819251995355", "abi": { "parameters": [ { @@ -127,27 +127,27 @@ }, "50": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, PK_GENERATION_BIT_E_SM, PK_GENERATION_BIT_EEK, PK_GENERATION_BIT_PK, PK_GENERATION_BIT_R1,\n PK_GENERATION_BIT_R2, PK_GENERATION_BIT_SK, PK_GENERATION_CONFIGS,\n};\nuse lib::core::threshold::pk_generation::PkGeneration;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n a: pub [Polynomial; L],\n eek: Polynomial,\n sk: Polynomial,\n e_sm: [Polynomial; L],\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n) -> pub (Field, Field, Field) {\n let pk_generation: PkGeneration = PkGeneration::new(\n PK_GENERATION_CONFIGS,\n a,\n eek,\n sk,\n e_sm,\n r1is,\n r2is,\n pk0is,\n pk1is,\n );\n pk_generation.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/threshold/pk_generation/src/main.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/pk_generation/src/main.nr" }, "70": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_threshold_pk_challenge, compute_threshold_pk_commitment,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for threshold public key generation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Bound for error polynomial (eek) coefficients\n pub eek_bound: Field,\n /// Bound for secret key polynomial (sk) coefficients\n pub sk_bound: Field,\n /// Bound for smudging noise polynomial (e_sm) coefficients\n pub e_sm_bound: Field,\n /// Bounds for r1 polynomials (modulus switching quotients) for each CRT basis\n pub r1_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients) for each CRT basis\n pub r2_bounds: [Field; L],\n}\n\nimpl Configs {\n pub fn new(\n qis: [Field; L],\n eek_bound: Field,\n sk_bound: Field,\n e_sm_bound: Field,\n r1_bounds: [Field; L],\n r2_bounds: [Field; L],\n ) -> Self {\n Configs { qis, eek_bound, sk_bound, e_sm_bound, r1_bounds, r2_bounds }\n }\n}\n\n/// Correct Threshold Public Key Generation Circuit (Circuit 1).\n///\n/// Verifies:\n/// 1. Range checks on all secret witnesses (secret key, error, smudging noise, quotients)\n/// 2. Correct public key generation: pk0_i = -a_i * sk + eek + r2_i * (X^N + 1) + r1_i * q_i\n/// and pk1_i = a_i\n///\n/// Outputs:\n/// - commit(threshold_sk)\n/// - commit(threshold_pk)\n/// - commit(e_sm)\npub struct PkGeneration {\n /// Cryptographic parameters including bounds, moduli, and constants.\n configs: Configs,\n\n /// Common Reference String polynomials (public witnesses)\n /// One polynomial per modulus i\n a: [Polynomial; L],\n\n /// Error polynomial (secret witness)\n /// Small coefficients sampled from error distribution\n eek: Polynomial,\n\n /// Secret key polynomial (secret witness)\n /// Small coefficients sampled from CBD (Centered Binomial Distribution)\n sk: Polynomial,\n\n /// Smudging noise polynomial (secret witness)\n /// Used for threshold decryption security\n e_sm: [Polynomial; L],\n\n /// Quotients from polynomial operations (secret witnesses)\n /// r1[i] are quotients from modulus switching for modulus i (can be negative, degree 2*N-1)\n r1: [Polynomial<2 * N - 1>; L],\n /// r2[i] are quotients from cyclotomic reduction for modulus i (typically positive, degree N-1)\n r2: [Polynomial; L],\n\n /// Threshold public key components (committed witnesses)\n /// pk0[i] is the first component of the public key for modulus i\n pk0: [Polynomial; L],\n /// pk1[i] is the second component of the public key for modulus i (should equal a[i])\n pk1: [Polynomial; L],\n}\n\nimpl PkGeneration {\n pub fn new(\n configs: Configs,\n a: [Polynomial; L],\n eek: Polynomial,\n sk: Polynomial,\n e_sm: [Polynomial; L],\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n ) -> Self {\n PkGeneration { configs, a, eek, sk, e_sm, r1, r2, pk0, pk1 }\n }\n\n /// Flattens all witness data into a single array for Fiat-Shamir challenge generation\n fn payload(\n self,\n sk_commitment: Field,\n pk_commitment: Field,\n e_sm_commitment: Field,\n ) -> Vec {\n let mut inputs = Vec::new();\n\n // Flatten CRS polynomials a (L polynomials of degree N)\n inputs = flatten::<_, _, BIT_PK>(inputs, self.a);\n\n // Flatten error polynomial eek (1 polynomial of degree N)\n inputs = flatten::<_, _, BIT_EEK>(inputs, [self.eek]);\n\n // Use commitments instead of full polynomials\n inputs.push(sk_commitment);\n inputs.push(pk_commitment);\n inputs.push(e_sm_commitment);\n\n // Flatten quotient polynomials (L polynomials each)\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2);\n\n inputs\n }\n\n /// Main execution function\n /// Returns (commit(threshold_sk), commit(threshold_pk), commit(e_sm))\n pub fn execute(self) -> (Field, Field, Field) {\n // Step 1: Perform range checks on all secret witness values\n self.perform_range_checks();\n\n // Step 2: Compute commitments\n let sk_commitment = compute_share_computation_sk_commitment::(self.sk);\n let e_sm_commitment =\n compute_share_computation_e_sm_commitment::(self.e_sm);\n let pk_commitment = compute_threshold_pk_commitment::(self.pk0, self.pk1);\n\n // Step 3: Generate Fiat-Shamir challenges using commitments\n let gammas = self.generate_challenge(sk_commitment, pk_commitment, e_sm_commitment);\n\n // Step 4: Verify public key equations for each modulus\n for i in 0..L {\n let gamma = gammas.get(i);\n self.verify_public_key_for_modulus(i, gamma);\n }\n\n // Step 5: Return all commitments\n (sk_commitment, pk_commitment, e_sm_commitment)\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge\n fn generate_challenge(\n self,\n sk_commitment: Field,\n pk_commitment: Field,\n e_sm_commitment: Field,\n ) -> Vec {\n let inputs = self.payload(sk_commitment, pk_commitment, e_sm_commitment);\n\n compute_threshold_pk_challenge::(inputs)\n }\n\n /// Performs range checks on all secret witness values\n fn perform_range_checks(self) {\n // Check that error polynomial has small coefficients\n self.eek.range_check_2bounds::(self.configs.eek_bound, self.configs.eek_bound);\n\n // Check that secret key polynomial has small coefficients\n self.sk.range_check_2bounds::(self.configs.sk_bound, self.configs.sk_bound);\n\n // Check quotient terms are within expected bounds (per modulus)\n for i in 0..L {\n self.e_sm[i].range_check_2bounds::(\n self.configs.e_sm_bound,\n self.configs.e_sm_bound,\n );\n\n self.r1[i].range_check_2bounds::(\n self.configs.r1_bounds[i],\n self.configs.r1_bounds[i],\n );\n\n self.r2[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n }\n }\n\n /// Verifies the threshold public key generation equations for a specific CRT basis\n fn verify_public_key_for_modulus(self, i: u32, gamma: Field) {\n // Evaluate all polynomials at the random challenge point gamma\n let a_at_gamma = self.a.map(|a_poly| a_poly.eval(gamma));\n\n let eek_at_gamma = self.eek.eval(gamma);\n let sk_at_gamma = self.sk.eval(gamma);\n\n let r1_at_gamma = self.r1.map(|r1_poly| r1_poly.eval(gamma));\n let r2_at_gamma = self.r2.map(|r2_poly| r2_poly.eval(gamma));\n\n let pk0_at_gamma = self.pk0.map(|pk0_poly| pk0_poly.eval(gamma));\n let pk1_at_gamma = self.pk1.map(|pk1_poly| pk1_poly.eval(gamma));\n\n // Evaluate the cyclotomic polynomial X^N + 1 at gamma\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n\n // pk0_i = -a_i * sk + eek + r2_i * (X^N + 1) + r1_i * q_i\n let expected_pk0 = -a_at_gamma[i] * sk_at_gamma\n + eek_at_gamma\n + r2_at_gamma[i] * cyclo_at_gamma\n + r1_at_gamma[i] * self.configs.qis[i];\n\n assert(pk0_at_gamma[i] == expected_pk0, \"Public key equation 1 failed\");\n\n // Equation 2: pk1_i = a_i\n assert(pk1_at_gamma[i] == a_at_gamma[i], \"Public key equation 2 failed\");\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/threshold/pk_generation.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/pk_generation.nr" }, "74": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" }, "75": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" }, "80": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" }, "81": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/pk_generation.vk b/crates/zk-prover/tests/fixtures/pk_generation.vk index dd90626e6ec65ce3a6339f6e716f1f13804101c9..e38d16b2d449b8408bf985bcdd2c8b451dd28204 100644 GIT binary patch delta 1747 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 {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", + "path": "std/field/mod.nr" + }, + "19": { + "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", + "path": "std/hash/mod.nr" + }, + "50": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, THRESHOLD_SHARE_DECRYPTION_BIT_CT, THRESHOLD_SHARE_DECRYPTION_BIT_D,\n THRESHOLD_SHARE_DECRYPTION_BIT_E_SM, THRESHOLD_SHARE_DECRYPTION_BIT_R1,\n THRESHOLD_SHARE_DECRYPTION_BIT_R2, THRESHOLD_SHARE_DECRYPTION_BIT_SK,\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n};\nuse lib::core::threshold::share_decryption::ShareDecryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_sk_commitment: pub Field,\n expected_e_sm_commitment: pub Field,\n ct0: pub [Polynomial; L],\n ct1: pub [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<(2 * N) - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n) {\n let share_decryption: ShareDecryption = ShareDecryption::new(\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n );\n share_decryption.execute()\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/share_decryption/src/main.nr" + }, + "71": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_aggregated_shares_commitment, compute_threshold_share_decryption_challenge,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold decryption share circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Bounds for r1 polynomials (modulus switching quotients) for each CRT basis\n pub r1_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients) for each CRT basis\n pub r2_bounds: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], r1_bounds: [Field; L], r2_bounds: [Field; L]) -> Self {\n Configs { qis, r1_bounds, r2_bounds }\n }\n}\n\n/// Threshold Share Decryption (Circuit 6).\n///\n/// Verifies:\n/// 1. Commitment to sk matches expected (from DKG decryption circuit)\n/// 2. Commitment to e_sm matches expected (from DKG decryption circuit)\n/// 3. Correct computation: d_i = c_0i + c_1i * s_i + e_i + r_2i * (X^N + 1) + r_1i * q_i\npub struct ShareDecryption {\n /// Circuit parameters including bounds and cryptographic constants\n configs: Configs,\n\n /// Expected commitment to aggregated sk shares (from DKG decryption circuit)\n /// (public witness)\n expected_sk_commitment: Field,\n\n /// Expected commitment to aggregated e_sm shares (from DKG decryption circuit)\n /// (public witness)\n expected_e_sm_commitment: Field,\n\n /// Ciphertext components (public witnesses)\n /// ct0 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct0: [Polynomial; L],\n /// ct1 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct1: [Polynomial; L],\n\n /// Aggregated sum of sk shares (secret witness)\n sk: [Polynomial; L],\n\n /// Aggregated sum of e_sm shares (secret witness, direct input)\n /// e_sm[basis] - sum of e_sm shares for each CRT basis (degree N-1 with N coefficients)\n e_sm: [Polynomial; L],\n\n /// Quotient polynomials for lifting to Z (secret witnesses)\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n\n /// Party's computed decryption share\n /// (public witnesses)\n d: [Polynomial; L],\n}\n\nimpl ShareDecryption {\n pub fn new(\n configs: Configs,\n expected_sk_commitment: Field,\n expected_e_sm_commitment: Field,\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n ) -> Self {\n ShareDecryption {\n configs,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n }\n }\n\n /// Verifies that aggregated secret shares hash to expected_sk_commitment\n fn verify_agg_sk_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.sk)\n == self.expected_sk_commitment,\n \"S commitment mismatch\",\n );\n }\n\n /// Verifies that aggregated noise shares hash to expected_e_sm_commitment\n fn verify_agg_e_sm_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.e_sm)\n == self.expected_e_sm_commitment,\n \"E commitment mismatch\",\n );\n }\n\n /// Flattens all witness data into a single array for Fiat-Shamir challenge generation.\n ///\n /// This function serializes all polynomial coefficients (both public inputs and\n /// secret witnesses) into a 1D array in a deterministic order. The flattened data\n /// is used to generate the Fiat-Shamir challenge via the SAFE sponge API.\n ///\n /// The order of serialization is:\n /// 1. Commitment to aggregated secret shares `sk` (expected_sk_commitment)\n /// 2. Commitment to aggregated noise shares `e_sm` (expected_e_sm_commitment)\n /// 3. Ciphertext components `c_0` for each CRT basis (serialized coefficients)\n /// 4. Ciphertext components `c_1` for each CRT basis (serialized coefficients)\n /// 5. Quotient polynomials `r_1` for each CRT basis (serialized coefficients)\n /// 6. Quotient polynomials `r_2` for each CRT basis (serialized coefficients)\n /// 7. Decryption shares `d` for each CRT basis (serialized coefficients)\n ///\n /// Note: Aggregated secret shares `sk` and noise shares `e_sm` are represented by their\n /// commitments rather than serialized coefficients. This saves constraints while\n /// still binding them to the transcript.\n ///\n /// # Returns\n /// A vector containing commitments and polynomial coefficients in flattened form,\n /// ready for hashing to generate the Fiat-Shamir challenge.\n fn payload(self) -> Vec {\n let mut inputs = Vec::new();\n\n // Use commitments instead of full polynomials (saves constraints)\n inputs.push(self.expected_sk_commitment);\n inputs.push(self.expected_e_sm_commitment);\n\n // Flatten ciphertext components (public inputs)\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1);\n\n // Flatten quotient polynomials (secret witnesses)\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2);\n\n // Flatten decryption shares (public outputs)\n inputs = flatten::<_, _, BIT_D>(inputs, self.d);\n\n inputs\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify sk commitment matches expected\n self.verify_agg_sk_commitment();\n\n // Step 2: Verify e_sm commitment matches expected\n self.verify_agg_e_sm_commitment();\n\n // Step 3: Perform range checks on quotient polynomials\n // Note: sk and e_sm range checks are handled by commitment verification\n // (the DKG decryption circuit already performed range checks on these values)\n self.check_range_bounds();\n\n // Step 4: Generate Fiat-Shamir challenge from the transcript\n let gamma = self.generate_challenge();\n\n // Step 5: Verify decryption share computation for each CRT basis\n for i in 0..L {\n self.verify_decryption_share_computation(i, gamma);\n }\n }\n\n /// Performs range checks on quotient polynomial witnesses.\n ///\n /// This function constrains quotient polynomials to be within their expected bounds\n /// as specified in the `configs`. This is critical for security because it prevents\n /// attacks where malicious provers provide out-of-range values that could break the\n /// security properties of the Threshold scheme.\n ///\n /// Note: Range checks on `sk` and `e_sm` are NOT performed here because:\n /// - Their commitments are verified against expected values from the DKG circuit\n /// - The DKG decryption circuit already performed range checks on these values\n /// - Commitment binding ensures the values match what was previously verified\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any quotient coefficient is\n /// outside its expected bounds.\n fn check_range_bounds(self) {\n // Check quotient polynomials are within bounds\n for basis_idx in 0..L {\n // r_1 quotients can be negative (modulus quotients)\n self.r1[basis_idx].range_check_2bounds::(\n self.configs.r1_bounds[basis_idx],\n self.configs.r1_bounds[basis_idx],\n );\n // r_2 quotients (cyclotomic quotients)\n self.r2[basis_idx].range_check_2bounds::(\n self.configs.r2_bounds[basis_idx],\n self.configs.r2_bounds[basis_idx],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge value using the SAFE cryptographic sponge.\n ///\n /// This function implements the Fiat-Shamir transform for the decryption share circuit:\n /// 1. Flattens all witness data (commitments for sk/e_sm, ciphertexts c_0/c_1, quotients r_1/r_2, decryption shares d) into a single array\n /// 2. Absorbs the flattened data into the SAFE sponge\n /// 3. Squeezes a single challenge value\n ///\n /// The challenge is used to evaluate polynomials for the Schwartz-Zippel lemma,\n /// which allows verification of polynomial equations by checking them at a random\n /// point rather than checking all coefficients.\n ///\n /// # Returns\n /// A single challenge value `gamma` used as the evaluation point for verifying\n /// the decryption share computation formula for all CRT bases.\n fn generate_challenge(self) -> Field {\n let inputs = self.payload();\n\n compute_threshold_share_decryption_challenge::(inputs)\n }\n\n /// Verifies the lifted decryption share computation formula for a specific CRT basis using the Schwartz-Zippel lemma.\n ///\n /// This function verifies that the decryption share for basis `i` satisfies:\n /// `d_i(gamma) = c_0i(gamma) + c_1i(gamma) * s_i(gamma) + e_i(gamma) + r_2i(gamma) * cyclo(gamma) + r_1i(gamma) * q_i`\n ///\n /// Where:\n /// - `c_0i`, `c_1i` are ciphertext components for basis i\n /// - `s_i` is the aggregated secret key shares for basis i\n /// - `e_i` is the aggregated noise shares for basis i\n /// - `r_1i`, `r_2i` are quotient witnesses for basis i\n /// - `cyclo(gamma) = gamma^N + 1` is the cyclotomic polynomial evaluated at gamma\n /// - `q_i` is the CRT modulus for basis i\n ///\n /// The Schwartz-Zippel lemma ensures that if this equation holds at a random point\n /// `gamma`, then the polynomials are identical with high probability.\n ///\n /// # Arguments\n /// * `basis_idx` - The index of the CRT basis to verify (0 <= basis_idx < L)\n /// * `gamma` - The Fiat-Shamir challenge value used as the evaluation point\n ///\n /// # Panics\n /// The circuit will fail if the decryption share computation formula doesn't hold for the specified basis.\n fn verify_decryption_share_computation(self, basis_idx: u32, gamma: Field) {\n // Evaluate ciphertext components at gamma\n let c_0_at_gamma = self.ct0[basis_idx].eval(gamma);\n let c_1_at_gamma = self.ct1[basis_idx].eval(gamma);\n\n // Evaluate aggregated sums at gamma\n let sk_at_gamma = self.sk[basis_idx].eval(gamma);\n let e_sm_at_gamma = self.e_sm[basis_idx].eval(gamma);\n\n // Evaluate quotient polynomials at gamma\n let r_1_at_gamma = self.r1[basis_idx].eval(gamma);\n let r_2_at_gamma = self.r2[basis_idx].eval(gamma);\n\n // Evaluate cyclotomic polynomial X^N + 1 at gamma\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n\n // Compute expected decryption share using the lifted formula:\n // d_i = c_0i + c_1i * sk_i + e_sm_i + r_2i * (X^N + 1) + r_1i * q_i\n let expected_decryption_share = c_0_at_gamma\n + c_1_at_gamma * sk_at_gamma\n + e_sm_at_gamma\n + r_2_at_gamma * cyclo_at_gamma\n + r_1_at_gamma * self.configs.qis[basis_idx];\n\n // Evaluate the party's claimed decryption share at gamma\n let computed_decryption_share = self.d[basis_idx].eval(gamma);\n\n // Enforce equality: computed decryption share must match expected value\n assert(\n computed_decryption_share == expected_decryption_share,\n \"Decryption share computation failed\",\n );\n }\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/share_decryption.nr" + }, + "74": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" + }, + "75": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" + }, + "80": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" + }, + "81": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" + } + }, + "expression_width": { "Bounded": { "width": 4 } } +} diff --git a/crates/zk-prover/tests/fixtures/share_decryption.vk b/crates/zk-prover/tests/fixtures/share_decryption.vk new file mode 100644 index 0000000000000000000000000000000000000000..e1ea1bfab34d1f30acc3b615f8a8adfa10ab19a4 GIT binary patch literal 1888 zcmajg`6Ckw0KoAL(`@Ee*u=)N8euYp`Jt0cjBZh@^Nbk+n`tq zHPN2-j*FzMosDHl_Uji*?~$bV%FPm5x2*iO zXfh*m8J1Z0cIJ*W9eUTc^_o+Sft*6{rk=O)BeDrnL{F{g#nrE4iMPSnZpAE~1#0d; zg<2AM%#&7UBYRX;(#t$!0~rPtxdP!CI*?J*2CHy zWM#M`Z!VRlox9T|dL-+)y{D)4*i?G36v1SKur*~krq@m!BVmPJcP?ogl(#ROV+XDo zrHAt^a@*j4#WOF2oAZF9S&m{UF}NayRoC5>PxMVYHh9P^V4dG67$_@X!@8%&qsb+8 zy(-kOpD@5sA3T`H2Qnf#{S!gmsdo=KzDQ{*b@vY5ju`oHI_+Gq?jE8E6JG3v3zoW3 z{;-sZ$)QY#!;F%s2SxUl#eHR2*^;x5c9)|R#fKAE+o0$Ht5B;%ZA*(MoKsj|CI23+(L>P>|FAsjW*_w9N z_x2SM*Is?`7^|2Z=n<^bJIC4(kdrJjbZ%rfMV^NvsBen+I*2eQzO+t<4n8rbN|o~$ z4^3#zEh2?(SRLN5ndP07fDU%XZVcGw{PL5Aptd_cD0~InQg_bcWgAcnJ9s@QpSRk> zg{OXfKkQSALJ?O%@2j`L@*|NsLIFJFpx~Ok%5dV3zI|iC@v>YHjRSh(!CUC;v))b) zGFLtb)2Piew2*FX8M5!dA+ehCtZ~yI>iZYCCo=z*O~Y?eKAl3%Qumy%bv8L?XgmOYPT)1qfkPNe z+rO;m1upHIf5o?2HlN+YA>cjk)v502Y`E6oKp;0+HDDH%8ePEJCi*EC=04|*-}^qf z-`$j4D=Mh_JZv$m;QMh}o5&X)j-zz$S{oGLV zWK9IR8cShTF9!T+@o_F5ro_^FN#Zp0KS5FV#p7X{_*ZtMi`xg)~F72rW|PeGNX7T0;X1)&6?3#Os|F zu2$!tCJNDYk)Ywjdm7)y)td|{w6#kW%p}BN?6Z3-I~PAKEXRqqvyVqpKNdr`eYKhN z`y&$Ti1<&s_kB2fAdZQS1x=))}0Ilm3^`y-;HZBVG(0AqW>{HiuU zWG%#`i|Ad!xXmW{;L63}k_WEY$@*v=;${2^q<>QI8J?@^xCI3mmtr70%4^-Jn8EZ%IXVZ-3A)M_Yr*;WC~_n{hP{XG zucaUjTVaN>jrX7d?kfqIgge{9?VUSOzjp4q=e)ox&8p0F@l2TBb_?Pn1gF5-5@3J*Gxx@3Xl00cB zQ`_i!ceBe~HkfaG`@ASf%m#$>RjyJcSMj9}B_)u?Um_epP;-4&!&D=+{1Rx^UkS#y zDHJFR5N;ZC@CyF=Zar^iG}9faK-Tw*K>I3cn(@ZM&MQX1(;uA6fYul!y+veYaVbhE z#Ycf>WJasZd7w630yKg;CLx1jwZW8H`j&C#5zz{1+`G0Q33&D)c@U>75hyB%B3w%M zi~{OU3rh#QcwY|Wry3bSl?E<;rGPOR)_9=Rm`p;m1T578M|L&)JbmIfu$pFLYKKeB z5&WD?`^aIyc}Wm5TaPs%n~w;i<-d=RzC3uszm$z&X_p-f%)KOdJe2*iNN(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", @@ -192,36 +192,36 @@ "path": "std/hash/mod.nr" }, "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n DKG_SHARE_ENCRYPTION_BIT_CT, DKG_SHARE_ENCRYPTION_BIT_E0, DKG_SHARE_ENCRYPTION_BIT_E1,\n DKG_SHARE_ENCRYPTION_BIT_MSG, DKG_SHARE_ENCRYPTION_BIT_P1, DKG_SHARE_ENCRYPTION_BIT_P2,\n DKG_SHARE_ENCRYPTION_BIT_PK, DKG_SHARE_ENCRYPTION_BIT_R1, DKG_SHARE_ENCRYPTION_BIT_R2,\n DKG_SHARE_ENCRYPTION_BIT_U, DKG_SHARE_ENCRYPTION_CONFIGS, L, N,\n};\nuse lib::core::dkg::share_encryption::ShareEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_pk_commitment: pub Field,\n expected_message_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: pub [Polynomial; L],\n ct1is: pub [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let share_encryption: ShareEncryption = ShareEncryption::new(\n DKG_SHARE_ENCRYPTION_CONFIGS,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n share_encryption.execute();\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/share_encryption/src/main.nr" + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n L, N, SHARE_ENCRYPTION_BIT_CT, SHARE_ENCRYPTION_BIT_E0, SHARE_ENCRYPTION_BIT_E1,\n SHARE_ENCRYPTION_BIT_MSG, SHARE_ENCRYPTION_BIT_P1, SHARE_ENCRYPTION_BIT_P2,\n SHARE_ENCRYPTION_BIT_PK, SHARE_ENCRYPTION_BIT_R1, SHARE_ENCRYPTION_BIT_R2,\n SHARE_ENCRYPTION_BIT_U, SHARE_ENCRYPTION_CONFIGS,\n};\nuse lib::core::dkg::share_encryption::ShareEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_pk_commitment: pub Field,\n expected_message_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: pub [Polynomial; L],\n ct1is: pub [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let share_encryption: ShareEncryption = ShareEncryption::new(\n SHARE_ENCRYPTION_CONFIGS,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n share_encryption.execute();\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/share_encryption/src/main.nr" }, "65": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_dkg_pk_commitment;\nuse crate::math::commitments::{\n compute_share_encryption_challenge, compute_share_encryption_commitment_from_message,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for DKG share encryption circuit.\npub struct Configs {\n /// Plaintext modulus t\n pub t: Field,\n /// Q mod t (for scaling message)\n pub q_mod_t: Field,\n /// CRT moduli for each basis: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Scaling factors for each basis: [k0_0, k0_1, ..., k0_{L-1}]\n pub k0is: [Field; L],\n /// Bounds for public key polynomials for each CRT basis\n pub pk_bounds: [Field; L],\n /// Bounds for error polynomials (e0)\n pub e0_bound: Field,\n /// Bounds for error polynomials (e1)\n pub e1_bound: Field,\n /// Bound for secret polynomial u (ternary distribution)\n pub u_bound: Field,\n /// Lower bounds for r1 polynomials (modulus switching quotients)\n pub r1_low_bounds: [Field; L],\n /// Upper bounds for r1 polynomials (modulus switching quotients)\n pub r1_up_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients)\n pub r2_bounds: [Field; L],\n /// Bounds for p1 polynomials (modulus switching quotients)\n pub p1_bounds: [Field; L],\n /// Bounds for p2 polynomials (cyclotomic reduction quotients)\n pub p2_bounds: [Field; L],\n /// Bound for message polynomial (m)\n pub msg_bound: Field,\n}\n\nimpl Configs {\n pub fn new(\n t: Field,\n q_mod_t: Field,\n qis: [Field; L],\n k0is: [Field; L],\n pk_bounds: [Field; L],\n e0_bound: Field,\n e1_bound: Field,\n u_bound: Field,\n r1_low_bounds: [Field; L],\n r1_up_bounds: [Field; L],\n r2_bounds: [Field; L],\n p1_bounds: [Field; L],\n p2_bounds: [Field; L],\n msg_bound: Field,\n ) -> Self {\n Configs {\n t,\n q_mod_t,\n qis,\n k0is,\n pk_bounds,\n e0_bound,\n e1_bound,\n u_bound,\n r1_low_bounds,\n r1_up_bounds,\n r2_bounds,\n p1_bounds,\n p2_bounds,\n msg_bound,\n }\n }\n}\n\n/// DKG Share Encryption Circuit (Circuit 3).\n///\n/// Verifies:\n/// 1. Public key commitment matches expected (from Circuit 0)\n/// 2. Message commitment matches expected (from SK shares circuit)\n/// 3. Correct DKG share encryption: ct0[l] = pk0[l] * u + e0[l] + k1 * k0[l] + r1[l] * q[l] + r2[l] * (X^N + 1)\n/// and ct1[l] = pk1[l] * u + e1 + p2[l] * (X^N + 1) + p1[l] * q[l]\npub struct ShareEncryption {\n /// Circuit parameters\n configs: Configs,\n /// Expected commitment to public key (from Circuit 0)\n /// (public witness)\n expected_pk_commitment: Field,\n /// Expected commitment to message (from SK shares verification circuit)\n /// (public witness)\n expected_message_commitment: Field,\n /// Public key component 0 for each CRT basis (committed witnesses)\n pk0is: [Polynomial; L],\n /// Public key component 1 for each CRT basis (committed witnesses)\n pk1is: [Polynomial; L],\n /// Ciphertext component 0 for each CRT basis (public witnesses)\n ct0is: [Polynomial; L],\n /// Ciphertext component 1 for each CRT basis (public witnesses)\n ct1is: [Polynomial; L],\n /// Random ternary polynomial u (secret witness)\n u: Polynomial,\n /// Error polynomial e0 (secret witness)\n e0: Polynomial,\n /// Per-basis error polynomials e0[l] (secret witnesses)\n e0is: [Polynomial; L],\n /// CRT quotients for e0 (secret witnesses)\n e0_quotients: [Polynomial; L],\n /// Error polynomial e1 (secret witness)\n e1: Polynomial,\n /// Raw message polynomial (secret witness)\n message: Polynomial,\n /// Modulus switching quotient polynomials r1 (secret witnesses, degree 2N-1)\n r1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials r2 (secret witnesses, degree N-1)\n r2is: [Polynomial; L],\n /// Modulus switching quotient polynomials p1 (secret witnesses, degree 2N-1)\n p1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials p2 (secret witnesses, degree N-1)\n p2is: [Polynomial; L],\n}\n\nimpl ShareEncryption {\n pub fn new(\n configs: Configs,\n expected_pk_commitment: Field,\n expected_message_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<2 * N - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<2 * N - 1>; L],\n p2is: [Polynomial; L],\n ) -> Self {\n ShareEncryption {\n configs,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n }\n }\n\n /// Verifies that the public key hashes to the expected commitment\n fn verify_pk_commitment(self) {\n assert(\n compute_dkg_pk_commitment::(self.pk0is, self.pk1is)\n == self.expected_pk_commitment,\n \"Public key commitment mismatch\",\n );\n }\n\n /// Verifies that the message polynomial hashes to the expected commitment\n fn verify_message_commitment(self) {\n assert(\n compute_share_encryption_commitment_from_message::(self.message)\n == self.expected_message_commitment,\n \"Message commitment mismatch\",\n );\n }\n\n /// Computes the scaled message k1 from the raw message in centered form\n /// k1[i] = (q_mod_t * message[i]) mod t, centered to [-t/2, t/2)\n fn compute_scaled_message(self) -> Polynomial {\n let t = self.configs.t;\n let t_mod = ModU128::new(t);\n let q_mod_t: Field = self.configs.q_mod_t;\n let mut k1_coeffs: [Field; N] = [0; N];\n\n // Integer division for t_half\n let t_half: u128 = (t as u128) / 2;\n\n for i in 0..N {\n let msg_i: Field = self.message.coefficients[i];\n let q_times_m_mod_t = t_mod.mul_mod(q_mod_t, msg_i);\n\n // Check if centering is needed (value > t/2 means negative in centered form)\n let needs_centering = (q_times_m_mod_t as u128) > t_half;\n\n k1_coeffs[i] = if needs_centering {\n // Value is in (t/2, t), negative in centered form\n // Represent as P - magnitude (i.e., 0 - magnitude in Field)\n let magnitude = t - q_times_m_mod_t;\n 0 - magnitude\n } else {\n // Value is in [0, t/2], stays positive\n q_times_m_mod_t\n };\n }\n\n Polynomial { coefficients: k1_coeffs }\n }\n\n /// Flattens all polynomial coefficients into a single array for Fiat-Shamir challenge generation\n fn payload(self, k1: Polynomial) -> Vec {\n let mut inputs = Vec::new();\n\n // Use pk commitment instead of full pk polynomials\n inputs.push(self.expected_pk_commitment);\n\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0is);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1is);\n\n inputs = flatten::<_, _, BIT_E0>(inputs, [self.e0]);\n inputs = flatten::<_, _, BIT_E1>(inputs, [self.e1]);\n inputs = flatten::<_, _, BIT_U>(inputs, [self.u]);\n\n // Use message commitment instead of full message\n inputs.push(self.expected_message_commitment);\n\n // Include computed k1 in payload\n for i in 0..N {\n inputs.push(k1.coefficients[i]);\n }\n\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1is);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2is);\n inputs = flatten::<_, _, BIT_P1>(inputs, self.p1is);\n inputs = flatten::<_, _, BIT_P2>(inputs, self.p2is);\n\n inputs\n }\n\n /// Performs coefficient-wise CRT consistency check for the e0 error polynomial\n fn check_e0_crt_consistency(self) {\n for i in 0..L {\n for j in 0..N {\n assert(\n self.e0.coefficients[j]\n == self.e0is[i].coefficients[j]\n + self.e0_quotients[i].coefficients[j] * self.configs.qis[i],\n );\n }\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify public key commitment matches expected\n self.verify_pk_commitment();\n\n // Step 2: Verify message commitment matches expected\n self.verify_message_commitment();\n\n // Step 3: Perform range checks\n self.check_range_bounds();\n\n // Step 4: Check CRT consistency for e0\n self.check_e0_crt_consistency();\n\n // Step 5: Compute scaled message k1 from message\n let k1 = self.compute_scaled_message();\n\n // Step 6: Generate Fiat-Shamir challenges\n let gammas = self.generate_challenge(k1);\n\n // Step 7: Verify encryption constraints\n self.verify_evaluations(gammas, k1)\n }\n\n /// Performs range checks on all secret witness polynomial coefficients\n fn check_range_bounds(self) {\n self.u.range_check_2bounds::(self.configs.u_bound, self.configs.u_bound);\n self.e0.range_check_2bounds::(self.configs.e0_bound, self.configs.e0_bound);\n self.e1.range_check_2bounds::(self.configs.e1_bound, self.configs.e1_bound);\n\n // Message should be in [0, t)\n self.message.range_check_standard::(self.configs.msg_bound);\n\n for i in 0..L {\n self.pk0is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n self.pk1is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n\n self.r1is[i].range_check_2bounds::(\n self.configs.r1_up_bounds[i],\n self.configs.r1_low_bounds[i],\n );\n self.r2is[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n\n self.p1is[i].range_check_2bounds::(\n self.configs.p1_bounds[i],\n self.configs.p1_bounds[i],\n );\n self.p2is[i].range_check_2bounds::(\n self.configs.p2_bounds[i],\n self.configs.p2_bounds[i],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge\n fn generate_challenge(self, k1: Polynomial) -> Vec {\n let inputs = self.payload(k1);\n\n compute_share_encryption_challenge::(inputs)\n }\n\n /// Verifies DKG encryption constraints using Fiat-Shamir challenges and the Schwartz-Zippel lemma\n fn verify_evaluations(self, gammas: Vec, k1: Polynomial) {\n let gamma = gammas.get(0);\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n let u_at_gamma = self.u.eval(gamma);\n let e1_at_gamma = self.e1.eval(gamma);\n let k1_at_gamma = k1.eval(gamma);\n\n let mut sum = (0, 0);\n for i in 0..L {\n let pk0is_at_gamma = self.pk0is[i].eval(gamma);\n let r1i_at_gamma = self.r1is[i].eval(gamma);\n let r2i_at_gamma = self.r2is[i].eval(gamma);\n let e0is_at_gamma = self.e0is[i].eval(gamma);\n\n // Verify ct0 equation: ct0[i] = pk0[i]*u + e0[i] + k1*k0[i] + r1[i]*q[i] + r2[i]*cyclo\n let mut ct0_rhs = (pk0is_at_gamma * u_at_gamma) + e0is_at_gamma;\n ct0_rhs += k1_at_gamma * self.configs.k0is[i];\n ct0_rhs += r1i_at_gamma * self.configs.qis[i];\n ct0_rhs += r2i_at_gamma * cyclo_at_gamma;\n let ct0_lhs = self.ct0is[i].eval(gamma);\n\n // Verify ct1 equation: ct1[i] = pk1[i]*u + e1 + p2[i]*cyclo + p1[i]*q[i]\n let pk1is_at_gamma = self.pk1is[i].eval(gamma);\n let p1is_at_gamma = self.p1is[i].eval(gamma);\n let p2is_at_gamma = self.p2is[i].eval(gamma);\n let mut ct1_rhs = (pk1is_at_gamma * u_at_gamma) + e1_at_gamma;\n ct1_rhs += p2is_at_gamma * cyclo_at_gamma;\n ct1_rhs += p1is_at_gamma * self.configs.qis[i];\n let ct1_lhs = self.ct1is[i].eval(gamma);\n\n // Accumulate weighted sums for batch verification\n let gamma_i = if i == 0 { 1 } else { gammas.get(i) };\n sum = (\n sum.0 + ct0_lhs * gamma_i + ct1_lhs * gammas.get(i + L),\n sum.1 + ct0_rhs * gamma_i + ct1_rhs * gammas.get(i + L),\n );\n }\n\n assert(sum.0 == sum.1);\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_encryption.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_encryption.nr" }, "74": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" }, "75": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" }, "77": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" }, "79": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" }, "80": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" }, "81": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/share_encryption.vk b/crates/zk-prover/tests/fixtures/share_encryption.vk new file mode 100644 index 0000000000000000000000000000000000000000..929d89b0c4f50c04eac7662bab4ff8b7e7ba6f16 GIT binary patch literal 1888 zcmajg=OY^k1IO{imL`ITvqy|ZG-{mj2%2bvm`7CAsoJ%xc3XR0>`^hQadw`nitQ*$ zOSQsdj~I;^GsxSgs z_JJ;qi(_q9BG|`f0=)EiESgMthfB{Ch+mC5T^!{Q51?$B`Y(;;ja1vr93D|eQN7d^ zw#T1VtNUnzWJ_j4`-Hm##q6o>qmW5T@|07hg3&qia6C;RVqN@Ic;nr;Z>vJr<6U== z$QaXK9iuP!q$Bjfw7+qpS95m8UCm#nRpX4&L9^DiUId4GK1s5=P<82SF@FuWr_O#H zSexdXW%p|OeL>P{h2sMf18ZR+AoCi&>5RVWCOxwJ_e0#nSt;ujk$j00V$eacSDZaa zv5BJPlC;v@?1ReI>wlM}p6zXD-qo(ETYw14vGG?ywzEL30vd3S#f$q!P-Gybth~;k zM3tf-2fVRyXbTs{yIwhSmoc@#=%aWo4cu$;pSD0qa#$Lq_6_g!OlzX1EcuN#WQK&unCWPt*yXcgU0YL|<}BnQ z|9?q3PSr5SpJj|4@IcVh*YAn&?j!`-dZPxej6PWd8g;2eokThjZvaVzG{qQpQ6@RKn}z4?@66XI+1 zwdMN}p6Vzo6(gTu<$K(fbVX*?5p+9vslwA)`*c&O;ek*8|4*3}Pt_E~gVMu?S$3R; zCc*NHs3GRUSH;Rkm{22e6zyveK+@*DN)hZpQhT58UiK-S)o4mlFJCHn{i=GqQ~;$z zBJpX{sVv@R^w6&Q2rkNHK})o<2BUfE3VilJY~*B{ygR?O&pJy4t=KAq$@Y!iJEDN*WHMAFQlo}HTAQXyF> zUNuo}|0PKKV2mL7ee~>eVo~Cku=q^xZIBzuv*EH5cr?8ia7cQnSYi=}X6&<)IJLYvy{_fG)KNKBskT805tq@0R>IuTcN86z zW)H;dLEZWu05s?8C)NC$b2!Vpc-$rL4!o`$PFa95yv1ncVE9Z~MoF?Avvk2uqA)sz zR1BK#Gwa$87^E;_A&j4)x#XrOPFt}1->Th4Bf-nv?|(o*9@v%ys~4v z&S-%L4?+~*Xs7Y;%q4dp1CYHNZ%9KnJ@kmjFyS(5@4WA56!e_wZ~k>vBy-9)@JO)Q zKdgYQFl?aTHx*cX4$q^N00~6V_v8VLmubDm(4!WK_dbEwFBrzyEqfbF;10$Z6d4sQ zS70o&X#3%!vTU!0*p^VFj!Ka$`_HBjZp-i$e;H<`yd2c=O^gf3-PuBJo9}3?#c(sd zR3U<&L;{ro@INMP??kMP?3XM}6x^0qq3L_XIk}@WZ$MKaGN?Goyzrm$FTFI(=#wIo z`B4Z}QUc$S(nK9z;F84~;kU8sE@}BqW(SK1)=oa}qhvFA+|b^J9H3$*lOCog8z>HQ zh{fbNCjj*q;0pdVW3@n`RxI|C>agxw6Q4`Ic_h$mQYo!d7LsEUM!R+6u;oV$| z>(*g8MX-;VZ|ArSc`z^#vnAA+h98GJA=wkujeumxvw~|(yq%Qi|CHf~0lp{do_^m8 zL){7ro~V;iTb8#BMN=7cb3mw`{lE3;U!3EL@JP++ek~ajPzUP&f{2KmJF6A>Xtt5k r2uqjIqPi$91)Y59{0)LEVYeMug=#osP0p1Us_,\n y: [[[Field; N_PARTIES + 1]; L_THRESHOLD]; N],\n) -> pub [[Field; L_THRESHOLD]; N_PARTIES] {\n let sk_share_computation: SecretKeyShareComputation = SecretKeyShareComputation::new(\n SHARE_COMPUTATION_SK_CONFIGS,\n expected_secret_commitment,\n sk_secret,\n y,\n PARITY_MATRIX,\n );\n\n sk_share_computation.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/sk_share_computation/src/main.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/sk_share_computation/src/main.nr" }, "63": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_share_encryption_commitment_from_shares,\n};\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold secret share verification circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Correct Threshold Secret Key Share Computation (Circuit 2a).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == sk_secret[i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For SK: sk_secret is the trinary coefficients\npub struct SecretKeyShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// (public witness)\n expected_secret_commitment: Field,\n /// Secret key polynomial: Polynomial\n /// trinary coefficients\n /// (secret witness)\n sk_secret: Polynomial,\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = sk_secret[i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n /// (secret witnesses)\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n /// (public constants)\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\n/// Correct Threshold Smudging Noise Share Computation (Circuit 2b).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == e_sm[j][i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For ESM: e_sm[j] is the RNS representation at modulus j\npub struct SmudgingNoiseShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// This is computed from all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n expected_secret_commitment: Field,\n /// Smudging noise polynomial per modulus: [Polynomial; L]\n /// For ESM: each modulus has its own polynomial (RNS representation)\n e_sm_secret: [Polynomial; L],\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = e_sm[j][i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\nimpl SecretKeyShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n sk_secret: Polynomial,\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SecretKeyShareComputation { configs, expected_secret_commitment, sk_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_sk_commitment::(self.sk_secret)\n == self.expected_secret_commitment,\n \"SK commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == sk_secret[i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// sk_secret is the trinary coefficients, so y[i][j][0] is the same for all j.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n let secret_coeff = self.sk_secret.coefficients[coeff_idx];\n\n for mod_idx in 0..L {\n assert(self.y[coeff_idx][mod_idx][0] == secret_coeff);\n }\n }\n }\n}\n\nimpl SmudgingNoiseShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n e_sm_secret: [Polynomial; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SmudgingNoiseShareComputation { configs, expected_secret_commitment, e_sm_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n /// The commitment is computed over all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_e_sm_commitment::(self.e_sm_secret)\n == self.expected_secret_commitment,\n \"ESM commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == e_sm_secret[j][i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// e_sm_secret[j] is the RNS representation at modulus j, so y[i][j][0] varies per modulus.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let secret_coeff = self.e_sm_secret[mod_idx].coefficients[coeff_idx];\n assert(\n self.y[coeff_idx][mod_idx][0] == secret_coeff,\n \"Secret consistency check failed\",\n );\n }\n }\n }\n}\n\n/// Performs range checks on secret key and share values.\n///\n/// This function constrains all values to be within their expected bounds:\n/// - Share values for parties k >= 1 must be in [0, q_j) for each CRT modulus q_j\n///\n/// These bounds are critical for security and correctness of the Threshold scheme.\n///\n/// # Panics\n/// This function will cause the circuit to fail if any value is outside\n/// its expected bounds.\npub fn check_range_bounds(\n qis: [Field; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n // Shares y[i][j][k] for k >= 1 should be in [0, q_j)\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n for coeff_idx in 0..N {\n for party_idx in 1..(N_PARTIES + 1) {\n // Use range_check_standard from Polynomial by creating a single-coefficient polynomial\n Polynomial::new([y[coeff_idx][mod_idx][party_idx]])\n .range_check_standard::(q_j);\n }\n }\n }\n}\n\n/// Verifies Reed-Solomon parity check: `H[j] * y[i][j]^T == 0 mod q_j` for all i, j.\n///\n/// This function verifies that for each coefficient i and CRT basis j, the share\n/// vector `y[i][j]` forms a valid Reed-Solomon codeword by satisfying the parity\n/// check equation with the parity check matrix `H[j]`.\n///\n/// The parity check matrix H[j] has dimensions `(N_PARTIES - T) * (N_PARTIES + 1)`,\n/// and the share vector `y[i][j]` has length `N_PARTIES + 1`. The parity check\n/// ensures that any T+1 shares can correctly reconstruct the secret key via\n/// Lagrange interpolation.\n///\n/// # Panics\n/// The circuit will fail if the parity check doesn't hold for any coefficient,\n/// CRT basis, or parity check row.\npub fn verify_parity_check(\n qis: [Field; L],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n // For each row of H, compute dot product with y and verify == 0\n for row in 0..(N_PARTIES - T) {\n let mut sum: Field = 0;\n\n for col in 0..(N_PARTIES + 1) {\n sum = sum + h[mod_idx][row][col] * y[coeff_idx][mod_idx][col];\n }\n\n // Reduce mod q_j and verify == 0\n let m = ModU128::new(q_j);\n let result = m.reduce_mod(sum);\n assert(result == 0, \"Parity check failed\");\n }\n }\n }\n}\n\n/// Commits to shares for each party and modulus\n/// Returns [[Field; L]; N_PARTIES] where commitments[party_idx][mod_idx]\npub fn commit_to_party_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) -> [[Field; L]; N_PARTIES] {\n let mut commitments: [[Field; L]; N_PARTIES] = [[0; L]; N_PARTIES];\n\n for party_idx in 0..N_PARTIES {\n for mod_idx in 0..L {\n commitments[party_idx][mod_idx] = compute_share_encryption_commitment_from_shares::(\n y,\n party_idx,\n mod_idx,\n );\n }\n }\n\n commitments\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_computation.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_computation.nr" }, "74": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" }, "75": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" }, "77": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" }, "79": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" }, "80": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" }, "81": { "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" } }, "expression_width": { "Bounded": { "width": 4 } } diff --git a/crates/zk-prover/tests/fixtures/sk_share_computation.vk b/crates/zk-prover/tests/fixtures/sk_share_computation.vk index 0f98f29ed3edb2f91831b1bd735aa026c4807773..56f249009a6465135172f73f87432d86ef724d1b 100644 GIT binary patch delta 1747 zcmV;^1}ypD9N-R+V1E_$mahlLN+d{PkDZ6ak4gcApCp@ZG$Vy2YGsQ1eNYchg2s?5 zAC^({|IF8R^oi+Bu@3u5y{O=IvBu&i_f8YUW5ow4=|6w%!VFu)$8-4(Xzr)@)h*Wd zpA~b1CIAz~2J-(!I)7H05>Qd;rS0W|+*eY4dfq7?s=&|9>3{McQy_VmZB$29&LGBz z=}dUoG{A|_5D38s!+r@}EI5@5yv3&j2n#yHLLiv^%UQvcPGGkk4-d{|LAfc+&gKge zcu%ydf&jQSF=~Q!tDm}Kq(xWuxucyx zR9(N8={*_?|9|Md0hqO@RfU3LqvUr>;tF(&D*Tz%QVl?4hj7WsgOn|eDU{4)shPWt zECemoO}y65BXw59wdaPe@1k`v`;+KcAM&`4Oa6LKBhi3$>5m3cE|In?I^_u~b<|8; z@eVIj5|`GL*D8C!ktaT->HOr^~LP*@Fs(Jtlp!^Cd0^lSf0o|~y{bU^L-a%CM9ra0yA?Ht@kWT*XbBUKkQ(j8=U%`q9Kt=~aN7G8L=&n3u zqv@4Ui2d5hF)g$31^|ak!*c`ubVJgm-2IueWiO#eYKK2luk59Yx2e=nDguiJqjS{K z3JE8hTkRrb4d456BNXT*3d>L-XvEIzj2tcg*LY$uQ}y*L>e?{iQr^dP7kLQRNq;f5 ztF@(qsmCDv6ncS+K))s<{x5lWqH>t1#2`r^FH4vx89FR)ore~}*SogF<@T*M$O72< z0ZFr>t==rgll5PDf&M6KOZF18nw9`-+fhW8of7o4!U_jawsurfAO0DEw*!K!g z%R@8N%n4`#qxHF6P}Q>-kmcX2Ds?~)MEVL?I>Sl7?kRgAD7oOXp8^{M-G9+u)U;M& z2kfCvEFD@@;zibL+V`#0HsO+VnE;nMbP?9ntnY<()Z+lH1QJ)s$gBbN z*<@38jIyfIZ&3d}SQWd%0U57sQJ5(qx2=nGiOo)H7f!|9;oCAhe6E zAKPDm6^;GYNC7mF_W}KJMSp*zCJ+@qm1nc+ya}E=)u5mXxBeIe0R_3Um9^Nnw5B@+ z-(@Qe5bqRiCIA(<(otP@;>_%s+|iU-At|pqV}Dv=Dl$Y5h7BGne;bi?7m^FDJ&V8` zm6Zu9A}ff22;3#nsznY9OTrSvelT8%lCenc+al)ak_UQ(NFhPT>wn}R0HM{4%XBy& zZ5b0*emjv|fdM+&6(eh<&!zzpv_L=$E6O+Gu?Sw0N_PQB(j|$x9}SO2bgx%L-rD_R z%Ic6yLr!#$mlNKM!`B2o20If9-?MWiPBE$%j zFl1`~mUCg0l#?)(Dw8t}9+40ZlYb2$K>{x=XFjTNT*+q)G7%Y03IVP)B+YuciGdr; p?-QK4t|u=}HkZ==N@=SMmYEb3f!5p33*g1yD8OD7bLo0u|F9X(MgRZ+ literal 3680 zcmajhc{r5o8wc=bP|S=a%S1;pjD6QBr$!jrW++)IQB=|ir4)lv8B0jEXoyao7Rgd$ zDkQ&jax!R+EwX1XWhyC4&Y|JV-}n5k)BE3ZectbTUGIB8@BQ2e{pY3lpNf#`4;%yB z8FTKs)^Eo*kP@|n4_{b3>joSl!dxy#ve8+K>YsTnnVShbg}?oQ>>}-H@d*7v!j#@+MR31JC3fQ3s%?xA`~eZCEI^11Y0 zZX>v1ay((c%j0bHkiL3pZCeX}8n`fDzjAunfy~@}MZwLTUkE&^cSCK;%T-c;O4h|- zeT_Ed07ppOlgP*m+3B>amDrHX-v<0omg|A4b#ij8hi$9%n_J)Efg^;ksV@?j!jtQ^ z67vL2-oXEN=(dB`x9WnMnH6Gz^Q7Nz14l?9YDYzBJbG+l9vn}gFa!%}(EE zxqPdi@XHf_07uBoirT(xGkQ2aa6a`_=sV!42H*3$JY*;V$)P-60?RlZI6|1b%Hmy# z@%{yGBVERD;lNu-^xfRb_eo__x9H}JmnQZAM@XO598i+~B;82DxO00=H*j~8tVf3A zajYS|bKAbJvZkKEh2MYrafZuM^bS&cES;aZ68OZO3#zBllf7q-@OVZTUO-BV0}J(OflQ1@AR*gtR5hZQmCX0?&lRzD%@?0KUO# z#HWIS&F6(u{aLPGEX#o-B$K{BQPFB;mp`q+kz7jxu1+h%dnaeSyiKzHLnJ>JAfl(de&VqD!7qxfu+j|YJ>H){aUy>RFI3SjXAa&yWKJ7 zzDQoxZ=;yX^sYg*PZqL%#0lWv)qGpD#m6J1Hw2AF6fYhe11|jj+cq{8qpj3|qS9!D zy8(Pz#kSutOn9k44(Ueu#Pk{&RN^|UM zV1?3;r&)?IwXP@uM@XDU-L(+&mB|Qfn*X*Jo_`)JW9LBz-=@YO>hqTU`?>J{LTHVc zXa48>@5Q(RelKZ=4W2(ywk4o|pW}93(9bhBF8>1i3qr(kCQgerNO6?3b$aE@0r|tG zH=Tl$Z9F-j3NKWZbh;S;7cP@s>cYeY;dUK`1A=_mA7q9XPmz=+v~f*t8iCx_k7*)# zvDB3XVVxZ~tnP1nCp80rdki(wl^Ie!H1o>4m4)#o@O(sQt?^P%l)sth+??TuezOsf zKb2R^CDMqdE_r%u$VMlwB?A|}|97S6xKzqB9nz91BkC4#TKO&ZkWs^>x&4f|CB36A zqWf?4^PVSlMQA+ zx3vW6J`~AoGJ7VnYNvB1*F{#ni@yL|-(uA(%1qKNyiZ9*P5j4@6yU=7!-=98UUKnx zSMVJluJ&HwftZ51YG1dma+QnY!*>nn6yONyI4l*U_GR)<3PGR}J#v`RFn^T)w;W-c({l=Nkn74}^@?`Rp8X z=swy%&+fDs%?5enz5vgNw1=e~C)}2;_Yj`I`XD5s;Pv9gJ=s+y;)6|Zyv0ENsIqJQ z;8^*u>FxX42C~D_7{G<|#~RKt_dI=#Dt2mkN(+3yta*&!qyw`+XBELZ=Sca78j(D) zB9*QFdVee-UC>R%Yyh59*;`d{$8yE+VMCc!Q%WJC11R=)%dQ(Ya8*kx5||a$@c-4& z=a3IEef$m9+sh@%s2MQ9^My;o;|_P%&DCJJ;~c%Zfv3 zbv?j^^`mxZr&O!UWIBd(yzJrmtT)+S^!C^}nX4?DVF!=30j(l=39FTsin!tOu&o@2 zmjoZ+m&|eu-f#1=TAkF_XKPN@N#b0K^6<-;S%;I=s#M+{r#i+ zF=ZRITB55{;#8Zb6t7m7>52qQjgMHDp4`VfBE4RIjVlg#_v=>tNd2&0tsfzbAAMk1 WbpA4RwYc1|(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n DKG_SHARE_ENCRYPTION_BIT_CT, DKG_SHARE_ENCRYPTION_BIT_E0, DKG_SHARE_ENCRYPTION_BIT_E1,\n DKG_SHARE_ENCRYPTION_BIT_MSG, DKG_SHARE_ENCRYPTION_BIT_P1, DKG_SHARE_ENCRYPTION_BIT_P2,\n DKG_SHARE_ENCRYPTION_BIT_PK, DKG_SHARE_ENCRYPTION_BIT_R1, DKG_SHARE_ENCRYPTION_BIT_R2,\n DKG_SHARE_ENCRYPTION_BIT_U, DKG_SHARE_ENCRYPTION_CONFIGS, L, N,\n};\nuse lib::core::dkg::share_encryption::ShareEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_pk_commitment: pub Field,\n expected_message_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: pub [Polynomial; L],\n ct1is: pub [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let share_encryption: ShareEncryption = ShareEncryption::new(\n DKG_SHARE_ENCRYPTION_CONFIGS,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n share_encryption.execute();\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/share_encryption/src/main.nr" - }, - "65": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_dkg_pk_commitment;\nuse crate::math::commitments::{\n compute_share_encryption_challenge, compute_share_encryption_commitment_from_message,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for DKG share encryption circuit.\npub struct Configs {\n /// Plaintext modulus t\n pub t: Field,\n /// Q mod t (for scaling message)\n pub q_mod_t: Field,\n /// CRT moduli for each basis: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Scaling factors for each basis: [k0_0, k0_1, ..., k0_{L-1}]\n pub k0is: [Field; L],\n /// Bounds for public key polynomials for each CRT basis\n pub pk_bounds: [Field; L],\n /// Bounds for error polynomials (e0)\n pub e0_bound: Field,\n /// Bounds for error polynomials (e1)\n pub e1_bound: Field,\n /// Bound for secret polynomial u (ternary distribution)\n pub u_bound: Field,\n /// Lower bounds for r1 polynomials (modulus switching quotients)\n pub r1_low_bounds: [Field; L],\n /// Upper bounds for r1 polynomials (modulus switching quotients)\n pub r1_up_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients)\n pub r2_bounds: [Field; L],\n /// Bounds for p1 polynomials (modulus switching quotients)\n pub p1_bounds: [Field; L],\n /// Bounds for p2 polynomials (cyclotomic reduction quotients)\n pub p2_bounds: [Field; L],\n /// Bound for message polynomial (m)\n pub msg_bound: Field,\n}\n\nimpl Configs {\n pub fn new(\n t: Field,\n q_mod_t: Field,\n qis: [Field; L],\n k0is: [Field; L],\n pk_bounds: [Field; L],\n e0_bound: Field,\n e1_bound: Field,\n u_bound: Field,\n r1_low_bounds: [Field; L],\n r1_up_bounds: [Field; L],\n r2_bounds: [Field; L],\n p1_bounds: [Field; L],\n p2_bounds: [Field; L],\n msg_bound: Field,\n ) -> Self {\n Configs {\n t,\n q_mod_t,\n qis,\n k0is,\n pk_bounds,\n e0_bound,\n e1_bound,\n u_bound,\n r1_low_bounds,\n r1_up_bounds,\n r2_bounds,\n p1_bounds,\n p2_bounds,\n msg_bound,\n }\n }\n}\n\n/// DKG Share Encryption Circuit (Circuit 3).\n///\n/// Verifies:\n/// 1. Public key commitment matches expected (from Circuit 0)\n/// 2. Message commitment matches expected (from SK shares circuit)\n/// 3. Correct DKG share encryption: ct0[l] = pk0[l] * u + e0[l] + k1 * k0[l] + r1[l] * q[l] + r2[l] * (X^N + 1)\n/// and ct1[l] = pk1[l] * u + e1 + p2[l] * (X^N + 1) + p1[l] * q[l]\npub struct ShareEncryption {\n /// Circuit parameters\n configs: Configs,\n /// Expected commitment to public key (from Circuit 0)\n /// (public witness)\n expected_pk_commitment: Field,\n /// Expected commitment to message (from SK shares verification circuit)\n /// (public witness)\n expected_message_commitment: Field,\n /// Public key component 0 for each CRT basis (committed witnesses)\n pk0is: [Polynomial; L],\n /// Public key component 1 for each CRT basis (committed witnesses)\n pk1is: [Polynomial; L],\n /// Ciphertext component 0 for each CRT basis (public witnesses)\n ct0is: [Polynomial; L],\n /// Ciphertext component 1 for each CRT basis (public witnesses)\n ct1is: [Polynomial; L],\n /// Random ternary polynomial u (secret witness)\n u: Polynomial,\n /// Error polynomial e0 (secret witness)\n e0: Polynomial,\n /// Per-basis error polynomials e0[l] (secret witnesses)\n e0is: [Polynomial; L],\n /// CRT quotients for e0 (secret witnesses)\n e0_quotients: [Polynomial; L],\n /// Error polynomial e1 (secret witness)\n e1: Polynomial,\n /// Raw message polynomial (secret witness)\n message: Polynomial,\n /// Modulus switching quotient polynomials r1 (secret witnesses, degree 2N-1)\n r1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials r2 (secret witnesses, degree N-1)\n r2is: [Polynomial; L],\n /// Modulus switching quotient polynomials p1 (secret witnesses, degree 2N-1)\n p1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials p2 (secret witnesses, degree N-1)\n p2is: [Polynomial; L],\n}\n\nimpl ShareEncryption {\n pub fn new(\n configs: Configs,\n expected_pk_commitment: Field,\n expected_message_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<2 * N - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<2 * N - 1>; L],\n p2is: [Polynomial; L],\n ) -> Self {\n ShareEncryption {\n configs,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n }\n }\n\n /// Verifies that the public key hashes to the expected commitment\n fn verify_pk_commitment(self) {\n assert(\n compute_dkg_pk_commitment::(self.pk0is, self.pk1is)\n == self.expected_pk_commitment,\n \"Public key commitment mismatch\",\n );\n }\n\n /// Verifies that the message polynomial hashes to the expected commitment\n fn verify_message_commitment(self) {\n assert(\n compute_share_encryption_commitment_from_message::(self.message)\n == self.expected_message_commitment,\n \"Message commitment mismatch\",\n );\n }\n\n /// Computes the scaled message k1 from the raw message in centered form\n /// k1[i] = (q_mod_t * message[i]) mod t, centered to [-t/2, t/2)\n fn compute_scaled_message(self) -> Polynomial {\n let t = self.configs.t;\n let t_mod = ModU128::new(t);\n let q_mod_t: Field = self.configs.q_mod_t;\n let mut k1_coeffs: [Field; N] = [0; N];\n\n // Integer division for t_half\n let t_half: u128 = (t as u128) / 2;\n\n for i in 0..N {\n let msg_i: Field = self.message.coefficients[i];\n let q_times_m_mod_t = t_mod.mul_mod(q_mod_t, msg_i);\n\n // Check if centering is needed (value > t/2 means negative in centered form)\n let needs_centering = (q_times_m_mod_t as u128) > t_half;\n\n k1_coeffs[i] = if needs_centering {\n // Value is in (t/2, t), negative in centered form\n // Represent as P - magnitude (i.e., 0 - magnitude in Field)\n let magnitude = t - q_times_m_mod_t;\n 0 - magnitude\n } else {\n // Value is in [0, t/2], stays positive\n q_times_m_mod_t\n };\n }\n\n Polynomial { coefficients: k1_coeffs }\n }\n\n /// Flattens all polynomial coefficients into a single array for Fiat-Shamir challenge generation\n fn payload(self, k1: Polynomial) -> Vec {\n let mut inputs = Vec::new();\n\n // Use pk commitment instead of full pk polynomials\n inputs.push(self.expected_pk_commitment);\n\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0is);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1is);\n\n inputs = flatten::<_, _, BIT_E0>(inputs, [self.e0]);\n inputs = flatten::<_, _, BIT_E1>(inputs, [self.e1]);\n inputs = flatten::<_, _, BIT_U>(inputs, [self.u]);\n\n // Use message commitment instead of full message\n inputs.push(self.expected_message_commitment);\n\n // Include computed k1 in payload\n for i in 0..N {\n inputs.push(k1.coefficients[i]);\n }\n\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1is);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2is);\n inputs = flatten::<_, _, BIT_P1>(inputs, self.p1is);\n inputs = flatten::<_, _, BIT_P2>(inputs, self.p2is);\n\n inputs\n }\n\n /// Performs coefficient-wise CRT consistency check for the e0 error polynomial\n fn check_e0_crt_consistency(self) {\n for i in 0..L {\n for j in 0..N {\n assert(\n self.e0.coefficients[j]\n == self.e0is[i].coefficients[j]\n + self.e0_quotients[i].coefficients[j] * self.configs.qis[i],\n );\n }\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify public key commitment matches expected\n self.verify_pk_commitment();\n\n // Step 2: Verify message commitment matches expected\n self.verify_message_commitment();\n\n // Step 3: Perform range checks\n self.check_range_bounds();\n\n // Step 4: Check CRT consistency for e0\n self.check_e0_crt_consistency();\n\n // Step 5: Compute scaled message k1 from message\n let k1 = self.compute_scaled_message();\n\n // Step 6: Generate Fiat-Shamir challenges\n let gammas = self.generate_challenge(k1);\n\n // Step 7: Verify encryption constraints\n self.verify_evaluations(gammas, k1)\n }\n\n /// Performs range checks on all secret witness polynomial coefficients\n fn check_range_bounds(self) {\n self.u.range_check_2bounds::(self.configs.u_bound, self.configs.u_bound);\n self.e0.range_check_2bounds::(self.configs.e0_bound, self.configs.e0_bound);\n self.e1.range_check_2bounds::(self.configs.e1_bound, self.configs.e1_bound);\n\n // Message should be in [0, t)\n self.message.range_check_standard::(self.configs.msg_bound);\n\n for i in 0..L {\n self.pk0is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n self.pk1is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n\n self.r1is[i].range_check_2bounds::(\n self.configs.r1_up_bounds[i],\n self.configs.r1_low_bounds[i],\n );\n self.r2is[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n\n self.p1is[i].range_check_2bounds::(\n self.configs.p1_bounds[i],\n self.configs.p1_bounds[i],\n );\n self.p2is[i].range_check_2bounds::(\n self.configs.p2_bounds[i],\n self.configs.p2_bounds[i],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge\n fn generate_challenge(self, k1: Polynomial) -> Vec {\n let inputs = self.payload(k1);\n\n compute_share_encryption_challenge::(inputs)\n }\n\n /// Verifies DKG encryption constraints using Fiat-Shamir challenges and the Schwartz-Zippel lemma\n fn verify_evaluations(self, gammas: Vec, k1: Polynomial) {\n let gamma = gammas.get(0);\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n let u_at_gamma = self.u.eval(gamma);\n let e1_at_gamma = self.e1.eval(gamma);\n let k1_at_gamma = k1.eval(gamma);\n\n let mut sum = (0, 0);\n for i in 0..L {\n let pk0is_at_gamma = self.pk0is[i].eval(gamma);\n let r1i_at_gamma = self.r1is[i].eval(gamma);\n let r2i_at_gamma = self.r2is[i].eval(gamma);\n let e0is_at_gamma = self.e0is[i].eval(gamma);\n\n // Verify ct0 equation: ct0[i] = pk0[i]*u + e0[i] + k1*k0[i] + r1[i]*q[i] + r2[i]*cyclo\n let mut ct0_rhs = (pk0is_at_gamma * u_at_gamma) + e0is_at_gamma;\n ct0_rhs += k1_at_gamma * self.configs.k0is[i];\n ct0_rhs += r1i_at_gamma * self.configs.qis[i];\n ct0_rhs += r2i_at_gamma * cyclo_at_gamma;\n let ct0_lhs = self.ct0is[i].eval(gamma);\n\n // Verify ct1 equation: ct1[i] = pk1[i]*u + e1 + p2[i]*cyclo + p1[i]*q[i]\n let pk1is_at_gamma = self.pk1is[i].eval(gamma);\n let p1is_at_gamma = self.p1is[i].eval(gamma);\n let p2is_at_gamma = self.p2is[i].eval(gamma);\n let mut ct1_rhs = (pk1is_at_gamma * u_at_gamma) + e1_at_gamma;\n ct1_rhs += p2is_at_gamma * cyclo_at_gamma;\n ct1_rhs += p1is_at_gamma * self.configs.qis[i];\n let ct1_lhs = self.ct1is[i].eval(gamma);\n\n // Accumulate weighted sums for batch verification\n let gamma_i = if i == 0 { 1 } else { gammas.get(i) };\n sum = (\n sum.0 + ct0_lhs * gamma_i + ct1_lhs * gammas.get(i + L),\n sum.1 + ct0_rhs * gamma_i + ct1_rhs * gammas.get(i + L),\n );\n }\n\n assert(sum.0 == sum.1);\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/share_encryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/sk_share_encryption.vk b/crates/zk-prover/tests/fixtures/sk_share_encryption.vk deleted file mode 100644 index 05163e1cbe3ac39ced1e8ac38809ddb99dac74b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3680 zcmajic|6ql9|!QyAjf2gG1i$|W2DfEbv2_VM`AUSwNgsuPB|;NwIjETBaM~w*EvzN zDWXWBbsvM8a!js~HcPS9Z~oo)JRa@*H}jm=_w#ssKJU-x{rMvF-H*(76^Y1x-w_75 zuk={ABH86l1n;Arlvqa`88|{)Y4}f7*eowQg)5J6S-${R3}n8u4H)an?ksm6So~1+ z5;#Hz4CXV+#Wbn7w^7TZFNJ{LuIoAC#hHNsqy^$$gUYvxS%VTW75_ZOe2X!gUZZprIzQEC|vI}IEmX+zZvg#aV( z%bxy1Wak>-X9iWAlI3!gmT18X1;=7tvA_|+I#h`Fr#6*Wn=v%LEmDA|8)h80a;UG< zH_g=y&U6mY1CEe(HFKL+;+sb`zN8GZ=4Zfzn8hX6EerLTTI!fxlZ!3{;0O`xxY&DA zMuelIYbULxiNF<08a~YZeM01g=1qbn_ZOpK;0Vc54{u&MqGtOP*XkD1J_$T0_UP2K z@wvCB7GLR#CMx%y0nVSl*qrsQCV{5x&c);GzqSBR%u`_1CKl4{(?yfcN8O(v0FIDw z;6zzpo3-Mdyw8q{mHEJ1WfIKHgBxrsqWT;qtS2|N0q4(Oe=Uo_3gNj&+J~#Q-36Xb z9F_PVeY;0F-u=goHf~h7zYvmPSoBBB#JpN5FmW!q>1xcS9!dV&zt#3&3fFq>Px%6{Z zv*aKDC{A3ftH%SUwDv^(Zsh6DO#AKd8}1{r3UGe?qLv9(cFlfSFOmwozXA9lm(0v! zUd@pm)~P5F3y_A+AOF#_jIUCwj^dIXA+xUgL4GY#smME@Zk$@RvTS!ikG>Z;LXz64 z4<5G^#4GkE`nNkr1OJqepYS;>F75a<)|>8gdy@`u{{GpzTet4#V3UO|d*yF0SAZAm zWKq`U%Hpf^R)nr!Qq_14oIn1{i;ZZJenz{@a_AOu1b9mK#~ra|XB~d{-R7o;frusC z-w26_C3q*(I>b~Y?rzX4Vu3uHYLrTqmg?;tZ#+ill73|ZM`%;yX=3zy8&-tpY0daW z1>ku(qRMoq8DW3wIucti!?hhaLi%{+oy!T04P?#RE*|Vxz~^MQd%n0gEZ*eKt5Fi+ z{jCO^-+%UG2Ixs+aN<&qNfT3Wf1kI}Iin#ln8_2tJi6X*;8F3EtsAHKR@6IZD@Nq=|t)3nYudK>bxxlI4AAg{cA(9D+795 z3@7GFVJvWjFbOFo{Vq*zqTG8?4$E(V(q1W5AUW^$awf>@0Ng?OkwEB^a5;ulU@CE zU@MaygJb_Fke4J36sHy@?c)@U>{H5v^*?(OE7nnV`U4@9(Go)o-yI>4m(F6O_x2k| zh1qZaG)~?Q+&o%KR=8k#PyK^tn)>Wi6};adq<7K*=VUySQ5SA$+9jL;@_X|qpVeS1 zM>o&7Ot9|~Lg4w1kWiQ--tWR5YDM~rK?8dV&KoZ|D4fcam@CnQQKMAe=BIU@%e_NWcA{orerAZtR4#F zv5`^H>bW)>M_pd5l@`PLV$=@bzgKCoj&n>Ox8c29kgh;pqS#`fqy&5atAYq--2*tj zh91lOXspK(lJPF-3%HFW!TLvpKYCpbMvQmP7moGh!uzwPK0RK1OsD5MRcig7C$djt z1jbj+4*wx%{Vl81CKU!l0ULi z0k6c!+#{3M>$jVZSBrb)I79+R2=5kSk?k3eF&`ml1ypnaANg{$eKu>)PN%TUeEjRQ zr$fN`>u1-ilkz|fm$^HPbzs+P;6z?e)ns52?n>?s4t1Z3&!52g=eL!p1s=<}8*0O% zb`v~+UovEn-Z>tylE1+2a6qAEuD}t}C1|#YUo!OZ|CSf(otrD*|NcSn{`PPGuW#`E z=D+?Q5jnI{DfilLGWibv;>K-NUIKy5vYi#n^OX#X!0XuN&ziuEJjuIPbw|pm={ljl bLw4>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, THRESHOLD_SHARE_DECRYPTION_BIT_CT, THRESHOLD_SHARE_DECRYPTION_BIT_D,\n THRESHOLD_SHARE_DECRYPTION_BIT_E_SM, THRESHOLD_SHARE_DECRYPTION_BIT_R1,\n THRESHOLD_SHARE_DECRYPTION_BIT_R2, THRESHOLD_SHARE_DECRYPTION_BIT_SK,\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n};\nuse lib::core::threshold::share_decryption::ShareDecryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_sk_commitment: pub Field,\n expected_e_sm_commitment: pub Field,\n ct0: pub [Polynomial; L],\n ct1: pub [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<(2 * N) - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n) {\n let share_decryption: ShareDecryption = ShareDecryption::new(\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n );\n share_decryption.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/threshold/share_decryption/src/main.nr" - }, - "71": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_aggregated_shares_commitment, compute_threshold_share_decryption_challenge,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold decryption share circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Bounds for r1 polynomials (modulus switching quotients) for each CRT basis\n pub r1_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients) for each CRT basis\n pub r2_bounds: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], r1_bounds: [Field; L], r2_bounds: [Field; L]) -> Self {\n Configs { qis, r1_bounds, r2_bounds }\n }\n}\n\n/// Threshold Share Decryption (Circuit 6).\n///\n/// Verifies:\n/// 1. Commitment to sk matches expected (from DKG decryption circuit)\n/// 2. Commitment to e_sm matches expected (from DKG decryption circuit)\n/// 3. Correct computation: d = c_0 + c_1 * s + e + r_2 * (X^N + 1) + r_1 * q_i\npub struct ShareDecryption {\n /// Circuit parameters including bounds and cryptographic constants\n configs: Configs,\n\n /// Expected commitment to aggregated sk shares (from DKG decryption circuit)\n /// (public witness)\n expected_sk_commitment: Field,\n\n /// Expected commitment to aggregated e_sm shares (from DKG decryption circuit)\n /// (public witness)\n expected_e_sm_commitment: Field,\n\n /// Ciphertext components (public witnesses)\n /// ct0 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct0: [Polynomial; L],\n /// ct1 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct1: [Polynomial; L],\n\n /// Aggregated sum of sk shares (secret witness)\n sk: [Polynomial; L],\n\n /// Aggregated sum of e_sm shares (secret witness, direct input)\n /// e_sm[basis] - sum of e_sm shares for each CRT basis (degree N-1 with N coefficients)\n e_sm: [Polynomial; L],\n\n /// Quotient polynomials for lifting to Z (secret witnesses)\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n\n /// Party's computed decryption share\n /// (public witnesses)\n d: [Polynomial; L],\n}\n\nimpl ShareDecryption {\n pub fn new(\n configs: Configs,\n expected_sk_commitment: Field,\n expected_e_sm_commitment: Field,\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n ) -> Self {\n ShareDecryption {\n configs,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n }\n }\n\n /// Verifies that aggregated secret shares hash to expected_sk_commitment\n fn verify_agg_sk_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.sk)\n == self.expected_sk_commitment,\n \"S commitment mismatch\",\n );\n }\n\n /// Verifies that aggregated noise shares hash to expected_e_sm_commitment\n fn verify_agg_e_sm_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.e_sm)\n == self.expected_e_sm_commitment,\n \"E commitment mismatch\",\n );\n }\n\n /// Flattens all witness data into a single array for Fiat-Shamir challenge generation.\n ///\n /// This function serializes all polynomial coefficients (both public inputs and\n /// secret witnesses) into a 1D array in a deterministic order. The flattened data\n /// is used to generate the Fiat-Shamir challenge via the SAFE sponge API.\n ///\n /// The order of serialization is:\n /// 1. Commitment to aggregated secret shares `sk` (expected_sk_commitment)\n /// 2. Commitment to aggregated noise shares `e_sm` (expected_e_sm_commitment)\n /// 3. Ciphertext components `c_0` for each CRT basis (serialized coefficients)\n /// 4. Ciphertext components `c_1` for each CRT basis (serialized coefficients)\n /// 5. Quotient polynomials `r_1` for each CRT basis (serialized coefficients)\n /// 6. Quotient polynomials `r_2` for each CRT basis (serialized coefficients)\n /// 7. Decryption shares `d` for each CRT basis (serialized coefficients)\n ///\n /// Note: Aggregated secret shares `s` and noise shares `e` are represented by their\n /// commitments rather than serialized coefficients. This saves constraints while\n /// still binding them to the transcript.\n ///\n /// # Returns\n /// A vector containing commitments and polynomial coefficients in flattened form,\n /// ready for hashing to generate the Fiat-Shamir challenge.\n fn payload(self) -> Vec {\n let mut inputs = Vec::new();\n\n // Use commitments instead of full polynomials (saves constraints)\n inputs.push(self.expected_sk_commitment);\n inputs.push(self.expected_e_sm_commitment);\n\n // Flatten ciphertext components (public inputs)\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1);\n\n // Flatten quotient polynomials (secret witnesses)\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2);\n\n // Flatten decryption shares (public outputs)\n inputs = flatten::<_, _, BIT_D>(inputs, self.d);\n\n inputs\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify s commitment matches expected\n self.verify_agg_sk_commitment();\n\n // Step 2: Verify e commitment matches expected\n self.verify_agg_e_sm_commitment();\n\n // Step 3: Perform range checks on all secret witness values\n self.check_range_bounds();\n\n // Step 4: Generate Fiat-Shamir challenge from the transcript\n let gamma = self.generate_challenge();\n\n // Step 5: Verify decryption share computation for each CRT basis\n for i in 0..L {\n self.verify_decryption_share_computation(i, gamma);\n }\n }\n\n /// Performs range checks on all secret witness values.\n ///\n /// This function constrains all secret witnesses to be within their expected bounds\n /// as specified in the `configs`. This is critical for security because it prevents\n /// attacks where malicious provers provide out-of-range values that could break the\n /// security properties of the Threshold scheme.\n ///\n /// The function checks:\n /// - Aggregated secret shares `sk` are within bounds for each CRT basis\n /// - Aggregated noise shares `e_sm` are within bounds for each CRT basis\n /// - Quotient polynomials `r_1` and `r_2` are within bounds for each CRT basis\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// its expected bounds. The bounds are defined per polynomial type in the `configs`.\n fn check_range_bounds(self) {\n // Check aggregated sums are within bounds\n for basis_idx in 0..L {\n self.sk[basis_idx].range_check_2bounds::(\n self.configs.r2_bounds[basis_idx],\n self.configs.r2_bounds[basis_idx],\n );\n self.e_sm[basis_idx].range_check_2bounds::(\n self.configs.r2_bounds[basis_idx],\n self.configs.r2_bounds[basis_idx],\n );\n }\n\n // Check quotient polynomials are within bounds\n for basis_idx in 0..L {\n // r_1 quotients can be negative (modulus quotients)\n self.r1[basis_idx].range_check_2bounds::(\n self.configs.r1_bounds[basis_idx],\n self.configs.r1_bounds[basis_idx],\n );\n // r_2 quotients (cyclotomic quotients)\n self.r2[basis_idx].range_check_2bounds::(\n self.configs.r2_bounds[basis_idx],\n self.configs.r2_bounds[basis_idx],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge value using the SAFE cryptographic sponge.\n ///\n /// This function implements the Fiat-Shamir transform for the decryption share circuit:\n /// 1. Flattens all witness data (commitments for s/e, ciphertexts c_0/c_1, quotients r_1/r_2, decryption shares d) into a single array\n /// 2. Absorbs the flattened data into the SAFE sponge\n /// 3. Squeezes a single challenge value\n ///\n /// The challenge is used to evaluate polynomials for the Schwartz-Zippel lemma,\n /// which allows verification of polynomial equations by checking them at a random\n /// point rather than checking all coefficients.\n ///\n /// # Returns\n /// A single challenge value `gamma` used as the evaluation point for verifying\n /// the decryption share computation formula for all CRT bases.\n fn generate_challenge(self) -> Field {\n let inputs = self.payload();\n\n compute_threshold_share_decryption_challenge::(inputs)\n }\n\n /// Verifies the lifted decryption share computation formula for a specific CRT basis using the Schwartz-Zippel lemma.\n ///\n /// This function verifies that the decryption share for basis `i` satisfies:\n /// `d_i(gamma) = c_0i(gamma) + c_1i(gamma) * s(gamma) + e_i(gamma) + r_2_i(gamma) * cyclo(gamma) + r_1_i(gamma) * q_i`\n ///\n /// Where:\n /// - `c_0i`, `c_1i` are ciphertext components for basis i\n /// - `s` is the aggregated secret key shares\n /// - `e_i` is the aggregated noise shares\n /// - `r_1_i`, `r_2_i` are quotient witnesses\n /// - `cyclo(gamma) = gamma^N + 1` is the cyclotomic polynomial evaluated at gamma\n /// - `q_i` is the CRT modulus for basis i\n ///\n /// The Schwartz-Zippel lemma ensures that if this equation holds at a random point\n /// `gamma`, then the polynomials are identical with high probability.\n ///\n /// # Arguments\n /// * `basis_idx` - The index of the CRT basis to verify (0 <= basis_idx < L)\n /// * `gamma` - The Fiat-Shamir challenge value used as the evaluation point\n ///\n /// # Panics\n /// The circuit will fail if the decryption share computation formula doesn't hold for the specified basis.\n fn verify_decryption_share_computation(self, basis_idx: u32, gamma: Field) {\n // Evaluate ciphertext components at gamma\n let c_0_at_gamma = self.ct0[basis_idx].eval(gamma);\n let c_1_at_gamma = self.ct1[basis_idx].eval(gamma);\n\n // Evaluate aggregated sums at gamma\n let sk_at_gamma = self.sk[basis_idx].eval(gamma);\n let e_sm_at_gamma = self.e_sm[basis_idx].eval(gamma);\n\n // Evaluate quotient polynomials at gamma\n let r_1_at_gamma = self.r1[basis_idx].eval(gamma);\n let r_2_at_gamma = self.r2[basis_idx].eval(gamma);\n\n // Evaluate cyclotomic polynomial X^N + 1 at gamma\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n\n // Compute expected decryption share using the lifted formula:\n // d_i = c_0i + c_1i * sk + e_sm_i + r_2_i * (X^N + 1) + r_1_i * q_i\n let expected_decryption_share = c_0_at_gamma\n + c_1_at_gamma * sk_at_gamma\n + e_sm_at_gamma\n + r_2_at_gamma * cyclo_at_gamma\n + r_1_at_gamma * self.configs.qis[basis_idx];\n\n // Evaluate the party's claimed decryption share at gamma\n let computed_decryption_share = self.d[basis_idx].eval(gamma);\n\n // Enforce equality: computed decryption share must match expected value\n assert(\n computed_decryption_share == expected_decryption_share,\n \"Decryption share computation failed\",\n );\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/threshold/share_decryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/threshold_share_decryption.vk b/crates/zk-prover/tests/fixtures/threshold_share_decryption.vk deleted file mode 100644 index c3cce82305ae452598786d1de5742b5b321bd06e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3680 zcmb8xc{tSD9|!O=S(+?aCnDQeE+#@ZWXN{ySu;o|p)66iQKJRfmnkx`-NqWaLy;|6 z>Sn2gY!z9Gk){QS%S~PBH@`pcXP&3~-1+a!>v^B&`<(OnoO2NR;ZNj;im;+Tc7y>w z=KD?rVVi6&*t*+we1GtwA2>qXeSA&Jt1KJd#Ajluj*o!X^_*j2Hl*6TlUxgv6H_VJ z034y8v=^M)t@R@8mfxTKWGM~YD@>!MAy+gnp;@u{>Fxm8cHr!Ml$60Sp^AeeJB3`m zgc!hwx*5fN+N)`My~Q2+^E}S@07q!sp;(#MSJO_0s%eG>cJ=`Gl-OPURpZtLbxLx^ z%klg#F~AWLaD7M~;MZW4?XC}Nc992u$~>(_H(u_jK-c;aVVa?KCvb#Bic0RB>NcH> z++PsW>=7kv=USRkMjE181+_C520i+(%_ehgxd0PZj`gCgmpP zCK%W6JtyN(sO%Lx1soyXgR)dcaLDHU-uH@iRQrIxZZ%|h2eipGv1~iD8EMHCz}dqb znZ2V&jP@0eCW|a3IRdBFujV^h6?BzmWy?>VU4F~C|I%V59yPnHloN7l#v%nxK>ob6 zt%IPgMqz1cm7h}AH?tt%2&v2TrF>cBiR(6fljbuD>%U50uELElU-qn}cIvgKzp5%n zeq*!nB%vQe%^Xq@zAD}eyxLDgs=cG)L1)&I>f^%1$0va!BuZ($n5#WOyCgvAZN>R)9~pjteaM(`egc;`)xDhcCu~5!o<0UbE2C%6+ymI*M$2_Y)kas?Yy)0XT5*U1I|7_ zB|pxk4@<7@KR(Jem$U~sf9Qh$+m^U%mmFU0;R`abx&fSBe`@iAoy_N2zcrWdM9jm$ zgPiWRl8LH*YVL~#uS)l9dj}k$9mAUjM@~BS`&Pw&UkictDbYsgvfby-aO<0ENSSwH zF*))|O03@d%FBu*a;5a;Ssd^pVLhgq|IfOoood$i6}++L>>o_lKrwa^&$4S}>hE$h z2l){zOX4&oi%hvuAE@J|JWvK4A$)Do?BdvE;fYLq%1TNX@DcnsLW|J8$Z>kiUlK~| z;%9&(#Irp8kT7qn$(YE`3>EPQKIBN9f3l9#BPq20W#vXLHwFIx`W2nMkVKP6h#~C^ zSLz48y3Hh5@2aEkxOTI~6Vp2BW#9;HI&^crJl>VrnWTF9cjIfocPOMtNmenY1$VJ3 zs+f15MgV7@-(IyDiH$R128vU6?mcP&p7_Og_`ZAohdA;yT}LLzEg3lb{A1DxE@^Zv zt`3g{-FX|}RGrmDx)S;PfI}PYGtc&=Zr})QHcOb0T9@)AjE7N{y*1bB_t(BhTF1nzP#d73vXQiDF=T+HM%F<#-RN(t8!JCm% zq*VK&XZ@-%)97pKagIEi31YBB{b)XGY0N+%*Lru<4r_pZ{>!ublVy{aD*f+ zB1w^&u_YgCd}m`NB7tW$ylAX1C-O`N5Cnx6#6wkpv+JjT_`IlyuW?)7aM{k>Av`@t?A67N z5so~@dPq5?Nlq}`GQ8UTmsh}5=LfIP9E%sEUooDvaM|V$?>F}Q)rglU#y43C%pW}YL!XWHaN^QqrsC1u65i9HIuEGd8RcUtO^kUB~CB+bev XocF)z%n6q^$FwvzA<4Ysz4QMA;<7yG diff --git a/crates/zk-prover/tests/fixtures/user_data_encryption.json b/crates/zk-prover/tests/fixtures/user_data_encryption.json new file mode 100644 index 0000000000..cc8b03d011 --- /dev/null +++ b/crates/zk-prover/tests/fixtures/user_data_encryption.json @@ -0,0 +1,214 @@ +{ + "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", + "hash": "9408608105749895694", + "abi": { + "parameters": [ + { "name": "pk_commitment", "type": { "kind": "field" }, "visibility": "public" }, + { + "name": "pk0is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "pk1is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "ct0is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "ct1is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "u", + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + }, + "visibility": "private" + }, + { + "name": "e0", + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + }, + "visibility": "private" + }, + { + "name": "e1", + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + }, + "visibility": "private" + }, + { + "name": "e0is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "e0_quotients", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "k1", + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] + }, + "visibility": "private" + }, + { + "name": "r1is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 1023, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "r2is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 511, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "p1is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 1023, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + }, + { + "name": "p2is", + "type": { + "kind": "array", + "length": 2, + "type": { + "kind": "struct", + "path": "lib::math::polynomial::Polynomial", + "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 511, "type": { "kind": "field" } } }] + } + }, + "visibility": "private" + } + ], + "return_type": null, + "error_types": { "12469291177396340830": { "error_kind": "string", "string": "call to assert_max_bit_size" } } + }, + "bytecode": "H4sIAAAAAAAA/6zQZdSW9R+1eenu7u7uhpPu7u7u7u7u7u6WEhEREREREREREREREBEQEekZ1zxrzT1rXtz/fVz7eiGuxT75/o5PhPf+n1/k//Nn7/bd+9y89t57KW689//7Rfw/f6Z/73/6RYgQ///d5u9UZ8CtAutyHK1X+fD48c1aZy90r9rwY/3mV7z1bOHj//vvXxQT/t3/+z+R/vuf//NdxHDeqdwOb/vyf39nxLDvfPk/vDOcX4SIgucr6PnK4PlK8HwNPV8bPCMJnm+g5xuD5xvB8y30fGvwjCx4voOe7wye7wTP94ozz/++C9UziuAZoTjzjFA8dM+wt8PbRoSeEQ2eUQXPSNAzksEzkuAZGXpGNnhGEzyjQM8oBs8ogmdU6BnV4Bld8IwGPaMZPKMJntGhZ3SDZwzBMwb0jGHwjCF4xoSeMQ2eMQXPWNAzlsEzluAZG3rGNnjGEjzjQM84Bs84gmdc6BnX4Blb8IwHPeMZPOMJnvGhZ3yDZxzBMwH0TGDwTCB4JoSeCQ2ecQXPRNAzkcEzkeCZGHomNnjGEzyTQM8kBs8kgmdS6JnU4Blf8EwGPZMZPJMJnsmhZ3KDZwLBMwX0TGHwTCF4poSeKQ2eCQXPVNAzlcEzleCZGnqmNngmEjzTQM80Bs80gmda6JnW4JlY8EwHPdMZPNMJnumhZ3qDZxLBMwP0zGDwzCB4ZoSeGQ2eSQXPTNAzk8Ezk+CZGXpmNngmEzyzQM8sBs8sgmdW6JnV4Jlc8MwGPbMZPLMJntmhZ3aDZwrBMwf0zGHwzCF45oSeOQ2eKQXPXNAzl8Ezl+CZG3rmNnimEjzzQM88Bs88gmde6JnX4Jla8MwHPfMZPPMJnvmhZ36DZxrBswD0LGDwLCB4FoSeBQ2eaQXPQtCzkMGzkOBZGHoWNnimEzyLQM8iBs8igmdR6FnU4Jle8CwGPYsZPIsJnsWhZ3GDZwbBswT0LGHwLCF4loSeJQ2eGQXPUtCzlMGzlOBZGnqWNnhmEjzLQM8yBs8ygmdZ6FnW4JlZ8CwHPcsZPMsJngH0DAyeWQTP8tCzvMGzvOBZAXpWMHhmFTwrQs+KBs+Kgmcl6FnJ4JlN8KwMPSsbPCsLnlWgZxWDZ3bBsyr0rGrwrCp4VoOe1QyeOQTP6tCzusGzuuBZA3rWMHjmFDxrQs+aBs+agmct6FnL4JlL8KwNPWsbPGsLnnWgZx2DZ27Bsy70rGvwrCt41oOe9QyeeQTP+tCzvsGzvuDZAHo2MHjmFTwbQs+GBs+Ggmcj6NnI4JlP8GwMPRsbPBsLnk2gZxODZ37Bsyn0bGrwbCp4NoOezQyeBQTP5tCzucGzueDZAnq2MHgWFDxbQs+WBs+Wgmcr6NnK4FlI8GwNPVsbPFsLnm2gZxuDZ2HBsy30bGvwbCt4toOe7QyeRQTP9tCzvcGzveDZAXp2MHgWFTw7Qs+OBs+Ogmcn6NnJ4FlM8OwMPTsbPDsLnl2gZxeDZ3HBsyv07Grw7Cp4doOe3QyeJQTP7tCzu8Gzu+DZA3r2MHiWFDx7Qs+eBs+egmcv6NnL4FlK8OwNPXsbPHsLnn2gZx+DZ2nBsy/07Gvw7Ct49oOe/QyeZQTP/tCzv8Gzv+A5AHoOMHiWFTwHQs+BBs+Bgucg6DnI4FlO8BwMPQcbPAcLnkOg5xCDZyB4DoWeQw2eQwXPYdBzmMGzvOA5HHoON3gOFzxHQM8RBs8KgudI6DnS4DlS8BwFPUcZPCsKnqOh52iD52jBcwz0HGPwrCR4joWeYw2eYwXPcdBznMGzsuA5HnqON3iOFzwnQM8JBs8qgudE6DnR4DlR8JwEPScZPKsKnpOh52SD52TBcwr0nGLwrCZ4ToWeUw2eUwXPadBzmsGzuuA5HXpON3hOFzxnQM8ZBs8agudM6DnT4DlT8JwFPWcZPGsKnrOh52yD52zBcw70nGPwrCV4zoWecw2ecwXPedBznsGztuA5H3rON3jOFzwXQM8FBs86gudC6LnQ4LlQ8FwEPRcZPOsKnouh52KD52LBcwn0XGLwrCd4LoWeSw2eSwXPZdBzmcGzvuC5HHouN3guFzxXQM8VBs8GgudK6LnS4LlS8FwFPVcZPBsKnquh52qD52rBcw30XGPwbCR4roWeaw2eawXPddBzncGzseC5HnquN3iuFzw3QM8NBs8mgudG6LnR4LlR8NwEPTcZPJsKnpuh52aD52bBcwv03GLwbCZ4boWeWw2eWwXPbdBzm8GzueC5HXpuN3huFzx3QM8dBs8WgudO6LnT4LlT8NwFPXcZPFsKnruh526D527Bcw/03GPwbCV47oWeew2eewXPfdBzn8GzteC5H3ruN3juFzwPQM8DBs82gudB6HnQ4HlQ8Hwfer5v8GwreB6CnocMnocEz8PQ87DBs53geQR6HjF4HhE8j0LPowbP9oLnMeh5zOB5TPD8AHp+YPDsIHgeh57HDZ7HBc8PoeeHBs+OgucJ6HnC4HlC8PwIen5k8OwkeJ6EnicNnicFz4+h58cGz86C5ynoecrgeUrw/AR6fmLw7CJ4noaepw2epwXPT6HnpwbProLnGeh5xuB5RvD8DHp+ZvDsJniehZ5nDZ5nBc/PoefnBs/uguc56HnO4HlO8PwCen5h8OwheJ6HnucNnucFzy+h55cGz56C5wXoecHgeUHw/Ap6fmXw7CV4XoSeFw2eFwXPr6Hn1wbP3oLnJeh5yeB5SfD8Bnp+Y/DsI3hehp6XDZ6XBc9voee3Bs++gucV6HnF4HlF8PwOen5n8OwneF6FnlcNnlcFz++h5/cGz/6C5zXoec3geU3w/AF6/mDwHCB4Xoee1w2e1wXPH6HnjwbPgYLnDeh5w+B5Q/D8CXr+ZPAcJHjehJ43DZ43Bc+foefPBs/Bguct6HnL4HlL8PwFev5i8BwieN6GnrcNnrcFz1+h568Gz6GC5x3oecfgeUfw/A16/mbwHCZ43oWedw2edwXPe9DznsFzuOB5H3reN3jeFzx/h56/GzxHCJ4PoOcDg+cDwfMP6PmHwXOk4PkQej40eD4UPP+Enn8aPEcJno+g5yOD5yPB8zH0fGzwHC14PoGeTwyeTwTPv6DnXwbPMYLnU+j51OD5VPD8G3r+bfAcK3g+g57PDJ7PBM9/oOc/Bs9xgudz6Pnc4Plc8PwXev5r8BwveL6Ani8Mni8Ez5fQ86XBc4Lg+Qp6vjJ4vhI8X0PP1wbPiYLnG+j5xuD5RvB8Cz3fGjwnCZ7voOc7g+c7wfO9Eszzv+9C9ZwseEYowTwjlAjdM+zt8LYRoWdEg+cUwTMS9Ixk8IwkeEaGnpENnlMFzyjQM4rBM4rgGRV6RjV4ThM8o0HPaAbPaIJndOgZ3eA5XfCMAT1jGDxjCJ4xoWdMg+cMwTMW9Ixl8IwleMaGnrENnjMFzzjQM47BM47gGRd6xjV4zhI840HPeAbPeIJnfOgZ3+A5W/BMAD0TGDwTCJ4JoWdCg+ccwTMR9Exk8EwkeCaGnokNnnMFzyTQM4nBM4ngmRR6JjV4zhM8k0HPZAbPZIJncuiZ3OA5X/BMAT1TGDxTCJ4poWdKg+cCwTMV9Exl8EwleKaGnqkNngsFzzTQM43BM43gmRZ6pjV4LhI800HPdAbPdIJneuiZ3uC5WPDMAD0zGDwzCJ4ZoWdGg+cSwTMT9Mxk8MwkeGaGnpkNnksFzyzQM4vBM4vgmRV6ZjV4LhM8s0HPbAbPbIJnduiZ3eC5XPDMAT1zGDxzCJ45oWdOg+cKwTMX9Mxl8MwleOaGnrkNnisFzzzQM4/BM4/gmRd65jV4rhI880HPfAbPfIJnfuiZ3+C5WvAsAD0LGDwLCJ4FoWdBg+cawbMQ9Cxk8CwkeBaGnoUNnmsFzyLQs4jBs4jgWRR6FjV4rhM8i0HPYgbPYoJncehZ3OC5XvAsAT1LGDxLCJ4loWdJg+cGwbMU9Cxl8CwleJaGnqUNnhsFzzLQs4zBs4zgWRZ6ljV4bhI8y0HPcgbPcoJnAD0Dg+dmwbM89Cxv8CwveFaAnhUMnlsEz4rQs6LBs6LgWQl6VjJ4bhU8K0PPygbPyoJnFehZxeC5TfCsCj2rGjyrCp7VoGc1g+d2wbM69Kxu8KwueNaAnjUMnjsEz5rQs6bBs6bgWQt61jJ47hQ8a0PP2gbP2oJnHehZx+C5S/CsCz3rGjzrCp71oGc9g+duwbM+9Kxv8KwveDaAng0MnnsEz4bQs6HBs6Hg2Qh6NjJ47hU8G0PPxgbPxoJnE+jZxOC5T/BsCj2bGjybCp7NoGczg+d+wbM59Gxu8GwueLaAni0MngcEz5bQs6XBs6Xg2Qp6tjJ4HhQ8W0PP1gbP1oJnG+jZxuD5vuDZFnq2NXi2FTzbQc92Bs9Dgmd76Nne4Nle8OwAPTsYPA8Lnh2hZ0eDZ0fBsxP07GTwPCJ4doaenQ2enQXPLtCzi8HzqODZFXp2NXh2FTy7Qc9uBs9jgmd36Nnd4Nld8OwBPXsYPD8QPHtCz54Gz56CZy/o2cvgeVzw7A09exs8ewuefaBnH4Pnh4JnX+jZ1+DZV/DsBz37GTxPCJ79oWd/g2d/wXMA9Bxg8PxI8BwIPQcaPAcKnoOg5yCD50nBczD0HGzwHCx4DoGeQwyeHwueQ6HnUIPnUMFzGPQcZvA8JXgOh57DDZ7DBc8R0HOEwfMTwXMk9Bxp8BwpeI6CnqMMnqcFz9HQc7TBc7TgOQZ6jjF4fip4joWeYw2eYwXPcdBznMHzjOA5HnqON3iOFzwnQM8JBs/PBM+J0HOiwXOi4DkJek4yeJ4VPCdDz8kGz8mC5xToOcXg+bngORV6TjV4ThU8p0HPaQbPc4LndOg53eA5XfCcAT1nGDy/EDxnQs+ZBs+Zgucs6DnL4Hle8JwNPWcbPGcLnnOg5xyD55eC51zoOdfgOVfwnAc95xk8Lwie86HnfIPnfMFzAfRcYPD8SvBcCD0XGjwXCp6LoOcig+dFwXMx9Fxs8FwseC6BnksMnl8Lnkuh51KD51LBcxn0XGbwvCR4Loeeyw2eywXPFdBzhcHzG8FzJfRcafBcKXiugp6rDJ6XBc/V0HO1wXO14LkGeq4xeH4reK6FnmsNnmsFz3XQc53B84rguR56rjd4rhc8N0DPDQbP7wTPjdBzo8Fzo+C5CXpuMnheFTw3Q8/NBs/NgucW6LnF4Pm94LkVem41eG4VPLdBz20Gz2uC53boud3guV3w3AE9dxg8fxA8d0LPnQbPnYLnLui5y+B5XfDcDT13Gzx3C557oOceg+ePgude6LnX4LlX8NwHPfcZPG8Invuh536D537B8wD0PGDw/EnwPAg9Dxo8Dwqe70PP9w2eNwXPQ9DzkMHzkOB5GHoeNnj+LHgegZ5HDJ5HBM+j0POowfOW4HkMeh4zeB4TPD+Anh8YPH8RPI9Dz+MGz+OC54fQ80OD523B8wT0PGHwPCF4fgQ9PzJ4/ip4noSeJw2eJwXPj6HnxwbPO4LnKeh5yuB5SvD8BHp+YvD8TfA8DT1PGzxPC56fQs9PDZ53Bc8z0POMwfOM4PkZ9PzM4HlP8DwLPc8aPM8Knp9Dz88NnvcFz3PQ85zB85zg+QX0/MLg+bvgeR56njd4nhc8v4SeXxo8HwieF6DnBYPnBcHzK+j5lcHzD8HzIvS8aPC8KHh+DT2/Nng+FDwvQc9LBs9Lguc30PMbg+efgudl6HnZ4HlZ8PwWen5r8HwkeF6BnlcMnlcEz++g53cGz8eC51XoedXgeVXw/B56fm/wfCJ4XoOe1wye1wTPH6DnDwbPvwTP69DzusHzuuD5I/T80eD5VPC8AT1vGDxvCJ4/Qc+fDJ5/C543oedNg+dNwfNn6PmzwfOZ4HkLet4yeN4SPH+Bnr8YPP8RPG9Dz9sGz9uC56/Q81eD53PB8w70vGPwvCN4/gY9fzN4/it43oWedw2edwXPe9DznsHzheB5H3reN3jeFzx/h56/GzxfCp4PoOcDg+cDwfMP6PmHwfOV4PkQej40eD4UPP+Enn8aPF8Lno+g5yOD5yPB8zH0fGzwfCN4PoGeTwyeTwTPv6DnXwbPt4LnU+j51OD5VPD8G3r+bfB8J3g+g57PDJ7PBM9/oOc/Bs/3Evzv73wOPZ8bPJ8Lnv9Cz38NnhEEzxfQ84XB84Xg+RJ6vjR4RhQ8X0HPVwbPV4Lna+j52uAZSfB8Az3fGDzfCJ5voedbg2dkwfMd9Hxn8HwneL5Xknn+912onlEEzwglmWeEkqF7hr0d3jYi9Ixo8IwqeEaCnpEMnpEEz8jQM7LBM5rgGQV6RjF4RhE8o0LPqAbP6IJnNOgZzeAZTfCMDj2jGzxjCJ4xoGcMg2cMwTMm9Ixp8IwpeMaCnrEMnrEEz9jQM7bBM5bgGQd6xjF4xhE840LPuAbP2IJnPOgZz+AZT/CMDz3jGzzjCJ4JoGcCg2cCwTMh9Exo8IwreCaCnokMnokEz8TQM7HBM57gmQR6JjF4JhE8k0LPpAbP+IJnMuiZzOCZTPBMDj2TGzwTCJ4poGcKg2cKwTMl9Exp8EwoeKaCnqkMnqkEz9TQM7XBM5HgmQZ6pjF4phE800LPtAbPxIJnOuiZzuCZTvBMDz3TGzyTCJ4ZoGcGg2cGwTMj9Mxo8EwqeGaCnpkMnpkEz8zQM7PBM5ngmQV6ZjF4ZhE8s0LPrAbP5IJnNuiZzeCZTfDMDj2zGzxTCJ45oGcOg2cOwTMn9Mxp8EwpeOaCnrkMnrkEz9zQM7fBM5XgmQd65jF45hE880LPvAbP1IJnPuiZz+CZT/DMDz3zGzzTCJ4FoGcBg2cBwbMg9Cxo8EwreBaCnoUMnoUEz8LQs7DBM53gWQR6FjF4FhE8i0LPogbP9IJnMehZzOBZTPAsDj2LGzwzCJ4loGcJg2cJwbMk9Cxp8MwoeJaCnqUMnqUEz9LQs7TBM5PgWQZ6ljF4lhE8y0LPsgbPzIJnOehZzuBZTvAMoGdg8MwieJaHnuUNnuUFzwrQs4LBM6vgWRF6VjR4VhQ8K0HPSgbPbIJnZehZ2eBZWfCsAj2rGDyzC55VoWdVg2dVwbMa9Kxm8MwheFaHntUNntUFzxrQs4bBM6fgWRN61jR41hQ8a0HPWgbPXIJnbehZ2+BZW/CsAz3rGDxzC551oWddg2ddwbMe9Kxn8MwjeNaHnvUNnvUFzwbQs4HBM6/g2RB6NjR4NhQ8G0HPRgbPfIJnY+jZ2ODZWPBsAj2bGDzzC55NoWdTg2dTwbMZ9Gxm8CwgeDaHns0Nns0FzxbQs4XBs6Dg2RJ6tjR4thQ8W0HPVgbPQoJna+jZ2uDZWvBsAz3bGDwLC55toWdbg2dbwbMd9Gxn8CwieLaHnu0Nnu0Fzw7Qs4PBs6jg2RF6djR4dhQ8O0HPTgbPYoJnZ+jZ2eDZWfDsAj27GDyLC55doWdXg2dXwbMb9Oxm8CwheHaHnt0Nnt0Fzx7Qs4fBs6Tg2RN69jR49hQ8e0HPXgbPUoJnb+jZ2+DZW/DsAz37GDxLC559oWdfg2dfwbMf9Oxn8CwjePaHnv0Nnv0FzwHQc4DBs6zgORB6DjR4DhQ8B0HPQQbPcoLnYOg52OA5WPAcAj2HGDwDwXMo9Bxq8BwqeA6DnsMMnuUFz+HQc7jBc7jgOQJ6jjB4VhA8R0LPkQbPkYLnKOg5yuBZUfAcDT1HGzxHC55joOcYg2clwXMs9Bxr8BwreI6DnuMMnpUFz/HQc7zBc7zgOQF6TjB4VhE8J0LPiQbPiYLnJOg5yeBZVfCcDD0nGzwnC55ToOcUg2c1wXMq9Jxq8JwqeE6DntMMntUFz+nQc7rBc7rgOQN6zjB41hA8Z0LPmQbPmYLnLOg5y+BZU/CcDT1nGzxnC55zoOccg2ctwXMu9Jxr8JwreM6DnvMMnrUFz/nQc77Bc77guQB6LjB41hE8F0LPhQbPhYLnIui5yOBZV/BcDD0XGzwXC55LoOcSg2c9wXMp9Fxq8FwqeC6DnssMnvUFz+XQc7nBc7nguQJ6rjB4NhA8V0LPlQbPlYLnKui5yuDZUPBcDT1XGzxXC55roOcag2cjwXMt9Fxr8FwreK6DnusMno0Fz/XQc73Bc73guQF6bjB4NhE8N0LPjQbPjYLnJui5yeDZVPDcDD03Gzw3C55boOcWg2czwXMr9Nxq8NwqeG6DntsMns0Fz+3Qc7vBc7vguQN67jB4thA8d0LPnQbPnYLnLui5y+DZUvDcDT13Gzx3C557oOceg2crwXMv9Nxr8NwreO6DnvsMnq0Fz/3Qc7/Bc7/geQB6HjB4thE8D0LPgwbPg4Ln+9DzfYNnW8HzEPQ8ZPA8JHgehp6HDZ7tBM8j0POIwfOI4HkUeh41eLYXPI9Bz2MGz2OC5wfQ8wODZwfB8zj0PG7wPC54fgg9PzR4dhQ8T0DPEwbPE4LnR9DzI4NnJ8HzJPQ8afA8KXh+DD0/Nnh2FjxPQc9TBs9Tgucn0PMTg2cXwfM09Dxt8DwteH4KPT81eHYVPM9AzzMGzzOC52fQ8zODZzfB8yz0PGvwPCt4fg49Pzd4dhc8z0HPcwbPc4LnF9DzC4NnD8HzPPQ8b/A8L3h+CT2/NHj2FDwvQM8LBs8LgudX0PMrg2cvwfMi9Lxo8LwoeH4NPb82ePYWPC9Bz0sGz0uC5zfQ8xuDZx/B8zL0vGzwvCx4fgs9vzV49hU8r0DPKwbPK4Lnd9DzO4NnP8HzKvS8avC8Knh+Dz2/N3j2FzyvQc9rBs9rgucP0PMHg+cAwfM69Lxu8LwueP4IPX80eA4UPG9AzxsGzxuC50/Q8yeD5yDB8yb0vGnwvCl4/gw9fzZ4DhY8b0HPWwbPW4LnL9DzF4PnEMHzNvS8bfC8LXj+Cj1/NXgOFTzvQM87Bs87gudv0PM3g+cwwfMu9Lxr8LwreN6DnvcMnsMFz/vQ877B877g+Tv0/N3gOULwfAA9Hxg8Hwief0DPPwyeIwXPh9DzocHzoeD5J/T80+A5SvB8BD0fGTwfCZ6Poedjg+dowfMJ9Hxi8HwieP4FPf8yeI4RPJ9Cz6cGz6eC59/Q82+D51jB8xn0fGbwfCZ4/gM9/zF4jhM8n0PP5wbP54Lnv9DzX4PneMHzBfR8YfB8IXi+hJ4vDZ4TBM9X0POVwfOV4Pkaer42eE4UPN9AzzcGzzeC51vo+dbgOUnwfAc93xk83wme75Vinv99F6rnZMEzQinmGaFU6J5hb4e3jQg9Ixo8pwiekaBnJINnJMEzMvSMbPCcKnhGgZ5RDJ5RBM+o0DOqwXOa4BkNekYzeEYTPKNDz+gGz+mCZwzoGcPgGUPwjAk9Yxo8ZwiesaBnLINnLMEzNvSMbfCcKXjGgZ5xDJ5xBM+40DOuwXOW4BkPesYzeMYTPONDz/gGz9mCZwLomcDgmUDwTAg9Exo85wieiaBnIoNnIsEzMfRMbPCcK3gmgZ5JDJ5JBM+k0DOpwXOe4JkMeiYzeCYTPJNDz+QGz/mCZwromcLgmULwTAk9Uxo8FwieqaBnKoNnKsEzNfRMbfBcKHimgZ5pDJ5pBM+00DOtwXOR4JkOeqYzeKYTPNNDz/QGz8WCZwbomcHgmUHwzAg9Mxo8lwiemaBnJoNnJsEzM/TMbPBcKnhmgZ5ZDJ5ZBM+s0DOrwXOZ4JkNemYzeGYTPLNDz+wGz+WCZw7omcPgmUPwzAk9cxo8VwieuaBnLoNnLsEzN/TMbfBcKXjmgZ55DJ55BM+80DOvwXOV4JkPeuYzeOYTPPNDz/wGz9WCZwHoWcDgWUDwLAg9Cxo81wiehaBnIYNnIcGzMPQsbPBcK3gWgZ5FDJ5FBM+i0LOowXOd4FkMehYzeBYTPItDz+IGz/WCZwnoWcLgWULwLAk9Sxo8NwiepaBnKYNnKcGzNPQsbfDcKHiWgZ5lDJ5lBM+y0LOswXOT4FkOepYzeJYTPAPoGRg8Nwue5aFneYNnecGzAvSsYPDcInhWhJ4VDZ4VBc9K0LOSwXOr4FkZelY2eFYWPKtAzyoGz22CZ1XoWdXgWVXwrAY9qxk8twue1aFndYNndcGzBvSsYfDcIXjWhJ41DZ41Bc9a0LOWwXOn4FkbetY2eNYWPOtAzzoGz12CZ13oWdfgWVfwrAc96xk8dwue9aFnfYNnfcGzAfRsYPDcI3g2hJ4NDZ4NBc9G0LORwXOv4NkYejY2eDYWPJtAzyYGz32CZ1Po2dTg2VTwbAY9mxk89wuezaFnc4Nnc8GzBfRsYfA8IHi2hJ4tDZ4tBc9W0LOVwfOg4NkaerY2eLYWPNtAzzYGz/cFz7bQs63Bs63g2Q56tjN4HhI820PP9gbP9oJnB+jZweB5WPDsCD07Gjw7Cp6doGcng+cRwbMz9Oxs8OwseHaBnl0MnkcFz67Qs6vBs6vg2Q16djN4HhM8u0PP7gbP7oJnD+jZw+D5geDZE3r2NHj2FDx7Qc9eBs/jgmdv6Nnb4Nlb8OwDPfsYPD8UPPtCz74Gz76CZz/o2c/geULw7A89+xs8+wueA6DnAIPnR4LnQOg50OA5UPAcBD0HGTxPCp6Doedgg+dgwXMI9Bxi8PxY8BwKPYcaPIcKnsOg5zCD5ynBczj0HG7wHC54joCeIwyenwieI6HnSIPnSMFzFPQcZfA8LXiOhp6jDZ6jBc8x0HOMwfNTwXMs9Bxr8BwreI6DnuMMnmcEz/HQc7zBc7zgOQF6TjB4fiZ4ToSeEw2eEwXPSdBzksHzrOA5GXpONnhOFjynQM8pBs/PBc+p0HOqwXOq4DkNek4zeJ4TPKdDz+kGz+mC5wzoOcPg+YXgORN6zjR4zhQ8Z0HPWQbP84LnbOg52+A5W/CcAz3nGDy/FDznQs+5Bs+5guc86DnP4HlB8JwPPecbPOcLngug5wKD51eC50LoudDguVDwXAQ9Fxk8Lwqei6HnYoPnYsFzCfRcYvD8WvBcCj2XGjyXCp7LoOcyg+clwXM59Fxu8FwueK6AnisMnt8Iniuh50qD50rBcxX0XGXwvCx4roaeqw2eqwXPNdBzjcHzW8FzLfRca/BcK3iug57rDJ5XBM/10HO9wXO94LkBem4weH4neG6EnhsNnhsFz03Qc5PB86rguRl6bjZ4bhY8t0DPLQbP7wXPrdBzq8Fzq+C5DXpuM3heEzy3Q8/tBs/tgucO6LnD4PmD4LkTeu40eO4UPHdBz10Gz+uC527oudvguVvw3AM99xg8fxQ890LPvQbPvYLnPui5z+B5Q/DcDz33Gzz3C54HoOcBg+dPgudB6HnQ4HlQ8Hwfer5v8LwpeB6CnocMnocEz8PQ87DB82fB8wj0PGLwPCJ4HoWeRw2etwTPY9DzmMHzmOD5AfT8wOD5i+B5HHoeN3geFzw/hJ4fGjxvC54noOcJg+cJwfMj6PmRwfNXwfMk9Dxp8DwpeH4MPT82eN4RPE9Bz1MGz1OC5yfQ8xOD52+C52noedrgeVrw/BR6fmrwvCt4noGeZwyeZwTPz6DnZwbPe4LnWeh51uB5VvD8HHp+bvC8L3ieg57nDJ7nBM8voOcXBs/fBc/z0PO8wfO84Pkl9PzS4PlA8LwAPS8YPC8Inl9Bz68Mnn8Inheh50WD50XB82vo+bXB86HgeQl6XjJ4XhI8v4Ge3xg8/xQ8L0PPywbPy4Lnt9DzW4PnI8HzCvS8YvC8Inh+Bz2/M3g+FjyvQs+rBs+rguf30PN7g+cTwfMa9Lxm8LwmeP4APX8weP4leF6HntcNntcFzx+h548Gz6eC5w3oecPgeUPw/Al6/mTw/FvwvAk9bxo8bwqeP0PPnw2ezwTPW9DzlsHzluD5C/T8xeD5j+B5G3reNnjeFjx/hZ6/GjyfC553oOcdg+cdwfM36PmbwfNfwfMu9Lxr8LwreN6DnvcMni8Ez/vQ877B877g+Tv0/N3g+VLwfAA9Hxg8Hwief0DPPwyerwTPh9DzocHzoeD5J/T80+D5WvB8BD0fGTwfCZ6Poedjg+cbwfMJ9Hxi8HwieP4FPf8yeL4VPJ9Cz6cGz6eC59/Q82+D5zvB8xn0fGbwfCZ4/gM9/zF4vpfwf3/nc+j53OD5XPD8F3r+a/CMIHi++N/fmTjsO//7Lmo471Ruh7d9+b+/M3vYd778H94Zzi9CRMHzFfR8ZfB8JXi+hp6vDZ6RBM830PONwfON4PkWer41eEYWPN9Bz3cGz3eC53ulmed/34XqGUXwjFCaeUYoHbpn2NvhbSNCz4gGz6iCZyToGcngGUnwjAw9Ixs8owmeUaBnFINnFMEzKvSMavCMLnhGg57RDJ7RBM/o0DO6wTOG4BkDesYweMYQPGNCz5gGz5iCZyzoGcvgGUvwjA09Yxs8YwmecaBnHINnHMEzLvSMa/CMLXjGg57xDJ7xBM/40DO+wTOO4JkAeiYweCYQPBNCz4QGz7iCZyLomcjgmUjwTAw9Exs84wmeSaBnEoNnEsEzKfRMavCML3gmg57JDJ7JBM/k0DO5wTOB4JkCeqYweKYQPFNCz5QGz4SCZyromcrgmUrwTA09Uxs8EwmeaaBnGoNnGsEzLfRMa/BMLHimg57pDJ7pBM/00DO9wTOJ4JkBemYweGYQPDNCz4wGz6SCZybomcngmUnwzAw9Mxs8kwmeWaBnFoNnFsEzK/TMavBMLnhmg57ZDJ7ZBM/s0DO7wTOF4JkDeuYweOYQPHNCz5wGz5SCZy7omcvgmUvwzA09cxs8UwmeeaBnHoNnHsEzL/TMa/BMLXjmg575DJ75BM/80DO/wTON4FkAehYweBYQPAtCz4IGz7SCZyHoWcjgWUjwLAw9Cxs80wmeRaBnEYNnEcGzKPQsavBML3gWg57FDJ7FBM/i0LO4wTOD4FkCepYweJYQPEtCz5IGz4yCZynoWcrgWUrwLA09Sxs8MwmeZaBnGYNnGcGzLPQsa/DMLHiWg57lDJ7lBM8AegYGzyyCZ3noWd7gWV7wrAA9Kxg8swqeFaFnRYNnRcGzEvSsZPDMJnhWhp6VDZ6VBc8q0LOKwTO74FkVelY1eFYVPKtBz2oGzxyCZ3XoWd3gWV3wrAE9axg8cwqeNaFnTYNnTcGzFvSsZfDMJXjWhp61DZ61Bc860LOOwTO34FkXetY1eNYVPOtBz3oGzzyCZ33oWd/gWV/wbAA9Gxg88wqeDaFnQ4NnQ8GzEfRsZPDMJ3g2hp6NDZ6NBc8m0LOJwTO/4NkUejY1eDYVPJtBz2YGzwKCZ3Po2dzg2VzwbAE9Wxg8CwqeLaFnS4NnS8GzFfRsZfAsJHi2hp6tDZ6tBc820LONwbOw4NkWerY1eLYVPNtBz3YGzyKCZ3vo2d7g2V7w7AA9Oxg8iwqeHaFnR4NnR8GzE/TsZPAsJnh2hp6dDZ6dBc8u0LOLwbO44NkVenY1eHYVPLtBz24GzxKCZ3fo2d3g2V3w7AE9exg8SwqePaFnT4NnT8GzF/TsZfAsJXj2hp69DZ69Bc8+0LOPwbO04NkXevY1ePYVPPtBz34GzzKCZ3/o2d/g2V/wHAA9Bxg8ywqeA6HnQIPnQMFzEPQcZPAsJ3gOhp6DDZ6DBc8h0HOIwTMQPIdCz6EGz6GC5zDoOczgWV7wHA49hxs8hwueI6DnCINnBcFzJPQcafAcKXiOgp6jDJ4VBc/R0HO0wXO04DkGeo4xeFYSPMdCz7EGz7GC5zjoOc7gWVnwHA89xxs8xwueE6DnBINnFcFzIvScaPCcKHhOgp6TDJ5VBc/J0HOywXOy4DkFek4xeFYTPKdCz6kGz6mC5zToOc3gWV3wnA49pxs8pwueM6DnDINnDcFzJvScafCcKXjOgp6zDJ41Bc/Z0HO2wXO24DkHes4xeNYSPOdCz7kGz7mC5zzoOc/gWVvwnA895xs85wueC6DnAoNnHcFzIfRcaPBcKHgugp6LDJ51Bc/F0HOxwXOx4LkEei4xeNYTPJdCz6UGz6WC5zLouczgWV/wXA49lxs8lwueK6DnCoNnA8FzJfRcafBcKXiugp6rDJ4NBc/V0HO1wXO14LkGeq4xeDYSPNdCz7UGz7WC5zrouc7g2VjwXA891xs81wueG6DnBoNnE8FzI/TcaPDcKHhugp6bDJ5NBc/N0HOzwXOz4LkFem4xeDYTPLdCz60Gz62C5zbouc3g2Vzw3A49txs8twueO6DnDoNnC8FzJ/TcafDcKXjugp67DJ4tBc/d0HO3wXO34LkHeu4xeLYSPPdCz70Gz72C5z7ouc/g2Vrw3A899xs89wueB6DnAYNnG8HzIPQ8aPA8KHi+Dz3fN3i2FTwPQc9DBs9Dgudh6HnY4NlO8DwCPY8YPI8Inkeh51GDZ3vB8xj0PGbwPCZ4fgA9PzB4dhA8j0PP4wbP44Lnh9DzQ4NnR8HzBPQ8YfA8IXh+BD0/Mnh2EjxPQs+TBs+TgufH0PNjg2dnwfMU9Dxl8DwleH4CPT8xeHYRPE9Dz9MGz9OC56fQ81ODZ1fB8wz0PGPwPCN4fgY9PzN4dhM8z0LPswbPs4Ln59Dzc4Nnd8HzHPQ8Z/A8J3h+AT2/MHj2EDzPQ8/zBs/zgueX0PNLg2dPwfMC9Lxg8LwgeH4FPb8yePYSPC9Cz4sGz4uC59fQ82uDZ2/B8xL0vGTwvCR4fgM9vzF49hE8L0PPywbPy4Lnt9DzW4NnX8HzCvS8YvC8Inh+Bz2/M3j2EzyvQs+rBs+rguf30PN7g2d/wfMa9Lxm8LwmeP4APX8weA4QPK9Dz+sGz+uC54/Q80eD50DB8wb0vGHwvCF4/gQ9fzJ4DhI8b0LPmwbPm4Lnz9DzZ4PnYMHzFvS8ZfC8JXj+Aj1/MXgOETxvQ8/bBs/bguev0PNXg+dQwfMO9Lxj8LwjeP4GPX8zeA4TPO9Cz7sGz7uC5z3oec/gOVzwvA897xs87wuev0PP3w2eIwTPB9DzgcHzgeD5B/T8w+A5UvB8CD0fGjwfCp5/Qs8/DZ6jBM9H0PORwfOR4PkYej42eI4WPJ9AzycGzyeC51/Q8y+D5xjB8yn0fGrwfCp4/g09/zZ4jhU8n0HPZwbPZ4LnP9DzH4PnOMHzOfR8bvB8Lnj+Cz3/NXiOFzxfQM8XBs8XgudL6PnS4DlB8HwFPV8ZPF8Jnq+h52uD50TB8w30fGPwfCN4voWebw2ekwTPd9DzncHzneD5Xhnm+d93oXpOFjwjlGGeEcqE7hn2dnjbiNAzosFziuAZCXpGMnhGEjwjQ8/IBs+pgmcU6BnF4BlF8IwKPaMaPKcJntGgZzSDZzTBMzr0jG7wnC54xoCeMQyeMQTPmNAzpsFzhuAZC3rGMnjGEjxjQ8/YBs+Zgmcc6BnH4BlH8IwLPeMaPGcJnvGgZzyDZzzBMz70jG/wnC14JoCeCQyeCQTPhNAzocFzjuCZCHomMngmEjwTQ8/EBs+5gmcS6JnE4JlE8EwKPZMaPOcJnsmgZzKDZzLBMzn0TG7wnC94poCeKQyeKQTPlNAzpcFzgeCZCnqmMnimEjxTQ8/UBs+Fgmca6JnG4JlG8EwLPdMaPBcJnumgZzqDZzrBMz30TG/wXCx4ZoCeGQyeGQTPjNAzo8FzieCZCXpmMnhmEjwzQ8/MBs+lgmcW6JnF4JlF8MwKPbMaPJcJntmgZzaDZzbBMzv0zG7wXC545oCeOQyeOQTPnNAzp8FzheCZC3rmMnjmEjxzQ8/cBs+Vgmce6JnH4JlH8MwLPfMaPFcJnvmgZz6DZz7BMz/0zG/wXC14FoCeBQyeBQTPgtCzoMFzjeBZCHoWMngWEjwLQ8/CBs+1gmcR6FnE4FlE8CwKPYsaPNcJnsWgZzGDZzHBszj0LG7wXC94loCeJQyeJQTPktCzpMFzg+BZCnqWMniWEjxLQ8/SBs+NgmcZ6FnG4FlG8CwLPcsaPDcJnuWgZzmDZznBM4CegcFzs+BZHnqWN3iWFzwrQM8KBs8tgmdF6FnR4FlR8KwEPSsZPLcKnpWhZ2WDZ2XBswr0rGLw3CZ4VoWeVQ2eVQXPatCzmsFzu+BZHXpWN3hWFzxrQM8aBs8dgmdN6FnT4FlT8KwFPWsZPHcKnrWhZ22DZ23Bsw70rGPw3CV41oWedQ2edQXPetCznsFzt+BZH3rWN3jWFzwbQM8GBs89gmdD6NnQ4NlQ8GwEPRsZPPcKno2hZ2ODZ2PBswn0bGLw3Cd4NoWeTQ2eTQXPZtCzmcFzv+DZHHo2N3g2FzxbQM8WBs8DgmdL6NnS4NlS8GwFPVsZPA8Knq2hZ2uDZ2vBsw30bGPwfF/wbAs92xo82wqe7aBnO4PnIcGzPfRsb/BsL3h2gJ4dDJ6HBc+O0LOjwbOj4NkJenYyeB4RPDtDz84Gz86CZxfo2cXgeVTw7Ao9uxo8uwqe3aBnN4PnMcGzO/TsbvDsLnj2gJ49DJ4fCJ49oWdPg2dPwbMX9Oxl8DwuePaGnr0Nnr0Fzz7Qs4/B80PBsy/07Gvw7Ct49oOe/QyeJwTP/tCzv8Gzv+A5AHoOMHh+JHgOhJ4DDZ4DBc9B0HOQwfOk4DkYeg42eA4WPIdAzyEGz48Fz6HQc6jBc6jgOQx6DjN4nhI8h0PP4QbP4YLnCOg5wuD5ieA5EnqONHiOFDxHQc9RBs/Tgudo6Dna4Dla8BwDPccYPD8VPMdCz7EGz7GC5zjoOc7geUbwHA89xxs8xwueE6DnBIPnZ4LnROg50eA5UfCcBD0nGTzPCp6Toedkg+dkwXMK9Jxi8Pxc8JwKPacaPKcKntOg5zSD5znBczr0nG7wnC54zoCeMwyeXwieM6HnTIPnTMFzFvScZfA8L3jOhp6zDZ6zBc850HOOwfNLwXMu9Jxr8JwreM6DnvMMnhcEz/nQc77Bc77guQB6LjB4fiV4LoSeCw2eCwXPRdBzkcHzouC5GHouNnguFjyXQM8lBs+vBc+l0HOpwXOp4LkMei4zeF4SPJdDz+UGz+WC5wroucLg+Y3guRJ6rjR4rhQ8V0HPVQbPy4Lnaui52uC5WvBcAz3XGDy/FTzXQs+1Bs+1guc66LnO4HlF8FwPPdcbPNcLnhug5waD53eC50boudHguVHw3AQ9Nxk8rwqem6HnZoPnZsFzC/TcYvD8XvDcCj23Gjy3Cp7boOc2g+c1wXM79Nxu8NwueO6AnjsMnj8Injuh506D507Bcxf03GXwvC547oaeuw2euwXPPdBzj8HzR8FzL/Tca/DcK3jug577DJ43BM/90HO/wXO/4HkAeh4weP4keB6EngcNngcFz/eh5/sGz5uC5yHoecjgeUjwPAw9Dxs8fxY8j0DPIwbPI4LnUeh51OB5S/A8Bj2PGTyPCZ4fQM8PDJ6/CJ7Hoedxg+dxwfND6PmhwfO24HkCep4weJ4QPD+Cnh8ZPH8VPE9Cz5MGz5OC58fQ82OD5x3B8xT0PGXwPCV4fgI9PzF4/iZ4noaepw2epwXPT6HnpwbPu4LnGeh5xuB5RvD8DHp+ZvC8J3iehZ5nDZ5nBc/PoefnBs/7guc56HnO4HlO8PwCen5h8Pxd8DwPPc8bPM8Lnl9Czy8Nng8EzwvQ84LB84Lg+RX0/Mrg+YfgeRF6XjR4XhQ8v4aeXxs8Hwqel6DnJYPnJcHzG+j5jcHzT8HzMvS8bPC8LHh+Cz2/NXg+EjyvQM8rBs8rgud30PM7g+djwfMq9Lxq8LwqeH4PPb83eD4RPK9Bz2sGz2uC5w/Q8weD51+C53Xoed3geV3w/BF6/mjwfCp43oCeNwyeNwTPn6DnTwbPvwXPm9DzpsHzpuD5M/T82eD5TPC8BT1vGTxvCZ6/QM9fDJ7/CJ63oedtg+dtwfNX6PmrwfO54HkHet4xeN4RPH+Dnr8ZPP8VPO9Cz7sGz7uC5z3oec/g+ULwvA897xs87wuev0PP3w2eLwXPB9DzgcHzgeD5B/T8w+D5SvB8CD0fGjwfCp5/Qs8/DZ6vBc9H0PORwfOR4PkYej42eL4RPJ9AzycGzyeC51/Q8y+D51vB8yn0fGrwfCp4/g09/zZ4vhM8n0HPZwbPZ4LnP9DzH4Pne4n+93c+h57PDZ7PBc9/oee/Bs8IgucL6PnC4PlC8HwJPV8aPCMKnq+g5yuD5yvB8zX0fG3wjCR4voGebwyebwTPt9DzrcEzsuD5Dnq+M3i+EzzfK8s8//suVM8ogmeEsswzQtnQPcPeDm8bEXpGNHhGFTwjQc9IBs9Igmdk6BnZ4BlN8IwCPaMYPKMInlGhZ1SDZ3TBMxr0jGbwjCZ4Roee0Q2eMQTPGNAzhsEzhuAZE3rGNHjGFDxjQc9YBs9Ygmds6Bnb4BlL8IwDPeMYPOMInnGhZ1yDZ2zBMx70jGfwjCd4xoee8Q2ecQTPBNAzgcEzgeCZEHomNHjGFTwTQc9EBs9Egmdi6JnY4BlP8EwCPZMYPJMInkmhZ1KDZ3zBMxn0TGbwTCZ4JoeeyQ2eCQTPFNAzhcEzheCZEnqmNHgmFDxTQc9UBs9Ugmdq6Jna4JlI8EwDPdMYPNMInmmhZ1qDZ2LBMx30TGfwTCd4poee6Q2eSQTPDNAzg8Ezg+CZEXpmNHgmFTwzQc9MBs9Mgmdm6JnZ4JlM8MwCPbMYPLMInlmhZ1aDZ3LBMxv0zGbwzCZ4Zoee2Q2eKQTPHNAzh8Ezh+CZE3rmNHimFDxzQc9cBs9cgmdu6Jnb4JlK8MwDPfMYPPMInnmhZ16DZ2rBMx/0zGfwzCd45oee+Q2eaQTPAtCzgMGzgOBZEHoWNHimFTwLQc9CBs9Cgmdh6FnY4JlO8CwCPYsYPIsInkWhZ1GDZ3rBsxj0LGbwLCZ4FoeexQ2eGQTPEtCzhMGzhOBZEnqWNHhmFDxLQc9SBs9Sgmdp6Fna4JlJ8CwDPcsYPMsInmWhZ1mDZ2bBsxz0LGfwLCd4BtAzMHhmETzLQ8/yBs/ygmcF6FnB4JlV8KwIPSsaPCsKnpWgZyWDZzbBszL0rGzwrCx4VoGeVQye2QXPqtCzqsGzquBZDXpWM3jmEDyrQ8/qBs/qgmcN6FnD4JlT8KwJPWsaPGsKnrWgZy2DZy7Bszb0rG3wrC141oGedQyeuQXPutCzrsGzruBZD3rWM3jmETzrQ8/6Bs/6gmcD6NnA4JlX8GwIPRsaPBsKno2gZyODZz7BszH0bGzwbCx4NoGeTQye+QXPptCzqcGzqeDZDHo2M3gWEDybQ8/mBs/mgmcL6NnC4FlQ8GwJPVsaPFsKnq2gZyuDZyHBszX0bG3wbC14toGebQyehQXPttCzrcGzreDZDnq2M3gWETzbQ8/2Bs/2gmcH6NnB4FlU8OwIPTsaPDsKnp2gZyeDZzHBszP07Gzw7Cx4doGeXQyexQXPrtCzq8Gzq+DZDXp2M3iWEDy7Q8/uBs/ugmcP6NnD4FlS8OwJPXsaPHsKnr2gZy+DZynBszf07G3w7C149oGefQyepQXPvtCzr8Gzr+DZD3r2M3iWETz7Q8/+Bs/+gucA6DnA4FlW8BwIPQcaPAcKnoOg5yCDZznBczD0HGzwHCx4DoGeQwyegeA5FHoONXgOFTyHQc9hBs/ygudw6Dnc4Dlc8BwBPUcYPCsIniOh50iD50jBcxT0HGXwrCh4joaeow2eowXPMdBzjMGzkuA5FnqONXiOFTzHQc9xBs/Kgud46Dne4Dle8JwAPScYPKsInhOh50SD50TBcxL0nGTwrCp4Toaekw2ekwXPKdBzisGzmuA5FXpONXhOFTynQc9pBs/qgud06Dnd4Dld8JwBPWcYPGsInjOh50yD50zBcxb0nGXwrCl4zoaesw2eswXPOdBzjsGzluA5F3rONXjOFTznQc95Bs/agud86Dnf4Dlf8FwAPRcYPOsInguh50KD50LBcxH0XGTwrCt4Loaeiw2eiwXPJdBzicGznuC5FHouNXguFTyXQc9lBs/6gudy6Lnc4Llc8FwBPVcYPBsIniuh50qD50rBcxX0XGXwbCh4roaeqw2eqwXPNdBzjcGzkeC5FnquNXiuFTzXQc91Bs/Ggud66Lne4Lle8NwAPTcYPJsInhuh50aD50bBcxP03GTwbCp4boaemw2emwXPLdBzi8GzmeC5FXpuNXhuFTy3Qc9tBs/mgud26Lnd4Lld8NwBPXcYPFsInjuh506D507Bcxf03GXwbCl47oaeuw2euwXPPdBzj8GzleC5F3ruNXjuFTz3Qc99Bs/Wgud+6Lnf4Llf8DwAPQ8YPNsIngeh50GD50HB833o+b7Bs63geQh6HjJ4HhI8D0PPwwbPdoLnEeh5xOB5RPA8Cj2PGjzbC57HoOcxg+cxwfMD6PmBwbOD4Hkceh43eB4XPD+Enh8aPDsKnieg5wmD5wnB8yPo+ZHBs5PgeRJ6njR4nhQ8P4aeHxs8Owuep6DnKYPnKcHzE+j5icGzi+B5GnqeNnieFjw/hZ6fGjy7Cp5noOcZg+cZwfMz6PmZwbOb4HkWep41eJ4VPD+Hnp8bPLsLnueg5zmD5znB8wvo+YXBs4fgeR56njd4nhc8v4SeXxo8ewqeF6DnBYPnBcHzK+j5lcGzl+B5EXpeNHheFDy/hp5fGzx7C56XoOclg+clwfMb6PmNwbOP4HkZel42eF4WPL+Fnt8aPPsKnleg5xWD5xXB8zvo+Z3Bs5/geRV6XjV4XhU8v4ee3xs8+wue16DnNYPnNcHzB+j5g8FzgOB5HXpeN3heFzx/hJ4/GjwHCp43oOcNg+cNwfMn6PmTwXOQ4HkTet40eN4UPH+Gnj8bPAcLnreg5y2D5y3B8xfo+YvBc4jgeRt63jZ43hY8f4Wevxo8hwqed6DnHYPnHcHzN+j5m8FzmOB5F3reNXjeFTzvQc97Bs/hgud96Hnf4Hlf8Pwdev5u8BwheD6Ang8Mng8Ezz+g5x8Gz5GC50Po+dDg+VDw/BN6/mnwHCV4PoKejwyejwTPx9DzscFztOD5BHo+MXg+ETz/gp5/GTzHCJ5PoedTg+dTwfNv6Pm3wXOs4PkMej4zeD4TPP+Bnv8YPMcJns+h53OD53PB81/o+a/Bc7zg+QJ6vjB4vhA8X0LPlwbPCYLnK+j5yuD5SvB8DT1fGzwnCp5voOcbg+cbwfMt9Hxr8JwkeL6Dnu8Mnu8Ez/fKMc//vgvVc7LgGaEc84xQLnTPsLfD20aEnhENnlMEz0jQM5LBM5LgGRl6RjZ4ThU8o0DPKAbPKIJnVOgZ1eA5TfCMBj2jGTyjCZ7RoWd0g+d0wTMG9Ixh8IwheMaEnjENnjMEz1jQM5bBM5bgGRt6xjZ4zhQ840DPOAbPOIJnXOgZ1+A5S/CMBz3jGTzjCZ7xoWd8g+dswTMB9Exg8EwgeCaEngkNnnMEz0TQM5HBM5HgmRh6JjZ4zhU8k0DPJAbPJIJnUuiZ1OA5T/BMBj2TGTyTCZ7JoWdyg+d8wTMF9Exh8EwheKaEnikNngsEz1TQM5XBM5XgmRp6pjZ4LhQ800DPNAbPNIJnWuiZ1uC5SPBMBz3TGTzTCZ7poWd6g+diwTMD9Mxg8MwgeGaEnhkNnksEz0zQM5PBM5PgmRl6ZjZ4LhU8s0DPLAbPLIJnVuiZ1eC5TPDMBj2zGTyzCZ7ZoWd2g+dywTMH9Mxh8MwheOaEnjkNnisEz1zQM5fBM5fgmRt65jZ4rhQ880DPPAbPPIJnXuiZ1+C5SvDMBz3zGTzzCZ75oWd+g+dqwbMA9Cxg8CwgeBaEngUNnmsEz0LQs5DBs5DgWRh6FjZ4rhU8i0DPIgbPIoJnUehZ1OC5TvAsBj2LGTyLCZ7FoWdxg+d6wbME9Cxh8CwheJaEniUNnhsEz1LQs5TBs5TgWRp6ljZ4bhQ8y0DPMgbPMoJnWehZ1uC5SfAsBz3LGTzLCZ4B9AwMnpsFz/LQs7zBs7zgWQF6VjB4bhE8K0LPigbPioJnJehZyeC5VfCsDD0rGzwrC55VoGcVg+c2wbMq9Kxq8KwqeFaDntUMntsFz+rQs7rBs7rgWQN61jB47hA8a0LPmgbPmoJnLehZy+C5U/CsDT1rGzxrC551oGcdg+cuwbMu9Kxr8KwreNaDnvUMnrsFz/rQs77Bs77g2QB6NjB47hE8G0LPhgbPhoJnI+jZyOC5V/BsDD0bGzwbC55NoGcTg+c+wbMp9Gxq8GwqeDaDns0MnvsFz+bQs7nBs7ng2QJ6tjB4HhA8W0LPlgbPloJnK+jZyuB5UPBsDT1bGzxbC55toGcbg+f7gmdb6NnW4NlW8GwHPdsZPA8Jnu2hZ3uDZ3vBswP07GDwPCx4doSeHQ2eHQXPTtCzk8HziODZGXp2Nnh2Fjy7QM8uBs+jgmdX6NnV4NlV8OwGPbsZPI8Jnt2hZ3eDZ3fBswf07GHw/EDw7Ak9exo8ewqevaBnL4PnccGzN/TsbfDsLXj2gZ59DJ4fCp59oWdfg2dfwbMf9Oxn8DwhePaHnv0Nnv0FzwHQc4DB8yPBcyD0HGjwHCh4DoKegwyeJwXPwdBzsMFzsOA5BHoOMXh+LHgOhZ5DDZ5DBc9h0HOYwfOU4Dkceg43eA4XPEdAzxEGz08Ez5HQc6TBc6TgOQp6jjJ4nhY8R0PP0QbP0YLnGOg5xuD5qeA5FnqONXiOFTzHQc9xBs8zgud46Dne4Dle8JwAPScYPD8TPCdCz4kGz4mC5yToOcngeVbwnAw9Jxs8JwueU6DnFIPn54LnVOg51eA5VfCcBj2nGTzPCZ7Toed0g+d0wXMG9Jxh8PxC8JwJPWcaPGcKnrOg5yyD53nBczb0nG3wnC14zoGecwyeXwqec6HnXIPnXMFzHvScZ/C8IHjOh57zDZ7zBc8F0HOBwfMrwXMh9Fxo8FwoeC6CnosMnhcFz8XQc7HBc7HguQR6LjF4fi14LoWeSw2eSwXPZdBzmcHzkuC5HHouN3guFzxXQM8VBs9vBM+V0HOlwXOl4LkKeq4yeF4WPFdDz9UGz9WC5xroucbg+a3guRZ6rjV4rhU810HPdQbPK4Lneui53uC5XvDcAD03GDy/Ezw3Qs+NBs+Ngucm6LnJ4HlV8NwMPTcbPDcLnlug5xaD5/eC51boudXguVXw3AY9txk8rwme26HndoPndsFzB/TcYfD8QfDcCT13Gjx3Cp67oOcug+d1wXM39Nxt8NwteO6BnnsMnj8Knnuh516D517Bcx/03GfwvCF47oee+w2e+wXPA9DzgMHzJ8HzIPQ8aPA8KHi+Dz3fN3jeFDwPQc9DBs9Dgudh6HnY4Pmz4HkEeh4xeB4RPI9Cz6MGz1uC5zHoeczgeUzw/AB6fmDw/EXwPA49jxs8jwueH0LPDw2etwXPE9DzhMHzhOD5EfT8yOD5q+B5EnqeNHieFDw/hp4fGzzvCJ6noOcpg+cpwfMT6PmJwfM3wfM09Dxt8DwteH4KPT81eN4VPM9AzzMGzzOC52fQ8zOD5z3B8yz0PGvwPCt4fg49Pzd43hc8z0HPcwbPc4LnF9DzC4Pn74Lneeh53uB5XvD8Enp+afB8IHhegJ4XDJ4XBM+voOdXBs8/BM+L0POiwfOi4Pk19Pza4PlQ8LwEPS8ZPC8Jnt9Az28Mnn8Knpeh52WD52XB81vo+a3B85HgeQV6XjF4XhE8v4Oe3xk8HwueV6HnVYPnVcHze+j5vcHzieB5DXpeM3heEzx/gJ4/GDz/EjyvQ8/rBs/rgueP0PNHg+dTwfMG9Lxh8LwheP4EPX8yeP4teN6EnjcNnjcFz5+h588Gz2eC5y3oecvgeUvw/AV6/mLw/EfwvA09bxs8bwuev0LPXw2ezwXPO9DzjsHzjuD5G/T8zeD5r+B5F3reNXjeFTzvQc97Bs8Xgud96Hnf4Hlf8Pwdev5u8HwpeD6Ang8Mng8Ezz+g5x8Gz1eC50Po+dDg+VDw/BN6/mnwfC14PoKejwyejwTPx9DzscHzjeD5BHo+MXg+ETz/gp5/GTzfCp5PoedTg+dTwfNv6Pm3wfOd4PkMej4zeD4TPP+Bnv8YPN9L/L+/8zn0fG7wfC54/gs9/zV4RhA8X0DPFwbPF4LnS+j50uAZUfB8BT1fGTxfCZ6voedrg2ckwfMN9Hxj8HwjeL6Fnm8NnpEFz3fQ853B853g+V7APP/7LlTPKIJnhIB5RghC9wx7O7xtxIB5RgxC94wqeEYKmGekIHTPsLfD20YOmGfkIHTPaIJnlIB5RglC9wx7O7xt1IB5Rg1C94wueEYLmGe0IHTPsLfD20YPmGf0IHTPGIJnjIB5xghC9wx7O7xtzIB5xgxC94wpeMYKmGesIHTPsLfD28YOmGfsIHTPWIJnnIB5xglC9wx7O7xt3IB5xg1C94wteMYLmGe8IHTPsLfD28YPmGf8IHTPOIJngoB5JghC9wx7O7xtwoB5JgxC94wreCYKmGeiIHTPsLfD2yYOmGfiIHTPeIJnkoB5JglC9wx7O7xt0oB5Jg1C94wveCYLmGeyIHTPsLfD2yYPmGfyIHTPBIJnioB5pghC9wx7O7xtyoB5pgxC90woeKYKmGeqIHTPsLfD26YOmGfqIHTPRIJnmoB5pglC9wx7O7xt2oB5pg1C90wseKYLmGe6IHTPsLfD26YPmGf6IHTPJIJnhoB5ZghC9wx7O7xtxoB5ZgxC90wqeGYKmGemIHTPsLfD22YOmGfmIHTPZIJnloB5ZglC9wx7O7xt1oB5Zg1C90wueGYLmGe2IHTPsLfD22YPmGf2IHTPFIJnjoB55ghC9wx7O7xtzoB55gxC90wpeOYKmGeuIHTPsLfD2+YOmGfuIHTPVIJnnoB55glC9wx7O7xt3oB55g1C90wteOYLmGe+IHTPsLfD2+YPmGf+IHTPNIJngYB5FghC9wx7O7xtwYB5FgxC90wreBYKmGehIHTPsLfD2xYOmGfhIHTPdIJnkYB5FglC9wx7O7xt0YB5Fg1C90wveBYLmGexIHTPsLfD2xYPmGfxIHTPDIJniYB5lghC9wx7O7xtyYB5lgxC98woeJYKmGepIHTPsLfD25YOmGfpIHTPTIJnmYB5lglC9wx7O7xt2YB5lg1C98wseJYLmGe5IHTPsLfD2wYB8wyC0D2zCJ7lA+ZZPgjdM+zt8LYVAuZZIQjdM6vgWTFgnhWD0D3D3g5vWylgnpWC0D2zCZ6VA+ZZOQjdM+zt8LZVAuZZJQjdM7vgWTVgnlWD0D3D3g5vWy1gntWC0D1zCJ7VA+ZZPQjdM+zt8LY1AuZZIwjdM6fgWTNgnjWD0D3D3g5vWytgnrWC0D1zCZ61A+ZZOwjdM+zt8LZ1AuZZJwjdM7fgWTdgnnWD0D3D3g5vWy9gnvWC0D3zCJ71A+ZZPwjdM+zt8LYNAubZIAjdM6/g2TBgng2D0D3D3g5v2yhgno2C0D3zCZ6NA+bZOAjdM+zt8LZNAubZJAjdM7/g2TRgnk2D0D3D3g5v2yxgns2C0D0LCJ7NA+bZPAjdM+zt8LYtAubZIgjds6Dg2TJgni2D0D3D3g5v2ypgnq2C0D0LCZ6tA+bZOgjdM+zt8LZtAubZJgjds7Dg2TZgnm2D0D3D3g5v2y5gnu2C0D2LCJ7tA+bZPgjdM+zt8LYdAubZIQjds6jg2TFgnh2D0D3D3g5v2ylgnp2C0D2LCZ6dA+bZOQjdM+zt8LZdAubZJQjds7jg2TVgnl2D0D3D3g5v2y1gnt2C0D1LCJ7dA+bZPQjdM+zt8LY9AubZIwjds6Tg2TNgnj2D0D3D3g5v2ytgnr2C0D1LCZ69A+bZOwjdM+zt8LZ9AubZJwjds7Tg2Tdgnn2D0D3D3g5v2y9gnv2C0D3LCJ79A+bZPwjdM+zt8LYDAuY5IAjds6zgOTBgngOD0D3D3g5vOyhgnoOC0D3LCZ6DA+Y5OAjdM+zt8LZDAuY5JAjdMxA8hwbMc2gQumfY2+FthwXMc1gQumd5wXN4wDyHB6F7hr0d3nZEwDxHBKF7VhA8RwbMc2QQumfY2+FtRwXMc1QQumdFwXN0wDxHB6F7hr0d3nZMwDzHBKF7VhI8xwbMc2wQumfY2+FtxwXMc1wQumdlwXN8wDzHB6F7hr0d3nZCwDwnBKF7VhE8JwbMc2IQumfY2+FtJwXMc1IQumdVwXNywDwnB6F7hr0d3nZKwDynBKF7VhM8pwbMc2oQumfY2+FtpwXMc1oQumd1wXN6wDynB6F7hr0d3nZGwDxnBKF71hA8ZwbMc2YQumfY2+FtZwXMc1YQumdNwXN2wDxnB6F7hr0d3nZOwDznBKF71hI85wbMc24QumfY2+Ft5wXMc14QumdtwXN+wDznB6F7hr0d3nZBwDwXBKF71hE8FwbMc2EQumfY2+FtFwXMc1EQumddwXNxwDwXB6F7hr0d3nZJwDyXBKF71hM8lwbMc2kQumfY2+FtlwXMc1kQumd9wXN5wDyXB6F7hr0d3nZFwDxXBKF7NhA8VwbMc2UQumfY2+FtVwXMc1UQumdDwXN1wDxXB6F7hr0d3nZNwDzXBKF7NhI81wbMc20QumfY2+Ft1wXMc10QumdjwXN9wDzXB6F7hr0d3nZDwDw3BKF7NhE8NwbMc2MQumfY2+FtNwXMc1MQumdTwXNzwDw3B6F7hr0d3nZLwDy3BKF7NhM8twbMc2sQumfY2+FttwXMc1sQumdzwXN7wDy3B6F7hr0d3nZHwDx3BKF7thA8dwbMc2cQumfY2+FtdwXMc1cQumdLwXN3wDx3B6F7hr0d3nZPwDz3BKF7thI89wbMc28QumfY2+Ft9wXMc18QumdrwXN/wDz3B6F7hr0d3vZAwDwPBKF7thE8DwbM82AQumfY2+Ft3w+Y5/tB6J5tBc9DAfM8FITuGfZ2eNvDAfM8HITu2U7wPBIwzyNB6J5hb4e3PRowz6NB6J7tBc9jAfM8FoTuGfZ2eNsPAub5QRC6ZwfB83jAPI8HoXuGvR3e9sOAeX4YhO7ZUfA8ETDPE0HonmFvh7f9KGCeHwWhe3YSPE8GzPNkELpn2NvhbT8OmOfHQeienQXPUwHzPBWE7hn2dnjbTwLm+UkQumcXwfN0wDxPB6F7hr0d3vbTgHl+GoTu2VXwPBMwzzNB6J5hb4e3/Sxgnp8FoXt2EzzPBszzbBC6Z9jb4W0/D5jn50Hont0Fz3MB8zwXhO4Z9nZ42y8C5vlFELpnD8HzfMA8zwehe4a9Hd72y4B5fhmE7tlT8LwQMM8LQeieYW+Ht/0qYJ5fBaF79hI8LwbM82IQumfY2+Ftvw6Y59dB6J69Bc9LAfO8FITuGfZ2eNtvAub5TRC6Zx/B83LAPC8HoXuGvR3e9tuAeX4bhO7ZV/C8EjDPK0HonmFvh7f9LmCe3wWhe/YTPK8GzPNqELpn2Nvhbb8PmOf3Qeie/QXPawHzvBaE7hn2dnjbHwLm+UMQuucAwfN6wDyvB6F7hr0d3vbHgHn+GITuOVDwvBEwzxtB6J5hb4e3/Slgnj8FoXsOEjxvBszzZhC6Z9jb4W1/Dpjnz0HonoMFz1sB87wVhO4Z9nZ4218C5vlLELrnEMHzdsA8bwehe4a9Hd7214B5/hqE7jlU8LwTMM87QeieYW+Ht/0tYJ6/BaF7DhM87wbM824QumfY2+Ft7wXM814QuudwwfN+wDzvB6F7hr0d3vb3gHn+HoTuOULwfBAwzwdB6J5hb4e3/SNgnn8EoXuOFDwfBszzYRC6Z9jb4W3/DJjnn0HonqMEz0cB83wUhO4Z9nZ428cB83wchO45WvB8EjDPJ0HonmFvh7f9K2CefwWhe44RPJ8GzPNpELpn2Nvhbf8OmOffQeieYwXPZwHzfBaE7hn2dnjbfwLm+U8Quuc4wfN5wDyfB6F7hr0d3vbfgHn+G4TuOV7wfBEwzxdB6J5hb4e3fRkwz5dB6J4TBM9XAfN8FYTuGfZ2eNvXAfN8HYTuOVHwfBMwzzdB6J5hb4e3fRswz7dB6J6TBM93AfN8F4TuGfZ2eNv3yjPP/74L1XOy4BmhPPOMUD50z7C3w9tGhJ4RDZ5TBM9I0DOSwTOS4BkZekY2eE4VPKNAzygGzyiCZ1ToGdXgOU3wjAY9oxk8owme0aFndIPndMEzBvSMYfCMIXjGhJ4xDZ4zBM9Y0DOWwTOW4BkbesY2eM4UPONAzzgGzziCZ1zoGdfgOUvwjAc94xk84wme8aFnfIPnbMEzAfRMYPBMIHgmhJ4JDZ5zBM9E0DORwTOR4JkYeiY2eM4VPJNAzyQGzySCZ1LomdTgOU/wTAY9kxk8kwmeyaFncoPnfMEzBfRMYfBMIXimhJ4pDZ4LBM9U0DOVwTOV4JkaeqY2eC4UPNNAzzQGzzSCZ1romdbguUjwTAc90xk80wme6aFneoPnYsEzA/TMYPDMIHhmhJ4ZDZ5LBM9M0DOTwTOT4JkZemY2eC4VPLNAzywGzyyCZ1bomdXguUzwzAY9sxk8swme2aFndoPncsEzB/TMYfDMIXjmhJ45DZ4rBM9c0DOXwTOX4JkbeuY2eK4UPPNAzzwGzzyCZ17omdfguUrwzAc98xk88wme+aFnfoPnasGzAPQsYPAsIHgWhJ4FDZ5rBM9C0LOQwbOQ4FkYehY2eK4VPItAzyIGzyKCZ1HoWdTguU7wLAY9ixk8iwmexaFncYPnesGzBPQsYfAsIXiWhJ4lDZ4bBM9S0LOUwbOU4FkaepY2eG4UPMtAzzIGzzKCZ1noWdbguUnwLAc9yxk8ywmeAfQMDJ6bBc/y0LO8wbO84FkBelYweG4RPCtCz4oGz4qCZyXoWcnguVXwrAw9Kxs8KwueVaBnFYPnNsGzKvSsavCsKnhWg57VDJ7bBc/q0LO6wbO64FkDetYweO4QPGtCz5oGz5qCZy3oWcvguVPwrA09axs8awuedaBnHYPnLsGzLvSsa/CsK3jWg571DJ67Bc/60LO+wbO+4NkAejYweO4RPBtCz4YGz4aCZyPo2cjguVfwbAw9Gxs8GwueTaBnE4PnPsGzKfRsavBsKng2g57NDJ77Bc/m0LO5wbO54NkCerYweB4QPFtCz5YGz5aCZyvo2crgeVDwbA09Wxs8WwuebaBnG4Pn+4JnW+jZ1uDZVvBsBz3bGTwPCZ7toWd7g2d7wbMD9Oxg8DwseHaEnh0Nnh0Fz07Qs5PB84jg2Rl6djZ4dhY8u0DPLgbPo4JnV+jZ1eDZVfDsBj27GTyPCZ7doWd3g2d3wbMH9Oxh8PxA8OwJPXsaPHsKnr2gZy+D53HBszf07G3w7C149oGefQyeHwqefaFnX4NnX8GzH/TsZ/A8IXj2h579DZ79Bc8B0HOAwfMjwXMg9Bxo8BwoeA6CnoMMnicFz8HQc7DBc7DgOQR6DjF4fix4DoWeQw2eQwXPYdBzmMHzlOA5HHoON3gOFzxHQM8RBs9PBM+R0HOkwXOk4DkKeo4yeJ4WPEdDz9EGz9GC5xjoOcbg+angORZ6jjV4jhU8x0HPcQbPM4LneOg53uA5XvCcAD0nGDw/EzwnQs+JBs+Jguck6DnJ4HlW8JwMPScbPCcLnlOg5xSD5+eC51ToOdXgOVXwnAY9pxk8zwme06HndIPndMFzBvScYfD8QvCcCT1nGjxnCp6zoOcsg+d5wXM29Jxt8JwteM6BnnMMnl8KnnOh51yD51zBcx70nGfwvCB4zoee8w2e8wXPBdBzgcHzK8FzIfRcaPBcKHgugp6LDJ4XBc/F0HOxwXOx4LkEei4xeH4teC6FnksNnksFz2XQc5nB85LguRx6Ljd4Lhc8V0DPFQbPbwTPldBzpcFzpeC5CnquMnheFjxXQ8/VBs/Vguca6LnG4Pmt4LkWeq41eK4VPNdBz3UGzyuC53roud7guV7w3AA9Nxg8vxM8N0LPjQbPjYLnJui5yeB5VfDcDD03Gzw3C55boOcWg+f3gudW6LnV4LlV8NwGPbcZPK8Jntuh53aD53bBcwf03GHw/EHw3Ak9dxo8dwqeu6DnLoPndcFzN/TcbfDcLXjugZ57DJ4/Cp57oedeg+dewXMf9Nxn8LwheO6HnvsNnvsFzwPQ84DB8yfB8yD0PGjwPCh4vg893zd43hQ8D0HPQwbPQ4LnYeh52OD5s+B5BHoeMXgeETyPQs+jBs9bgucx6HnM4HlM8PwAen5g8PxF8DwOPY8bPI8Lnh9Czw8NnrcFzxPQ84TB84Tg+RH0/Mjg+avgeRJ6njR4nhQ8P4aeHxs87wiep6DnKYPnKcHzE+j5icHzN8HzNPQ8bfA8LXh+Cj0/NXjeFTzPQM8zBs8zgudn0PMzg+c9wfMs9Dxr8DwreH4OPT83eN4XPM9Bz3MGz3OC5xfQ8wuD5++C53noed7geV7w/BJ6fmnwfCB4XoCeFwyeFwTPr6DnVwbPPwTPi9DzosHzouD5NfT82uD5UPC8BD0vGTwvCZ7fQM9vDJ5/Cp6Xoedlg+dlwfNb6PmtwfOR4HkFel4xeF4RPL+Dnt8ZPB8Lnleh51WD51XB83vo+b3B84ngeQ16XjN4XhM8f4CePxg8/xI8r0PP6wbP64Lnj9DzR4PnU8HzBvS8YfC8IXj+BD1/Mnj+LXjehJ43DZ43Bc+foefPBs9nguct6HnL4HlL8PwFev5i8PxH8LwNPW8bPG8Lnr9Cz18Nns8FzzvQ847B847g+Rv0/M3g+a/geRd63jV43hU870HPewbPF4Lnfeh53+B5X/D8HXr+bvB8KXg+gJ4PDJ4PBM8/oOcfBs9XgudD6PnQ4PlQ8PwTev5p8HwteD6Cno8Mno8Ez8fQ87HB843g+QR6PjF4PhE8/4Kefxk83wqeT6HnU4PnU8Hzb+j5t8HzneD5DHo+M3g+Ezz/gZ7/GDzfS/K/v/M59Hxu8HwueP4LPf81eEYQPF9AzxcGzxeC50vo+dLgGVHwfAU9Xxk8Xwmer6Hna4NnJMHzDfR8Y/B8I3i+hZ5vDZ6RBc930POdwfOd4PleBeb533ehekYRPCNUYJ4RKoTuGfZ2eNuI0DOiwTOq4BkJekYyeEYSPCNDz8gGz2iCZxToGcXgGUXwjAo9oxo8owue0aBnNINnNMEzOvSMbvCMIXjGgJ4xDJ4xBM+Y0DOmwTOm4BkLesYyeMYSPGNDz9gGz1iCZxzoGcfgGUfwjAs94xo8Ywue8aBnPINnPMEzPvSMb/CMI3gmgJ4JDJ4JBM+E0DOhwTOu4JkIeiYyeCYSPBNDz8QGz3iCZxLomcTgmUTwTAo9kxo84wueyaBnMoNnMsEzOfRMbvBMIHimgJ4pDJ4pBM+U0DOlwTOh4JkKeqYyeKYSPFNDz9QGz0SCZxromcbgmUbwTAs90xo8Ewue6aBnOoNnOsEzPfRMb/BMInhmgJ4ZDJ4ZBM+M0DOjwTOp4JkJemYyeGYSPDNDz8wGz2SCZxbomcXgmUXwzAo9sxo8kwue2aBnNoNnNsEzO/TMbvBMIXjmgJ45DJ45BM+c0DOnwTOl4JkLeuYyeOYSPHNDz9wGz1SCZx7omcfgmUfwzAs98xo8Uwue+aBnPoNnPsEzP/TMb/BMI3gWgJ4FDJ4FBM+C0LOgwTOt4FkIehYyeBYSPAtDz8IGz3SCZxHoWcTgWUTwLAo9ixo80wuexaBnMYNnMcGzOPQsbvDMIHiWgJ4lDJ4lBM+S0LOkwTOj4FkKepYyeJYSPEtDz9IGz0yCZxnoWcbgWUbwLAs9yxo8Mwue5aBnOYNnOcEzgJ6BwTOL4FkeepY3eJYXPCtAzwoGz6yCZ0XoWdHgWVHwrAQ9Kxk8swmelaFnZYNnZcGzCvSsYvDMLnhWhZ5VDZ5VBc9q0LOawTOH4FkdelY3eFYXPGtAzxoGz5yCZ03oWdPgWVPwrAU9axk8cwmetaFnbYNnbcGzDvSsY/DMLXjWhZ51DZ51Bc960LOewTOP4FkfetY3eNYXPBtAzwYGz7yCZ0Po2dDg2VDwbAQ9Gxk88wmejaFnY4NnY8GzCfRsYvDML3g2hZ5NDZ5NBc9m0LOZwbOA4NkcejY3eDYXPFtAzxYGz4KCZ0vo2dLg2VLwbAU9Wxk8CwmeraFna4Nna8GzDfRsY/AsLHi2hZ5tDZ5tBc920LOdwbOI4NkeerY3eLYXPDtAzw4Gz6KCZ0fo2dHg2VHw7AQ9Oxk8iwmenaFnZ4NnZ8GzC/TsYvAsLnh2hZ5dDZ5dBc9u0LObwbOE4NkdenY3eHYXPHtAzx4Gz5KCZ0/o2dPg2VPw7AU9exk8SwmevaFnb4Nnb8GzD/TsY/AsLXj2hZ59DZ59Bc9+0LOfwbOM4NkfevY3ePYXPAdAzwEGz7KC50DoOdDgOVDwHAQ9Bxk8ywmeg6HnYIPnYMFzCPQcYvAMBM+h0HOowXOo4DkMeg4zeJYXPIdDz+EGz+GC5wjoOcLgWUHwHAk9Rxo8Rwqeo6DnKINnRcFzNPQcbfAcLXiOgZ5jDJ6VBM+x0HOswXOs4DkOeo4zeFYWPMdDz/EGz/GC5wToOcHgWUXwnAg9Jxo8Jwqek6DnJINnVcFzMvScbPCcLHhOgZ5TDJ7VBM+p0HOqwXOq4DkNek4zeFYXPKdDz+kGz+mC5wzoOcPgWUPwnAk9Zxo8Zwqes6DnLINnTcFzNvScbfCcLXjOgZ5zDJ61BM+50HOuwXOu4DkPes4zeNYWPOdDz/kGz/mC5wLoucDgWUfwXAg9Fxo8Fwqei6DnIoNnXcFzMfRcbPBcLHgugZ5LDJ71BM+l0HOpwXOp4LkMei4zeNYXPJdDz+UGz+WC5wroucLg2UDwXAk9Vxo8Vwqeq6DnKoNnQ8FzNfRcbfBcLXiugZ5rDJ6NBM+10HOtwXOt4LkOeq4zeDYWPNdDz/UGz/WC5wboucHg2UTw3Ag9Nxo8Nwqem6DnJoNnU8FzM/TcbPDcLHhugZ5bDJ7NBM+t0HOrwXOr4LkNem4zeDYXPLdDz+0Gz+2C5w7oucPg2ULw3Ak9dxo8dwqeu6DnLoNnS8FzN/TcbfDcLXjugZ57DJ6tBM+90HOvwXOv4LkPeu4zeLYWPPdDz/0Gz/2C5wHoecDg2UbwPAg9Dxo8Dwqe70PP9w2ebQXPQ9DzkMHzkOB5GHoeNni2EzyPQM8jBs8jgudR6HnU4Nle8DwGPY8ZPI8Jnh9Azw8Mnh0Ez+PQ87jB87jg+SH0/NDg2VHwPAE9Txg8TwieH0HPjwyenQTPk9DzpMHzpOD5MfT82ODZWfA8BT1PGTxPCZ6fQM9PDJ5dBM/T0PO0wfO04Pkp9PzU4NlV8DwDPc8YPM8Inp9Bz88Mnt0Ez7PQ86zB86zg+Tn0/Nzg2V3wPAc9zxk8zwmeX0DPLwyePQTP89DzvMHzvOD5JfT80uDZU/C8AD0vGDwvCJ5fQc+vDJ69BM+L0POiwfOi4Pk19Pza4Nlb8LwEPS8ZPC8Jnt9Az28Mnn0Ez8vQ87LB87Lg+S30/Nbg2VfwvAI9rxg8rwie30HP7wye/QTPq9DzqsHzquD5PfT83uDZX/C8Bj2vGTyvCZ4/QM8fDJ4DBM/r0PO6wfO64Pkj9PzR4DlQ8LwBPW8YPG8Inj9Bz58MnoMEz5vQ86bB86bg+TP0/NngOVjwvAU9bxk8bwmev0DPXwyeQwTP29DztsHztuD5K/T81eA5VPC8Az3vGDzvCJ6/Qc/fDJ7DBM+70POuwfOu4HkPet4zeA4XPO9Dz/sGz/uC5+/Q83eD5wjB8wH0fGDwfCB4/gE9/zB4jhQ8H0LPhwbPh4Lnn9DzT4PnKMHzEfR8ZPB8JHg+hp6PDZ6jBc8n0POJwfOJ4PkX9PzL4DlG8HwKPZ8aPJ8Knn9Dz78NnmMFz2fQ85nB85ng+Q/0/MfgOU7wfA49nxs8nwue/0LPfw2e4wXPF9DzhcHzheD5Enq+NHhOEDxfQc9XBs9Xgudr6Pna4DlR8HwDPd8YPN8Inm+h51uD5yTB8x30fGfwfCd4vleRef73XaiekwXPCBWZZ4SKoXuGvR3eNiL0jGjwnCJ4RoKekQyekQTPyNAzssFzquAZBXpGMXhGETyjQs+oBs9pgmc06BnN4BlN8IwOPaMbPKcLnjGgZwyDZwzBMyb0jGnwnCF4xoKesQyesQTP2NAztsFzpuAZB3rGMXjGETzjQs+4Bs9Zgmc86BnP4BlP8IwPPeMbPGcLngmgZwKDZwLBMyH0TGjwnCN4JoKeiQyeiQTPxNAzscFzruCZBHomMXgmETyTQs+kBs95gmcy6JnM4JlM8EwOPZMbPOcLnimgZwqDZwrBMyX0TGnwXCB4poKeqQyeqQTP1NAztcFzoeCZBnqmMXimETzTQs+0Bs9Fgmc66JnO4JlO8EwPPdMbPBcLnhmgZwaDZwbBMyP0zGjwXCJ4ZoKemQyemQTPzNAzs8FzqeCZBXpmMXhmETyzQs+sBs9lgmc26JnN4JlN8MwOPbMbPJcLnjmgZw6DZw7BMyf0zGnwXCF45oKeuQyeuQTP3NAzt8FzpeCZB3rmMXjmETzzQs+8Bs9Vgmc+6JnP4JlP8MwPPfMbPFcLngWgZwGDZwHBsyD0LGjwXCN4FoKehQyehQTPwtCzsMFzreBZBHoWMXgWETyLQs+iBs91gmcx6FnM4FlM8CwOPYsbPNcLniWgZwmDZwnBsyT0LGnw3CB4loKepQyepQTP0tCztMFzo+BZBnqWMXiWETzLQs+yBs9Ngmc56FnO4FlO8AygZ2Dw3Cx4loee5Q2e5QXPCtCzgsFzi+BZEXpWNHhWFDwrQc9KBs+tgmdl6FnZ4FlZ8KwCPasYPLcJnlWhZ1WDZ1XBsxr0rGbw3C54Voee1Q2e1QXPGtCzhsFzh+BZE3rWNHjWFDxrQc9aBs+dgmdt6Fnb4Flb8KwDPesYPHcJnnWhZ12DZ13Bsx70rGfw3C141oee9Q2e9QXPBtCzgcFzj+DZEHo2NHg2FDwbQc9GBs+9gmdj6NnY4NlY8GwCPZsYPPcJnk2hZ1ODZ1PBsxn0bGbw3C94NoeezQ2ezQXPFtCzhcHzgODZEnq2NHi2FDxbQc9WBs+Dgmdr6Nna4Nla8GwDPdsYPN8XPNtCz7YGz7aCZzvo2c7geUjwbA892xs82wueHaBnB4PnYcGzI/TsaPDsKHh2gp6dDJ5HBM/O0LOzwbOz4NkFenYxeB4VPLtCz64Gz66CZzfo2c3geUzw7A49uxs8uwuePaBnD4PnB4JnT+jZ0+DZU/DsBT17GTyPC569oWdvg2dvwbMP9Oxj8PxQ8OwLPfsaPPsKnv2gZz+D5wnBsz/07G/w7C94DoCeAwyeHwmeA6HnQIPnQMFzEPQcZPA8KXgOhp6DDZ6DBc8h0HOIwfNjwXMo9Bxq8BwqeA6DnsMMnqcEz+HQc7jBc7jgOQJ6jjB4fiJ4joSeIw2eIwXPUdBzlMHztOA5GnqONniOFjzHQM8xBs9PBc+x0HOswXOs4DkOeo4zeJ4RPMdDz/EGz/GC5wToOcHg+ZngORF6TjR4ThQ8J0HPSQbPs4LnZOg52eA5WfCcAj2nGDw/FzynQs+pBs+pguc06DnN4HlO8JwOPacbPKcLnjOg5wyD5xeC50zoOdPgOVPwnAU9Zxk8zwues6HnbIPnbMFzDvScY/D8UvCcCz3nGjznCp7zoOc8g+cFwXM+9Jxv8JwveC6AngsMnl8Jnguh50KD50LBcxH0XGTwvCh4Loaeiw2eiwXPJdBzicHza8FzKfRcavBcKngug57LDJ6XBM/l0HO5wXO54LkCeq4weH4jeK6EnisNnisFz1XQc5XB87LguRp6rjZ4rhY810DPNQbPbwXPtdBzrcFzreC5DnquM3heETzXQ8/1Bs/1gucG6LnB4Pmd4LkRem40eG4UPDdBz00Gz6uC52boudnguVnw3AI9txg8vxc8t0LPrQbPrYLnNui5zeB5TfDcDj23Gzy3C547oOcOg+cPgudO6LnT4LlT8NwFPXcZPK8Lnruh526D527Bcw/03GPw/FHw3As99xo89wqe+6DnPoPnDcFzP/Tcb/DcL3gegJ4HDJ4/CZ4HoedBg+dBwfN96Pm+wfOm4HkIeh4yeB4SPA9Dz8MGz58FzyPQ84jB84jgeRR6HjV43hI8j0HPYwbPY4LnB9DzA4PnL4Lnceh53OB5XPD8EHp+aPC8LXiegJ4nDJ4nBM+PoOdHBs9fBc+T0POkwfOk4Pkx9PzY4HlH8DwFPU8ZPE8Jnp9Az08Mnr8Jnqeh52mD52nB81Po+anB867geQZ6njF4nhE8P4Oenxk87wmeZ6HnWYPnWcHzc+j5ucHzvuB5DnqeM3ieEzy/gJ5fGDx/FzzPQ8/zBs/zgueX0PNLg+cDwfMC9Lxg8LwgeH4FPb8yeP4heF6EnhcNnhcFz6+h59cGz4eC5yXoecngeUnw/AZ6fmPw/FPwvAw9Lxs8Lwue30LPbw2ejwTPK9DzisHziuD5HfT8zuD5WPC8Cj2vGjyvCp7fQ8/vDZ5PBM9r0POawfOa4PkD9PzB4PmX4Hkdel43eF4XPH+Enj8aPJ8Knjeg5w2D5w3B8yfo+ZPB82/B8yb0vGnwvCl4/gw9fzZ4PhM8b0HPWwbPW4LnL9DzF4PnP4Lnbeh52+B5W/D8FXr+avB8LnjegZ53DJ53BM/foOdvBs9/Bc+70POuwfOu4HkPet4zeL4QPO9Dz/sGz/uC5+/Q83eD50vB8wH0fGDwfCB4/gE9/zB4vhI8H0LPhwbPh4Lnn9DzT4Pna8HzEfR8ZPB8JHg+hp6PDZ5vBM8n0POJwfOJ4PkX9PzL4PlW8HwKPZ8aPJ8Knn9Dz78Nnu8Ez2fQ85nB85ng+Q/0/Mfg+V7S//2dz6Hnc4Pnc8HzX+j5r8EzQtr//Z0v/vd3Fgz7zv++ixbOO5Xb4W1f/u/v7Bj2nS//h3eG84sQUfB8BT1fGTxfCZ6voedrg2ckwfMN9Hxj8HwjeL6Fnm8NnpEFz3fQ853B853g+V4l5vnfd6F6RhE8I1RinhEqhe4Z9nZ424jQM6LBM6rgGQl6RjJ4RhI8I0PPyAbPaIJnFOgZxeAZRfCMCj2jGjyjC57RoGc0g2c0wTM69Ixu8IwheMaAnjEMnjEEz5jQM6bBM6bgGQt6xjJ4xhI8Y0PP2AbPWIJnHOgZx+AZR/CMCz3jGjxjC57xoGc8g2c8wTM+9Ixv8IwjeCaAngkMngkEz4TQM6HBM67gmQh6JjJ4JhI8E0PPxAbPeIJnEuiZxOCZRPBMCj2TGjzjC57JoGcyg2cywTM59Exu8EwgeKaAnikMnikEz5TQM6XBM6HgmQp6pjJ4phI8U0PP1AbPRIJnGuiZxuCZRvBMCz3TGjwTC57poGc6g2c6wTM99Exv8EwieGaAnhkMnhkEz4zQM6PBM6ngmQl6ZjJ4ZhI8M0PPzAbPZIJnFuiZxeCZRfDMCj2zGjyTC57ZoGc2g2c2wTM79Mxu8EwheOaAnjkMnjkEz5zQM6fBM6XgmQt65jJ45hI8c0PP3AbPVIJnHuiZx+CZR/DMCz3zGjxTC575oGc+g2c+wTM/9Mxv8EwjeBaAngUMngUEz4LQs6DBM63gWQh6FjJ4FhI8C0PPwgbPdIJnEehZxOBZRPAsCj2LGjzTC57FoGcxg2cxwbM49Cxu8MwgeJaAniUMniUEz5LQs6TBM6PgWQp6ljJ4lhI8S0PP0gbPTIJnGehZxuBZRvAsCz3LGjwzC57loGc5g2c5wTOAnoHBM4vgWR56ljd4lhc8K0DPCgbPrIJnRehZ0eBZUfCsBD0rGTyzCZ6VoWdlg2dlwbMK9Kxi8MwueFaFnlUNnlUFz2rQs5rBM4fgWR16Vjd4Vhc8a0DPGgbPnIJnTehZ0+BZU/CsBT1rGTxzCZ61oWdtg2dtwbMO9Kxj8MwteNaFnnUNnnUFz3rQs57BM4/gWR961jd41hc8G0DPBgbPvIJnQ+jZ0ODZUPBsBD0bGTzzCZ6NoWdjg2djwbMJ9Gxi8MwveDaFnk0Nnk0Fz2bQs5nBs4Dg2Rx6Njd4Nhc8W0DPFgbPgoJnS+jZ0uDZUvBsBT1bGTwLCZ6toWdrg2drwbMN9Gxj8CwseLaFnm0Nnm0Fz3bQs53Bs4jg2R56tjd4thc8O0DPDgbPooJnR+jZ0eDZUfDsBD07GTyLCZ6doWdng2dnwbML9Oxi8CwueHaFnl0Nnl0Fz27Qs5vBs4Tg2R16djd4dhc8e0DPHgbPkoJnT+jZ0+DZU/DsBT17GTxLCZ69oWdvg2dvwbMP9Oxj8CwtePaFnn0Nnn0Fz37Qs5/Bs4zg2R969jd49hc8B0DPAQbPsoLnQOg50OA5UPAcBD0HGTzLCZ6Doedgg+dgwXMI9Bxi8AwEz6HQc6jBc6jgOQx6DjN4lhc8h0PP4QbP4YLnCOg5wuBZQfAcCT1HGjxHCp6joOcog2dFwXM09Bxt8BwteI6BnmMMnpUEz7HQc6zBc6zgOQ56jjN4VhY8x0PP8QbP8YLnBOg5weBZRfCcCD0nGjwnCp6ToOckg2dVwXMy9Jxs8JwseE6BnlMMntUEz6nQc6rBc6rgOQ16TjN4Vhc8p0PP6QbP6YLnDOg5w+BZQ/CcCT1nGjxnCp6zoOcsg2dNwXM29Jxt8JwteM6BnnMMnrUEz7nQc67Bc67gOQ96zjN41hY850PP+QbP+YLnAui5wOBZR/BcCD0XGjwXCp6LoOcig2ddwXMx9Fxs8FwseC6BnksMnvUEz6XQc6nBc6nguQx6LjN41hc8l0PP5QbP5YLnCui5wuDZQPBcCT1XGjxXCp6roOcqg2dDwXM19Fxt8FwteK6BnmsMno0Ez7XQc63Bc63guQ56rjN4NhY810PP9QbP9YLnBui5weDZRPDcCD03Gjw3Cp6boOcmg2dTwXMz9Nxs8NwseG6BnlsMns0Ez63Qc6vBc6vguQ16bjN4Nhc8t0PP7QbP7YLnDui5w+DZQvDcCT13Gjx3Cp67oOcug2dLwXM39Nxt8NwteO6BnnsMnq0Ez73Qc6/Bc6/guQ967jN4thY890PP/QbP/YLnAeh5wODZRvA8CD0PGjwPCp7vQ8/3DZ5tBc9D0POQwfOQ4HkYeh42eLYTPI9AzyMGzyOC51HoedTg2V7wPAY9jxk8jwmeH0DPDwyeHQTP49DzuMHzuOD5IfT80ODZUfA8AT1PGDxPCJ4fQc+PDJ6dBM+T0POkwfOk4Pkx9PzY4NlZ8DwFPU8ZPE8Jnp9Az08Mnl0Ez9PQ87TB87Tg+Sn0/NTg2VXwPAM9zxg8zwien0HPzwye3QTPs9DzrMHzrOD5OfT83ODZXfA8Bz3PGTzPCZ5fQM8vDJ49BM/z0PO8wfO84Pkl9PzS4NlT8LwAPS8YPC8Inl9Bz68Mnr0Ez4vQ86LB86Lg+TX0/Nrg2VvwvAQ9Lxk8Lwme30DPbwyefQTPy9DzssHzsuD5LfT81uDZV/C8Aj2vGDyvCJ7fQc/vDJ79BM+r0POqwfOq4Pk99Pze4Nlf8LwGPa8ZPK8Jnj9Azx8MngMEz+vQ87rB87rg+SP0/NHgOVDwvAE9bxg8bwieP0HPnwyegwTPm9DzpsHzpuD5M/T82eA5WPC8BT1vGTxvCZ6/QM9fDJ5DBM/b0PO2wfO24Pkr9PzV4DlU8LwDPe8YPO8Inr9Bz98MnsMEz7vQ867B867geQ963jN4Dhc870PP+wbP+4Ln79Dzd4PnCMHzAfR8YPB8IHj+AT3/MHiOFDwfQs+HBs+Hguef0PNPg+cowfMR9Hxk8HwkeD6Gno8NnqMFzyfQ84nB84ng+Rf0/MvgOUbwfAo9nxo8nwqef0PPvw2eYwXPZ9DzmcHzmeD5D/T8x+A5TvB8Dj2fGzyfC57/Qs9/DZ7jBc8X0POFwfOF4PkSer40eE4QPF9Bz1cGz1eC52vo+drgOVHwfAM93xg83wieb6HnW4PnJMHzHfR8Z/B8J3i+V5l5/vddqJ6TBc8IlZlnhMqhe4a9Hd42IvSMaPCcInhGgp6RDJ6RBM/I0DOywXOq4BkFekYxeEYRPKNCz6gGz2mCZzToGc3gGU3wjA49oxs8pwueMaBnDINnDMEzJvSMafCcIXjGgp6xDJ6xBM/Y0DO2wXOm4BkHesYxeMYRPONCz7gGz1mCZzzoGc/gGU/wjA894xs8ZwueCaBnAoNnAsEzIfRMaPCcI3gmgp6JDJ6JBM/E0DOxwXOu4JkEeiYxeCYRPJNCz6QGz3mCZzLomczgmUzwTA49kxs85wueKaBnCoNnCsEzJfRMafBcIHimgp6pDJ6pBM/U0DO1wXOh4JkGeqYxeKYRPNNCz7QGz0WCZzromc7gmU7wTA890xs8FwueGaBnBoNnBsEzI/TMaPBcInhmgp6ZDJ6ZBM/M0DOzwXOp4JkFemYxeGYRPLNCz6wGz2WCZzbomc3gmU3wzA49sxs8lwueOaBnDoNnDsEzJ/TMafBcIXjmgp65DJ65BM/c0DO3wXOl4JkHeuYxeOYRPPNCz7wGz1WCZz7omc/gmU/wzA898xs8VwueBaBnAYNnAcGzIPQsaPBcI3gWgp6FDJ6FBM/C0LOwwXOt4FkEehYxeBYRPItCz6IGz3WCZzHoWczgWUzwLA49ixs81wueJaBnCYNnCcGzJPQsafDcIHiWgp6lDJ6lBM/S0LO0wXOj4FkGepYxeJYRPMtCz7IGz02CZznoWc7gWU7wDKBnYPDcLHiWh57lDZ7lBc8K0LOCwXOL4FkRelY0eFYUPCtBz0oGz62CZ2XoWdngWVnwrAI9qxg8twmeVaFnVYNnVcGzGvSsZvDcLnhWh57VDZ7VBc8a0LOGwXOH4FkTetY0eNYUPGtBz1oGz52CZ23oWdvgWVvwrAM96xg8dwmedaFnXYNnXcGzHvSsZ/DcLXjWh571DZ71Bc8G0LOBwXOP4NkQejY0eDYUPBtBz0YGz72CZ2Po2djg2VjwbAI9mxg89wmeTaFnU4NnU8GzGfRsZvDcL3g2h57NDZ7NBc8W0LOFwfOA4NkSerY0eLYUPFtBz1YGz4OCZ2vo2drg2VrwbAM92xg83xc820LPtgbPtoJnO+jZzuB5SPBsDz3bGzzbC54doGcHg+dhwbMj9Oxo8OwoeHaCnp0MnkcEz87Qs7PBs7Pg2QV6djF4HhU8u0LPrgbProJnN+jZzeB5TPDsDj27Gzy7C549oGcPg+cHgmdP6NnT4NlT8OwFPXsZPI8Lnr2hZ2+DZ2/Bsw/07GPw/FDw7As9+xo8+wqe/aBnP4PnCcGzP/Tsb/DsL3gOgJ4DDJ4fCZ4DoedAg+dAwXMQ9Bxk8DwpeA6GnoMNnoMFzyHQc4jB82PBcyj0HGrwHCp4DoOewwyepwTP4dBzuMFzuOA5AnqOMHh+IniOhJ4jDZ4jBc9R0HOUwfO04Dkaeo42eI4WPMdAzzEGz08Fz7HQc6zBc6zgOQ56jjN4nhE8x0PP8QbP8YLnBOg5weD5meA5EXpONHhOFDwnQc9JBs+zgudk6DnZ4DlZ8JwCPacYPD8XPKdCz6kGz6mC5zToOc3geU7wnA49pxs8pwueM6DnDIPnF4LnTOg50+A5U/CcBT1nGTzPC56zoedsg+dswXMO9Jxj8PxS8JwLPecaPOcKnvOg5zyD5wXBcz70nG/wnC94LoCeCwyeXwmeC6HnQoPnQsFzEfRcZPC8KHguhp6LDZ6LBc8l0HOJwfNrwXMp9Fxq8FwqeC6DnssMnpcEz+XQc7nBc7nguQJ6rjB4fiN4roSeKw2eKwXPVdBzlcHzsuC5GnquNniuFjzXQM81Bs9vBc+10HOtwXOt4LkOeq4zeF4RPNdDz/UGz/WC5wboucHg+Z3guRF6bjR4bhQ8N0HPTQbPq4LnZui52eC5WfDcAj23GDy/Fzy3Qs+tBs+tguc26LnN4HlN8NwOPbcbPLcLnjug5w6D5w+C507oudPguVPw3AU9dxk8rwueu6HnboPnbsFzD/TcY/D8UfDcCz33Gjz3Cp77oOc+g+cNwXM/9Nxv8NwveB6AngcMnj8Jngeh50GD50HB833o+b7B86bgeQh6HjJ4HhI8D0PPwwbPnwXPI9DziMHziOB5FHoeNXjeEjyPQc9jBs9jgucH0PMDg+cvgudx6Hnc4Hlc8PwQen5o8LwteJ6AnicMnicEz4+g50cGz18Fz5PQ86TB86Tg+TH0/NjgeUfwPAU9Txk8Twmen0DPTwyevwmep6HnaYPnacHzU+j5qcHzruB5BnqeMXieETw/g56fGTzvCZ5noedZg+dZwfNz6Pm5wfO+4HkOep4zeJ4TPL+Anl8YPH8XPM9Dz/MGz/OC55fQ80uD5wPB8wL0vGDwvCB4fgU9vzJ4/iF4XoSeFw2eFwXPr6Hn1wbPh4LnJeh5yeB5SfD8Bnp+Y/D8U/C8DD0vGzwvC57fQs9vDZ6PBM8r0POKwfOK4Pkd9PzO4PlY8LwKPa8aPK8Knt9Dz+8Nnk8Ez2vQ85rB85rg+QP0/MHg+ZfgeR16Xjd4Xhc8f4SePxo8nwqeN6DnDYPnDcHzJ+j5k8Hzb8HzJvS8afC8KXj+DD1/Nng+EzxvQc9bBs9bgucv0PMXg+c/gudt6Hnb4Hlb8PwVev5q8HwueN6BnncMnncEz9+g528Gz38Fz7vQ867B867geQ963jN4vhA870PP+wbP+4Ln79Dzd4PnS8HzAfR8YPB8IHj+AT3/MHi+EjwfQs+HBs+Hguef0PNPg+drwfMR9Hxk8HwkeD6Gno8Nnm8EzyfQ84nB84ng+Rf0/Mvg+VbwfAo9nxo8nwqef0PPvw2e7wTPZ9DzmcHzmeD5D/T8x+D5Xrr//Z3Poedzg+dzwfNf6PmvwTOC4PkCer4weL4QPF9Cz5cGz4iC5yvo+crg+UrwfA09Xxs8Iwmeb6DnG4PnG8HzLfR8a/CMLHi+g57vDJ7vBM/3qjDP/74L1TOK4BmhCvOMUCV0z7C3w9tGhJ4RDZ5RBc9I0DOSwTOS4BkZekY2eEYTPKNAzygGzyiCZ1ToGdXgGV3wjAY9oxk8owme0aFndINnDMEzBvSMYfCMIXjGhJ4xDZ4xBc9Y0DOWwTOW4BkbesY2eMYSPONAzzgGzziCZ1zoGdfgGVvwjAc94xk84wme8aFnfINnHMEzAfRMYPBMIHgmhJ4JDZ5xBc9E0DORwTOR4JkYeiY2eMYTPJNAzyQGzySCZ1LomdTgGV/wTAY9kxk8kwmeyaFncoNnAsEzBfRMYfBMIXimhJ4pDZ4JBc9U0DOVwTOV4JkaeqY2eCYSPNNAzzQGzzSCZ1romdbgmVjwTAc90xk80wme6aFneoNnEsEzA/TMYPDMIHhmhJ4ZDZ5JBc9M0DOTwTOT4JkZemY2eCYTPLNAzywGzyyCZ1bomdXgmVzwzAY9sxk8swme2aFndoNnCsEzB/TMYfDMIXjmhJ45DZ4pBc9c0DOXwTOX4JkbeuY2eKYSPPNAzzwGzzyCZ17omdfgmVrwzAc98xk88wme+aFnfoNnGsGzAPQsYPAsIHgWhJ4FDZ5pBc9C0LOQwbOQ4FkYehY2eKYTPItAzyIGzyKCZ1HoWdTgmV7wLAY9ixk8iwmexaFncYNnBsGzBPQsYfAsIXiWhJ4lDZ4ZBc9S0LOUwbOU4FkaepY2eGYSPMtAzzIGzzKCZ1noWdbgmVnwLAc9yxk8ywmeAfQMDJ5ZBM/y0LO8wbO84FkBelYweGYVPCtCz4oGz4qCZyXoWcngmU3wrAw9Kxs8KwueVaBnFYNndsGzKvSsavCsKnhWg57VDJ45BM/q0LO6wbO64FkDetYweOYUPGtCz5oGz5qCZy3oWcvgmUvwrA09axs8awuedaBnHYNnbsGzLvSsa/CsK3jWg571DJ55BM/60LO+wbO+4NkAejYweOYVPBtCz4YGz4aCZyPo2cjgmU/wbAw9Gxs8GwueTaBnE4NnfsGzKfRsavBsKng2g57NDJ4FBM/m0LO5wbO54NkCerYweBYUPFtCz5YGz5aCZyvo2crgWUjwbA09Wxs8WwuebaBnG4NnYcGzLfRsa/BsK3i2g57tDJ5FBM/20LO9wbO94NkBenYweBYVPDtCz44Gz46CZyfo2cngWUzw7Aw9Oxs8OwueXaBnF4NnccGzK/TsavDsKnh2g57dDJ4lBM/u0LO7wbO74NkDevYweJYUPHtCz54Gz56CZy/o2cvgWUrw7A09exs8ewuefaBnH4NnacGzL/Tsa/DsK3j2g579DJ5lBM/+0LO/wbO/4DkAeg4weJYVPAdCz4EGz4GC5yDoOcjgWU7wHAw9Bxs8BwueQ6DnEINnIHgOhZ5DDZ5DBc9h0HOYwbO84Dkceg43eA4XPEdAzxEGzwqC50joOdLgOVLwHAU9Rxk8Kwqeo6HnaIPnaMFzDPQcY/CsJHiOhZ5jDZ5jBc9x0HOcwbOy4Dkeeo43eI4XPCdAzwkGzyqC50ToOdHgOVHwnAQ9Jxk8qwqek6HnZIPnZMFzCvScYvCsJnhOhZ5TDZ5TBc9p0HOawbO64Dkdek43eE4XPGdAzxkGzxqC50zoOdPgOVPwnAU9Zxk8awqes6HnbIPnbMFzDvScY/CsJXjOhZ5zDZ5zBc950HOewbO24Dkfes43eM4XPBdAzwUGzzqC50LoudDguVDwXAQ9Fxk86wqei6HnYoPnYsFzCfRcYvCsJ3guhZ5LDZ5LBc9l0HOZwbO+4Lkcei43eC4XPFdAzxUGzwaC50roudLguVLwXAU9Vxk8Gwqeq6HnaoPnasFzDfRcY/BsJHiuhZ5rDZ5rBc910HOdwbOx4Lkeeq43eK4XPDdAzw0GzyaC50boudHguVHw3AQ9Nxk8mwqem6HnZoPnZsFzC/TcYvBsJnhuhZ5bDZ5bBc9t0HObwbO54Lkdem43eG4XPHdAzx0GzxaC507oudPguVPw3AU9dxk8Wwqeu6HnboPnbsFzD/TcY/BsJXjuhZ57DZ57Bc990HOfwbO14Lkfeu43eO4XPA9AzwMGzzaC50HoedDgeVDwfB96vm/wbCt4HoKehwyehwTPw9DzsMGzneB5BHoeMXgeETyPQs+jBs/2gucx6HnM4HlM8PwAen5g8OwgeB6HnscNnscFzw+h54cGz46C5wnoecLgeULw/Ah6fmTw7CR4noSeJw2eJwXPj6HnxwbPzoLnKeh5yuB5SvD8BHp+YvDsIniehp6nDZ6nBc9PoeenBs+ugucZ6HnG4HlG8PwMen5m8OwmeJ6FnmcNnmcFz8+h5+cGz+6C5znoec7geU7w/AJ6fmHw7CF4noee5w2e5wXPL6HnlwbPnoLnBeh5weB5QfD8Cnp+ZfDsJXhehJ4XDZ4XBc+voefXBs/egucl6HnJ4HlJ8PwGen5j8OwjeF6GnpcNnpcFz2+h57cGz76C5xXoecXgeUXw/A56fmfw7Cd4XoWeVw2eVwXP76Hn9wbP/oLnNeh5zeB5TfD8AXr+YPAcIHheh57XDZ7XBc8foeePBs+BgucN6HnD4HlD8PwJev5k8BwkeN6EnjcNnjcFz5+h588Gz8GC5y3oecvgeUvw/AV6/mLwHCJ43oaetw2etwXPX6HnrwbPoYLnHeh5x+B5R/D8DXr+ZvAcJnjehZ53DZ53Bc970POewXO44Hkfet43eN4XPH+Hnr8bPEcIng+g5wOD5wPB8w/o+YfBc6Tg+RB6PjR4PhQ8/4Sefxo8Rwmej6DnI4PnI8HzMfR8bPAcLXg+gZ5PDJ5PBM+/oOdfBs8xgudT6PnU4PlU8Pwbev5t8BwreD6Dns8Mns8Ez3+g5z8Gz3GC53Po+dzg+Vzw/Bd6/mvwHC94voCeLwyeLwTPl9DzpcFzguD5Cnq+Mni+EjxfQ8/XBs+Jgucb6PnG4PlG8HwLPd8aPCcJnu+g5zuD5zvB872qzPO/70L1nCx4RqjKPCNUDd0z7O3wthGhZ0SD5xTBMxL0jGTwjCR4RoaekQ2eUwXPKNAzisEziuAZFXpGNXhOEzyjQc9oBs9ogmd06Bnd4Dld8IwBPWMYPGMInjGhZ0yD5wzBMxb0jGXwjCV4xoaesQ2eMwXPONAzjsEzjuAZF3rGNXjOEjzjQc94Bs94gmd86Bnf4Dlb8EwAPRMYPBMIngmhZ0KD5xzBMxH0TGTwTCR4JoaeiQ2ecwXPJNAzicEzieCZFHomNXjOEzyTQc9kBs9kgmdy6Jnc4Dlf8EwBPVMYPFMInimhZ0qD5wLBMxX0TGXwTCV4poaeqQ2eCwXPNNAzjcEzjeCZFnqmNXguEjzTQc90Bs90gmd66Jne4LlY8MwAPTMYPDMInhmhZ0aD5xLBMxP0zGTwzCR4ZoaemQ2eSwXPLNAzi8Ezi+CZFXpmNXguEzyzQc9sBs9sgmd26Jnd4Llc8MwBPXMYPHMInjmhZ06D5wrBMxf0zGXwzCV45oaeuQ2eKwXPPNAzj8Ezj+CZF3rmNXiuEjzzQc98Bs98gmd+6Jnf4Lla8CwAPQsYPAsIngWhZ0GD5xrBsxD0LGTwLCR4FoaehQ2eawXPItCziMGziOBZFHoWNXiuEzyLQc9iBs9igmdx6Fnc4Lle8CwBPUsYPEsIniWhZ0mD5wbBsxT0LGXwLCV4loaepQ2eGwXPMtCzjMGzjOBZFnqWNXhuEjzLQc9yBs9ygmcAPQOD52bBszz0LG/wLC94VoCeFQyeWwTPitCzosGzouBZCXpWMnhuFTwrQ8/KBs/KgmcV6FnF4LlN8KwKPasaPKsKntWgZzWD53bBszr0rG7wrC541oCeNQyeOwTPmtCzpsGzpuBZC3rWMnjuFDxrQ8/aBs/agmcd6FnH4LlL8KwLPesaPOsKnvWgZz2D527Bsz70rG/wrC94NoCeDQyeewTPhtCzocGzoeDZCHo2MnjuFTwbQ8/GBs/GgmcT6NnE4LlP8GwKPZsaPJsKns2gZzOD537Bszn0bG7wbC54toCeLQyeBwTPltCzpcGzpeDZCnq2MngeFDxbQ8/WBs/Wgmcb6NnG4Pm+4NkWerY1eLYVPNtBz3YGz0OCZ3vo2d7g2V7w7AA9Oxg8DwueHaFnR4NnR8GzE/TsZPA8Inh2hp6dDZ6dBc8u0LOLwfOo4NkVenY1eHYVPLtBz24Gz2OCZ3fo2d3g2V3w7AE9exg8PxA8e0LPngbPnoJnL+jZy+B5XPDsDT17Gzx7C559oGcfg+eHgmdf6NnX4NlX8OwHPfsZPE8Inv2hZ3+DZ3/BcwD0HGDw/EjwHAg9Bxo8Bwqeg6DnIIPnScFzMPQcbPAcLHgOgZ5DDJ4fC55DoedQg+dQwXMY9Bxm8DwleA6HnsMNnsMFzxHQc4TB8xPBcyT0HGnwHCl4joKeowyepwXP0dBztMFztOA5BnqOMXh+KniOhZ5jDZ5jBc9x0HOcwfOM4Dkeeo43eI4XPCdAzwkGz88Ez4nQc6LBc6LgOQl6TjJ4nhU8J0PPyQbPyYLnFOg5xeD5ueA5FXpONXhOFTynQc9pBs9zgud06Dnd4Dld8JwBPWcYPL8QPGdCz5kGz5mC5yzoOcvgeV7wnA09Zxs8Zwuec6DnHIPnl4LnXOg51+A5V/CcBz3nGTwvCJ7zoed8g+d8wXMB9Fxg8PxK8FwIPRcaPBcKnoug5yKD50XBczH0XGzwXCx4LoGeSwyeXwueS6HnUoPnUsFzGfRcZvC8JHguh57LDZ7LBc8V0HOFwfMbwXMl9Fxp8FwpeK6CnqsMnpcFz9XQc7XBc7XguQZ6rjF4fit4roWeaw2eawXPddBzncHziuC5HnquN3iuFzw3QM8NBs/vBM+N0HOjwXOj4LkJem4yeF4VPDdDz80Gz82C5xboucXg+b3guRV6bjV4bhU8t0HPbQbPa4Lndui53eC5XfDcAT13GDx/EDx3Qs+dBs+dgucu6LnL4Hld8NwNPXcbPHcLnnug5x6D54+C517oudfguVfw3Ac99xk8bwie+6HnfoPnfsHzAPQ8YPD8SfA8CD0PGjwPCp7vQ8/3DZ43Bc9D0POQwfOQ4HkYeh42eP4seB6BnkcMnkcEz6PQ86jB85bgeQx6HjN4HhM8P4CeHxg8fxE8j0PP4wbP44Lnh9DzQ4PnbcHzBPQ8YfA8IXh+BD0/Mnj+KniehJ4nDZ4nBc+PoefHBs87gucp6HnK4HlK8PwEen5i8PxN8DwNPU8bPE8Lnp9Cz08NnncFzzPQ84zB84zg+Rn0/MzgeU/wPAs9zxo8zwqen0PPzw2e9wXPc9DznMHznOD5BfT8wuD5u+B5HnqeN3ieFzy/hJ5fGjwfCJ4XoOcFg+cFwfMr6PmVwfMPwfMi9Lxo8LwoeH4NPb82eD4UPC9Bz0sGz0uC5zfQ8xuD55+C52XoedngeVnw/BZ6fmvwfCR4XoGeVwyeVwTP76DndwbPx4LnVeh51eB5VfD8Hnp+b/B8Inheg57XDJ7XBM8foOcPBs+/BM/r0PO6wfO64Pkj9PzR4PlU8LwBPW8YPG8Inj9Bz58Mnn8Lnjeh502D503B82fo+bPB85ngeQt63jJ43hI8f4Gevxg8/xE8b0PP2wbP24Lnr9DzV4Pnc8HzDvS8Y/C8I3j+Bj1/M3j+K3jehZ53DZ53Bc970POewfOF4Hkfet43eN4XPH+Hnr8bPF8Kng+g5wOD5wPB8w/o+YfB85Xg+RB6PjR4PhQ8/4Sefxo8Xwuej6DnI4PnI8HzMfR8bPB8I3g+gZ5PDJ5PBM+/oOdfBs+3gudT6PnU4PlU8Pwbev5t8HwneD6Dns8Mns8Ez3+g5z8Gz/+G6f/Hdz6Hns8Nns8Fz3+h578GzwhC04v/7Z3R3r3r917Yd/73XeZw3qncDm/78n97Z7x3b3/+/7zz5f/wznB+ESIKTa+g5yuD5yvB8zX0fG3wjCQ0vYGebwyebwTPt9DzrcEzstD0Dnq+M3i+Ezzfq8Y8//suVM8oQlOEaswzQrXQPcPeDm8bEXpGNHhGFZoiQc9IBs9Igmdk6BnZ4BlNaIoCPaMYPKMInlGhZ1SDZ3ShKRr0jGbwjCZ4Roee0Q2eMYSmGNAzhsEzhuAZE3rGNHjGFJpiQc9YBs9Ygmds6Bnb4BlLaIoDPeMYPOMInnGhZ1yDZ2yhKR70jGfwjCd4xoee8Q2ecYSmBNAzgcEzgeCZEHomNHjGFZoSQc9EBs9Egmdi6JnY4BlPaEoCPZMYPJMInkmhZ1KDZ3yhKRn0TGbwTCZ4JoeeyQ2eCYSmFNAzhcEzheCZEnqmNHgmFJpSQc9UBs9Ugmdq6Jna4JlIaEoDPdMYPNMInmmhZ1qDZ2KhKR30TGfwTCd4poee6Q2eSYSmDNAzg8Ezg+CZEXpmNHgmFZoyQc9MBs9Mgmdm6JnZ4JlMaMoCPbMYPLMInlmhZ1aDZ3KhKRv0zGbwzCZ4Zoee2Q2eKYSmHNAzh8Ezh+CZE3rmNHimFJpyQc9cBs9cgmdu6Jnb4JlKaMoDPfMYPPMInnmhZ16DZ2qhKR/0zGfwzCd45oee+Q2eaYSmAtCzgMGzgOBZEHoWNHimFZoKQc9CBs9Cgmdh6FnY4JlOaCoCPYsYPIsInkWhZ1GDZ3qhqRj0LGbwLCZ4FoeexQ2eGYSmEtCzhMGzhOBZEnqWNHhmFJpKQc9SBs9Sgmdp6Fna4JlJaCoDPcsYPMsInmWhZ1mDZ2ahqRz0LGfwLCd4BtAzMHhmEZrKQ8/yBs/ygmcF6FnB4JlVaKoIPSsaPCsKnpWgZyWDZzahqTL0rGzwrCx4VoGeVQye2YWmqtCzqsGzquBZDXpWM3jmEJqqQ8/qBs/qgmcN6FnD4JlTaKoJPWsaPGsKnrWgZy2DZy6hqTb0rG3wrC141oGedQyeuYWmutCzrsGzruBZD3rWM3jmEZrqQ8/6Bs/6gmcD6NnA4JlXaGoIPRsaPBsKno2gZyODZz6hqTH0bGzwbCx4NoGeTQye+YWmptCzqcGzqeDZDHo2M3gWEJqaQ8/mBs/mgmcL6NnC4FlQaGoJPVsaPFsKnq2gZyuDZyGhqTX0bG3wbC14toGebQyehYWmttCzrcGzreDZDnq2M3gWEZraQ8/2Bs/2gmcH6NnB4FlUaOoIPTsaPDsKnp2gZyeDZzGhqTP07Gzw7Cx4doGeXQyexYWmrtCzq8Gzq+DZDXp2M3iWEJq6Q8/uBs/ugmcP6NnD4FlSaOoJPXsaPHsKnr2gZy+DZymhqTf07G3w7C149oGefQyepYWmvtCzr8Gzr+DZD3r2M3iWEZr6Q8/+Bs/+gucA6DnA4FlWaBoIPQcaPAcKnoOg5yCDZzmhaTD0HGzwHCx4DoGeQwyegdA0FHoONXgOFTyHQc9hBs/yQtNw6Dnc4Dlc8BwBPUcYPCsITSOh50iD50jBcxT0HGXwrCg0jYaeow2eowXPMdBzjMGzktA0FnqONXiOFTzHQc9xBs/KQtN46Dne4Dle8JwAPScYPKsITROh50SD50TBcxL0nGTwrCo0TYaekw2ekwXPKdBzisGzmtA0FXpONXhOFTynQc9pBs/qQtN06Dnd4Dld8JwBPWcYPGsITTOh50yD50zBcxb0nGXwrCk0zYaesw2eswXPOdBzjsGzltA0F3rONXjOFTznQc95Bs/aQtN86Dnf4Dlf8FwAPRcYPOsITQuh50KD50LBcxH0XGTwrCs0LYaeiw2eiwXPJdBzicGzntC0FHouNXguFTyXQc9lBs/6QtNy6Lnc4Llc8FwBPVcYPBsITSuh50qD50rBcxX0XGXwbCg0rYaeqw2eqwXPNdBzjcGzkdC0FnquNXiuFTzXQc91Bs/GQtN66Lne4Lle8NwAPTcYPJsITRuh50aD50bBcxP03GTwbCo0bYaemw2emwXPLdBzi8GzmdC0FXpuNXhuFTy3Qc9tBs/mQtN26Lnd4Lld8NwBPXcYPFsITTuh506D507Bcxf03GXwbCk07Yaeuw2euwXPPdBzj8GzldC0F3ruNXjuFTz3Qc99Bs/WQtN+6Lnf4Llf8DwAPQ8YPNsITQeh50GD50HB833o+b7Bs63QdAh6HjJ4HhI8D0PPwwbPdkLTEeh5xOB5RPA8Cj2PGjzbC03HoOcxg+cxwfMD6PmBwbOD0HQceh43eB4XPD+Enh8aPDsKTSeg5wmD5wnB8yPo+ZHBs5PQdBJ6njR4nhQ8P4aeHxs8OwtNp6DnKYPnKcHzE+j5icGzi9B0GnqeNnieFjw/hZ6fGjy7Ck1noOcZg+cZwfMz6PmZwbOb0HQWep41eJ4VPD+Hnp8bPLsLTeeg5zmD5znB8wvo+YXBs4fQdB56njd4nhc8v4SeXxo8ewpNF6DnBYPnBcHzK+j5lcGzl9B0EXpeNHheFDy/hp5fGzx7C02XoOclg+clwfMb6PmNwbOP0HQZel42eF4WPL+Fnt8aPPsKTVeg5xWD5xXB8zvo+Z3Bs5/QdBV6XjV4XhU8v4ee3xs8+wtN16DnNYPnNcHzB+j5g8FzgNB0HXpeN3heFzx/hJ4/GjwHCk03oOcNg+cNwfMn6PmTwXOQ0HQTet40eN4UPH+Gnj8bPAcLTbeg5y2D5y3B8xfo+YvBc4jQdBt63jZ43hY8f4Wevxo8hwpNd6DnHYPnHcHzN+j5m8FzmNB0F3reNXjeFTzvQc97Bs/hQtN96Hnf4Hlf8Pwdev5u8BwhND2Ang8Mng8Ezz+g5x8Gz5FC00Po+dDg+VDw/BN6/mnwHCU0PYKejwyejwTPx9DzscFztND0BHo+MXg+ETz/gp5/GTzHCE1PoedTg+dTwfNv6Pm3wXOs0PQMej4zeD4TPP+Bnv8YPMcJTc+h53OD53PB81/o+a/Bc7zQ9AJ6vjB4vhA8X0LPlwbPCULTK+j5yuD5SvB8DT1fGzwnCk1voOcbg+cbwfMt9Hxr8JwkNL2Dnu8Mnu8Ez/eqM8//vgvVc7LQFKE684xQPXTPsLfD20aEnhENnlOEpkjQM5LBM5LgGRl6RjZ4ThWaokDPKAbPKIJnVOgZ1eA5TWiKBj2jGTyjCZ7RoWd0g+d0oSkG9Ixh8IwheMaEnjENnjOEpljQM5bBM5bgGRt6xjZ4zhSa4kDPOAbPOIJnXOgZ1+A5S2iKBz3jGTzjCZ7xoWd8g+dsoSkB9Exg8EwgeCaEngkNnnOEpkTQM5HBM5HgmRh6JjZ4zhWakkDPJAbPJIJnUuiZ1OA5T2hKBj2TGTyTCZ7JoWdyg+d8oSkF9Exh8EwheKaEnikNnguEplTQM5XBM5XgmRp6pjZ4LhSa0kDPNAbPNIJnWuiZ1uC5SGhKBz3TGTzTCZ7poWd6g+dioSkD9Mxg8MwgeGaEnhkNnkuEpkzQM5PBM5PgmRl6ZjZ4LhWaskDPLAbPLIJnVuiZ1eC5TGjKBj2zGTyzCZ7ZoWd2g+dyoSkH9Mxh8MwheOaEnjkNniuEplzQM5fBM5fgmRt65jZ4rhSa8kDPPAbPPIJnXuiZ1+C5SmjKBz3zGTzzCZ75oWd+g+dqoakA9Cxg8CwgeBaEngUNnmuEpkLQs5DBs5DgWRh6FjZ4rhWaikDPIgbPIoJnUehZ1OC5TmgqBj2LGTyLCZ7FoWdxg+d6oakE9Cxh8CwheJaEniUNnhuEplLQs5TBs5TgWRp6ljZ4bhSaykDPMgbPMoJnWehZ1uC5SWgqBz3LGTzLCZ4B9AwMnpuFpvLQs7zBs7zgWQF6VjB4bhGaKkLPigbPioJnJehZyeC5VWiqDD0rGzwrC55VoGcVg+c2oakq9Kxq8KwqeFaDntUMntuFpurQs7rBs7rgWQN61jB47hCaakLPmgbPmoJnLehZy+C5U2iqDT1rGzxrC551oGcdg+cuoaku9Kxr8KwreNaDnvUMnruFpvrQs77Bs77g2QB6NjB47hGaGkLPhgbPhoJnI+jZyOC5V2hqDD0bGzwbC55NoGcTg+c+oakp9Gxq8GwqeDaDns0MnvuFpubQs7nBs7ng2QJ6tjB4HhCaWkLPlgbPloJnK+jZyuB5UGhqDT1bGzxbC55toGcbg+f7QlNb6NnW4NlW8GwHPdsZPA8JTe2hZ3uDZ3vBswP07GDwPCw0dYSeHQ2eHQXPTtCzk8HziNDUGXp2Nnh2Fjy7QM8uBs+jQlNX6NnV4NlV8OwGPbsZPI8JTd2hZ3eDZ3fBswf07GHw/EBo6gk9exo8ewqevaBnL4PncaGpN/TsbfDsLXj2gZ59DJ4fCk19oWdfg2dfwbMf9Oxn8DwhNPWHnv0Nnv0FzwHQc4DB8yOhaSD0HGjwHCh4DoKegwyeJ4WmwdBzsMFzsOA5BHoOMXh+LDQNhZ5DDZ5DBc9h0HOYwfOU0DQceg43eA4XPEdAzxEGz0+EppHQc6TBc6TgOQp6jjJ4nhaaRkPP0QbP0YLnGOg5xuD5qdA0FnqONXiOFTzHQc9xBs8zQtN46Dne4Dle8JwAPScYPD8TmiZCz4kGz4mC5yToOcngeVZomgw9Jxs8JwueU6DnFIPn50LTVOg51eA5VfCcBj2nGTzPCU3Toed0g+d0wXMG9Jxh8PxCaJoJPWcaPGcKnrOg5yyD53mhaTb0nG3wnC14zoGecwyeXwpNc6HnXIPnXMFzHvScZ/C8IDTNh57zDZ7zBc8F0HOBwfMroWkh9Fxo8FwoeC6CnosMnheFpsXQc7HBc7HguQR6LjF4fi00LYWeSw2eSwXPZdBzmcHzktC0HHouN3guFzxXQM8VBs9vhKaV0HOlwXOl4LkKeq4yeF4WmlZDz9UGz9WC5xroucbg+a3QtBZ6rjV4rhU810HPdQbPK0LTeui53uC5XvDcAD03GDy/E5o2Qs+NBs+Ngucm6LnJ4HlVaNoMPTcbPDcLnlug5xaD5/dC01boudXguVXw3AY9txk8rwlN26HndoPndsFzB/TcYfD8QWjaCT13Gjx3Cp67oOcug+d1oWk39Nxt8NwteO6BnnsMnj8KTXuh516D517Bcx/03GfwvCE07Yee+w2e+wXPA9DzgMHzJ6HpIPQ8aPA8KHi+Dz3fN3jeFJoOQc9DBs9Dgudh6HnY4Pmz0HQEeh4xeB4RPI9Cz6MGz1tC0zHoeczgeUzw/AB6fmDw/EVoOg49jxs8jwueH0LPDw2et4WmE9DzhMHzhOD5EfT8yOD5q9B0EnqeNHieFDw/hp4fGzzvCE2noOcpg+cpwfMT6PmJwfM3oek09Dxt8DwteH4KPT81eN4Vms5AzzMGzzOC52fQ8zOD5z2h6Sz0PGvwPCt4fg49Pzd43heazkHPcwbPc4LnF9DzC4Pn70LTeeh53uB5XvD8Enp+afB8IDRdgJ4XDJ4XBM+voOdXBs8/hKaL0POiwfOi4Pk19Pza4PlQaLoEPS8ZPC8Jnt9Az28Mnn8KTZeh52WD52XB81vo+a3B85HQdAV6XjF4XhE8v4Oe3xk8HwtNV6HnVYPnVcHze+j5vcHzidB0DXpeM3heEzx/gJ4/GDz/EpquQ8/rBs/rgueP0PNHg+dToekG9Lxh8LwheP4EPX8yeP4tNN2EnjcNnjcFz5+h588Gz2dC0y3oecvgeUvw/AV6/mLw/Edoug09bxs8bwuev0LPXw2ez4WmO9DzjsHzjuD5G/T8zeD5r9B0F3reNXjeFTzvQc97Bs8XQtN96Hnf4Hlf8Pwdev5u8HwpND2Ang8Mng8Ezz+g5x8Gz1dC00Po+dDg+VDw/BN6/mnwfC00PYKejwyejwTPx9DzscHzjdD0BHo+MXg+ETz/gp5/GTzfCk1PoedTg+dTwfNv6Pm3wfOd0PQMej4zeD4TPP+Bnv8YPP/7h9L/j+98Dj2fGzyfC57/Qs9/DZ4RBM8X0POFwfOF4PkSer40eEYUPF9Bz1cGz1eC52vo+drgGUnwfAM93xg83wieb6HnW4NnZMHzHfR8Z/B8J3i+V4N5/vddqJ5RBM8INZhnhBqhe4a9Hd42IvSMaPCMKnhGgp6RDJ6RBM/I0DOywTOa4BkFekYxeEYRPKNCz6gGz+iCZzToGc3gGU3wjA49oxs8YwieMaBnDINnDMEzJvSMafCMKXjGgp6xDJ6xBM/Y0DO2wTOW4BkHesYxeMYRPONCz7gGz9iCZzzoGc/gGU/wjA894xs84wieCaBnAoNnAsEzIfRMaPCMK3gmgp6JDJ6JBM/E0DOxwTOe4JkEeiYxeCYRPJNCz6QGz/iCZzLomczgmUzwTA49kxs8EwieKaBnCoNnCsEzJfRMafBMKHimgp6pDJ6pBM/U0DO1wTOR4JkGeqYxeKYRPNNCz7QGz8SCZzromc7gmU7wTA890xs8kwieGaBnBoNnBsEzI/TMaPBMKnhmgp6ZDJ6ZBM/M0DOzwTOZ4JkFemYxeGYRPLNCz6wGz+SCZzbomc3gmU3wzA49sxs8UwieOaBnDoNnDsEzJ/TMafBMKXjmgp65DJ65BM/c0DO3wTOV4JkHeuYxeOYRPPNCz7wGz9SCZz7omc/gmU/wzA898xs80wieBaBnAYNnAcGzIPQsaPBMK3gWgp6FDJ6FBM/C0LOwwTOd4FkEehYxeBYRPItCz6IGz/SCZzHoWczgWUzwLA49ixs8MwieJaBnCYNnCcGzJPQsafDMKHiWgp6lDJ6lBM/S0LO0wTOT4FkGepYxeJYRPMtCz7IGz8yCZznoWc7gWU7wDKBnYPDMIniWh57lDZ7lBc8K0LOCwTOr4FkRelY0eFYUPCtBz0oGz2yCZ2XoWdngWVnwrAI9qxg8swueVaFnVYNnVcGzGvSsZvDMIXhWh57VDZ7VBc8a0LOGwTOn4FkTetY0eNYUPGtBz1oGz1yCZ23oWdvgWVvwrAM96xg8cwuedaFnXYNnXcGzHvSsZ/DMI3jWh571DZ71Bc8G0LOBwTOv4NkQejY0eDYUPBtBz0YGz3yCZ2Po2djg2VjwbAI9mxg88wueTaFnU4NnU8GzGfRsZvAsIHg2h57NDZ7NBc8W0LOFwbOg4NkSerY0eLYUPFtBz1YGz0KCZ2vo2drg2VrwbAM92xg8CwuebaFnW4NnW8GzHfRsZ/AsIni2h57tDZ7tBc8O0LODwbOo4NkRenY0eHYUPDtBz04Gz2KCZ2fo2dng2Vnw7AI9uxg8iwueXaFnV4NnV8GzG/TsZvAsIXh2h57dDZ7dBc8e0LOHwbOk4NkTevY0ePYUPHtBz14Gz1KCZ2/o2dvg2Vvw7AM9+xg8SwuefaFnX4NnX8GzH/TsZ/AsI3j2h579DZ79Bc8B0HOAwbOs4DkQeg40eA4UPAdBz0EGz3KC52DoOdjgOVjwHAI9hxg8A8FzKPQcavAcKngOg57DDJ7lBc/h0HO4wXO44DkCeo4weFYQPEdCz5EGz5GC5yjoOcrgWVHwHA09Rxs8RwueY6DnGINnJcFzLPQca/AcK3iOg57jDJ6VBc/x0HO8wXO84DkBek4weFYRPCdCz4kGz4mC5yToOcngWVXwnAw9Jxs8JwueU6DnFINnNcFzKvScavCcKnhOg57TDJ7VBc/p0HO6wXO64DkDes4weNYQPGdCz5kGz5mC5yzoOcvgWVPwnA09Zxs8Zwuec6DnHINnLcFzLvSca/CcK3jOg57zDJ61Bc/50HO+wXO+4LkAei4weNYRPBdCz4UGz4WC5yLoucjgWVfwXAw9Fxs8FwueS6DnEoNnPcFzKfRcavBcKngug57LDJ71Bc/l0HO5wXO54LkCeq4weDYQPFdCz5UGz5WC5yroucrg2VDwXA09Vxs8Vwuea6DnGoNnI8FzLfRca/BcK3iug57rDJ6NBc/10HO9wXO94LkBem4weDYRPDdCz40Gz42C5yboucng2VTw3Aw9Nxs8NwueW6DnFoNnM8FzK/TcavDcKnhug57bDJ7NBc/t0HO7wXO74LkDeu4weLYQPHdCz50Gz52C5y7oucvg2VLw3A09dxs8dwuee6DnHoNnK8FzL/Tca/DcK3jug577DJ6tBc/90HO/wXO/4HkAeh4weLYRPA9Cz4MGz4OC5/vQ832DZ1vB8xD0PGTwPCR4Hoaehw2e7QTPI9DziMHziOB5FHoeNXi2FzyPQc9jBs9jgucH0PMDg2cHwfM49Dxu8DwueH4IPT80eHYUPE9AzxMGzxOC50fQ8yODZyfB8yT0PGnwPCl4fgw9PzZ4dhY8T0HPUwbPU4LnJ9DzE4NnF8HzNPQ8bfA8LXh+Cj0/NXh2FTzPQM8zBs8zgudn0PMzg2c3wfMs9Dxr8DwreH4OPT83eHYXPM9Bz3MGz3OC5xfQ8wuDZw/B8zz0PG/wPC94fgk9vzR49hQ8L0DPCwbPC4LnV9DzK4NnL8HzIvS8aPC8KHh+DT2/Nnj2FjwvQc9LBs9Lguc30PMbg2cfwfMy9Lxs8LwseH4LPb81ePYVPK9AzysGzyuC53fQ8zuDZz/B8yr0vGrwvCp4fg89vzd49hc8r0HPawbPa4LnD9DzB4PnAMHzOvS8bvC8Lnj+CD1/NHgOFDxvQM8bBs8bgudP0PMng+cgwfMm9Lxp8LwpeP4MPX82eA4WPG9Bz1sGz1uC5y/Q8xeD5xDB8zb0vG3wvC14/go9fzV4DhU870DPOwbPO4Lnb9DzN4PnMMHzLvS8a/C8K3jeg573DJ7DBc/70PO+wfO+4Pk79Pzd4DlC8HwAPR8YPB8Inn9Azz8MniMFz4fQ86HB86Hg+Sf0/NPgOUrwfAQ9Hxk8Hwmej6HnY4PnaMHzCfR8YvB8Inj+BT3/MniOETyfQs+nBs+nguff0PNvg+dYwfMZ9Hxm8HwmeP4DPf8xeI4TPJ9Dz+cGz+eC57/Q81+D53jB8wX0fGHwfCF4voSeLw2eEwTPV9DzlcHzleD5Gnq+NnhOFDzfQM83Bs83gudb6PnW4DlJ8HwHPd8ZPN8Jnu/VZJ7/fReq52TBM0JN5hmhZuieYW+Ht40IPSMaPKcInpGgZySDZyTBMzL0jGzwnCp4RoGeUQyeUQTPqNAzqsFzmuAZDXpGM3hGEzyjQ8/oBs/pgmcM6BnD4BlD8IwJPWMaPGcInrGgZyyDZyzBMzb0jG3wnCl4xoGecQyecQTPuNAzrsFzluAZD3rGM3jGEzzjQ8/4Bs/ZgmcC6JnA4JlA8EwIPRMaPOcInomgZyKDZyLBMzH0TGzwnCt4JoGeSQyeSQTPpNAzqcFznuCZDHomM3gmEzyTQ8/kBs/5gmcK6JnC4JlC8EwJPVMaPBcInqmgZyqDZyrBMzX0TG3wXCh4poGeaQyeaQTPtNAzrcFzkeCZDnqmM3imEzzTQ8/0Bs/FgmcG6JnB4JlB8MwIPTMaPJcInpmgZyaDZybBMzP0zGzwXCp4ZoGeWQyeWQTPrNAzq8FzmeCZDXpmM3hmEzyzQ8/sBs/lgmcO6JnD4JlD8MwJPXMaPFcInrmgZy6DZy7BMzf0zG3wXCl45oGeeQyeeQTPvNAzr8FzleCZD3rmM3jmEzzzQ8/8Bs/VgmcB6FnA4FlA8CwIPQsaPNcInoWgZyGDZyHBszD0LGzwXCt4FoGeRQyeRQTPotCzqMFzneBZDHoWM3gWEzyLQ8/iBs/1gmcJ6FnC4FlC8CwJPUsaPDcInqWgZymDZynBszT0LG3w3Ch4loGeZQyeZQTPstCzrMFzk+BZDnqWM3iWEzwD6BkYPDcLnuWhZ3mDZ3nBswL0rGDw3CJ4VoSeFQ2eFQXPStCzksFzq+BZGXpWNnhWFjyrQM8qBs9tgmdV6FnV4FlV8KwGPasZPLcLntWhZ3WDZ3XBswb0rGHw3CF41oSeNQ2eNQXPWtCzlsFzp+BZG3rWNnjWFjzrQM86Bs9dgmdd6FnX4FlX8KwHPesZPHcLnvWhZ32DZ33BswH0bGDw3CN4NoSeDQ2eDQXPRtCzkcFzr+DZGHo2Nng2FjybQM8mBs99gmdT6NnU4NlU8GwGPZsZPPcLns2hZ3ODZ3PBswX0bGHwPCB4toSeLQ2eLQXPVtCzlcHzoODZGnq2Nni2FjzbQM82Bs/3Bc+20LOtwbOt4NkOerYzeB4SPNtDz/YGz/aCZwfo2cHgeVjw7Ag9Oxo8OwqenaBnJ4PnEcGzM/TsbPDsLHh2gZ5dDJ5HBc+u0LOrwbOr4NkNenYzeB4TPLtDz+4Gz+6CZw/o2cPg+YHg2RN69jR49hQ8e0HPXgbP44Jnb+jZ2+DZW/DsAz37GDw/FDz7Qs++Bs++gmc/6NnP4HlC8OwPPfsbPPsLngOg5wCD50eC50DoOdDgOVDwHAQ9Bxk8Twqeg6HnYIPnYMFzCPQcYvD8WPAcCj2HGjyHCp7DoOcwg+cpwXM49Bxu8BwueI6AniMMnp8IniOh50iD50jBcxT0HGXwPC14joaeow2eowXPMdBzjMHzU8FzLPQca/AcK3iOg57jDJ5nBM/x0HO8wXO84DkBek4weH4meE6EnhMNnhMFz0nQc5LB86zgORl6TjZ4ThY8p0DPKQbPzwXPqdBzqsFzquA5DXpOM3ieEzynQ8/pBs/pgucM6DnD4PmF4DkTes40eM4UPGdBz1kGz/OC52zoOdvgOVvwnAM95xg8vxQ850LPuQbPuYLnPOg5z+B5QfCcDz3nGzznC54LoOcCg+dXgudC6LnQ4LlQ8FwEPRcZPC8Knouh52KD52LBcwn0XGLw/FrwXAo9lxo8lwqey6DnMoPnJcFzOfRcbvBcLniugJ4rDJ7fCJ4roedKg+dKwXMV9Fxl8LwseK6GnqsNnqsFzzXQc43B81vBcy30XGvwXCt4roOe6wyeVwTP9dBzvcFzveC5AXpuMHh+J3huhJ4bDZ4bBc9N0HOTwfOq4LkZem42eG4WPLdAzy0Gz+8Fz63Qc6vBc6vguQ16bjN4XhM8t0PP7QbP7YLnDui5w+D5g+C5E3ruNHjuFDx3Qc9dBs/rgudu6Lnb4Llb8NwDPfcYPH8UPPdCz70Gz72C5z7ouc/geUPw3A899xs89wueB6Dngf+LFboKo4LqtjAs3d296e7u7u7u7u7u7i4REREREenubhERke7urvN4958r9/gc63rONb/nNXheFjzXQc91Bs91gud66Lne4HlF8NwAPTcYPDcInhuh50aD51XBcxP03GTw3CR4boaemw2e1wTPLdBzi8Fzi+C5FXpuNXheFzy3Qc9tBs9tgud26Lnd4HlD8NwBPXcYPHcInjuh506D503Bcxf03GXw3CV47oaeuw2etwTPPdBzj8Fzj+C5F3ruNXjeFjz3Qc99Bs99gud+6Lnf4HlH8DwAPQ8YPA8Ingeh50GD513B8xD0PGTwPCR4Hoaehw2e9wTPI9DziMHziOB5FHoeNXjeFzyPQc9jBs9jgudx6Hnc4PlA8DwBPU8YPE8Inieh50mD50PB8xT0PGXwPCV4noaepw2ejwTPM9DzjMHzjOD5G/T8zeD5WPA8Cz3PGjzPCp6/Q8/fDZ5PBM9z0POcwfOc4PkH9PzD4PlU8DwPPc8bPM8Lnn9Czz8Nns8EzwvQ84LB84Lg+Rf0/Mvg+VzwvAg9Lxo8Lwqef0PPvw2eLwTPS9DzksHzkuB5GXpeNni+FDyvQM8rBs8rgudV6HnV4PlK8LwGPa8ZPK8Jnteh53WD52vB8wb0vGHwvCF43oSeNw2ebwTPW9DzlsHzluB5G3reNni+FTzvQM87Bs87gudd6HnX4PlO8LwHPe8ZPO8Jnveh532D53vB8wH0fGDwfCB4PoSeDw2eHwTPR9DzkcHzkeD5GHo+Nnh+FDyfQM8nBs8ngudT6PnU4PlJ8HwGPZ8ZPJ8Jns+h53OD52fB8wX0fGHwfCF4voSeLw2eXwTPV9DzlcHzleD5Gnq+Nnj+sxAIsvMN9Hxj8HwjeL6Fnm8NniFCB9/5Dnq+M3i+EzzfQ8/3Bs+QgucH6PnB4PlB8PwIPT8aPEMJnp+g5yeD5yfB8zP0/GzwDC14foGeXwyeXwTPryoxz3/2/qtnGMEzRCXmGaLSf/f839v/NhsSeoY0eIYVPENBz1AGz1CCZ2joGdrgGU7wDAM9wxg8wwieYaFnWINneMEzHPQMZ/AMJ3iGh57hDZ4RBM8I0DOCwTOC4BkRekY0eEYUPCNBz0gGz0iCZ2ToGdngGUnwjAI9oxg8owieUaFnVINnZMEzGvSMZvCMJnhGh57RDZ5RBM8Y0DOGwTOG4BkTesY0eEYVPGNBz1gGz1iCZ2zoGdvgGU3wjAM94xg84wiecaFnXINndMEzHvSMZ/CMJ3jGh57xDZ4xBM8E0DOBwTOB4JkQeiY0eMYUPBNBz0QGz0SCZ2LomdjgGUvwTAI9kxg8kwieSaFnUoNnbMEzGfRMZvBMJngGoGfA4BlH8EwOPZMbPJMLnimgZwqDZ1zBMyX0TGnwTCl4poKeqQye8QTP1NAztcEzteCZBnqmMXjGFzzTQs+0Bs+0gmc66JnO4JlA8EwPPdMbPNMLnhmgZwaDZ0LBMyP0zGjwzCh4ZoKemQyeiQTPzNAzs8Ezs+CZBXpmMXgmFjyzQs+sBs+sgmc26JnN4JlE8MwOPbMbPLMLnjmgZw6DZ1LBMyf0zGnwzCl45oKeuQyeyQTP3NAzt8Ezt+CZB3rmMXgGBM+80DOvwTOv4JkPeuYzeCYXPPNDz/wGz/yCZwHoWcDgmULwLAg9Cxo8CwqehaBnIYNnSsGzMPQsbPAsLHgWgZ5FDJ6pBM+i0LOowbOo4FkMehYzeKYWPItDz+IGz+KCZwnoWcLgmUbwLAk9Sxo8SwqepaBnKYNnWsGzNPQsbfAsLXiWgZ5lDJ7pBM+y0LOswbOs4FkOepYzeKYXPMtDz/IGz/KCZwXoWcHgmUHwrAg9Kxo8KwqelaBnJYNnRsGzMvSsbPCsLHhWgZ5VDJ6ZBM+q0LOqwbOq4FkNelYzeGYWPKtDz+oGz+qCZw3oWcPgmUXwrAk9axo8awqetaBnLYNnVsGzNvSsbfCsLXjWgZ51DJ7ZBM+60LOuwbOu4FkPetYzeGYXPOtDz/oGz/qCZwPo2cDgmUPwbAg9Gxo8GwqejaBnI4NnTsGzMfRsbPBsLHg2gZ5NDJ65BM+m0LOpwbOp4NkMejYzeOYWPJtDz+YGz+aCZwvo2cLgmUfwbAk9Wxo8WwqeraBnK4NnXsGzNfRsbfBsLXi2gZ5tDJ75BM+20LOtwbOt4NkOerYzeOYXPNtDz/YGz/aCZwfo2cHgWUDw7Ag9Oxo8OwqenaBnJ4NnQcGzM/TsbPDsLHh2gZ5dDJ6FBM+u0LOrwbOr4NkNenYzeBYWPLtDz+4Gz+6CZw/o2cPgWUTw7Ak9exo8ewqevaBnL4NnUcGzN/TsbfDsLXj2gZ59DJ7FBM++0LOvwbOv4NkPevYzeBYXPPtDz/4Gz/6C5wDoOcDgWULwHAg9Bxo8Bwqeg6DnIINnScFzMPQcbPAcLHgOgZ5DDJ6lBM+h0HOowXOo4DkMeg4zeJYWPIdDz+EGz+GC5wjoOcLgWUbwHAk9Rxo8Rwqeo6DnKINnWcFzNPQcbfAcLXiOgZ5jDJ7lBM+x0HOswXOs4DkOeo4zeJYXPMdDz/EGz/GC5wToOcHgWUHwnAg9Jxo8Jwqek6DnJINnRcFzMvScbPCcLHhOgZ5TDJ6VBM+p0HOqwXOq4DkNek4zeFYWPKdDz+kGz+mC5wzoOcPgWUXwnAk9Zxo8Zwqes6DnLINnVcFzNvScbfCcLXjOgZ5zDJ7VBM+50HOuwXOu4DkPes4zeFYXPOdDz/kGz/mC5wLoucDgWUPwXAg9Fxo8Fwqei6DnIoNnTcFzMfRcbPBcLHh+DT2/NnjWEjyXQM8lBs8lguc30PMbg2dtwXMp9Fxq8FwqeH4LPb81eNYRPJdBz2UGz2WC53fQ8zuDZ13Bczn0XG7wXC54fg89vzd41hM8V0DPFQbPFYLnD9DzB4NnfcFzJfRcafBcKXj+CD1/NHg2EDxXQc9VBs9VgudP0PMng2dDwXM19Fxt8FwteP4MPX82eDYSPNdAzzUGzzWC5y/Q8xeDZ2PBcy30XGvwXCt4/go9fzV4NhE810HPdQbPdYLneui53uDZVPDcAD03GDw3CJ4boedGg2czwXMT9Nxk8NwkeG6GnpsNns0Fzy3Qc4vBc4vguRV6bjV4thA8t0HPbQbPbYLndui53eDZUvDcAT13GDx3CJ47oedOg2crwXMX9Nxl8NwleO6GnrsNnq0Fzz3Qc4/Bc4/guRd67jV4thE890HPfQbPfYLnfui53+DZVvA8AD0PGDwPCJ4HoedBg2c7wfMQ9Dxk8DwkeB6GnocNnu0FzyPQ84jB84jgeRR6HjV4dhA8j0HPYwbPY4Lnceh53ODZUfA8AT1PGDxPCJ4noedJg2cnwfMU9Dxl8DwleJ6GnqcNnp0FzzPQ84zB84zg+Rv0/M3g2UXwPAs9zxo8zwqev0PP3w2eXQXPc9DznMHznOD5B/T8w+DZTfA8Dz3PGzzPC55/Qs8/DZ7dBc8L0POCwfOC4PkX9PzL4NlD8LwIPS8aPC8Knn9Dz78Nnj0Fz0vQ85LB85LgeRl6XjZ49hI8r0DPKwbPK4LnVeh51eDZW/C8Bj2vGTyvCZ7Xoed1g2cfwfMG9Lxh8LwheN6EnjcNnn0Fz1vQ85bB85bgeRt63jZ49hM870DPOwbPO4LnXeh51+DZX/C8Bz3vGTzvCZ73oed9g+cAwfMB9Hxg8HwgeD6Eng8NngMFz0fQ85HB85Hg+Rh6PjZ4DhI8n0DPJwbPJ4LnU+j51OA5WPB8Bj2fGTyfCZ7Poedzg+cQwfMF9Hxh8HwheL6Eni8NnkMFz1fQ85XB85Xg+Rp6vjZ4DhM830DPNwbPN4LnW+j51uA5XPB8Bz3fGTzfCZ7voed7g+cIwfMD9Pxg8PwgeH6Enh8NniMFz0/Q85PB85Pg+Rl6fjZ4jhI8v0DPLwbPL4LnV5WZ5z97/9VztOAZojLzDFH5v3v+7+1/mw0JPUMaPMcInqGgZyiDZyjBMzT0DG3wHCt4hoGeYQyeYQTPsNAzrMFznOAZDnqGM3iGEzzDQ8/wBs/xgmcE6BnB4BlB8IwIPSMaPCcInpGgZySDZyTBMzL0jGzwnCh4RoGeUQyeUQTPqNAzqsFzkuAZDXpGM3hGEzyjQ8/oBs/JgmcM6BnD4BlD8IwJPWMaPKcInrGgZyyDZyzBMzb0jG3wnCp4xoGecQyecQTPuNAzrsFzmuAZD3rGM3jGEzzjQ8/4Bs/pgmcC6JnA4JlA8EwIPRMaPGcInomgZyKDZyLBMzH0TGzwnCl4JoGeSQyeSQTPpNAzqcFzluCZDHomM3gmEzwD0DNg8JwteCaHnskNnskFzxTQM4XBc47gmRJ6pjR4phQ8U0HPVAbPuYJnauiZ2uCZWvBMAz3TGDznCZ5poWdag2dawTMd9Exn8JwveKaHnukNnukFzwzQM4PBc4HgmRF6ZjR4ZhQ8M0HPTAbPhYJnZuiZ2eCZWfDMAj2zGDwXCZ5ZoWdWg2dWwTMb9Mxm8FwseGaHntkNntkFzxzQM4fB82vBMyf0zGnwzCl45oKeuQyeSwTP3NAzt8Ezt+CZB3rmMXh+I3jmhZ55DZ55Bc980DOfwXOp4JkfeuY3eOYXPAtAzwIGz28Fz4LQs6DBs6DgWQh6FjJ4LhM8C0PPwgbPwoJnEehZxOD5neBZFHoWNXgWFTyLQc9iBs/lgmdx6Fnc4Flc8CwBPUsYPL8XPEtCz5IGz5KCZynoWcrguULwLA09Sxs8SwueZaBnGYPnD4JnWehZ1uBZVvAsBz3LGTxXCp7loWd5g2d5wbMC9Kxg8PxR8KwIPSsaPCsKnpWgZyWD5yrBszL0rGzwrCx4VoGeVQyePwmeVaFnVYNnVcGzGvSsZvBcLXhWh57VDZ7VBc8a0LOGwfNnwbMm9Kxp8KwpeNaCnrUMnmsEz9rQs7bBs7bgWQd61jF4/iJ41oWedQ2edQXPetCznsFzreBZH3rWN3jWFzwbQM8GBs9fBc+G0LOhwbOh4NkIejYyeK4TPBtDz8YGz8aCZxPo2cTguV7wbAo9mxo8mwqezaBnM4PnBsGzOfRsbvBsLni2gJ4tDJ4bBc+W0LOlwbOl4NkKerYyeG4SPFtDz9YGz9aCZxvo2cbguVnwbAs92xo82wqe7aBnO4PnFsGzPfRsb/BsL3h2gJ4dDJ5bBc+O0LOjwbOj4NkJenYyeG4TPDtDz84Gz86CZxfo2cXguV3w7Ao9uxo8uwqe3aBnN4PnDsGzO/TsbvDsLnj2gJ49DJ47Bc+e0LOnwbOn4NkLevYyeO4SPHtDz94Gz96CZx/o2cfguVvw7As9+xo8+wqe/aBnP4PnHsGzP/Tsb/DsL3gOgJ4DDJ57Bc+B0HOgwXOg4DkIeg4yeO4TPAdDz8EGz8GC5xDoOcTguV/wHAo9hxo8hwqew6DnMIPnAcFzOPQcbvAcLniOgJ4jDJ4HBc+R0HOkwXOk4DkKeo4yeB4SPEdDz9EGz9GC5xjoOcbgeVjwHAs9xxo8xwqe46DnOIPnEcFzPPQcb/AcL3hOgJ4TDJ5HBc+J0HOiwXOi4DkJek4yeB4TPCdDz8kGz8mC5xToOcXgeVzwnAo9pxo8pwqe06DnNIPnCcFzOvScbvCcLnjOgJ4zDJ4nBc+Z0HOmwXOm4DkLes4yeJ4SPGdDz9kGz9mC5xzoOcfgeVrwnAs95xo85wqe86DnPIPnGcFzPvScb/CcL3gugJ4LDJ6/CZ4LoedCg+dCwXMR9Fxk8DwreC6GnosNnosFz6+h59cGz98FzyXQc4nBc4ng+Q30/MbgeU7wXAo9lxo8lwqe30LPbw2efwiey6DnMoPnMsHzO+j5ncHzvOC5HHouN3guFzy/h57fGzz/FDxXQM8VBs8VgucP0PMHg+cFwXMl9Fxp8FwpeP4IPX80eP4leK6CnqsMnqsEz5+g508Gz4uC52roudrguVrw/Bl6/mzw/FvwXAM91xg81wiev0DPXwyelwTPtdBzrcFzreD5K/T81eB5WfBcBz3XGTzXCZ7roed6g+cVwXMD9Nxg8NwgeG6EnhsNnlcFz03Qc5PBc5PguRl6bjZ4XhM8t0DPLQbPLYLnVui51eB5XfDcBj23GTy3CZ7boed2g+cNwXMH9Nxh8NwheO6EnjsNnjcFz13Qc5fBc5fguRt67jZ43hI890DPPQbPPYLnXui51+B5W/DcBz33GTz3CZ77oed+g+cdwfMA9Dxg8DwgeB6EngcNnncFz0PQ85DB85DgeRh6HjZ43hM8j0DPIwbPI4LnUeh51OB5X/A8Bj2PGTyPCZ7Hoedxg+cDwfME9Dxh8DwheJ6EnicNng8Fz1PQ85TB85TgeRp6njZ4PhI8z0DPMwbPM4Lnb9DzN4PnY8HzLPQ8a/A8K3j+Dj1/N3g+ETzPQc9zBs9zgucf0PMPg+dTwfM89Dxv8DwveP4JPf80eD4TPC9AzwsGzwuC51/Q8y+D53PB8yL0vGjwvCh4/g09/zZ4vhA8L0HPSwbPS4LnZeh52eD5UvC8Aj2vGDyvCJ5XoedVg+crwfMa9Lxm8LwmeF6HntcNnq8FzxvQ84bB84bgeRN63jR4vhE8b0HPWwbPW4Lnbeh52+D5VvC8Az3vGDzvCJ53oeddg+c7wfMe9Lxn8LwneN6HnvcNnu8FzwfQ84HB84Hg+RB6PjR4fhA8H0HPRwbPR4LnY+j52OD5UfB8Aj2fGDyfCJ5PoedTg+cnwfMZ9Hxm8HwmeD6Hns8Nnp8FzxfQ84XB84Xg+RJ6vjR4fhE8X0HPVwbPV4Lna+j52uD5VZjgO99AzzcGzzeC51vo+dbgGULwfAc93xk83wme76Hne4NnSMHzA/T8YPD8IHh+hJ4fDZ6hBM9P0POTwfOT4PkZen42eIYWPL9Azy8Gzy+C51dVmOc/e//VM4zgGaIK8wxR5b97/u/tf5sNCT1DGjzDCp6hoGcog2cowTM09Axt8AwneIaBnmEMnmEEz7DQM6zBM7zgGQ56hjN4hhM8w0PP8AbPCIJnBOgZweAZQfCMCD0jGjwjCp6RoGckg2ckwTMy9Ixs8IwkeEaBnlEMnlEEz6jQM6rBM7LgGQ16RjN4RhM8o0PP6AbPKIJnDOgZw+AZQ/CMCT1jGjyjCp6xoGcsg2cswTM29Ixt8IwmeMaBnnEMnnEEz7jQM67BM7rgGQ96xjN4xhM840PP+AbPGIJnAuiZwOCZQPBMCD0TGjxjCp6JoGcig2ciwTMx9Exs8IwleCaBnkkMnkkEz6TQM6nBM7bgmQx6JjN4JhM8A9AzYPCMI3gmh57JDZ7JBc8U0DOFwTOu4JkSeqY0eKYUPFNBz1QGz3iCZ2romdrgmVrwTAM90xg84wueaaFnWoNnWsEzHfRMZ/BMIHimh57pDZ7pBc8M0DODwTOh4JkRemY0eGYUPDNBz0wGz0SCZ2bomdngmVnwzAI9sxg8EwueWaFnVoNnVsEzG/TMZvBMInhmh57ZDZ7ZBc8c0DOHwTOp4JkTeuY0eOYUPHNBz1wGz2SCZ27omdvgmVvwzAM98xg8A4JnXuiZ1+CZV/DMBz3zGTyTC575oWd+g2d+wbMA9Cxg8EwheBaEngUNngUFz0LQs5DBM6XgWRh6FjZ4FhY8i0DPIgbPVIJnUehZ1OBZVPAsBj2LGTxTC57FoWdxg2dxwbME9Cxh8EwjeJaEniUNniUFz1LQs5TBM63gWRp6ljZ4lhY8y0DPMgbPdIJnWehZ1uBZVvAsBz3LGTzTC57loWd5g2d5wbMC9Kxg8MwgeFaEnhUNnhUFz0rQs5LBM6PgWRl6VjZ4VhY8q0DPKgbPTIJnVehZ1eBZVfCsBj2rGTwzC57VoWd1g2d1wbMG9Kxh8MwieNaEnjUNnjUFz1rQs5bBM6vgWRt61jZ41hY860DPOgbPbIJnXehZ1+BZV/CsBz3rGTyzC571oWd9g2d9wbMB9Gxg8MwheDaEng0Nng0Fz0bQs5HBM6fg2Rh6NjZ4NhY8m0DPJgbPXIJnU+jZ1ODZVPBsBj2bGTxzC57NoWdzg2dzwbMF9Gxh8MwjeLaEni0Nni0Fz1bQs5XBM6/g2Rp6tjZ4thY820DPNgbPfIJnW+jZ1uDZVvBsBz3bGTzzC57toWd7g2d7wbMD9Oxg8CwgeHaEnh0Nnh0Fz07Qs5PBs6Dg2Rl6djZ4dhY8u0DPLgbPQoJnV+jZ1eDZVfDsBj27GTwLC57doWd3g2d3wbMH9Oxh8CwiePaEnj0Nnj0Fz17Qs5fBs6jg2Rt69jZ49hY8+0DPPgbPYoJnX+jZ1+DZV/DsBz37GTyLC579oWd/g2d/wXMA9Bxg8CwheA6EngMNngMFz0HQc5DBs6TgORh6DjZ4DhY8h0DPIQbPUoLnUOg51OA5VPAcBj2HGTxLC57Doedwg+dwwXME9Bxh8CwjeI6EniMNniMFz1HQc5TBs6zgORp6jjZ4jhY8x0DPMQbPcoLnWOg51uA5VvAcBz3HGTzLC57joed4g+d4wXMC9Jxg8KwgeE6EnhMNnhMFz0nQc5LBs6LgORl6TjZ4ThY8p0DPKQbPSoLnVOg51eA5VfCcBj2nGTwrC57Toed0g+d0wXMG9Jxh8KwieM6EnjMNnjMFz1nQc5bBs6rgORt6zjZ4zhY850DPOQbPaoLnXOg51+A5V/CcBz3nGTyrC57zoed8g+d8wXMB9Fxg8KwheC6EngsNngsFz0XQc5HBs6bguRh6LjZ4LhY8v4aeXxs8awmeS6DnEoPnEsHzG+j5jcGztuC5FHouNXguFTy/hZ7fGjzrCJ7LoOcyg+cywfM76PmdwbOu4Lkcei43eC4XPL+Hnt8bPOsJniug5wqD5wrB8wfo+YPBs77guRJ6rjR4rhQ8f4SePxo8Gwieq6DnKoPnKsHzJ+j5k8GzoeC5GnquNniuFjx/hp4/GzwbCZ5roOcag+cawfMX6PmLwbOx4LkWeq41eK4VPH+Fnr8aPJsInuug5zqD5zrBcz30XG/wbCp4boCeGwyeGwTPjdBzo8GzmeC5CXpuMnhuEjw3Q8/NBs/mgucW6LnF4LlF8NwKPbcaPFsIntug5zaD5zbBczv03G7wbCl47oCeOwyeOwTPndBzp8GzleC5C3ruMnjuEjx3Q8/dBs/Wguce6LnH4LlH8NwLPfcaPNsInvug5z6D5z7Bcz/03G/wbCt4HoCeBwyeBwTPg9DzoMGzneB5CHoeMngeEjwPQ8/DBs/2gucR6HnE4HlE8DwKPY8aPDsInseg5zGD5zHB8zj0PG7w7Ch4noCeJwyeJwTPk9DzpMGzk+B5CnqeMnieEjxPQ8/TBs/OgucZ6HnG4HlG8PwNev5m8OwieJ6FnmcNnmcFz9+h5+8Gz66C5znoec7geU7w/AN6/mHw7CZ4noee5w2e5wXPP6HnnwbP7oLnBeh5weB5QfD8C3r+ZfDsIXhehJ4XDZ4XBc+/oeffBs+egucl6HnJ4HlJ8LwMPS8bPHsJnleg5xWD5xXB8yr0vGrw7C14XoOe1wye1wTP69DzusGzj+B5A3reMHjeEDxvQs+bBs++guct6HnL4HlL8LwNPW8bPPsJnneg5x2D5x3B8y70vGvw7C943oOe9wye9wTP+9DzvsFzgOD5AHo+MHg+EDwfQs+HBs+Bgucj6PnI4PlI8HwMPR8bPAcJnk+g5xOD5xPB8yn0fGrwHCx4PoOezwyezwTP59DzucFziOD5Anq+MHi+EDxfQs+XBs+hgucr6PnK4PlK8HwNPV8bPIcJnm+g5xuD5xvB8y30fGvwHC54voOe7wye7wTP99DzvcFzhOD5AXp+MHh+EDw/Qs+PBs+Rgucn6PnJ4PlJ8PwMPT8bPEcJnl+g5xeD5xfB86uqzPOfvf/qOVrwDFGVeYao+t89//f2v82GhJ4hDZ5jBM9Q0DOUwTOU4BkaeoY2eI4VPMNAzzAGzzCCZ1joGdbgOU7wDAc9wxk8wwme4aFneIPneMEzAvSMYPCMIHhGhJ4RDZ4TBM9I0DOSwTOS4BkZekY2eE4UPKNAzygGzyiCZ1ToGdXgOUnwjAY9oxk8owme0aFndIPnZMEzBvSMYfCMIXjGhJ4xDZ5TBM9Y0DOWwTOW4BkbesY2eE4VPONAzzgGzziCZ1zoGdfgOU3wjAc94xk84wme8aFnfIPndMEzAfRMYPBMIHgmhJ4JDZ4zBM9E0DORwTOR4JkYeiY2eM4UPJNAzyQGzySCZ1LomdTgOUvwTAY9kxk8kwmeAegZMHjOFjyTQ8/kBs/kgmcK6JnC4DlH8EwJPVMaPFMKnqmgZyqD51zBMzX0TG3wTC14poGeaQye8wTPtNAzrcEzreCZDnqmM3jOFzzTQ8/0Bs/0gmcG6JnB4LlA8MwIPTMaPDMKnpmgZyaD50LBMzP0zGzwzCx4ZoGeWQyeiwTPrNAzq8Ezq+CZDXpmM3guFjyzQ8/sBs/sgmcO6JnD4Pm14JkTeuY0eOYUPHNBz1wGzyWCZ27omdvgmVvwzAM98xg8vxE880LPvAbPvIJnPuiZz+C5VPDMDz3zGzzzC54FoGcBg+e3gmdB6FnQ4FlQ8CwEPQsZPJcJnoWhZ2GDZ2HBswj0LGLw/E7wLAo9ixo8iwqexaBnMYPncsGzOPQsbvAsLniWgJ4lDJ7fC54loWdJg2dJwbMU9Cxl8FwheJaGnqUNnqUFzzLQs4zB8wfBsyz0LGvwLCt4loOe5QyeKwXP8tCzvMGzvOBZAXpWMHj+KHhWhJ4VDZ4VBc9K0LOSwXOV4FkZelY2eFYWPKtAzyoGz58Ez6rQs6rBs6rgWQ16VjN4rhY8q0PP6gbP6oJnDehZw+D5s+BZE3rWNHjWFDxrQc9aBs81gmdt6Fnb4Flb8KwDPesYPH8RPOtCz7oGz7qCZz3oWc/guVbwrA896xs86wueDaBnA4Pnr4JnQ+jZ0ODZUPBsBD0bGTzXCZ6NoWdjg2djwbMJ9Gxi8FwveDaFnk0Nnk0Fz2bQs5nBc4Pg2Rx6Njd4Nhc8W0DPFgbPjYJnS+jZ0uDZUvBsBT1bGTw3CZ6toWdrg2drwbMN9Gxj8NwseLaFnm0Nnm0Fz3bQs53Bc4vg2R56tjd4thc8O0DPDgbPrYJnR+jZ0eDZUfDsBD07GTy3CZ6doWdng2dnwbML9Oxi8NwueHaFnl0Nnl0Fz27Qs5vBc4fg2R16djd4dhc8e0DPHgbPnYJnT+jZ0+DZU/DsBT17GTx3CZ69oWdvg2dvwbMP9Oxj8NwtePaFnn0Nnn0Fz37Qs5/Bc4/g2R969jd49hc8B0DPAQbPvYLnQOg50OA5UPAcBD0HGTz3CZ6Doedgg+dgwXMI9Bxi8NwveA6FnkMNnkMFz2HQc5jB84DgORx6Djd4Dhc8R0DPEQbPg4LnSOg50uA5UvAcBT1HGTwPCZ6joedog+dowXMM9Bxj8DwseI6FnmMNnmMFz3HQc5zB84jgOR56jjd4jhc8J0DPCQbPo4LnROg50eA5UfCcBD0nGTyPCZ6Toedkg+dkwXMK9Jxi8DwueE6FnlMNnlMFz2nQc5rB84TgOR16Tjd4Thc8Z0DPGQbPk4LnTOg50+A5U/CcBT1nGTxPCZ6zoedsg+dswXMO9Jxj8DwteM6FnnMNnnMFz3nQc57B84zgOR96zjd4zhc8F0DPBQbP3wTPhdBzocFzoeC5CHouMnieFTwXQ8/FBs/FgufX0PNrg+fvgucS6LnE4LlE8PwGen5j8DwneC6FnksNnksFz2+h57cGzz8Ez2XQc5nBc5ng+R30/M7geV7wXA49lxs8lwue30PP7w2efwqeK6DnCoPnCsHzB+j5g8HzguC5EnquNHiuFDx/hJ4/Gjz/EjxXQc9VBs9VgudP0PMng+dFwXM19Fxt8FwteP4MPX82eP4teK6BnmsMnmsEz1+g5y8Gz0uC51roudbguVbw/BV6/mrwvCx4roOe6wye6wTP9dBzvcHziuC5AXpuMHhuEDw3Qs+NBs+rgucm6LnJ4LlJ8NwMPTcbPK8Jnlug5xaD5xbBcyv03GrwvC54boOe2wye2wTP7dBzu8HzhuC5A3ruMHjuEDx3Qs+dBs+bgucu6LnL4LlL8NwNPXcbPG8Jnnug5x6D5x7Bcy/03GvwvC147oOe+wye+wTP/dBzv8HzjuB5AHoeMHgeEDwPQs+DBs+7guch6HnI4HlI8DwMPQ8bPO8Jnkeg5xGD5xHB8yj0PGrwvC94HoOexwyexwTP49DzuMHzgeB5AnqeMHieEDxPQs+TBs+Hgucp6HnK4HlK8DwNPU8bPB8Jnmeg5xmD5xnB8zfo+ZvB87HgeRZ6njV4nhU8f4eevxs8nwie56DnOYPnOcHzD+j5h8HzqeB5HnqeN3ieFzz/hJ5/GjyfCZ4XoOcFg+cFwfMv6PmXwfO54HkRel40eF4UPP+Gnn8bPF8Inpeg5yWD5yXB8zL0vGzwfCl4XoGeVwyeVwTPq9DzqsHzleB5DXpeM3heEzyvQ8/rBs/XgucN6HnD4HlD8LwJPW8aPN8Inreg5y2D5y3B8zb0vG3wfCt43oGedwyedwTPu9DzrsHzneB5D3reM3jeEzzvQ8/7Bs/3gucD6PnA4PlA8HwIPR8aPD8Ino+g5yOD5yPB8zH0fGzw/Ch4PoGeTwyeTwTPp9DzqcHzk+D5DHo+M3g+EzyfQ8/nBs/PgucL6PnC4PlC8HwJPV8aPL8Inq+g5yuD5yvB8zX0fG3w/Cps8J1voOcbg+cbwfMt9Hxr8AwRCL7zXdVg/w2R+X87/9mL+C+dyu1/m30fdGfI+v/b+T6Izn95IUIGgu/8AD0/GDw/CJ4foedHg2eoQPCdn6DnJ4PnJ8HzM/T8bPAMHQi+8wv0/GLw/CJ4flWNef6z9189wwSC7wxRjXmGqPbfPf/39r/NhoSeIQ2eYQPBd4aCnqEMnqEEz9DQM7TBM1wg+M4w0DOMwTOM4BkWeoY1eIYPBN8ZDnqGM3iGEzzDQ8/wBs8IgeA7I0DPCAbPCIJnROgZ0eAZMRB8ZyToGcngGUnwjAw9Ixs8IwWC74wCPaMYPKMInlGhZ1SDZ+RA8J3RoGc0g2c0wTM69Ixu8IwSCL4zBvSMYfCMIXjGhJ4xDZ5RA8F3xoKesQyesQTP2NAztsEzWiD4zjjQM47BM47gGRd6xjV4Rg8E3xkPesYzeMYTPONDz/gGzxiB4DsTQM8EBs8EgmdC6JnQ4BkzEHxnIuiZyOCZSPBMDD0TGzxjBYLvTAI9kxg8kwieSaFnUoNn7EDwncmgZzKDZzLBMwA9AwbPOIHgO5NDz+QGz+SCZwromcLgGTcQfGdK6JnS4JlS8EwFPVMZPOMFgu9MDT1TGzxTC55poGcag2f8QPCdaaFnWoNnWsEzHfRMZ/BMEAi+Mz30TG/wTC94ZoCeGQyeCQPBd2aEnhkNnhkFz0zQM5PBM1Eg+M7M0DOzwTOz4JkFemYxeCYOBN+ZFXpmNXhmFTyzQc9sBs8kgeA7s0PP7AbP7IJnDuiZw+CZNBB8Z07omdPgmVPwzAU9cxk8kwWC78wNPXMbPHMLnnmgZx6DZyAQfGde6JnX4JlX8MwHPfMZPJMHgu/MDz3zGzzzC54FoGcBg2eKQPCdBaFnQYNnQcGzEPQsZPBMGQi+szD0LGzwLCx4FoGeRQyeqQLBdxaFnkUNnkUFz2LQs5jBM3Ug+M7i0LO4wbO44FkCepYweKYJBN9ZEnqWNHiWFDxLQc9SBs+0geA7S0PP0gbP0oJnGehZxuCZLhB8Z1noWdbgWVbwLAc9yxk80weC7ywPPcsbPMsLnhWgZwWDZ4ZA8J0VoWdFg2dFwbMS9Kxk8MwYCL6zMvSsbPCsLHhWgZ5VDJ6ZAsF3VoWeVQ2eVQXPatCzmsEzcyD4zurQs7rBs7rgWQN61jB4ZgkE31kTetY0eNYUPGtBz1oGz6yB4DtrQ8/aBs/agmcd6FnH4JktEHxnXehZ1+BZV/CsBz3rGTyzB4LvrA896xs8//f2v802qMY8/9n7r545AsF3NqzGPBtW+++eDQXPRtCzkcEzZyD4zsbQs7HBs7Hg2QR6NjF45goE39kUejY1eDYVPJtBz2YGz9yB4DubQ8/mBs/mgmcL6NnC4JknEHxnS+jZ0uDZUvBsBT1bGTzzBoLvbA09Wxs8WwuebaBnG4NnvkDwnW2hZ1uDZ1vBsx30bGfwzB8IvrM99Gxv8GwveHaAnh0MngUCwXd2hJ4dDZ4dBc9O0LOTwbNgIPjOztCzs8Gzs+DZBXp2MXgWCgTf2RV6djV4dhU8u0HPbgbPwoHgO7tDz+4Gz+6CZw/o2cPgWSQQfGdP6NnT4NlT8OwFPXsZPIsGgu/sDT17Gzx7C559oGcfg2exQPCdfaFnX4NnX8GzH/TsZ/AsHgi+sz/07G/w7C94DoCeAwyeJQLBdw6EngMNngMFz0HQc5DBs2Qg+M7B0HOwwXOw4DkEeg4xeJYKBN85FHoONXgOFTyHQc9hBs/SgeA7h0PP4QbP4YLnCOg5wuBZJhB850joOdLgOVLwHAU9Rxk8ywaC7xwNPUcbPEcLnmOg5xiDZ7lA8J1joedYg+dYwXMc9Bxn8CwfCL5zPPQcb/AcL3hOgJ4TDJ4VAsF3ToSeEw2eEwXPSdBzksGzYiD4zsnQc7LBc7LgOQV6TjF4VgoE3zkVek41eE4VPKdBz2kGz8qB4DunQ8/pBs/pgucM6DnD4FklEHznTOg50+A5U/CcBT1nGTyrBoLvnA09Zxs8Zwuec6DnHINntUDwnXOh51yD51zBcx70nGfwrB4IvnM+9Jxv8JwveC6AngsMnjUCwXcuhJ4LDZ4LBc9F0HORwbNmIPjOxdBzscFzseD5NfT82uBZKxB85xLoucTguUTw/AZ6fmPwrB0IvnMp9Fxq8FwqeH4LPb81eNYJBN+5DHouM3guEzy/g57fGTzrBoLvXA49lxs8lwue30PP7w2e9QLBd66AnisMnisEzx+g5w8Gz/qB4DtXQs+VBs+VgueP0PNHg2eDQPCdq6DnKoPnKsHzJ+j5k8GzYSD4ztXQc7XBc7Xg+TP0/Nng2SgQfOca6LnG4LlG8PwFev5i8GwcCL5zLfRca/BcK3j+Cj1/NXg2CQTfuQ56rjN4rhM810PP9QbPpoHgOzdAzw0Gzw2C50boudHg2SwQfOcm6LnJ4LlJ8NwMPTcbPJsHgu/cAj23GDy3CJ5boedWg2eLQPCd26DnNoPnNsFzO/TcbvBsGQi+cwf03GHw3CF47oSeOw2erQLBd+6CnrsMnrsEz93Qc7fBs3Ug+M490HOPwXOP4LkXeu41eLYJBN+5D3ruM3juEzz3Q8/9Bs+2geA7D0DPAwbPA4LnQeh50ODZLhB85yHoecjgeUjwPAw9Dxs82weC7zwCPY8YPI8Inkeh51GDZ4dA8J3HoOcxg+cxwfM49Dxu8OwYCL7zBPQ8YfA8IXiehJ4nDZ6dAsF3noKepwyepwTP09DztMGzcyD4zjPQ84zB84zg+Rv0/M3g2SUQfOdZ6HnW4HlW8Pwdev5u8OwaCL7zHPQ8Z/A8J3j+AT3/MHh2CwTfeR56njd4nhc8/4Sefxo8uweC77wAPS8YPC8Inn9Bz78Mnj0CwXdehJ4XDZ4XBc+/oeffBs+egeA7L0HPSwbPS4LnZeh52eDZKxB85xXoecXgeUXwvAo9rxo8eweC77wGPa8ZPK8Jnteh53WDZ59A8J03oOcNg+cNwfMm9Lxp8OwbCL7zFvS8ZfC8JXjehp63DZ79AsF33oGedwyedwTPu9DzrsGzfyD4znvQ857B857geR963jd4DggE3/kAej4weD4QPB9Cz4cGz4GB4DsfQc9HBs9Hgudj6PnY4DkoEHznE+j5xOD5RPB8Cj2fGjwHB4LvfAY9nxk8nwmez6Hnc4PnkEDwnS+g5wuD5wvB8yX0fGnwHBoIvvMV9Hxl8HwleL6Gnq8NnsMCwXe+gZ5vDJ5vBM+30POtwXN4IPjOd9DzncHzneD5Hnq+N3iOCATf+QF6fjB4fhA8P0LPjwbPkYHgOz9Bz08Gz0+C52fo+dngOSoQfOcX6PnF4PlF8PyqOvP8Z++/eo4OBN8ZojrzDFH9v3v+7+1/mw0JPUMaPMcEgu8MBT1DGTxDCZ6hoWdog+fYQPCdYaBnGINnGMEzLPQMa/AcFwi+Mxz0DGfwDCd4hoee4Q2e4wPBd0aAnhEMnhEEz4jQM6LBc0Ig+M5I0DOSwTOS4BkZekY2eE4MBN8ZBXpGMXhGETyjQs+oBs9JgeA7o0HPaAbPaIJndOgZ3eA5ORB8ZwzoGcPgGUPwjAk9Yxo8pwSC74wFPWMZPGMJnrGhZ2yD59RA8J1xoGccg2ccwTMu9Ixr8JwWCL4zHvSMZ/CMJ3jGh57xDZ7TA8F3JoCeCQyeCQTPhNAzocFzRiD4zkTQM5HBM5HgmRh6JjZ4zgwE35kEeiYxeCYRPJNCz6QGz1mB4DuTQc9kBs9kgmcAegYMnrMDwXcmh57JDZ7JBc8U0DOFwXNOIPjOlNAzpcEzpeCZCnqmMnjODQTfmRp6pjZ4phY800DPNAbPeYHgO9NCz7QGz7SCZzromc7gOT8QfGd66Jne4Jle8MwAPTMYPBcEgu/MCD0zGjwzCp6ZoGcmg+fCQPCdmaFnZoNnZsEzC/TMYvBcFAi+Myv0zGrwzCp4ZoOe2QyeiwPBd2aHntkNntkFzxzQM4fB8+tA8J05oWdOg2dOwTMX9Mxl8FwSCL4zN/TMbfDMLXjmgZ55DJ7fBILvzAs98xo88wqe+aBnPoPn0kDwnfmhZ36DZ37BswD0LGDw/DYQfGdB6FnQ4FlQ8CwEPQsZPJcFgu8sDD0LGzwLC55FoGcRg+d3geA7i0LPogbPooJnMehZzOC5PBB8Z3HoWdzgWVzwLAE9Sxg8vw8E31kSepY0eJYUPEtBz1IGzxWB4DtLQ8/SBs/SgmcZ6FnG4PlDIPjOstCzrMGzrOBZDnqWM3iuDATfWR56ljd4lhc8K0DPCgbPHwPBd1aEnhUNnhUFz0rQs5LBc1Ug+M7K0LOywbOy4FkFelYxeP4UCL6zKvSsavCsKnhWg57VDJ6rA8F3Voee1Q2e1QXPGtCzhsHz50DwnTWhZ02DZ03Bsxb0rGXwXBMIvrM29Kxt8KwteNaBnnUMnr8Egu+sCz3rGjzrCp71oGc9g+faQPCd9aFnfYNnfcGzAfRsYPD8NRB8Z0Po2dDg2VDwbAQ9Gxk81wWC72wMPRsbPBsLnk2gZxOD5/pA8J1NoWdTg2dTwbMZ9Gxm8NwQCL6zOfRsbvBsLni2gJ4tDJ4bA8F3toSeLQ2eLQXPVtCzlcFzUyD4ztbQs7XBs7Xg2QZ6tjF4bg4E39kWerY1eLYVPNtBz3YGzy2B4DvbQ8/2Bs/2gmcH6NnB4Lk1EHxnR+jZ0eDZUfDsBD07GTy3BYLv7Aw9Oxs8OwueXaBnF4Pn9kDwnV2hZ1eDZ1fBsxv07Gbw3BEIvrM79Oxu8OwuePaAnj0MnjsDwXf2hJ49DZ49Bc9e0LOXwXNXIPjO3tCzt8Gzt+DZB3r2MXjuDgTf2Rd69jV49hU8+0HPfgbPPYHgO/tDz/4Gz/6C5wDoOcDguTcQfOdA6DnQ4DlQ8BwEPQcZPPcFgu8cDD0HGzwHC55DoOcQg+f+QPCdQ6HnUIPnUMFzGPQcZvA8EAi+czj0HG7wHC54joCeIwyeBwPBd46EniMNniMFz1HQc5TB81Ag+M7R0HO0wXO04DkGeo4xeB4OBN85FnqONXiOFTzHQc9xBs8jgeA7x0PP8QbP8YLnBOg5weB5NBB850ToOdHgOVHwnAQ9Jxk8jwWC75wMPScbPCcLnlOg5xSD5/FA8J1ToedUg+dUwXMa9Jxm8DwRCL5zOvScbvCcLnjOgJ4zDJ4nA8F3zoSeMw2eMwXPWdBzlsHzVCD4ztnQc7bBc7bgOQd6zjF4ng4E3zkXes41eM4VPOdBz3kGzzOB4DvnQ8/5Bs/5gucC6LnA4PlbIPjOhdBzocFzoeC5CHouMnieDQTfuRh6LjZ4LhY8v4aeXxs8fw8E37kEei4xeC4RPL+Bnt8YPM8Fgu9cCj2XGjyXCp7fQs9vDZ5/BILvXAY9lxk8lwme30HP7wye5wPBdy6HnssNnssFz++h5/cGzz8DwXeugJ4rDJ4rBM8foOcPBs8LgeA7V0LPlQbPlYLnj9DzR4PnX4HgO1dBz1UGz1WC50/Q8yeD58VA8J2roedqg+dqwfNn6PmzwfPvQPCda6DnGoPnGsHzF+j5i8HzUiD4zrXQc63Bc63g+Sv0/NXgeTkQfOc66LnO4LlO8FwPPdcbPK8Egu/cAD03GDw3CJ4boedGg+fVQPCdm6DnJoPnJsFzM/TcbPC8Fgi+cwv03GLw3CJ4boWeWw2e1wPBd26DntsMntsEz+3Qc7vB80Yg+M4d0HOHwXOH4LkTeu40eN4MBN+5C3ruMnjuEjx3Q8/dBs9bgeA790DPPQbPPYLnXui51+B5OxB85z7ouc/guU/w3A899xs87wSC7zwAPQ8YPA8Ingeh50GD591A8J2HoOchg+chwfMw9Dxs8LwXCL7zCPQ8YvA8IngehZ5HDZ73A8F3HoOexwyexwTP49DzuMHzQSD4zhPQ84TB84TgeRJ6njR4PgwE33kKep4yeJ4SPE9Dz9MGz0eB4DvPQM8zBs8zgudv0PM3g+fjQPCdZ6HnWYPnWcHzd+j5u8HzSSD4znPQ85zB85zg+Qf0/MPg+TQQfOd56Hne4Hle8PwTev5p8HwWCL7zAvS8YPC8IHj+BT3/Mng+DwTfeRF6XjR4XhQ8/4aefxs8XwSC77wEPS8ZPC8Jnpeh52WD58tA8J1XoOcVg+cVwfMq9Lxq8HwVCL7zGvS8ZvC8Jnheh57XDZ6vA8F33oCeNwyeNwTPm9DzpsHzTSD4zlvQ85bB85bgeRt63jZ4vg0E33kHet4xeN4RPO9Cz7sGz3eB4DvvQc97Bs97gud96Hnf4Pk+EHznA+j5wOD5QPB8CD0fGjw/BILvfAQ9Hxk8Hwmej6HnY4Pnx0DwnU+g5xOD5xPB8yn0fGrw/BQIvvMZ9Hxm8HwmeD6Hns8Nnp8DwXe+gJ4vDJ4vBM+X0POlwfNLIPjOV9DzlcHzleD5Gnq+Nnh+lTz4zjfQ843B843g+RZ6vjV4hhA830HPdwbPd4Lne+j53uAZUvD8AD0/GDw/CJ4foedHg2cowfMT9Pxk8PwkeH6Gnp8NnqEFzy/Q84vB84vg+VUN5vnP3n/1DCN4hqjBPEPU+O+e/3v732ZDQs+QBs+wgmco6BnK4BlK8AwNPUMbPMMJnmGgZxiDZxjBMyz0DGvwDC94hoOe4Qye4QTP8NAzvMEzguAZAXpGMHhGEDwjQs+IBs+Igmck6BnJ4BlJ8IwMPSMbPCMJnlGgZxSDZxTBMyr0jGrwjCx4RoOe0Qye0QTP6NAzusEziuAZA3rGMHjGEDxjQs+YBs+ogmcs6BnL4BlL8IwNPWMbPKMJnnGgZxyDZxzBMy70jGvwjC54xoOe8Qye8QTP+NAzvsEzhuCZAHomMHgmEDwTQs+EBs+Ygmci6JnI4JlI8EwMPRMbPGMJnkmgZxKDZxLBMyn0TGrwjC14JoOeyQyeyQTPAPQMGDzjCJ7JoWdyg2dywTMF9Exh8IwreKaEnikNnikFz1TQM5XBM57gmRp6pjZ4phY800DPNAbP+IJnWuiZ1uCZVvBMBz3TGTwTCJ7poWd6g2d6wTMD9Mxg8EwoeGaEnhkNnhkFz0zQM5PBM5HgmRl6ZjZ4ZhY8s0DPLAbPxIJnVuiZ1eCZVfDMBj2zGTyTCJ7ZoWd2g2d2wTMH9Mxh8EwqeOaEnjkNnjkFz1zQM5fBM5ngmRt65jZ45hY880DPPAbPgOCZF3rmNXjmFTzzQc98Bs/kgmd+6Jnf4Jlf8CwAPQsYPFMIngWhZ0GDZ0HBsxD0LGTwTCl4FoaehQ2ehQXPItCziMEzleBZFHoWNXgWFTyLQc9iBs/Ugmdx6Fnc4Flc8CwBPUsYPNMIniWhZ0mDZ0nBsxT0LGXwTCt4loaepQ2epQXPMtCzjMEzneBZFnqWNXiWFTzLQc9yBs/0gmd56Fne4Fle8KwAPSsYPDMInhWhZ0WDZ0XBsxL0rGTwzCh4VoaelQ2elQXPKtCzisEzk+BZFXpWNXhWFTyrQc9qBs/Mgmd16Fnd4Fld8KwBPWsYPLMInjWhZ02DZ03Bsxb0rGXwzCp41oaetQ2etQXPOtCzjsEzm+BZF3rWNXjWFTzrQc96Bs/sgmd96Fnf4Flf8GwAPRsYPHMIng2hZ0ODZ0PBsxH0bGTwzCl4NoaejQ2ejQXPJtCzicEzl+DZFHo2NXg2FTybQc9mBs/cgmdz6Nnc4Nlc8GwBPVsYPPMIni2hZ0uDZ0vBsxX0bGXwzCt4toaerQ2erQXPNtCzjcEzn+DZFnq2NXi2FTzbQc92Bs/8gmd76Nne4Nle8OwAPTsYPAsInh2hZ0eDZ0fBsxP07GTwLCh4doaenQ2enQXPLtCzi8GzkODZFXp2NXh2FTy7Qc9uBs/Cgmd36Nnd4Nld8OwBPXsYPIsInj2hZ0+DZ0/Bsxf07GXwLCp49oaevQ2evQXPPtCzj8GzmODZF3r2NXj2FTz7Qc9+Bs/igmd/6Nnf4Nlf8BwAPQcYPEsIngOh50CD50DBcxD0HGTwLCl4Doaegw2egwXPIdBziMGzlOA5FHoONXgOFTyHQc9hBs/Sgudw6Dnc4Dlc8BwBPUcYPMsIniOh50iD50jBcxT0HGXwLCt4joaeow2eowXPMdBzjMGznOA5FnqONXiOFTzHQc9xBs/ygud46Dne4Dle8JwAPScYPCsInhOh50SD50TBcxL0nGTwrCh4Toaekw2ekwXPKdBzisGzkuA5FXpONXhOFTynQc9pBs/Kgud06Dnd4Dld8JwBPWcYPKsInjOh50yD50zBcxb0nGXwrCp4zoaesw2eswXPOdBzjsGzmuA5F3rONXjOFTznQc95Bs/qgud86Dnf4Dlf8FwAPRcYPGsInguh50KD50LBcxH0XGTwrCl4Loaeiw2eiwXPr6Hn1wbPWoLnEui5xOC5RPD8Bnp+Y/CsLXguhZ5LDZ5LBc9voee3Bs86gucy6LnM4LlM8PwOen5n8KwreC6HnssNnssFz++h5/cGz3qC5wroucLguULw/AF6/mDwrC94roSeKw2eKwXPH6HnjwbPBoLnKui5yuC5SvD8CXr+ZPBsKHiuhp6rDZ6rBc+foefPBs9Gguca6LnG4LlG8PwFev5i8GwseK6FnmsNnmsFz1+h568GzyaC5zrouc7guU7wXA891xs8mwqeG6DnBoPnBsFzI/TcaPBsJnhugp6bDJ6bBM/N0HOzwbO54LkFem4xeG4RPLdCz60GzxaC5zbouc3guU3w3A49txs8WwqeO6DnDoPnDsFzJ/TcafBsJXjugp67DJ67BM/d0HO3wbO14LkHeu4xeO4RPPdCz70GzzaC5z7ouc/guU/w3A899xs82wqeB6DnAYPnAcHzIPQ8aPBsJ3gegp6HDJ6HBM/D0POwwbO94HkEeh4xeB4RPI9Cz6MGzw6C5zHoeczgeUzwPA49jxs8OwqeJ6DnCYPnCcHzJPQ8afDsJHiegp6nDJ6nBM/T0PO0wbOz4HkGep4xeJ4RPH+Dnr8ZPLsInmeh51mD51nB83fo+bvBs6vgeQ56njN4nhM8/4Cefxg8uwme56HneYPnecHzT+j5p8Gzu+B5AXpeMHheEDz/gp5/GTx7CJ4XoedFg+dFwfNv6Pm3wbOn4HkJel4yeF4SPC9Dz8sGz16C5xXoecXgeUXwvAo9rxo8ewue16DnNYPnNcHzOvS8bvDsI3jegJ43DJ43BM+b0POmwbOv4HkLet4yeN4SPG9Dz9sGz36C5x3oecfgeUfwvAs97xo8+wue96DnPYPnPcHzPvS8b/AcIHg+gJ4PDJ4PBM+H0POhwXOg4PkIej4yeD4SPB9Dz8cGz0GC5xPo+cTg+UTwfAo9nxo8Bwuez6DnM4PnM8HzOfR8bvAcIni+gJ4vDJ4vBM+X0POlwXOo4PkKer4yeL4SPF9Dz9cGz2GC5xvo+cbg+UbwfAs93xo8hwue76DnO4PnO8HzPfR8b/AcIXh+gJ4fDJ4fBM+P0POjwXOk4PkJen4yeH4SPD9Dz88Gz1GC5xfo+cXg+UXw/Kom8/xn7796jhY8Q9RkniFq/nfP/739b7MhoWdIg+cYwTMU9Axl8AwleIaGnqENnmMFzzDQM4zBM4zgGRZ6hjV4jhM8w0HPcAbPcIJneOgZ3uA5XvCMAD0jGDwjCJ4RoWdEg+cEwTMS9Ixk8IwkeEaGnpENnhMFzyjQM4rBM4rgGRV6RjV4ThI8o0HPaAbPaIJndOgZ3eA5WfCMAT1jGDxjCJ4xoWdMg+cUwTMW9Ixl8IwleMaGnrENnlMFzzjQM47BM47gGRd6xjV4ThM840HPeAbPeIJnfOgZ3+A5XfBMAD0TGDwTCJ4JoWdCg+cMwTMR9Exk8EwkeCaGnokNnjMFzyTQM4nBM4ngmRR6JjV4zhI8k0HPZAbPZIJnAHoGDJ6zBc/k0DO5wTO54JkCeqYweM4RPFNCz5QGz5SCZyromcrgOVfwTA09Uxs8UwueaaBnGoPnPMEzLfRMa/BMK3img57pDJ7zBc/00DO9wTO94JkBemYweC4QPDNCz4wGz4yCZybomcnguVDwzAw9Mxs8MwueWaBnFoPnIsEzK/TMavDMKnhmg57ZDJ6LBc/s0DO7wTO74JkDeuYweH4teOaEnjkNnjkFz1zQM5fBc4ngmRt65jZ45hY880DPPAbPbwTPvNAzr8Ezr+CZD3rmM3guFTzzQ8/8Bs/8gmcB6FnA4Pmt4FkQehY0eBYUPAtBz0IGz2WCZ2HoWdjgWVjwLAI9ixg8vxM8i0LPogbPooJnMehZzOC5XPAsDj2LGzyLC54loGcJg+f3gmdJ6FnS4FlS8CwFPUsZPFcInqWhZ2mDZ2nBswz0LGPw/EHwLAs9yxo8ywqe5aBnOYPnSsGzPPQsb/AsL3hWgJ4VDJ4/Cp4VoWdFg2dFwbMS9Kxk8FwleFaGnpUNnpUFzyrQs4rB8yfBsyr0rGrwrCp4VoOe1QyeqwXP6tCzusGzuuBZA3rWMHj+LHjWhJ41DZ41Bc9a0LOWwXON4FkbetY2eNYWPOtAzzoGz18Ez7rQs67Bs67gWQ961jN4rhU860PP+gbP+oJnA+jZwOD5q+DZEHo2NHg2FDwbQc9GBs91gmdj6NnY4NlY8GwCPZsYPNcLnk2hZ1ODZ1PBsxn0bGbw3CB4NoeezQ2ezQXPFtCzhcFzo+DZEnq2NHi2FDxbQc9WBs9Ngmdr6Nna4Nla8GwDPdsYPDcLnm2hZ1uDZ1vBsx30bGfw3CJ4toee7Q2e7QXPDtCzg8Fzq+DZEXp2NHh2FDw7Qc9OBs9tgmdn6NnZ4NlZ8OwCPbsYPLcLnl2hZ1eDZ1fBsxv07Gbw3CF4doee3Q2e3QXPHtCzh8Fzp+DZE3r2NHj2FDx7Qc9eBs9dgmdv6Nnb4Nlb8OwDPfsYPHcLnn2hZ1+DZ1/Bsx/07Gfw3CN49oee/Q2e/QXPAdBzgMFzr+A5EHoONHgOFDwHQc9BBs99gudg6DnY4DlY8BwCPYcYPPcLnkOh51CD51DBcxj0HGbwPCB4Doeeww2ewwXPEdBzhMHzoOA5EnqONHiOFDxHQc9RBs9Dgudo6Dna4Dla8BwDPccYPA8LnmOh51iD51jBcxz0HGfwPCJ4joee4w2e4wXPCdBzgsHzqOA5EXpONHhOFDwnQc9JBs9jgudk6DnZ4DlZ8JwCPacYPI8LnlOh51SD51TBcxr0nGbwPCF4Toee0w2e0wXPGdBzhsHzpOA5E3rONHjOFDxnQc9ZBs9Tguds6Dnb4Dlb8JwDPecYPE8LnnOh51yD51zBcx70nGfwPCN4zoee8w2e8wXPBdBzgcHzN8FzIfRcaPBcKHgugp6LDJ5nBc/F0HOxwXOx4Pk19Pza4Pm74LkEei4xeC4RPL+Bnt8YPM8Jnkuh51KD51LB81vo+a3B8w/Bcxn0XGbwXCZ4fgc9vzN4nhc8l0PP5QbP5YLn99Dze4Pnn4LnCui5wuC5QvD8AXr+YPC8IHiuhJ4rDZ4rBc8foeePBs+/BM9V0HOVwXOV4PkT9PzJ4HlR8FwNPVcbPFcLnj9Dz58Nnn8Lnmug5xqD5xrB8xfo+YvB85LguRZ6rjV4rhU8f4Wevxo8Lwue66DnOoPnOsFzPfRcb/C8InhugJ4bDJ4bBM+N0HOjwfOq4LkJem4yeG4SPDdDz80Gz2uC5xboucXguUXw3Ao9txo8rwue26DnNoPnNsFzO/TcbvC8IXjugJ47DJ47BM+d0HOnwfOm4LkLeu4yeO4SPHdDz90Gz1uC5x7oucfguUfw3As99xo8bwue+6DnPoPnPsFzP/Tcb/C8I3gegJ4HDJ4HBM+D0POgwfOu4HkIeh4yeB4SPA9Dz8MGz3uC5xHoecTgeUTwPAo9jxo87wuex6DnMYPnMcHzOPQ8bvB8IHiegJ4nDJ4nBM+T0POkwfOh4HkKep4yeJ4SPE9Dz9MGz0eC5xnoecbgeUbw/A16/mbwfCx4noWeZw2eZwXP36Hn7wbPJ4LnOeh5zuB5TvD8A3r+YfB8Knieh57nDZ7nBc8/oeefBs9ngucF6HnB4HlB8PwLev5l8HwueF6EnhcNnhcFz7+h598GzxeC5yXoecngeUnwvAw9Lxs8XwqeV6DnFYPnFcHzKvS8avB8JXheg57XDJ7XBM/r0PO6wfO14HkDet4weN4QPG9Cz5sGzzeC5y3oecvgeUvwvA09bxs83wqed6DnHYPnHcHzLvS8a/B8J3jeg573DJ73BM/70PO+wfO94PkAej4weD4QPB9Cz4cGzw+C5yPo+cjg+UjwfAw9Hxs8PwqeT6DnE4PnE8HzKfR8avD8JHg+g57PDJ7PBM/n0PO5wfOz4PkCer4weL4QPF9Cz5cGzy+C5yvo+crg+UrwfA09Xxs8v0oRfOcb6PnG4PlG8HwLPd8aPEMInu+g5zuD5zvB8z30fG/wDCl4foCeHwyeHwTPj9Dzo8EzlOD5CXp+Mnh+Ejw/Q8/PBs/QgucX6PnF4PlF8PyqFvP8Z++/eoYRPEPUYp4hav13z/+9/W+zIaFnSINnWMEzFPQMZfAMJXiGhp6hDZ7hBM8w0DOMwTOM4BkWeoY1eIYXPMNBz3AGz3CCZ3joGd7gGUHwjAA9Ixg8IwieEaFnRINnRMEzEvSMZPCMJHhGhp6RDZ6RBM8o0DOKwTOK4BkVekY1eEYWPKNBz2gGz2iCZ3ToGd3gGUXwjAE9Yxg8YwieMaFnTINnVMEzFvSMZfCMJXjGhp6xDZ7RBM840DOOwTOO4BkXesY1eEYXPONBz3gGz3iCZ3zoGd/gGUPwTAA9Exg8EwieCaFnQoNnTMEzEfRMZPBMJHgmhp6JDZ6xBM8k0DOJwTOJ4JkUeiY1eMYWPJNBz2QGz2SCZwB6BgyecQTP5NAzucEzueCZAnqmMHjGFTxTQs+UBs+Ugmcq6JnK4BlP8EwNPVMbPFMLnmmgZxqDZ3zBMy30TGvwTCt4poOe6QyeCQTP9NAzvcEzveCZAXpmMHgmFDwzQs+MBs+Mgmcm6JnJ4JlI8MwMPTMbPDMLnlmgZxaDZ2LBMyv0zGrwzCp4ZoOe2QyeSQTP7NAzu8Ezu+CZA3rmMHgmFTxzQs+cBs+cgmcu6JnL4JlM8MwNPXMbPHMLnnmgZx6DZ0DwzAs98xo88wqe+aBnPoNncsEzP/TMb/DML3gWgJ4FDJ4pBM+C0LOgwbOg4FkIehYyeKYUPAtDz8IGz8KCZxHoWcTgmUrwLAo9ixo8iwqexaBnMYNnasGzOPQsbvAsLniWgJ4lDJ5pBM+S0LOkwbOk4FkKepYyeKYVPEtDz9IGz9KCZxnoWcbgmU7wLAs9yxo8ywqe5aBnOYNnesGzPPQsb/AsL3hWgJ4VDJ4ZBM+K0LOiwbOi4FkJelYyeGYUPCtDz8oGz8qCZxXoWcXgmUnwrAo9qxo8qwqe1aBnNYNnZsGzOvSsbvCsLnjWgJ41DJ5ZBM+a0LOmwbOm4FkLetYyeGYVPGtDz9oGz9qCZx3oWcfgmU3wrAs96xo86wqe9aBnPYNndsGzPvSsb/CsL3g2gJ4NDJ45BM+G0LOhwbOh4NkIejYyeOYUPBtDz8YGz8aCZxPo2cTgmUvwbAo9mxo8mwqezaBnM4NnbsGzOfRsbvBsLni2gJ4tDJ55BM+W0LOlwbOl4NkKerYyeOYVPFtDz9YGz9aCZxvo2cbgmU/wbAs92xo82wqe7aBnO4NnfsGzPfRsb/BsL3h2gJ4dDJ4FBM+O0LOjwbOj4NkJenYyeBYUPDtDz84Gz86CZxfo2cXgWUjw7Ao9uxo8uwqe3aBnN4NnYcGzO/TsbvDsLnj2gJ49DJ5FBM+e0LOnwbOn4NkLevYyeBYVPHtDz94Gz96CZx/o2cfgWUzw7As9+xo8+wqe/aBnP4NnccGzP/Tsb/DsL3gOgJ4DDJ4lBM+B0HOgwXOg4DkIeg4yeJYUPAdDz8EGz8GC5xDoOcTgWUrwHAo9hxo8hwqew6DnMINnacFzOPQcbvAcLniOgJ4jDJ5lBM+R0HOkwXOk4DkKeo4yeJYVPEdDz9EGz9GC5xjoOcbgWU7wHAs9xxo8xwqe46DnOINnecFzPPQcb/AcL3hOgJ4TDJ4VBM+J0HOiwXOi4DkJek4yeFYUPCdDz8kGz8mC5xToOcXgWUnwnAo9pxo8pwqe06DnNINnZcFzOvScbvCcLnjOgJ4zDJ5VBM+Z0HOmwXOm4DkLes4yeFYVPGdDz9kGz9mC5xzoOcfgWU3wnAs95xo85wqe86DnPINndcFzPvScb/CcL3gugJ4LDJ41BM+F0HOhwXOh4LkIei4yeNYUPBdDz8UGz8WC59fQ82uDZy3Bcwn0XGLwXCJ4fgM9vzF41hY8l0LPpQbPpYLnt9DzW4NnHcFzGfRcZvBcJnh+Bz2/M3jWFTyXQ8/lBs/lguf30PN7g2c9wXMF9Fxh8FwheP4APX8weNYXPFdCz5UGz5WC54/Q80eDZwPBcxX0XGXwXCV4/gQ9fzJ4NhQ8V0PP1QbP1YLnz9DzZ4NnI8FzDfRcY/BcI3j+Aj1/MXg2FjzXQs+1Bs+1guev0PNXg2cTwXMd9Fxn8FwneK6HnusNnk0Fzw3Qc4PBc4PguRF6bjR4NhM8N0HPTQbPTYLnZui52eDZXPDcAj23GDy3CJ5boedWg2cLwXMb9Nxm8NwmeG6HntsNni0Fzx3Qc4fBc4fguRN67jR4thI8d0HPXQbPXYLnbui52+DZWvDcAz33GDz3CJ57oedeg2cbwXMf9Nxn8NwneO6HnvsNnm0FzwPQ84DB84DgeRB6HjR4thM8D0HPQwbPQ4LnYeh52ODZXvA8Aj2PGDyPCJ5HoedRg2cHwfMY9Dxm8DwmeB6HnscNnh0FzxPQ84TB84TgeRJ6njR4dhI8T0HPUwbPU4Lnaeh52uDZWfA8Az3PGDzPCJ6/Qc/fDJ5dBM+z0POswfOs4Pk79Pzd4NlV8DwHPc8ZPM8Jnn9Azz8Mnt0Ez/PQ87zB87zg+Sf0/NPg2V3wvAA9Lxg8Lwief0HPvwyePQTPi9DzosHzouD5N/T82+DZU/C8BD0vGTwvCZ6Xoedlg2cvwfMK9Lxi8LwieF6FnlcNnr0Fz2vQ85rB85rgeR16Xjd49hE8b0DPGwbPG4LnTeh50+DZV/C8BT1vGTxvCZ63oedtg2c/wfMO9Lxj8LwjeN6FnncNnv0Fz3vQ857B857geR963jd4DhA8H0DPBwbPB4LnQ+j50OA5UPB8BD0fGTwfCZ6Poedjg+cgwfMJ9Hxi8HwieD6Fnk8NnoMFz2fQ85nB85ng+Rx6Pjd4DhE8X0DPFwbPF4LnS+j50uA5VPB8BT1fGTxfCZ6voedrg+cwwfMN9Hxj8HwjeL6Fnm8NnsMFz3fQ853B853g+R56vjd4jhA8P0DPDwbPD4LnR+j50eA5UvD8BD0/GTw/CZ6foedng+cowfML9Pxi8PwieH5Vm3n+s/dfPUcLniFqM88Qtf+75//e/rfZkNAzpMFzjOAZCnqGMniGEjxDQ8/QBs+xgmcY6BnG4BlG8AwLPcMaPMcJnuGgZziDZzjBMzz0DG/wHC94RoCeEQyeEQTPiNAzosFzguAZCXpGMnhGEjwjQ8/IBs+JgmcU6BnF4BlF8IwKPaMaPCcJntGgZzSDZzTBMzr0jG7wnCx4xoCeMQyeMQTPmNAzpsFziuAZC3rGMnjGEjxjQ8/YBs+pgmcc6BnH4BlH8IwLPeMaPKcJnvGgZzyDZzzBMz70jG/wnC54JoCeCQyeCQTPhNAzocFzhuCZCHomMngmEjwTQ8/EBs+ZgmcS6JnE4JlE8EwKPZMaPGcJnsmgZzKDZzLBMwA9AwbP2YJncuiZ3OCZXPBMAT1TGDznCJ4poWdKg2dKwTMV9Exl8JwreKaGnqkNnqkFzzTQM43Bc57gmRZ6pjV4phU800HPdAbP+YJneuiZ3uCZXvDMAD0zGDwXCJ4ZoWdGg2dGwTMT9Mxk8FwoeGaGnpkNnpkFzyzQM4vBc5HgmRV6ZjV4ZhU8s0HPbAbPxYJnduiZ3eCZXfDMAT1zGDy/FjxzQs+cBs+cgmcu6JnL4LlE8MwNPXMbPHMLnnmgZx6D5zeCZ17omdfgmVfwzAc98xk8lwqe+aFnfoNnfsGzAPQsYPD8VvAsCD0LGjwLCp6FoGchg+cywbMw9Cxs8CwseBaBnkUMnt8JnkWhZ1GDZ1HBsxj0LGbwXC54FoeexQ2exQXPEtCzhMHze8GzJPQsafAsKXiWgp6lDJ4rBM/S0LO0wbO04FkGepYxeP4geJaFnmUNnmUFz3LQs5zBc6XgWR56ljd4lhc8K0DPCgbPHwXPitCzosGzouBZCXpWMniuEjwrQ8/KBs/KgmcV6FnF4PmT4FkVelY1eFYVPKtBz2oGz9WCZ3XoWd3gWV3wrAE9axg8fxY8a0LPmgbPmoJnLehZy+C5RvCsDT1rGzxrC551oGcdg+cvgmdd6FnX4FlX8KwHPesZPNcKnvWhZ32DZ33BswH0bGDw/FXwbAg9Gxo8GwqejaBnI4PnOsGzMfRsbPBsLHg2gZ5NDJ7rBc+m0LOpwbOp4NkMejYzeG4QPJtDz+YGz+aCZwvo2cLguVHwbAk9Wxo8WwqeraBnK4PnJsGzNfRsbfBsLXi2gZ5tDJ6bBc+20LOtwbOt4NkOerYzeG4RPNtDz/YGz/aCZwfo2cHguVXw7Ag9Oxo8OwqenaBnJ4PnNsGzM/TsbPDsLHh2gZ5dDJ7bBc+u0LOrwbOr4NkNenYzeO4QPLtDz+4Gz+6CZw/o2cPguVPw7Ak9exo8ewqevaBnL4PnLsGzN/TsbfDsLXj2gZ59DJ67Bc++0LOvwbOv4NkPevYzeO4RPPtDz/4Gz/6C5wDoOcDguVfwHAg9Bxo8Bwqeg6DnIIPnPsFzMPQcbPAcLHgOgZ5DDJ77Bc+h0HOowXOo4DkMeg4zeB4QPIdDz+EGz+GC5wjoOcLgeVDwHAk9Rxo8Rwqeo6DnKIPnIcFzNPQcbfAcLXiOgZ5jDJ6HBc+x0HOswXOs4DkOeo4zeB4RPMdDz/EGz/GC5wToOcHgeVTwnAg9Jxo8Jwqek6DnJIPnMcFzMvScbPCcLHhOgZ5TDJ7HBc+p0HOqwXOq4DkNek4zeJ4QPKdDz+kGz+mC5wzoOcPgeVLwnAk9Zxo8Zwqes6DnLIPnKcFzNvScbfCcLXjOgZ5zDJ6nBc+50HOuwXOu4DkPes4zeJ4RPOdDz/kGz/mC5wLoucDg+ZvguRB6LjR4LhQ8F0HPRQbPs4LnYui52OC5WPD8Gnp+bfD8XfBcAj2XGDyXCJ7fQM9vDJ7nBM+l0HOpwXOp4Pkt9PzW4PmH4LkMei4zeC4TPL+Dnt8ZPM8Lnsuh53KD53LB83vo+b3B80/BcwX0XGHwXCF4/gA9fzB4XhA8V0LPlQbPlYLnj9DzR4PnX4LnKui5yuC5SvD8CXr+ZPC8KHiuhp6rDZ6rBc+foefPBs+/Bc810HONwXON4PkL9PzF4HlJ8FwLPdcaPNcKnr9Cz18NnpcFz3XQc53Bc53guR56rjd4XhE8N0DPDQbPDYLnRui50eB5VfDcBD03GTw3CZ6boedmg+c1wXML9Nxi8NwieG6FnlsNntcFz23Qc5vBc5vguR16bjd43hA8d0DPHQbPHYLnTui50+B5U/DcBT13GTx3CZ67oedug+ctwXMP9Nxj8NwjeO6FnnsNnrcFz33Qc5/Bc5/guR967jd43hE8D0DPAwbPA4LnQeh50OB5V/A8BD0PGTwPCZ6Hoedhg+c9wfMI9Dxi8DwieB6FnkcNnvcFz2PQ85jB85jgeRx6Hjd4PhA8T0DPEwbPE4LnSeh50uD5UPA8BT1PGTxPCZ6noedpg+cjwfMM9Dxj8DwjeP4GPX8zeD4WPM9Cz7MGz7OC5+/Q83eD5xPB8xz0PGfwPCd4/gE9/zB4PhU8z0PP8wbP84Lnn9DzT4PnM8HzAvS8YPC8IHj+BT3/Mng+FzwvQs+LBs+Lguff0PNvg+cLwfMS9Lxk8LwkeF6GnpcNni8FzyvQ84rB84rgeRV6XjV4vhI8r0HPawbPa4Lndeh53eD5WvC8AT1vGDxvCJ43oedNg+cbwfMW9Lxl8LwleN6GnrcNnm8FzzvQ847B847geRd63jV4vhM870HPewbPe4Lnfeh53+D5XvB8AD0fGDwfCJ4PoedDg+cHwfMR9Hxk8HwkeD6Gno8Nnh8FzyfQ84nB84ng+RR6PjV4fhI8n0HPZwbPZ4Lnc+j53OD5WfB8AT1fGDxfCJ4voedLg+cXwfMV9Hxl8HwleL6Gnq8Nnl+lDL7zDfR8Y/B8I3i+hZ5vDZ4hBM930POdwfOd4Pkeer43eIYUPD9Azw8Gzw+C50fo+dHgGUrw/AQ9Pxk8Pwmen6HnZ4NnaMHzC/T8YvD8Inh+VYd5/rP3Xz3DCJ4h6jDPEHX+u+f/3v632ZDQM6TBM6zgGQp6hjJ4hhI8Q0PP0AbPcIJnGOgZxuAZRvAMCz3DGjzDC57hoGc4g2c4wTM89Axv8IwgeEaAnhEMnhEEz4jQM6LBM6LgGQl6RjJ4RhI8I0PPyAbPSIJnFOgZxeAZRfCMCj2jGjwjC57RoGc0g2c0wTM69Ixu8IwieMaAnjEMnjEEz5jQM6bBM6rgGQt6xjJ4xhI8Y0PP2AbPaIJnHOgZx+AZR/CMCz3jGjyjC57xoGc8g2c8wTM+9Ixv8IwheCaAngkMngkEz4TQM6HBM6bgmQh6JjJ4JhI8E0PPxAbPWIJnEuiZxOCZRPBMCj2TGjxjC57JoGcyg2cywTMAPQMGzziCZ3LomdzgmVzwTAE9Uxg84wqeKaFnSoNnSsEzFfRMZfCMJ3imhp6pDZ6pBc800DONwTO+4JkWeqY1eKYVPNNBz3QGzwSCZ3romd7gmV7wzAA9Mxg8EwqeGaFnRoNnRsEzE/TMZPBMJHhmhp6ZDZ6ZBc8s0DOLwTOx4JkVemY1eGYVPLNBz2wGzySCZ3bomd3gmV3wzAE9cxg8kwqeOaFnToNnTsEzF/TMZfBMJnjmhp65DZ65Bc880DOPwTMgeOaFnnkNnnkFz3zQM5/BM7ngmR965jd45hc8C0DPAgbPFIJnQehZ0OBZUPAsBD0LGTxTCp6FoWdhg2dhwbMI9Cxi8EwleBaFnkUNnkUFz2LQs5jBM7XgWRx6Fjd4Fhc8S0DPEgbPNIJnSehZ0uBZUvAsBT1LGTzTCp6loWdpg2dpwbMM9Cxj8EwneJaFnmUNnmUFz3LQs5zBM73gWR56ljd4lhc8K0DPCgbPDIJnRehZ0eBZUfCsBD0rGTwzCp6VoWdlg2dlwbMK9Kxi8MwkeFaFnlUNnlUFz2rQs5rBM7PgWR16Vjd4Vhc8a0DPGgbPLIJnTehZ0+BZU/CsBT1rGTyzCp61oWdtg2dtwbMO9Kxj8MwmeNaFnnUNnnUFz3rQs57BM7vgWR961jd41hc8G0DPBgbPHIJnQ+jZ0ODZUPBsBD0bGTxzCp6NoWdjg2djwbMJ9Gxi8MwleDaFnk0Nnk0Fz2bQs5nBM7fg2Rx6Njd4Nhc8W0DPFgbPPIJnS+jZ0uDZUvBsBT1bGTzzCp6toWdrg2drwbMN9Gxj8MwneLaFnm0Nnm0Fz3bQs53BM7/g2R56tjd4thc8O0DPDgbPAoJnR+jZ0eDZUfDsBD07GTwLCp6doWdng2dnwbML9Oxi8CwkeHaFnl0Nnl0Fz27Qs5vBs7Dg2R16djd4dhc8e0DPHgbPIoJnT+jZ0+DZU/DsBT17GTyLCp69oWdvg2dvwbMP9Oxj8CwmePaFnn0Nnn0Fz37Qs5/Bs7jg2R969jd49hc8B0DPAQbPEoLnQOg50OA5UPAcBD0HGTxLCp6Doedgg+dgwXMI9Bxi8CwleA6FnkMNnkMFz2HQc5jBs7TgORx6Djd4Dhc8R0DPEQbPMoLnSOg50uA5UvAcBT1HGTzLCp6joedog+dowXMM9Bxj8CwneI6FnmMNnmMFz3HQc5zBs7zgOR56jjd4jhc8J0DPCQbPCoLnROg50eA5UfCcBD0nGTwrCp6Toedkg+dkwXMK9Jxi8KwkeE6FnlMNnlMFz2nQc5rBs7LgOR16Tjd4Thc8Z0DPGQbPKoLnTOg50+A5U/CcBT1nGTyrCp6zoedsg+dswXMO9Jxj8KwmeM6FnnMNnnMFz3nQc57Bs7rgOR96zjd4zhc8F0DPBQbPGoLnQui50OC5UPBcBD0XGTxrCp6Loedig+diwfNr6Pm1wbOW4LkEei4xeC4RPL+Bnt8YPGsLnkuh51KD51LB81vo+a3Bs47guQx6LjN4LhM8v4Oe3xk86wqey6HncoPncsHze+j5vcGznuC5AnquMHiuEDx/gJ4/GDzrC54roedKg+dKwfNH6PmjwbOB4LkKeq4yeK4SPH+Cnj8ZPBsKnquh52qD52rB82fo+bPBs5HguQZ6rjF4rhE8f4Gevxg8Gwuea6HnWoPnWsHzV+j5q8GzieC5DnquM3iuEzzXQ8/1Bs+mgucG6LnB4LlB8NwIPTcaPJsJnpug5yaD5ybBczP03GzwbC54boGeWwyeWwTPrdBzq8GzheC5DXpuM3huEzy3Q8/tBs+WgucO6LnD4LlD8NwJPXcaPFsJnrug5y6D5y7Bczf03G3wbC147oGeewyeewTPvdBzr8GzjeC5D3ruM3juEzz3Q8/9Bs+2gucB6HnA4HlA8DwIPQ8aPNsJnoeg5yGD5yHB8zD0PGzwbC94HoGeRwyeRwTPo9DzqMGzg+B5DHoeM3geEzyPQ8/jBs+OgucJ6HnC4HlC8DwJPU8aPDsJnqeg5ymD5ynB8zT0PG3w7Cx4noGeZwyeZwTP36DnbwbPLoLnWeh51uB5VvD8HXr+bvDsKnieg57nDJ7nBM8/oOcfBs9ugud56Hne4Hle8PwTev5p8OwueF6AnhcMnhcEz7+g518Gzx6C50XoedHgeVHw/Bt6/m3w7Cl4XoKelwyelwTPy9DzssGzl+B5BXpeMXheETyvQs+rBs/eguc16HnN4HlN8LwOPa8bPPsInjeg5w2D5w3B8yb0vGnw7Ct43oKetwyetwTP29DztsGzn+B5B3reMXjeETzvQs+7Bs/+guc96HnP4HlP8LwPPe8bPAcIng+g5wOD5wPB8yH0fGjwHCh4PoKejwyejwTPx9DzscFzkOD5BHo+MXg+ETyfQs+nBs/Bgucz6PnM4PlM8HwOPZ8bPIcIni+g5wuD5wvB8yX0fGnwHCp4voKerwyerwTP19DztcFzmOD5Bnq+MXi+ETzfQs+3Bs/hguc76PnO4PlO8HwPPd8bPEcInh+g5weD5wfB8yP0/GjwHCl4foKenwyenwTPz9Dzs8FzlOD5BXp+MXh+ETy/qss8/9n7r56jBc8QdZlniLr/3fN/b//bbEjoGdLgOUbwDAU9Qxk8QwmeoaFnaIPnWMEzDPQMY/AMI3iGhZ5hDZ7jBM9w0DOcwTOc4BkeeoY3eI4XPCNAzwgGzwiCZ0ToGdHgOUHwjAQ9Ixk8IwmekaFnZIPnRMEzCvSMYvCMInhGhZ5RDZ6TBM9o0DOawTOa4BkdekY3eE4WPGNAzxgGzxiCZ0zoGdPgOUXwjAU9Yxk8YwmesaFnbIPnVMEzDvSMY/CMI3jGhZ5xDZ7TBM940DOewTOe4BkfesY3eE4XPBNAzwQGzwSCZ0LomdDgOUPwTAQ9Exk8EwmeiaFnYoPnTMEzCfRMYvBMIngmhZ5JDZ6zBM9k0DOZwTOZ4BmAngGD52zBMzn0TG7wTC54poCeKQyecwTPlNAzpcEzpeCZCnqmMnjOFTxTQ8/UBs/Ugmca6JnG4DlP8EwLPdMaPNMKnumgZzqD53zBMz30TG/wTC94ZoCeGQyeCwTPjNAzo8Ezo+CZCXpmMnguFDwzQ8/MBs/MgmcW6JnF4LlI8MwKPbMaPLMKntmgZzaD52LBMzv0zG7wzC545oCeOQyeXwueOaFnToNnTsEzF/TMZfBcInjmhp65DZ65Bc880DOPwfMbwTMv9Mxr8MwreOaDnvkMnksFz/zQM7/BM7/gWQB6FjB4fit4FoSeBQ2eBQXPQtCzkMFzmeBZGHoWNngWFjyLQM8iBs/vBM+i0LOowbOo4FkMehYzeC4XPItDz+IGz+KCZwnoWcLg+b3gWRJ6ljR4lhQ8S0HPUgbPFYJnaehZ2uBZWvAsAz3LGDx/EDzLQs+yBs+ygmc56FnO4LlS8CwPPcsbPMsLnhWgZwWD54+CZ0XoWdHgWVHwrAQ9Kxk8VwmelaFnZYNnZcGzCvSsYvD8SfCsCj2rGjyrCp7VoGc1g+dqwbM69Kxu8KwueNaAnjUMnj8LnjWhZ02DZ03Bsxb0rGXwXCN41oaetQ2etQXPOtCzjsHzF8GzLvSsa/CsK3jWg571DJ5rBc/60LO+wbO+4NkAejYweP4qeDaEng0Nng0Fz0bQs5HBc53g2Rh6NjZ4NhY8m0DPJgbP9YJnU+jZ1ODZVPBsBj2bGTw3CJ7NoWdzg2dzwbMF9Gxh8NwoeLaEni0Nni0Fz1bQs5XBc5Pg2Rp6tjZ4thY820DPNgbPzYJnW+jZ1uDZVvBsBz3bGTy3CJ7toWd7g2d7wbMD9Oxg8NwqeHaEnh0Nnh0Fz07Qs5PBc5vg2Rl6djZ4dhY8u0DPLgbP7YJnV+jZ1eDZVfDsBj27GTx3CJ7doWd3g2d3wbMH9Oxh8NwpePaEnj0Nnj0Fz17Qs5fBc5fg2Rt69jZ49hY8+0DPPgbP3YJnX+jZ1+DZV/DsBz37GTz3CJ79oWd/g2d/wXMA9Bxg8NwreA6EngMNngMFz0HQc5DBc5/gORh6DjZ4DhY8h0DPIQbP/YLnUOg51OA5VPAcBj2HGTwPCJ7Doedwg+dwwXME9Bxh8DwoeI6EniMNniMFz1HQc5TB85DgORp6jjZ4jhY8x0DPMQbPw4LnWOg51uA5VvAcBz3HGTyPCJ7joed4g+d4wXMC9Jxg8DwqeE6EnhMNnhMFz0nQc5LB85jgORl6TjZ4ThY8p0DPKQbP44LnVOg51eA5VfCcBj2nGTxPCJ7Toed0g+d0wXMG9Jxh8DwpeM6EnjMNnjMFz1nQc5bB85TgORt6zjZ4zhY850DPOQbP04LnXOg51+A5V/CcBz3nGTzPCJ7zoed8g+d8wXMB9Fxg8PxN8FwIPRcaPBcKnoug5yKD51nBczH0XGzwXCx4fg09vzZ4/i54LoGeSwyeSwTPb6DnNwbPc4LnUui51OC5VPD8Fnp+a/D8Q/BcBj2XGTyXCZ7fQc/vDJ7nBc/l0HO5wXO54Pk99Pze4Pmn4LkCeq4weK4QPH+Anj8YPC8Iniuh50qD50rB80fo+aPB8y/BcxX0XGXwXCV4/gQ9fzJ4XhQ8V0PP1QbP1YLnz9DzZ4Pn34LnGui5xuC5RvD8BXr+YvC8JHiuhZ5rDZ5rBc9foeevBs/Lguc66LnO4LlO8FwPPdcbPK8Inhug5waD5wbBcyP03GjwvCp4boKemwyemwTPzdBzs8HzmuC5BXpuMXhuETy3Qs+tBs/rguc26LnN4LlN8NwOPbcbPG8Injug5w6D5w7Bcyf03GnwvCl47oKeuwyeuwTP3dBzt8HzluC5B3ruMXjuETz3Qs+9Bs/bguc+6LnP4LlP8NwPPfcbPO8Ingeg5wGD5wHB8yD0PGjwvCt4HoKehwyehwTPw9DzsMHznuB5BHoeMXgeETyPQs+jBs/7gucx6HnM4HlM8DwOPY8bPB8Inieg5wmD5wnB8yT0PGnwfCh4noKepwyepwTP09DztMHzkeB5BnqeMXieETx/g56/GTwfC55noedZg+dZwfN36Pm7wfOJ4HkOep4zeJ4TPP+Ann8YPJ8Knueh53mD53nB80/o+afB85ngeQF6XjB4XhA8/4Kefxk8nwueF6HnRYPnRcHzb+j5t8HzheB5CXpeMnheEjwvQ8/LBs+XgucV6HnF4HlF8LwKPa8aPF8Jnteg5zWD5zXB8zr0vG7wfC143oCeNwyeNwTPm9DzpsHzjeB5C3reMnjeEjxvQ8/bBs+3gucd6HnH4HlH8LwLPe8aPN8Jnveg5z2D5z3B8z70vG/wfC94PoCeDwyeDwTPh9DzocHzg+D5CHo+Mng+EjwfQ8/HBs+PgucT6PnE4PlE8HwKPZ8aPD8Jns+g5zOD5zPB8zn0fG7w/Cx4voCeLwyeLwTPl9DzpcHzi+D5Cnq+Mni+EjxfQ8/XDs+0wXe+Ca4z3Jcv3b76385/9lL9S6dy+99m3wbXGe3L56v/r/NtEJ3/8kJ8lS74znfQ853B853g+R56vjd4hhA8P0DPDwbPD4LnR+j50eAZUvD8BD0/GTw/CZ6foedng2cowfML9Pxi8PwieH5Vj3n+s/dfPUMLniHqMc8Q9f675//e/rfZkNAzpMEzjOAZCnqGMniGEjxDQ8/QBs+wgmcY6BnG4BlG8AwLPcMaPMMJnuGgZziDZzjBMzz0DG/wDC94RoCeEQyeEQTPiNAzosEzguAZCXpGMnhGEjwjQ8/IBs+IgmcU6BnF4BlF8IwKPaMaPCMJntGgZzSDZzTBMzr0jG7wjCx4xoCeMQyeMQTPmNAzpsEziuAZC3rGMnjGEjxjQ8/YBs+ogmcc6BnH4BlH8IwLPeMaPKMJnvGgZzyDZzzBMz70jG/wjC54JoCeCQyeCQTPhNAzocEzhuCZCHomMngmEjwTQ8/EBs+YgmcS6JnE4JlE8EwKPZMaPGMJnsmgZzKDZzLBMwA9AwbP2IJncuiZ3OCZXPBMAT1TGDzjCJ4poWdKg2dKwTMV9Exl8IwreKaGnqkNnqkFzzTQM43BM57gmRZ6pjV4phU800HPdAbP+IJneuiZ3uCZXvDMAD0zGDwTCJ4ZoWdGg2dGwTMT9Mxk8EwoeGaGnpkNnpkFzyzQM4vBM5HgmRV6ZjV4ZhU8s0HPbAbPxIJnduiZ3eCZXfDMAT1zGDyTCJ45oWdOg2dOwTMX9Mxl8EwqeOaGnrkNnrkFzzzQM4/BM5ngmRd65jV45hU880HPfAbPgOCZH3rmN3jmFzwLQM8CBs/kgmdB6FnQ4FlQ8CwEPQsZPFMInoWhZ2GDZ2HBswj0LGLwTCl4FoWeRQ2eRQXPYtCzmMEzleBZHHoWN3gWFzxLQM8SBs/UgmdJ6FnS4FlS8CwFPUsZPNMInqWhZ2mDZ2nBswz0LGPwTCt4loWeZQ2eZQXPctCznMEzneBZHnqWN3iWFzwrQM8KBs/0gmdF6FnR4FlR8KwEPSsZPDMInpWhZ2WDZ2XBswr0rGLwzCh4VoWeVQ2eVQXPatCzmsEzk+BZHXpWN3hWFzxrQM8aBs/MgmdN6FnT4FlT8KwFPWsZPLMInrWhZ22DZ23Bsw70rGPwzCp41oWedQ2edQXPetCznsEzm+BZH3rWN3jWFzwbQM8GBs/sgmdD6NnQ4NlQ8GwEPRsZPHMIno2hZ2ODZ2PBswn0bGLwzCl4NoWeTQ2eTQXPZtCzmcEzl+DZHHo2N3g2FzxbQM8WBs/cgmdL6NnS4NlS8GwFPVsZPPMInq2hZ2uDZ2vBsw30bGPwzCt4toWebQ2ebQXPdtCzncEzn+DZHnq2N3i2Fzw7QM8OBs/8gmdH6NnR4NlR8OwEPTsZPAsInp2hZ2eDZ2fBswv07GLwLCh4doWeXQ2eXQXPbtCzm8GzkODZHXp2N3h2Fzx7QM8eBs/CgmdP6NnT4NlT8OwFPXsZPIsInr2hZ2+DZ2/Bsw/07GPwLCp49oWefQ2efQXPftCzn8GzmODZH3r2N3j2FzwHQM8BBs/igudA6DnQ4DlQ8BwEPQcZPEsInoOh52CD52DBcwj0HGLwLCl4DoWeQw2eQwXPYdBzmMGzlOA5HHoON3gOFzxHQM8RBs/SgudI6DnS4DlS8BwFPUcZPMsInqOh52iD52jBcwz0HGPwLCt4joWeYw2eYwXPcdBznMGznOA5HnqON3iOFzwnQM8JBs/ygudE6DnR4DlR8JwEPScZPCsInpOh52SD52TBcwr0nGLwrCh4ToWeUw2eUwXPadBzmsGzkuA5HXpON3hOFzxnQM8ZBs/KgudM6DnT4DlT8JwFPWcZPKsInrOh52yD52zBcw70nGPwrCp4zoWecw2ecwXPedBznsGzmuA5H3rON3jOFzwXQM8FBs/qgudC6LnQ4LlQ8FwEPRcZPGsInouh52KD52LB82vo+bXBs6bguQR6LjF4LhE8v4Ge3xg8awmeS6HnUoPnUsHzW+j5rcGztuC5DHouM3guEzy/g57fGTzrCJ7Loedyg+dywfN76Pm9wbOu4LkCeq4weK4QPH+Anj8YPOsJniuh50qD50rB80fo+aPBs77guQp6rjJ4rhI8f4KePxk8Gwieq6HnaoPnasHzZ+j5s8GzoeC5BnquMXiuETx/gZ6/GDwbCZ5roedag+dawfNX6PmrwbOx4LkOeq4zeK4TPNdDz/UGzyaC5wboucHguUHw3Ag9Nxo8mwqem6DnJoPnJsFzM/TcbPBsJnhugZ5bDJ5bBM+t0HOrwbO54LkNem4zeG4TPLdDz+0GzxaC5w7oucPguUPw3Ak9dxo8Wwqeu6DnLoPnLsFzN/TcbfBsJXjugZ57DJ57BM+90HOvwbO14LkPeu4zeO4TPPdDz/0GzzaC5wHoecDgeUDwPAg9Dxo82wqeh6DnIYPnIcHzMPQ8bPBsJ3gegZ5HDJ5HBM+j0POowbO94HkMeh4zeB4TPI9Dz+MGzw6C5wnoecLgeULwPAk9Txo8Owqep6DnKYPnKcHzNPQ8bfDsJHiegZ5nDJ5nBM/foOdvBs/OgudZ6HnW4HlW8Pwdev5u8OwieJ6DnucMnucEzz+g5x8Gz66C53noed7geV7w/BN6/mnw7CZ4XoCeFwyeFwTPv6DnXwbP7oLnReh50eB5UfD8G3r+bfDsIXhegp6XDJ6XBM/L0POywbOn4HkFel4xeF4RPK9Cz6sGz16C5zXoec3geU3wvA49rxs8ewueN6DnDYPnDcHzJvS8afDsI3jegp63DJ63BM/b0PO2wbOv4HkHet4xeN4RPO9Cz7sGz36C5z3oec/geU/wvA897xs8+wueD6DnA4PnA8HzIfR8aPAcIHg+gp6PDJ6PBM/H0POxwXOg4PkEej4xeD4RPJ9Cz6cGz0GC5zPo+czg+UzwfA49nxs8BwueL6DnC4PnC8HzJfR8afAcIni+gp6vDJ6vBM/X0PO1wXOo4PkGer4xeL4RPN9Cz7cGz2GC5zvo+c7g+U7wfA893xs8hwueH6DnB4PnB8HzI/T8aPAcIXh+gp6fDJ6fBM/P0POzwXOk4PkFen4xeH4RPL+qzzz/2fuvnqMEzxD1mWeI+v/d839v/9tsSOgZ0uA5WvAMBT1DGTxDCZ6hoWdog+cYwTMM9Axj8AwjeIaFnmENnmMFz3DQM5zBM5zgGR56hjd4jhM8I0DPCAbPCIJnROgZ0eA5XvCMBD0jGTwjCZ6RoWdkg+cEwTMK9Ixi8IwieEaFnlENnhMFz2jQM5rBM5rgGR16Rjd4ThI8Y0DPGAbPGIJnTOgZ0+A5WfCMBT1jGTxjCZ6xoWdsg+cUwTMO9Ixj8IwjeMaFnnENnlMFz3jQM57BM57gGR96xjd4ThM8E0DPBAbPBIJnQuiZ0OA5XfBMBD0TGTwTCZ6JoWdig+cMwTMJ9Exi8EwieCaFnkkNnjMFz2TQM5nBM5ngGYCeAYPnLMEzOfRMbvBMLnimgJ4pDJ6zBc+U0DOlwTOl4JkKeqYyeM4RPFNDz9QGz9SCZxromcbgOVfwTAs90xo80wqe6aBnOoPnPMEzPfRMb/BML3hmgJ4ZDJ7zBc+M0DOjwTOj4JkJemYyeC4QPDNDz8wGz8yCZxbomcXguVDwzAo9sxo8swqe2aBnNoPnIsEzO/TMbvDMLnjmgJ45DJ6LBc+c0DOnwTOn4JkLeuYyeH4teOaGnrkNnrkFzzzQM4/Bc4ngmRd65jV45hU880HPfAbPbwTP/NAzv8Ezv+BZAHoWMHguFTwLQs+CBs+Cgmch6FnI4Pmt4FkYehY2eBYWPItAzyIGz2WCZ1HoWdTgWVTwLAY9ixk8vxM8i0PP4gbP4oJnCehZwuC5XPAsCT1LGjxLCp6loGcpg+f3gmdp6Fna4Fla8CwDPcsYPFcInmWhZ1mDZ1nBsxz0LGfw/EHwLA89yxs8ywueFaBnBYPnSsGzIvSsaPCsKHhWgp6VDJ4/Cp6VoWdlg2dlwbMK9Kxi8FwleFaFnlUNnlUFz2rQs5rB8yfBszr0rG7wrC541oCeNQyeqwXPmtCzpsGzpuBZC3rWMnj+LHjWhp61DZ61Bc860LOOwXON4FkXetY1eNYVPOtBz3oGz18Ez/rQs77Bs77g2QB6NjB4rhU8G0LPhgbPhoJnI+jZyOD5q+DZGHo2Nng2FjybQM8mBs91gmdT6NnU4NlU8GwGPZsZPNcLns2hZ3ODZ3PBswX0bGHw3CB4toSeLQ2eLQXPVtCzlcFzo+DZGnq2Nni2FjzbQM82Bs9Ngmdb6NnW4NlW8GwHPdsZPDcLnu2hZ3uDZ3vBswP07GDw3CJ4doSeHQ2eHQXPTtCzk8Fzq+DZGXp2Nnh2Fjy7QM8uBs9tgmdX6NnV4NlV8OwGPbsZPLcLnt2hZ3eDZ3fBswf07GHw3CF49oSePQ2ePQXPXtCzl8Fzp+DZG3r2Nnj2Fjz7QM8+Bs9dgmdf6NnX4NlX8OwHPfsZPHcLnv2hZ3+DZ3/BcwD0HGDw3CN4DoSeAw2eAwXPQdBzkMFzr+A5GHoONngOFjyHQM8hBs99gudQ6DnU4DlU8BwGPYcZPPcLnsOh53CD53DBcwT0HGHwPCB4joSeIw2eIwXPUdBzlMHzoOA5GnqONniOFjzHQM8xBs9DgudY6DnW4DlW8BwHPccZPA8LnuOh53iD53jBcwL0nGDwPCJ4ToSeEw2eEwXPSdBzksHzqOA5GXpONnhOFjynQM8pBs9jgudU6DnV4DlV8JwGPacZPI8LntOh53SD53TBcwb0nGHwPCF4zoSeMw2eMwXPWdBzlsHzpOA5G3rONnjOFjznQM85Bs9Tgudc6DnX4DlX8JwHPecZPE8LnvOh53yD53zBcwH0XGDwPCN4LoSeCw2eCwXPRdBzkcHzN8FzMfRcbPBcLHh+DT2/NnieFTyXQM8lBs8lguc30PMbg+fvgudS6LnU4LlU8PwWen5r8DwneC6DnssMnssEz++g53cGzz8Ez+XQc7nBc7ng+T30/N7geV7wXAE9Vxg8VwieP0DPHwyefwqeK6HnSoPnSsHzR+j5o8HzguC5CnquMniuEjx/gp4/GTz/EjxXQ8/VBs/VgufP0PNng+dFwXMN9Fxj8FwjeP4CPX8xeP4teK6FnmsNnmsFz1+h568Gz0uC5zrouc7guU7wXA891xs8LwueG6DnBoPnBsFzI/TcaPC8Inhugp6bDJ6bBM/N0HOzwfOq4LkFem4xeG4RPLdCz60Gz2uC5zbouc3guU3w3A49txs8rwueO6DnDoPnDsFzJ/TcafC8IXjugp67DJ67BM/d0HO3wfOm4LkHeu4xeO4RPPdCz70Gz1uC5z7ouc/guU/w3A899xs8bwueB6DnAYPnAcHzIPQ8aPC8I3gegp6HDJ6HBM/D0POwwfOu4HkEeh4xeB4RPI9Cz6MGz3uC5zHoeczgeUzwPA49jxs87wueJ6DnCYPnCcHzJPQ8afB8IHiegp6nDJ6nBM/T0PO0wfOh4HkGep4xeJ4RPH+Dnr8ZPB8Jnmeh51mD51nB83fo+bvB87HgeQ56njN4nhM8/4Cefxg8nwie56HneYPnecHzT+j5p8HzqeB5AXpeMHheEDz/gp5/GTyfCZ4XoedFg+dFwfNv6Pm3wfO54HkJel4yeF4SPC9Dz8sGzxeC5xXoecXgeUXwvAo9rxo8Xwqe16DnNYPnNcHzOvS8bvB8JXjegJ43DJ43BM+b0POmwfO14HkLet4yeN4SPG9Dz9sGzzeC5x3oecfgeUfwvAs97xo83wqe96DnPYPnPcHzPvS8b/B8J3g+gJ4PDJ4PBM+H0POhwfO94PkIej4yeD4SPB9Dz8cGzw+C5xPo+cTg+UTwfAo9nxo8Pwqez6DnM4PnM8HzOfR8bvD8JHi+gJ4vDJ4vBM+X0POlwfOz4PkKer4yeL4SPF9Dz9cGzy+C5xvo+cbg+UbwfAs93xo8v0offOc76PnO4PlO8HwPPd8bPEMInh+g5weD5wfB8yP0/GjwDCl4foKenwyenwTPz9Dzs8EzlOD5BXp+MXh+ETy/asA8/9n7r56hBc8QDZhniAb/3fN/b//bbEjoGdLgGUbwDAU9Qxk8QwmeoaFnaINnWMEzDPQMY/AMI3iGhZ5hDZ7hBM9w0DOcwTOc4BkeeoY3eIYXPCNAzwgGzwiCZ0ToGdHgGUHwjAQ9Ixk8IwmekaFnZINnRMEzCvSMYvCMInhGhZ5RDZ6RBM9o0DOawTOa4BkdekY3eEYWPGNAzxgGzxiCZ0zoGdPgGUXwjAU9Yxk8YwmesaFnbINnVMEzDvSMY/CMI3jGhZ5xDZ7RBM940DOewTOe4BkfesY3eEYXPBNAzwQGzwSCZ0LomdDgGUPwTAQ9Exk8EwmeiaFnYoNnTMEzCfRMYvBMIngmhZ5JDZ6xBM9k0DOZwTOZ4BmAngGDZ2zBMzn0TG7wTC54poCeKQyecQTPlNAzpcEzpeCZCnqmMnjGFTxTQ8/UBs/Ugmca6JnG4BlP8EwLPdMaPNMKnumgZzqDZ3zBMz30TG/wTC94ZoCeGQyeCQTPjNAzo8Ezo+CZCXpmMngmFDwzQ8/MBs/MgmcW6JnF4JlI8MwKPbMaPLMKntmgZzaDZ2LBMzv0zG7wzC545oCeOQyeSQTPnNAzp8Ezp+CZC3rmMngmFTxzQ8/cBs/cgmce6JnH4JlM8MwLPfMaPPMKnvmgZz6DZ0DwzA898xs88wueBaBnAYNncsGzIPQsaPAsKHgWgp6FDJ4pBM/C0LOwwbOw4FkEehYxeKYUPItCz6IGz6KCZzHoWczgmUrwLA49ixs8iwueJaBnCYNnasGzJPQsafAsKXiWgp6lDJ5pBM/S0LO0wbO04FkGepYxeKYVPMtCz7IGz7KCZznoWc7gmU7wLA89yxs8ywueFaBnBYNnesGzIvSsaPCsKHhWgp6VDJ4ZBM/K0LOywbOy4FkFelYxeGYUPKtCz6oGz6qCZzXoWc3gmUnwrA49qxs8qwueNaBnDYNnZsGzJvSsafCsKXjWgp61DJ5ZBM/a0LO2wbO24FkHetYxeGYVPOtCz7oGz7qCZz3oWc/gmU3wrA896xs86wueDaBnA4NndsGzIfRsaPBsKHg2gp6NDJ45BM/G0LOxwbOx4NkEejYxeOYUPJtCz6YGz6aCZzPo2czgmUvwbA49mxs8mwueLaBnC4NnbsGzJfRsafBsKXi2gp6tDJ55BM/W0LO1wbO14NkGerYxeOYVPNtCz7YGz7aCZzvo2c7gmU/wbA892xs82wueHaBnB4NnfsGzI/TsaPDsKHh2gp6dDJ4FBM/O0LOzwbOz4NkFenYxeBYUPLtCz64Gz66CZzfo2c3gWUjw7A49uxs8uwuePaBnD4NnYcGzJ/TsafDsKXj2gp69DJ5FBM/e0LO3wbO34NkHevYxeBYVPPtCz74Gz76CZz/o2c/gWUzw7A89+xs8+wueA6DnAINnccFzIPQcaPAcKHgOgp6DDJ4lBM/B0HOwwXOw4DkEeg4xeJYUPIdCz6EGz6GC5zDoOczgWUrwHA49hxs8hwueI6DnCINnacFzJPQcafAcKXiOgp6jDJ5lBM/R0HO0wXO04DkGeo4xeJYVPMdCz7EGz7GC5zjoOc7gWU7wHA89xxs8xwueE6DnBINnecFzIvScaPCcKHhOgp6TDJ4VBM/J0HOywXOy4DkFek4xeFYUPKdCz6kGz6mC5zToOc3gWUnwnA49pxs8pwueM6DnDINnZcFzJvScafCcKXjOgp6zDJ5VBM/Z0HO2wXO24DkHes4xeFYVPOdCz7kGz7mC5zzoOc/gWU3wnA895xs85wueC6DnAoNndcFzIfRcaPBcKHgugp6LDJ41BM/F0HOxwXOx4Pk19Pza4FlT8FwCPZcYPJcInt9Az28MnrUEz6XQc6nBc6ng+S30/NbgWVvwXAY9lxk8lwme30HP7wyedQTP5dBzucFzueD5PfT83uBZV/BcAT1XGDxXCJ4/QM8fDJ71BM+V0HOlwXOl4Pkj9PzR4Flf8FwFPVcZPFcJnj9Bz58Mng0Ez9XQc7XBc7Xg+TP0/Nng2VDwXAM91xg81wiev0DPXwyejQTPtdBzrcFzreD5K/T81eDZWPBcBz3XGTzXCZ7roed6g2cTwXMD9Nxg8NwgeG6EnhsNnk0Fz03Qc5PBc5PguRl6bjZ4NhM8t0DPLQbPLYLnVui51eDZXPDcBj23GTy3CZ7boed2g2cLwXMH9Nxh8NwheO6EnjsNni0Fz13Qc5fBc5fguRt67jZ4thI890DPPQbPPYLnXui51+DZWvDcBz33GTz3CZ77oed+g2cbwfMA9Dxg8DwgeB6EngcNnm0Fz0PQ85DB85DgeRh6HjZ4thM8j0DPIwbPI4LnUeh51ODZXvA8Bj2PGTyPCZ7Hoedxg2cHwfME9Dxh8DwheJ6EnicNnh0Fz1PQ85TB85TgeRp6njZ4dhI8z0DPMwbPM4Lnb9DzN4NnZ8HzLPQ8a/A8K3j+Dj1/N3h2ETzPQc9zBs9zgucf0PMPg2dXwfM89Dxv8DwveP4JPf80eHYTPC9AzwsGzwuC51/Q8y+DZ3fB8yL0vGjwvCh4/g09/zZ49hA8L0HPSwbPS4LnZeh52eDZU/C8Aj2vGDyvCJ5XoedVg2cvwfMa9Lxm8LwmeF6HntcNnr0FzxvQ84bB84bgeRN63jR49hE8b0HPWwbPW4Lnbeh52+DZV/C8Az3vGDzvCJ53oeddg2c/wfMe9Lxn8LwneN6HnvcNnv0FzwfQ84HB84Hg+RB6PjR4DhA8H0HPRwbPR4LnY+j52OA5UPB8Aj2fGDyfCJ5PoedTg+cgwfMZ9Hxm8HwmeD6Hns8NnoMFzxfQ84XB84Xg+RJ6vjR4DhE8X0HPVwbPV4Lna+j52uA5VPB8Az3fGDzfCJ5voedbg+cwwfMd9Hxn8HwneL6Hnu8NnsMFzw/Q84PB84Pg+RF6fjR4jhA8P0HPTwbPT4LnZ+j52eA5UvD8Aj2/GDy/CJ5fNWSe/+z9V89RgmeIhswzRMP/7vm/t/9tNiT0DGnwHC14hoKeoQyeoQTP0NAztMFzjOAZBnqGMXiGETzDQs+wBs+xgmc46BnO4BlO8AwPPcMbPMcJnhGgZwSDZwTBMyL0jGjwHC94RoKekQyekQTPyNAzssFzguAZBXpGMXhGETyjQs+oBs+Jgmc06BnN4BlN8IwOPaMbPCcJnjGgZwyDZwzBMyb0jGnwnCx4xoKesQyesQTP2NAztsFziuAZB3rGMXjGETzjQs+4Bs+pgmc86BnP4BlP8IwPPeMbPKcJngmgZwKDZwLBMyH0TGjwnC54JoKeiQyeiQTPxNAzscFzhuCZBHomMXgmETyTQs+kBs+Zgmcy6JnM4JlM8AxAz4DBc5bgmRx6Jjd4Jhc8U0DPFAbP2YJnSuiZ0uCZUvBMBT1TGTznCJ6poWdqg2dqwTMN9Exj8JwreKaFnmkNnmkFz3TQM53Bc57gmR56pjd4phc8M0DPDAbP+YJnRuiZ0eCZUfDMBD0zGTwXCJ6ZoWdmg2dmwTML9Mxi8FwoeGaFnlkNnlkFz2zQM5vBc5HgmR16Zjd4Zhc8c0DPHAbPxYJnTuiZ0+CZU/DMBT1zGTy/FjxzQ8/cBs/cgmce6JnH4LlE8MwLPfMaPPMKnvmgZz6D5zeCZ37omd/gmV/wLAA9Cxg8lwqeBaFnQYNnQcGzEPQsZPD8VvAsDD0LGzwLC55FoGcRg+cywbMo9Cxq8CwqeBaDnsUMnt8JnsWhZ3GDZ3HBswT0LGHwXC54loSeJQ2eJQXPUtCzlMHze8GzNPQsbfAsLXiWgZ5lDJ4rBM+y0LOswbOs4FkOepYzeP4geJaHnuUNnuUFzwrQs4LBc6XgWRF6VjR4VhQ8K0HPSgbPHwXPytCzssGzsuBZBXpWMXiuEjyrQs+qBs+qgmc16FnN4PmT4FkdelY3eFYXPGtAzxoGz9WCZ03oWdPgWVPwrAU9axk8fxY8a0PP2gbP2oJnHehZx+C5RvCsCz3rGjzrCp71oGc9g+cvgmd96Fnf4Flf8GwAPRsYPNcKng2hZ0ODZ0PBsxH0bGTw/FXwbAw9Gxs8GwueTaBnE4PnOsGzKfRsavBsKng2g57NDJ7rBc/m0LO5wbO54NkCerYweG4QPFtCz5YGz5aCZyvo2crguVHwbA09Wxs8WwuebaBnG4PnJsGzLfRsa/BsK3i2g57tDJ6bBc/20LO9wbO94NkBenYweG4RPDtCz44Gz46CZyfo2cnguVXw7Aw9Oxs8OwueXaBnF4PnNsGzK/TsavDsKnh2g57dDJ7bBc/u0LO7wbO74NkDevYweO4QPHtCz54Gz56CZy/o2cvguVPw7A09exs8ewuefaBnH4PnLsGzL/Tsa/DsK3j2g579DJ67Bc/+0LO/wbO/4DkAeg4weO4RPAdCz4EGz4GC5yDoOcjguVfwHAw9Bxs8BwueQ6DnEIPnPsFzKPQcavAcKngOg57DDJ77Bc/h0HO4wXO44DkCeo4weB4QPEdCz5EGz5GC5yjoOcrgeVDwHA09Rxs8RwueY6DnGIPnIcFzLPQca/AcK3iOg57jDJ6HBc/x0HO8wXO84DkBek4weB4RPCdCz4kGz4mC5yToOcngeVTwnAw9Jxs8JwueU6DnFIPnMcFzKvScavCcKnhOg57TDJ7HBc/p0HO6wXO64DkDes4weJ4QPGdCz5kGz5mC5yzoOcvgeVLwnA09Zxs8Zwuec6DnHIPnKcFzLvSca/CcK3jOg57zDJ6nBc/50HO+wXO+4LkAei4weJ4RPBdCz4UGz4WC5yLoucjg+ZvguRh6LjZ4LhY8v4aeXxs8zwqeS6DnEoPnEsHzG+j5jcHzd8FzKfRcavBcKnh+Cz2/NXieEzyXQc9lBs9lgud30PM7g+cfgudy6Lnc4Llc8Pween5v8DwveK6AnisMnisEzx+g5w8Gzz8Fz5XQc6XBc6Xg+SP0/NHgeUHwXAU9Vxk8VwmeP0HPnwyefwmeq6HnaoPnasHzZ+j5s8HzouC5BnquMXiuETx/gZ6/GDz/FjzXQs+1Bs+1guev0PNXg+clwXMd9Fxn8FwneK6HnusNnpcFzw3Qc4PBc4PguRF6bjR4XhE8N0HPTQbPTYLnZui52eB5VfDcAj23GDy3CJ5boedWg+c1wXMb9Nxm8NwmeG6HntsNntcFzx3Qc4fBc4fguRN67jR43hA8d0HPXQbPXYLnbui52+B5U/DcAz33GDz3CJ57oedeg+ctwXMf9Nxn8NwneO6HnvsNnrcFzwPQ84DB84DgeRB6HjR43hE8D0HPQwbPQ4LnYeh52OB5V/A8Aj2PGDyPCJ5HoedRg+c9wfMY9Dxm8DwmeB6HnscNnvcFzxPQ84TB84TgeRJ6njR4PhA8T0HPUwbPU4Lnaeh52uD5UPA8Az3PGDzPCJ6/Qc/fDJ6PBM+z0POswfOs4Pk79Pzd4PlY8DwHPc8ZPM8Jnn9Azz8Mnk8Ez/PQ87zB87zg+Sf0/NPg+VTwvAA9Lxg8Lwief0HPvwyezwTPi9DzosHzouD5N/T82+D5XPC8BD0vGTwvCZ6Xoedlg+cLwfMK9Lxi8LwieF6FnlcNni8Fz2vQ85rB85rgeR16Xjd4vhI8b0DPGwbPG4LnTeh50+D5WvC8BT1vGTxvCZ63oedtg+cbwfMO9Lxj8LwjeN6FnncNnm8Fz3vQ857B857geR963jd4vhM8H0DPBwbPB4LnQ+j50OD5XvB8BD0fGTwfCZ6Poedjg+cHwfMJ9Hxi8HwieD6Fnk8Nnh8Fz2fQ85nB85ng+Rx6Pjd4fhI8X0DPFwbPF4LnS+j50uGZMfjOVw2D/TfE/+v8Zy/iv3Qqt/9t9nXQnSH/X+frIDr/5YX4LHi+gZ5vDJ5vBM+30POtwfOL4PkOer4zeL4TPN9Dz/cGz68yBd/5AXp+MHh+EDw/Qs+PBs8Qgucn6PnJ4PlJ8PwMPT8bPEMKnl+g5xeD5xfB86tGzPOfvf/qGUrwDNGIeYZo9N89//f2v82GhJ4hDZ6hBc9Q0DOUwTOU4BkaeoY2eIYRPMNAzzAGzzCCZ1joGdbgGVbwDAc9wxk8wwme4aFneINnOMEzAvSMYPCMIHhGhJ4RDZ7hBc9I0DOSwTOS4BkZekY2eEYQPKNAzygGzyiCZ1ToGdXgGVHwjAY9oxk8owme0aFndINnJMEzBvSMYfCMIXjGhJ4xDZ6RBc9Y0DOWwTOW4BkbesY2eEYRPONAzzgGzziCZ1zoGdfgGVXwjAc94xk84wme8aFnfINnNMEzAfRMYPBMIHgmhJ4JDZ7RBc9E0DORwTOR4JkYeiY2eMYQPJNAzyQGzySCZ1LomdTgGVPwTAY9kxk8kwmeAegZMHjGEjyTQ8/kBs/kgmcK6JnC4Blb8EwJPVMaPFMKnqmgZyqDZxzBMzX0TG3wTC14poGeaQyecQXPtNAzrcEzreCZDnqmM3jGEzzTQ8/0Bs/0gmcG6JnB4Blf8MwIPTMaPDMKnpmgZyaDZwLBMzP0zGzwzCx4ZoGeWQyeCQXPrNAzq8Ezq+CZDXpmM3gmEjyzQ8/sBs/sgmcO6JnD4JlY8MwJPXMaPHMKnrmgZy6DZxLBMzf0zG3wzC145oGeeQyeSQXPvNAzr8Ezr+CZD3rmM3gmEzzzQ8/8Bs/8gmcB6FnA4BkQPAtCz4IGz4KCZyHoWcjgmVzwLAw9Cxs8CwueRaBnEYNnCsGzKPQsavAsKngWg57FDJ4pBc/i0LO4wbO44FkCepYweKYSPEtCz5IGz5KCZynoWcrgmVrwLA09Sxs8SwueZaBnGYNnGsGzLPQsa/AsK3iWg57lDJ5pBc/y0LO8wbO84FkBelYweKYTPCtCz4oGz4qCZyXoWcngmV7wrAw9Kxs8KwueVaBnFYNnBsGzKvSsavCsKnhWg57VDJ4ZBc/q0LO6wbO64FkDetYweGYSPGtCz5oGz5qCZy3oWcvgmVnwrA09axs8awuedaBnHYNnFsGzLvSsa/CsK3jWg571DJ5ZBc/60LO+wbO+4NkAejYweGYTPBtCz4YGz4aCZyPo2cjgmV3wbAw9Gxs8GwueTaBnE4NnDsGzKfRsavBsKng2g57NDJ45Bc/m0LO5wbO54NkCerYweOYSPFtCz5YGz5aCZyvo2crgmVvwbA09Wxs8WwuebaBnG4NnHsGzLfRsa/BsK3i2g57tDJ55Bc/20LO9wbO94NkBenYweOYTPDtCz44Gz46CZyfo2cngmV/w7Aw9Oxs8OwueXaBnF4NnAcGzK/TsavDsKnh2g57dDJ4FBc/u0LO7wbO74NkDevYweBYSPHtCz54Gz56CZy/o2cvgWVjw7A09exs8ewuefaBnH4NnEcGzL/Tsa/DsK3j2g579DJ5FBc/+0LO/wbO/4DkAeg4weBYTPAdCz4EGz4GC5yDoOcjgWVzwHAw9Bxs8BwueQ6DnEINnCcFzKPQcavAcKngOg57DDJ4lBc/h0HO4wXO44DkCeo4weJYSPEdCz5EGz5GC5yjoOcrgWVrwHA09Rxs8RwueY6DnGINnGcFzLPQca/AcK3iOg57jDJ5lBc/x0HO8wXO84DkBek4weJYTPCdCz4kGz4mC5yToOcngWV7wnAw9Jxs8JwueU6DnFINnBcFzKvScavCcKnhOg57TDJ4VBc/p0HO6wXO64DkDes4weFYSPGdCz5kGz5mC5yzoOcvgWVnwnA09Zxs8Zwuec6DnHINnFcFzLvSca/CcK3jOg57zDJ5VBc/50HO+wXO+4LkAei4weFYTPBdCz4UGz4WC5yLoucjgWV3wXAw9Fxs8FwueX0PPrw2eNQTPJdBzicFzieD5DfT8xuBZU/BcCj2XGjyXCp7fQs9vDZ61BM9l0HOZwXOZ4Pkd9PzO4Flb8FwOPZcbPJcLnt9Dz+8NnnUEzxXQc4XBc4Xg+QP0/MHgWVfwXAk9Vxo8VwqeP0LPHw2e9QTPVdBzlcFzleD5E/T8yeBZX/BcDT1XGzxXC54/Q8+fDZ4NBM810HONwXON4PkL9PzF4NlQ8FwLPdcaPNcKnr9Cz18Nno0Ez3XQc53Bc53guR56rjd4NhY8N0DPDQbPDYLnRui50eDZRPDcBD03GTw3CZ6boedmg2dTwXML9Nxi8NwieG6FnlsNns0Ez23Qc5vBc5vguR16bjd4Nhc8d0DPHQbPHYLnTui50+DZQvDcBT13GTx3CZ67oedug2dLwXMP9Nxj8NwjeO6FnnsNnq0Ez33Qc5/Bc5/guR967jd4thY8D0DPAwbPA4LnQeh50ODZRvA8BD0PGTwPCZ6Hoedhg2dbwfMI9Dxi8DwieB6FnkcNnu0Ez2PQ85jB85jgeRx6Hjd4thc8T0DPEwbPE4LnSeh50uDZQfA8BT1PGTxPCZ6noedpg2dHwfMM9Dxj8DwjeP4GPX8zeHYSPM9Cz7MGz7OC5+/Q83eDZ2fB8xz0PGfwPCd4/gE9/zB4dhE8z0PP8wbP84Lnn9DzT4NnV8HzAvS8YPC8IHj+BT3/Mnh2EzwvQs+LBs+Lguff0PNvg2d3wfMS9Lxk8LwkeF6GnpcNnj0EzyvQ84rB84rgeRV6XjV49hQ8r0HPawbPa4Lndeh53eDZS/C8AT1vGDxvCJ43oedNg2dvwfMW9Lxl8LwleN6GnrcNnn0EzzvQ847B847geRd63jV49hU870HPewbPe4Lnfeh53+DZT/B8AD0fGDwfCJ4PoedDg2d/wfMR9Hxk8HwkeD6Gno8NngMEzyfQ84nB84ng+RR6PjV4DhQ8n0HPZwbPZ4Lnc+j53OA5SPB8AT1fGDxfCJ4voedLg+dgwfMV9Hxl8HwleL6Gnq8NnkMEzzfQ843B843g+RZ6vjV4DhU830HPdwbPd4Lne+j53uA5TPD8AD0/GDw/CJ4foedHg+dwwfMT9Pxk8PwkeH6Gnp8NniMEzy/Q84vB84vg+VVj5vnP3n/1HCl4hmjMPEM0/u+e/3v732ZDQs+QBs9Rgmco6BnK4BlK8AwNPUMbPEcLnmGgZxiDZxjBMyz0DGvwHCN4hoOe4Qye4QTP8NAzvMFzrOAZAXpGMHhGEDwjQs+IBs9xgmck6BnJ4BlJ8IwMPSMbPMcLnlGgZxSDZxTBMyr0jGrwnCB4RoOe0Qye0QTP6NAzusFzouAZA3rGMHjGEDxjQs+YBs9Jgmcs6BnL4BlL8IwNPWMbPCcLnnGgZxyDZxzBMy70jGvwnCJ4xoOe8Qye8QTP+NAzvsFzquCZAHomMHgmEDwTQs+EBs9pgmci6JnI4JlI8EwMPRMbPKcLnkmgZxKDZxLBMyn0TGrwnCF4JoOeyQyeyQTPAPQMGDxnCp7JoWdyg2dywTMF9Exh8JwleKaEnikNnikFz1TQM5XBc7bgmRp6pjZ4phY800DPNAbPOYJnWuiZ1uCZVvBMBz3TGTznCp7poWd6g2d6wTMD9Mxg8JwneGaEnhkNnhkFz0zQM5PBc77gmRl6ZjZ4ZhY8s0DPLAbPBYJnVuiZ1eCZVfDMBj2zGTwXCp7ZoWd2g2d2wTMH9Mxh8FwkeOaEnjkNnjkFz1zQM5fBc7HgmRt65jZ45hY880DPPAbPrwXPvNAzr8Ezr+CZD3rmM3guETzzQ8/8Bs/8gmcB6FnA4PmN4FkQehY0eBYUPAtBz0IGz6WCZ2HoWdjgWVjwLAI9ixg8vxU8i0LPogbPooJnMehZzOC5TPAsDj2LGzyLC54loGcJg+d3gmdJ6FnS4FlS8CwFPUsZPJcLnqWhZ2mDZ2nBswz0LGPw/F7wLAs9yxo8ywqe5aBnOYPnCsGzPPQsb/AsL3hWgJ4VDJ4/CJ4VoWdFg2dFwbMS9Kxk8FwpeFaGnpUNnpUFzyrQs4rB80fBsyr0rGrwrCp4VoOe1QyeqwTP6tCzusGzuuBZA3rWMHj+JHjWhJ41DZ41Bc9a0LOWwXO14FkbetY2eNYWPOtAzzoGz58Fz7rQs67Bs67gWQ961jN4rhE860PP+gbP+oJnA+jZwOD5i+DZEHo2NHg2FDwbQc9GBs+1gmdj6NnY4NlY8GwCPZsYPH8VPJtCz6YGz6aCZzPo2czguU7wbA49mxs8mwueLaBnC4PnesGzJfRsafBsKXi2gp6tDJ4bBM/W0LO1wbO14NkGerYxeG4UPNtCz7YGz7aCZzvo2c7guUnwbA892xs82wueHaBnB4PnZsGzI/TsaPDsKHh2gp6dDJ5bBM/O0LOzwbOz4NkFenYxeG4VPLtCz64Gz66CZzfo2c3guU3w7A49uxs8uwuePaBnD4PndsGzJ/TsafDsKXj2gp69DJ47BM/e0LO3wbO34NkHevYxeO4UPPtCz74Gz76CZz/o2c/guUvw7A89+xs8+wueA6DnAIPnbsFzIPQcaPAcKHgOgp6DDJ57BM/B0HOwwXOw4DkEeg4xeO4VPIdCz6EGz6GC5zDoOczguU/wHA49hxs8hwueI6DnCIPnfsFzJPQcafAcKXiOgp6jDJ4HBM/R0HO0wXO04DkGeo4xeB4UPMdCz7EGz7GC5zjoOc7geUjwHA89xxs8xwueE6DnBIPnYcFzIvScaPCcKHhOgp6TDJ5HBM/J0HOywXOy4DkFek4xeB4VPKdCz6kGz6mC5zToOc3geUzwnA49pxs8pwueM6DnDIPnccFzJvScafCcKXjOgp6zDJ4nBM/Z0HO2wXO24DkHes4xeJ4UPOdCz7kGz7mC5zzoOc/geUrwnA895xs85wueC6DnAoPnacFzIfRcaPBcKHgugp6LDJ5nBM/F0HOxwXOx4Pk19Pza4Pmb4LkEei4xeC4RPL+Bnt8YPM8Knkuh51KD51LB81vo+a3B83fBcxn0XGbwXCZ4fgc9vzN4nhM8l0PP5QbP5YLn99Dze4PnH4LnCui5wuC5QvD8AXr+YPA8L3iuhJ4rDZ4rBc8foeePBs8/Bc9V0HOVwXOV4PkT9PzJ4HlB8FwNPVcbPFcLnj9Dz58Nnn8Jnmug5xqD5xrB8xfo+YvB86LguRZ6rjV4rhU8f4Wevxo8/xY810HPdQbPdYLneui53uB5SfDcAD03GDw3CJ4boedGg+dlwXMT9Nxk8NwkeG6GnpsNnlcEzy3Qc4vBc4vguRV6bjV4XhU8t0HPbQbPbYLndui53eB5TfDcAT13GDx3CJ47oedOg+d1wXMX9Nxl8NwleO6GnrsNnjcEzz3Qc4/Bc4/guRd67jV43hQ890HPfQbPfYLnfui53+B5S/A8AD0PGDwPCJ4HoedBg+dtwfMQ9Dxk8DwkeB6GnocNnncEzyPQ84jB84jgeRR6HjV43hU8j0HPYwbPY4Lnceh53OB5T/A8AT1PGDxPCJ4noedJg+d9wfMU9Dxl8DwleJ6GnqcNng8EzzPQ84zB84zg+Rv0/M3g+VDwPAs9zxo8zwqev0PP3w2ejwTPc9DznMHznOD5B/T8w+D5WPA8Dz3PGzzPC55/Qs8/DZ5PBM8L0POCwfOC4PkX9PzL4PlU8LwIPS8aPC8Knn9Dz78Nns8Ez0vQ85LB85LgeRl6XjZ4Phc8r0DPKwbPK4LnVeh51eD5QvC8Bj2vGTyvCZ7Xoed1g+dLwfMG9Lxh8LwheN6EnjcNnq8Ez1vQ85bB85bgeRt63jZ4vhY870DPOwbPO4LnXeh51+D5RvC8Bz3vGTzvCZ73oed9g+dbwfMB9Hxg8HwgeD6Eng8Nnu8Ez0fQ85HB85Hg+Rh6PjZ4vhc8n0DPJwbPJ4LnU+j51OD5QfB8Bj2fGTyfCZ7Poedzg+dHwfMF9Hxh8HwheL6Eni8Nnp8Ez1fQ85XB85Xg+Rp6vjZ4fhY830DPNwbPN4LnW+j51uD5RfB8Bz3fGTzfCZ7voed7g+dXmYPv/AA9Pxg8PwieH6HnR4NnCMHzE/T8ZPD8JHh+hp6fDZ4hBc8v0POLwfOL4PlVE+b5z95/9QwleIZowjxDNPnvnv97+99mQ0LPkAbP0IJnKOgZyuAZSvAMDT1DGzzDCJ5hoGcYg2cYwTMs9Axr8AwreIaDnuEMnuEEz/DQM7zBM5zgGQF6RjB4RhA8I0LPiAbP8IJnJOgZyeAZSfCMDD0jGzwjCJ5RoGcUg2cUwTMq9Ixq8IwoeEaDntEMntEEz+jQM7rBM5LgGQN6xjB4xhA8Y0LPmAbPyIJnLOgZy+AZS/CMDT1jGzyjCJ5xoGccg2ccwTMu9Ixr8IwqeMaDnvEMnvEEz/jQM77BM5rgmQB6JjB4JhA8E0LPhAbP6IJnIuiZyOCZSPBMDD0TGzxjCJ5JoGcSg2cSwTMp9Exq8IwpeCaDnskMnskEzwD0DBg8YwmeyaFncoNncsEzBfRMYfCMLXimhJ4pDZ4pBc9U0DOVwTOO4JkaeqY2eKYWPNNAzzQGz7iCZ1romdbgmVbwTAc90xk84wme6aFneoNnesEzA/TMYPCML3hmhJ4ZDZ4ZBc9M0DOTwTOB4JkZemY2eGYWPLNAzywGz4SCZ1bomdXgmVXwzAY9sxk8Ewme2aFndoNndsEzB/TMYfBMLHjmhJ45DZ45Bc9c0DOXwTOJ4JkbeuY2eOYWPPNAzzwGz6SCZ17omdfgmVfwzAc98xk8kwme+aFnfoNnfsGzAPQsYPAMCJ4FoWdBg2dBwbMQ9Cxk8EwueBaGnoUNnoUFzyLQs4jBM4XgWRR6FjV4FhU8i0HPYgbPlIJncehZ3OBZXPAsAT1LGDxTCZ4loWdJg2dJwbMU9Cxl8EwteJaGnqUNnqUFzzLQs4zBM43gWRZ6ljV4lhU8y0HPcgbPtIJneehZ3uBZXvCsAD0rGDzTCZ4VoWdFg2dFwbMS9Kxk8EwveFaGnpUNnpUFzyrQs4rBM4PgWRV6VjV4VhU8q0HPagbPjIJndehZ3eBZXfCsAT1rGDwzCZ41oWdNg2dNwbMW9Kxl8MwseNaGnrUNnrUFzzrQs47BM4vgWRd61jV41hU860HPegbPrIJnfehZ3+BZX/BsAD0bGDyzCZ4NoWdDg2dDwbMR9Gxk8MwueDaGno0Nno0FzybQs4nBM4fg2RR6NjV4NhU8m0HPZgbPnIJnc+jZ3ODZXPBsAT1bGDxzCZ4toWdLg2dLwbMV9Gxl8MwteLaGnq0Nnq0FzzbQs43BM4/g2RZ6tjV4thU820HPdgbPvIJne+jZ3uDZXvDsAD07GDzzCZ4doWdHg2dHwbMT9Oxk8MwveHaGnp0Nnp0Fzy7Qs4vBs4Dg2RV6djV4dhU8u0HPbgbPgoJnd+jZ3eDZXfDsAT17GDwLCZ49oWdPg2dPwbMX9Oxl8CwsePaGnr0Nnr0Fzz7Qs4/Bs4jg2Rd69jV49hU8+0HPfgbPooJnf+jZ3+DZX/AcAD0HGDyLCZ4DoedAg+dAwXMQ9Bxk8CwueA6GnoMNnoMFzyHQc4jBs4TgORR6DjV4DhU8h0HPYQbPkoLncOg53OA5XPAcAT1HGDxLCZ4joedIg+dIwXMU9Bxl8CwteI6GnqMNnqMFzzHQc4zBs4zgORZ6jjV4jhU8x0HPcQbPsoLneOg53uA5XvCcAD0nGDzLCZ4ToedEg+dEwXMS9Jxk8CwveE6GnpMNnpMFzynQc4rBs4LgORV6TjV4ThU8p0HPaQbPioLndOg53eA5XfCcAT1nGDwrCZ4zoedMg+dMwXMW9Jxl8KwseM6GnrMNnrMFzznQc47Bs4rgORd6zjV4zhU850HPeQbPqoLnfOg53+A5X/BcAD0XGDyrCZ4LoedCg+dCwXMR9Fxk8KwueC6GnosNnosFz6+h59cGzxqC5xLoucTguUTw/AZ6fmPwrCl4LoWeSw2eSwXPb6HntwbPWoLnMui5zOC5TPD8Dnp+Z/CsLXguh57LDZ7LBc/voef3Bs86gucK6LnC4LlC8PwBev5g8KwreK6EnisNnisFzx+h548Gz3qC5yroucrguUrw/Al6/mTwrC94roaeqw2eqwXPn6HnzwbPBoLnGui5xuC5RvD8BXr+YvBsKHiuhZ5rDZ5rBc9foeevBs9Gguc66LnO4LlO8FwPPdcbPBsLnhug5waD5wbBcyP03GjwbCJ4boKemwyemwTPzdBzs8GzqeC5BXpuMXhuETy3Qs+tBs9mguc26LnN4LlN8NwOPbcbPJsLnjug5w6D5w7Bcyf03GnwbCF47oKeuwyeuwTP3dBzt8GzpeC5B3ruMXjuETz3Qs+9Bs9Wguc+6LnP4LlP8NwPPfcbPFsLngeg5wGD5wHB8yD0PGjwbCN4HoKehwyehwTPw9DzsMGzreB5BHoeMXgeETyPQs+jBs92gucx6HnM4HlM8DwOPY8bPNsLnieg5wmD5wnB8yT0PGnw7CB4noKepwyepwTP09DztMGzo+B5BnqeMXieETx/g56/GTw7CZ5noedZg+dZwfN36Pm7wbOz4HkOep4zeJ4TPP+Ann8YPLsInueh53mD53nB80/o+afBs6vgeQF6XjB4XhA8/4Kefxk8uwmeF6HnRYPnRcHzb+j5t8Gzu+B5CXpeMnheEjwvQ8/LBs8egucV6HnF4HlF8LwKPa8aPHsKnteg5zWD5zXB8zr0vG7w7CV43oCeNwyeNwTPm9DzpsGzt+B5C3reMnjeEjxvQ8/bBs8+gucd6HnH4HlH8LwLPe8aPPsKnveg5z2D5z3B8z70vG/w7Cd4PoCeDwyeDwTPh9DzocGzv+D5CHo+Mng+EjwfQ8/HBs8BgucT6PnE4PlE8HwKPZ8aPAcKns+g5zOD5zPB8zn0fG7wHCR4voCeLwyeLwTPl9DzpcFzsOD5Cnq+Mni+EjxfQ8/XBs8hgucb6PnG4PlG8HwLPd8aPIcKnu+g5zuD5zvB8z30fG/wHCZ4foCeHwyeHwTPj9Dzo8FzuOD5CXp+Mnh+Ejw/Q8/PBs8RgucX6PnF4PlF8PyqKfP8Z++/eo4UPEM0ZZ4hmv53z/+9/W+zIaFnSIPnKMEzFPQMZfAMJXiGhp6hDZ6jBc8w0DOMwTOM4BkWeoY1eI4RPMNBz3AGz3CCZ3joGd7gOVbwjAA9Ixg8IwieEaFnRIPnOMEzEvSMZPCMJHhGhp6RDZ7jBc8o0DOKwTOK4BkVekY1eE4QPKNBz2gGz2iCZ3ToGd3gOVHwjAE9Yxg8YwieMaFnTIPnJMEzFvSMZfCMJXjGhp6xDZ6TBc840DOOwTOO4BkXesY1eE4RPONBz3gGz3iCZ3zoGd/gOVXwTAA9Exg8EwieCaFnQoPnNMEzEfRMZPBMJHgmhp6JDZ7TBc8k0DOJwTOJ4JkUeiY1eM4QPJNBz2QGz2SCZwB6BgyeMwXP5NAzucEzueCZAnqmMHjOEjxTQs+UBs+Ugmcq6JnK4Dlb8EwNPVMbPFMLnmmgZxqD5xzBMy30TGvwTCt4poOe6QyecwXP9NAzvcEzveCZAXpmMHjOEzwzQs+MBs+Mgmcm6JnJ4Dlf8MwMPTMbPDMLnlmgZxaD5wLBMyv0zGrwzCp4ZoOe2QyeCwXP7NAzu8Ezu+CZA3rmMHguEjxzQs+cBs+cgmcu6JnL4LlY8MwNPXMbPHMLnnmgZx6D59eCZ17omdfgmVfwzAc98xk8lwie+aFnfoNnfsGzAPQsYPD8RvAsCD0LGjwLCp6FoGchg+dSwbMw9Cxs8CwseBaBnkUMnt8KnkWhZ1GDZ1HBsxj0LGbwXCZ4FoeexQ2exQXPEtCzhMHzO8GzJPQsafAsKXiWgp6lDJ7LBc/S0LO0wbO04FkGepYxeH4veJaFnmUNnmUFz3LQs5zBc4XgWR56ljd4lhc8K0DPCgbPHwTPitCzosGzouBZCXpWMniuFDwrQ8/KBs/KgmcV6FnF4Pmj4FkVelY1eFYVPKtBz2oGz1WCZ3XoWd3gWV3wrAE9axg8fxI8a0LPmgbPmoJnLehZy+C5WvCsDT1rGzxrC551oGcdg+fPgmdd6FnX4FlX8KwHPesZPNcInvWhZ32DZ33BswH0bGDw/EXwbAg9Gxo8GwqejaBnI4PnWsGzMfRsbPBsLHg2gZ5NDJ6/Cp5NoWdTg2dTwbMZ9Gxm8FwneDaHns0Nns0FzxbQs4XBc73g2RJ6tjR4thQ8W0HPVgbPDYJna+jZ2uDZWvBsAz3bGDw3Cp5toWdbg2dbwbMd9Gxn8NwkeLaHnu0Nnu0Fzw7Qs4PBc7Pg2RF6djR4dhQ8O0HPTgbPLYJnZ+jZ2eDZWfDsAj27GDy3Cp5doWdXg2dXwbMb9Oxm8NwmeHaHnt0Nnt0Fzx7Qs4fBc7vg2RN69jR49hQ8e0HPXgbPHYJnb+jZ2+DZW/DsAz37GDx3Cp59oWdfg2dfwbMf9Oxn8NwlePaHnv0Nnv0FzwHQc4DBc7fgORB6DjR4DhQ8B0HPQQbPPYLnYOg52OA5WPAcAj2HGDz3Cp5DoedQg+dQwXMY9Bxm8NwneA6HnsMNnsMFzxHQc4TBc7/gORJ6jjR4jhQ8R0HPUQbPA4LnaOg52uA5WvAcAz3HGDwPCp5joedYg+dYwXMc9Bxn8DwkeI6HnuMNnuMFzwnQc4LB87DgORF6TjR4ThQ8J0HPSQbPI4LnZOg52eA5WfCcAj2nGDyPCp5ToedUg+dUwXMa9Jxm8DwmeE6HntMNntMFzxnQc4bB87jgORN6zjR4zhQ8Z0HPWQbPE4LnbOg52+A5W/CcAz3nGDxPCp5zoedcg+dcwXMe9Jxn8DwleM6HnvMNnvMFzwXQc4HB87TguRB6LjR4LhQ8F0HPRQbPM4Ln/7FCV2Fble0WhqW7u7u7u7u7BGTS3SIiIiIiIiIiIiLS3Q0iIiIi3d3d3Q3rcO9bW98/rnfM7fHM6z7OKdBzisFziuA5FXpONXgeFDynQc9pBs9pgud06Dnd4HlI8JwBPWcYPGcInjOh50yD52HBcxb0nGXwnCV4zoaesw2eRwTPOdBzjsFzjuA5F3rONXgeFTznQc95Bs95gud86Dnf4HlM8FwAPRcYPBcInguh50KD53HBcxH0XGTwXCR4Loaeiw2eJwTPJdBzicFzieC5FHouNXieFDyXQc9lBs9lgudy6Lnc4HlK8FwBPVcYPFcIniuh50qD52nBcxX0XGXwXCV4roaeqw2eZwTPNdBzjcFzjeC5FnquNXieFTzXQc91Bs91gudv0PM3g+c5wXM99Fxv8FwveP4OPX83eJ4XPDdAzw0Gzw2C5x/Q8w+D5wXBcyP03Gjw3Ch4/gk9/zR4XhQ8N0HPTQbPTYLnX9DzL4PnJcFzM/TcbPDcLHj+DT3/NnheFjy3QM8tBs8tguc/0PMfg+cVwXMr9Nxq8NwqeP4LPf81eF4VPLdBz20Gz22C53boud3geU3w3AE9dxg8dwieO6HnToPndcFzF/TcZfDcJXjuhp67DZ43BM890HOPwXOP4LkXeu41eN4UPPdBz30Gz32C537oud/geUvwPAA9Dxg8DwieB6HnQYPnbcHzEPQ8ZPA8JHgehp6HDZ53BM8j0POIwfOI4HkUeh41eN4VPI9Bz2MGz2OC53HoedzgeU/wPAE9Txg8TwieJ6HnSYPnfcHzFPQ8ZfA8JXiehp6nDZ4PBM8z0POMwfOM4HkWep41eD4UPM9Bz3MGz3OC53noed7g+UjwvAA9Lxg8LwieF6HnRYPnY8HzEvS8ZPC8JHhehp6XDZ5PBM8r0POKwfOK4HkVel41eD4VPK9Bz2sGz2uC53Xoed3g+UzwvAE9bxg8bwieN6HnTYPnc8HzFvS8ZfC8JXjehp63DZ4vBM870POOwfOO4HkXet41eL4UPO9Bz3sGz3uC533oed/g+UrwfAA9Hxg8HwieD6HnQ4Pna8HzEfR8ZPB8JHg+hp6PDZ5vBM8n0POJwfOJ4PkUej41eL4VPJ9Bz2cGz2eC53Po+dzg+U7wfAE9Xxg8XwieL6HnS4Pne3n/9ztfQc9XBs9Xgudr6Pna4BlB8HwDPd8YPN8Inm+h51uDZ0TB8x30fGfwfCd4vhcwz//eheoZSfCMEDDPCEHonmHb4W0jBswzYhC6Z2TBM1LAPCMFoXuGbYe3jRwwz8hB6J5RBM8oAfOMEoTuGbYd3jZqwDyjBqF7RhU8owXMM1oQumfYdnjb6AHzjB6E7hlN8IwRMM8YQeieYdvhbWMGzDNmELpndMEzVsA8YwWhe4Zth7eNHTDP2EHonjEEzzgB84wThO4Zth3eNm7APOMGoXvGFDzjBcwzXhC6Z9h2eNv4AfOMH4TuGUvwTBAwzwRB6J5h2+FtEwbMM2EQumdswTNRwDwTBaF7hm2Ht00cMM/EQeiecQTPJAHzTBKE7hm2Hd42acA8kwahe8YVPJMFzDNZELpn2HZ42+QB80wehO4ZT/BMETDPFEHonmHb4W1TBswzZRC6Z3zBM1XAPFMFoXuGbYe3TR0wz9RB6J4JBM80AfNME4TuGbYd3jZtwDzTBqF7JhQ80wXMM10QumfYdnjb9AHzTB+E7plI8MwQMM8MQeieYdvhbTMGzDNjELpnYsEzU8A8MwWhe4Zth7fNHDDPzEHonkkEzywB88wShO4Zth3eNmvAPLMGoXsmFTyzBcwzWxC6Z9h2eNvsAfPMHoTumUzwzBEwzxxB6J5h2+FtcwbMM2cQumdywTNXwDxzBaF7hm2Ht80dMM/cQeieKQTPPAHzzBOE7hm2Hd42b8A88wahe6YUPPMFzDNfELpn2HZ42/wB88wfhO6ZSvAsEDDPAkHonmHb4W0LBsyzYBC6Z2rBs1DAPAsFoXuGbYe3LRwwz8JB6J5pBM8iAfMsEoTuGbYd3rZowDyLBqF7phU8iwXMs1gQumfYdnjb4gHzLB6E7plO8CwRMM8SQeieYdvhbUsGzLNkELpnesGzVMA8SwWhe4Zth7ctHTDP0kHonhkEzzIB8ywThO4Zth3etmzAPMsGoXtmFDzLBcyzXBC6Z9h2eNvyAfMsH4TumUnwrBAwzwpB6J5h2+FtKwbMs2IQumdmwbNSwDwrBaF7hm2Ht60cMM/KQeieWQTPKgHzrBKE7hm2Hd62asA8qwahe2YVPKsFzLNaELpn2HZ42+oB86wehO6ZTfCsETDPGkHonmHb4W1rBsyzZhC6Z3bBs1bAPGsFoXuGbYe3rR0wz9pB6J45BM86AfOsE4TuGbYd3rZuwDzrBqF75hQ86wXMs14QumfYdnjb+gHzrB+E7plL8GwQMM8GQeieYdvhbRsGzLNhELpnbsGzUcA8GwWhe4Zth7dtHDDPxkHonnkEzyYB82wShO4Zth3etmnAPJsGoXvmFTybBcyzWRC6Z9h2eNvmAfNsHoTumU/wbBEwzxZB6J5h2+Ft3w+Y5/tB6J75Bc+WAfNsGYTuGbYd3rZVwDxbBaF7FhA8WwfMs3UQumfYdnjbDwLm+UEQumdBwbNNwDzbBKF7hm2Htw0C5hkEoXsWEjzbBsyzbRC6Z9h2eNt2AfNsF4TuWVjwbB8wz/ZB6J5h2+FtOwTMs0MQumcRwbNjwDw7BqF7hm2Ht+0UMM9OQeieRQXPzgHz7ByE7hm2Hd62S8A8uwShexYTPLsGzLNrELpn2HZ4224B8+wWhO5ZXPDsHjDP7kHonmHb4W17BMyzRxC6ZwnBs2fAPHsGoXuGbYe37RUwz15B6J4lBc/eAfPsHYTuGbYd3rZPwDz7BKF7lhI8+wbMs28QumfYdnjbfgHz7BeE7lla8OwfMM/+QeieYdvhbT8MmOeHQeieZQTPAQHzHBCE7hm2Hd72o4B5fhSE7llW8BwYMM+BQeieYdvhbT8OmOfHQeie5QTPQQHzHBSE7hm2Hd72k4B5fhKE7lle8BwcMM/BQeieYdvhbT8NmOenQeieFQTPIQHzHBKE7hm2Hd72s4B5fhaE7llR8BwaMM+hQeieYdvhbT8PmOfnQeielQTPYQHzHBaE7hm2Hd72i4B5fhGE7llZ8BweMM/hQeieYdvhbb8MmOeXQeieVQTPEQHzHBGE7hm2Hd72q4B5fhWE7llV8BwZMM+RQeieYdvhbb8OmOfXQeie1QTPUQHzHBWE7hm2Hd72m4B5fhOE7lld8BwdMM/RQeieYdvhbb8NmOe3QeieNQTPMQHzHBOE7hm2Hd72u4B5fheE7llT8BwbMM+xQeieYdvhbb8PmOf3QeietQTPcQHzHBeE7hm2Hd72h4B5/hCE7llb8BwfMM/xQeieYdvhbX8MmOePQeiedQTPCQHznBCE7hm2Hd72p4B5/hSE7llX8JwYMM+JQeieYdvhbX8OmOfPQeie9QTPSQHznBSE7hm2Hd72l4B5/hKE7llf8JwcMM/JQeieYdvhbX8NmOevQeieDQTPKQHznBKE7hm2Hd52asA8pwahezYUPKcFzHNaELpn2HZ42+kB85wehO7ZSPCcETDPGUHonmHb4W1nBsxzZhC6Z2PBc1bAPGcFoXuGbYe3nR0wz9lB6J5NBM85AfOcE4TuGbYd3nZuwDznBqF7NhU85wXMc14QumfYdnjb+QHznB+E7tlM8FwQMM8FQeieYdvhbRcGzHNhELpnc8FzUcA8FwWhe4Zth7ddHDDPxUHoni0EzyUB81wShO4Zth3edmnAPJcGoXu+L3guC5jnsiB0z7Dt8LbLA+a5PAjds6XguSJgniuC0D3DtsPbrgyY58ogdM9WgueqgHmuCkL3DNsOb7s6YJ6rg9A9WwueawLmuSYI3TNsO7zt2oB5rg1C9/xA8FwXMM91QeieYdvhbX8LmOdvQeiebQTP9QHzXB+E7hm2Hd7294B5/h6E7hkInhsC5rkhCN0zbDu87R8B8/wjCN2zreC5MWCeG4PQPcO2w9v+GTDPP4PQPdsJnpsC5rkpCN0zbDu87V8B8/wrCN2zveC5OWCem4PQPcO2w9v+HTDPv4PQPTsInlsC5rklCN0zbDu87T8B8/wnCN2zo+C5NWCeW4PQPcO2w9v+GzDPf4PQPTsJntsC5rktCN0zbDu87faAeW4PQvfsLHjuCJjnjiB0z7Dt8LY7A+a5Mwjds4vguStgnruC0D3DtsPb7g6Y5+4gdM+ugueegHnuCUL3DNsOb7s3YJ57g9A9uwme+wLmuS8I3TNsO7zt/oB57g9C9+wueB4ImOeBIHTPsO3wtgcD5nkwCN2zh+B5KGCeh4LQPcO2w9seDpjn4SB0z56C55GAeR4JQvcM2w5vezRgnkeD0D17CZ7HAuZ5LAjdM2w7vO3xgHkeD0L37C14ngiY54kgdM+w7fC2JwPmeTII3bOP4HkqYJ6ngtA9w7bD254OmOfpIHTPvoLnmYB5nglC9wzbDm97NmCeZ4PQPfsJnucC5nkuCN0zbDu87fmAeZ4PQvfsL3heCJjnhSB0z7Dt8LYXA+Z5MQjd80PB81LAPC8FoXuGbYe3vRwwz8tB6J4DBM8rAfO8EoTuGbYd3vZqwDyvBqF7fiR4XguY57UgdM+w7fC21wPmeT0I3XOg4HkjYJ43gtA9w7bD294MmOfNIHTPjwXPWwHzvBWE7hm2Hd72dsA8bwehew4SPO8EzPNOELpn2HZ427sB87wbhO75ieB5L2Ce94LQPcO2w9veD5jn/SB0z8GC54OAeT4IQvcM2w5v+zBgng+D0D0/FTwfBczzURC6Z9h2eNvHAfN8HITuOUTwfBIwzydB6J5h2+FtnwbM82kQuudnguezgHk+C0L3DNsOb/s8YJ7Pg9A9hwqeLwLm+SII3TNsO7zty4B5vgxC9/xc8HwVMM9XQeieYdvhbV8HzPN1ELrnMMHzTcA83wShe4Zth7d9GzDPt0Honl8Inu8C5vkuCN0zbDu87Xttmed/70L1HC54RmjLPCO0Dd0zbDu8bUToGdHg+aXgGQl6RjJ4RhI8I0PPyAbPEYJnFOgZxeAZRfCMCj2jGjy/EjyjQc9oBs9ogmd06Bnd4DlS8IwBPWMYPGMInjGhZ0yD59eCZyzoGcvgGUvwjA09Yxs8RwmecaBnHINnHMEzLvSMa/D8RvCMBz3jGTzjCZ7xoWd8g+dowTMB9Exg8EwgeCaEngkNnt8KnomgZyKDZyLBMzH0TGzwHCN4JoGeSQyeSQTPpNAzqcHzO8EzGfRMZvBMJngmh57JDZ5jBc8U0DOFwTOF4JkSeqY0eH4veKaCnqkMnqkEz9TQM7XBc5zgmQZ6pjF4phE800LPtAbPHwTPdNAzncEzneCZHnqmN3iOFzwzQM8MBs8MgmdG6JnR4Pmj4JkJemYyeGYSPDNDz8wGzwmCZxbomcXgmUXwzAo9sxo8fxI8s0HPbAbPbIJnduiZ3eA5UfDMAT1zGDxzCJ45oWdOg+fPgmcu6JnL4JlL8MwNPXMbPCcJnnmgZx6DZx7BMy/0zGvw/EXwzAc98xk88wme+aFnfoPnZMGzAPQsYPAsIHgWhJ4FDZ6/Cp6FoGchg2chwbMw9Cxs8JwieBaBnkUMnkUEz6LQs6jBc6rgWQx6FjN4FhM8i0PP4gbPaYJnCehZwuBZQvAsCT1LGjynC56loGcpg2cpwbM09Cxt8JwheJaBnmUMnmUEz7LQs6zBc6bgWQ56ljN4lhM8y0PP8gbPWYJnBehZweBZQfCsCD0rGjxnC56VoGclg2clwbMy9Kxs8JwjeFaBnlUMnlUEz6rQs6rBc67gWQ16VjN4VhM8q0PP6gbPeYJnDehZw+BZQ/CsCT1rGjznC561oGctg2ctwbM29Kxt8FwgeNaBnnUMnnUEz7rQs67Bc6HgWQ961jN41hM860PP+gbPRYJnA+jZwODZQPBsCD0bGjwXC56NoGcjg2cjwbMx9Gxs8FwieDaBnk0Mnk0Ez6bQs6nBc6ng2Qx6NjN4NhM8m0PP5gbPZYJnC+jZwuDZQvB8H3q+b/BcLni2hJ4tDZ4tBc9W0LOVwXOF4NkaerY2eLYWPD+Anh8YPFcKnm2gZxuDZxvBM4CegcFzleDZFnq2NXi2FTzbQc92Bs/Vgmd76Nne4Nle8OwAPTsYPNcInh2hZ0eDZ0fBsxP07GTwXCt4doaenQ2enQXPLtCzi8FzneDZFXp2NXh2FTy7Qc9uBs/fBM/u0LO7wbO74NkDevYweK4XPHtCz54Gz56CZy/o2cvg+bvg2Rt69jZ49hY8+0DPPgbPDYJnX+jZ1+DZV/DsBz37GTz/EDz7Q8/+Bs/+gueH0PNDg+dGwXMA9Bxg8BwgeH4EPT8yeP4peA6EngMNngMFz4+h58cGz02C5yDoOcjgOUjw/AR6fmLw/EvwHAw9Bxs8Bwuen0LPTw2emwXPIdBziMFziOD5GfT8zOD5t+A5FHoONXgOFTw/h56fGzy3CJ7DoOcwg+cwwfML6PmFwfMfwXM49Bxu8BwueH4JPb80eG4VPEdAzxEGzxGC51fQ8yuD57+C50joOdLgOVLw/Bp6fm3w3CZ4joKeowyeowTPb6DnNwbP7YLnaOg52uA5WvD8Fnp+a/DcIXiOgZ5jDJ5jBM/voOd3Bs+dgudY6DnW4DlW8Pween5v8NwleI6DnuMMnuMEzx+g5w8Gz92C53joOd7gOV7w/BF6/mjw3CN4ToCeEwyeEwTPn6DnTwbPvYLnROg50eA5UfD8GXr+bPDcJ3hOgp6TDJ6TBM9foOcvBs/9gudk6DnZ4DlZ8PwVev5q8DwgeE6BnlMMnlMEz6nQc6rB86DgOQ16TjN4ThM8p0PP6QbPQ4LnDOg5w+A5Q/CcCT1nGjwPC56zoOcsg+cswXM29Jxt8DwieM6BnnMMnnMEz7nQc67B86jgOQ96zjN4zhM850PP+QbPY4LnAui5wOC5QPBcCD0XGjyPC56LoOcig+ciwXMx9Fxs8DwheC6BnksMnksEz6XQc6nB86TguQx6LjN4LhM8l0PP5QbPU4LnCui5wuC5QvBcCT1XGjxPC56roOcqg+cqwXM19Fxt8DwjeK6BnmsMnmsEz7XQc63B86zguQ56rjN4rhM8f4Oevxk8zwme66HneoPnesHzd+j5u8HzvOC5AXpuMHhuEDz/gJ5/GDwvCJ4boedGg+dGwfNP6PmnwfOi4LkJem4yeG4SPP+Cnn8ZPC8Jnpuh52aD52bB82/o+bfB87LguQV6bjF4bhE8/4Ge/xg8rwieW6HnVoPnVsHzX+j5r8HzquC5DXpuM3huEzy3Q8/tBs9rgucO6LnD4LlD8NwJPXcaPK8Lnrug5y6D5y7Bczf03G3wvCF47oGeewyeewTPvdBzr8HzpuC5D3ruM3juEzz3Q8/9Bs9bgucB6HnA4HlA8DwIPQ8aPG8Lnoeg5yGD5yHB8zD0PGzwvCN4HoGeRwyeRwTPo9DzqMHzruB5DHoeM3geEzyPQ8/jBs97gucJ6HnC4HlC8DwJPU8aPO8Lnqeg5ymD5ynB8zT0PG3wfCB4noGeZwyeZwTPs9DzrMHzoeB5DnqeM3ieEzzPQ8/zBs9HgucF6HnB4HlB8LwIPS8aPB8Lnpeg5yWD5yXB8zL0vGzwfCJ4XoGeVwyeVwTPq9DzqsHzqeB5DXpeM3heEzyvQ8/rBs9ngucN6HnD4HlD8LwJPW8aPJ8Lnreg5y2D5y3B8zb0vG3wfCF43oGedwyedwTPu9DzrsHzpeB5D3reM3jeEzzvQ8/7Bs9XgucD6PnA4PlA8HwIPR8aPF8Lno+g5yOD5yPB8zH0fGzwfCN4PoGeTwyeTwTPp9DzqcHzreD5DHo+M3g+EzyfQ8/nBs93gucL6PnC4PlC8HwJPV8aPN/L97/f+Qp6vjJ4vhI8X0PP1wbPCILnG+j5xuD5RvB8Cz3fGjwjCp7voOc7g+c7wfO9dszzv3ehekYSPCO0Y54R2oXuGbYd3jYi9Ixo8IwseEaCnpEMnpEEz8jQM7LBM4rgGQV6RjF4RhE8o0LPqAbPqIJnNOgZzeAZTfCMDj2jGzyjCZ4xoGcMg2cMwTMm9Ixp8IwueMaCnrEMnrEEz9jQM7bBM4bgGQd6xjF4xhE840LPuAbPmIJnPOgZz+AZT/CMDz3jGzxjCZ4JoGcCg2cCwTMh9Exo8IwteCaCnokMnokEz8TQM7HBM47gmQR6JjF4JhE8k0LPpAbPuIJnMuiZzOCZTPBMDj2TGzzjCZ4poGcKg2cKwTMl9Exp8IwveKaCnqkMnqkEz9TQM7XBM4HgmQZ6pjF4phE800LPtAbPhIJnOuiZzuCZTvBMDz3TGzwTCZ4ZoGcGg2cGwTMj9Mxo8EwseGaCnpkMnpkEz8zQM7PBM4ngmQV6ZjF4ZhE8s0LPrAbPpIJnNuiZzeCZTfDMDj2zGzyTCZ45oGcOg2cOwTMn9Mxp8EwueOaCnrkMnrkEz9zQM7fBM4XgmQd65jF45hE880LPvAbPlIJnPuiZz+CZT/DMDz3zGzxTCZ4FoGcBg2cBwbMg9Cxo8EwteBaCnoUMnoUEz8LQs7DBM43gWQR6FjF4FhE8i0LPogbPtIJnMehZzOBZTPAsDj2LGzzTCZ4loGcJg2cJwbMk9Cxp8EwveJaCnqUMnqUEz9LQs7TBM4PgWQZ6ljF4lhE8y0LPsgbPjIJnOehZzuBZTvAsDz3LGzwzCZ4VoGcFg2cFwbMi9Kxo8MwseFaCnpUMnpUEz8rQs7LBM4vgWQV6VjF4VhE8q0LPqgbPrIJnNehZzeBZTfCsDj2rGzyzCZ41oGcNg2cNwbMm9Kxp8MwueNaCnrUMnrUEz9rQs7bBM4fgWQd61jF41hE860LPugbPnIJnPehZz+BZT/CsDz3rGzxzCZ4NoGcDg2cDwbMh9Gxo8MwteDaCno0Mno0Ez8bQs7HBM4/g2QR6NjF4NhE8m0LPpgbPvIJnM+jZzODZTPBsDj2bGzzzCZ4toGcLg2cLwfN96Pm+wTO/4NkSerY0eLYUPFtBz1YGzwKCZ2vo2drg2Vrw/AB6fmDwLCh4toGebQyebQTPAHoGBs9Cgmdb6NnW4NlW8GwHPdsZPAsLnu2hZ3uDZ3vBswP07GDwLCJ4doSeHQ2eHQXPTtCzk8GzqODZGXp2Nnh2Fjy7QM8uBs9igmdX6NnV4NlV8OwGPbsZPIsLnt2hZ3eDZ3fBswf07GHwLCF49oSePQ2ePQXPXtCzl8GzpODZG3r2Nnj2Fjz7QM8+Bs9Sgmdf6NnX4NlX8OwHPfsZPEsLnv2hZ3+DZ3/B80Po+aHBs4zgOQB6DjB4DhA8P4KeHxk8ywqeA6HnQIPnQMHzY+j5scGznOA5CHoOMngOEjw/gZ6fGDzLC56Doedgg+dgwfNT6PmpwbOC4DkEeg4xeA4RPD+Dnp8ZPCsKnkOh51CD51DB83Po+bnBs5LgOQx6DjN4DhM8v4CeXxg8Kwuew6HncIPncMHzS+j5pcGziuA5AnqOMHiOEDy/gp5fGTyrCp4joedIg+dIwfNr6Pm1wbOa4DkKeo4yeI4SPL+Bnt8YPKsLnqOh52iD52jB81vo+a3Bs4bgOQZ6jjF4jhE8v4Oe3xk8awqeY6HnWIPnWMHze+j5vcGzluA5DnqOM3iOEzx/gJ4/GDxrC57joed4g+d4wfNH6PmjwbOO4DkBek4weE4QPH+Cnj8ZPOsKnhOh50SD50TB82fo+bPBs57gOQl6TjJ4ThI8f4Gevxg86wuek6HnZIPnZMHzV+j5q8GzgeA5BXpOMXhOETynQs+pBs+Gguc06DnN4DlN8JwOPacbPBsJnjOg5wyD5wzBcyb0nGnwbCx4zoKeswyeswTP2dBztsGzieA5B3rOMXjOETznQs+5Bs+mguc86DnP4DlP8JwPPecbPJsJngug5wKD5wLBcyH0XGjwbC54LoKeiwyeiwTPxdBzscGzheC5BHouMXguETyXQs+lBs/3Bc9l0HOZwXOZ4Lkcei43eLYUPFdAzxUGzxWC50roudLg2UrwXAU9Vxk8Vwmeq6HnaoNna8FzDfRcY/BcI3iuhZ5rDZ4fCJ7roOc6g+c6wfM36PmbwbON4Lkeeq43eK4XPH+Hnr8bPAPBcwP03GDw3CB4/gE9/zB4thU8N0LPjQbPjYLnn9DzT4NnO8FzE/TcZPDcJHj+BT3/Mni2Fzw3Q8/NBs/Nguff0PNvg2cHwXML9Nxi8NwieP4DPf8xeHYUPLdCz60Gz62C57/Q81+DZyfBcxv03Gbw3CZ4boee2w2enQXPHdBzh8Fzh+C5E3ruNHh2ETx3Qc9dBs9dgudu6Lnb4NlV8NwDPfcYPPcInnuh516DZzfBcx/03Gfw3Cd47oee+w2e3QXPA9DzgMHzgOB5EHoeNHj2EDwPQc9DBs9Dgudh6HnY4NlT8DwCPY8YPI8Inkeh51GDZy/B8xj0PGbwPCZ4Hoeexw2evQXPE9DzhMHzhOB5EnqeNHj2ETxPQc9TBs9Tgudp6Hna4NlX8DwDPc8YPM8Inmeh51mDZz/B8xz0PGfwPCd4noee5w2e/QXPC9DzgsHzguB5EXpeNHh+KHhegp6XDJ6XBM/L0POywXOA4HkFel4xeF4RPK9Cz6sGz48Ez2vQ85rB85rgeR16Xjd4DhQ8b0DPGwbPG4LnTeh50+D5seB5C3reMnjeEjxvQ8/bBs9Bgucd6HnH4HlH8LwLPe8aPD8RPO9Bz3sGz3uC533oed/gOVjwfAA9Hxg8HwieD6HnQ4Pnp4LnI+j5yOD5SPB8DD0fGzyHCJ5PoOcTg+cTwfMp9Hxq8PxM8HwGPZ8ZPJ8Jns+h53OD51DB8wX0fGHwfCF4voSeLw2enwuer6DnK4PnK8HzNfR8bfAcJni+gZ5vDJ5vBM+30POtwfMLwfMd9Hxn8HwneL7Xnnn+9y5Uz+GCZ4T2zDNC+9A9w7bD20aEnhENnl8KnpGgZySDZyTBMzL0jGzwHCF4RoGeUQyeUQTPqNAzqsHzK8EzGvSMZvCMJnhGh57RDZ4jBc8Y0DOGwTOG4BkTesY0eH4teMaCnrEMnrEEz9jQM7bBc5TgGQd6xjF4xhE840LPuAbPbwTPeNAznsEznuAZH3rGN3iOFjwTQM8EBs8EgmdC6JnQ4Pmt4JkIeiYyeCYSPBNDz8QGzzGCZxLomcTgmUTwTAo9kxo8vxM8k0HPZAbPZIJncuiZ3OA5VvBMAT1TGDxTCJ4poWdKg+f3gmcq6JnK4JlK8EwNPVMbPMcJnmmgZxqDZxrBMy30TGvw/EHwTAc90xk80wme6aFneoPneMEzA/TMYPDMIHhmhJ4ZDZ4/Cp6ZoGcmg2cmwTMz9Mxs8JwgeGaBnlkMnlkEz6zQM6vB8yfBMxv0zGbwzCZ4Zoee2Q2eEwXPHNAzh8Ezh+CZE3rmNHj+LHjmgp65DJ65BM/c0DO3wXOS4JkHeuYxeOYRPPNCz7wGz18Ez3zQM5/BM5/gmR965jd4ThY8C0DPAgbPAoJnQehZ0OD5q+BZCHoWMngWEjwLQ8/CBs8pgmcR6FnE4FlE8CwKPYsaPKcKnsWgZzGDZzHBszj0LG7wnCZ4loCeJQyeJQTPktCzpMFzuuBZCnqWMniWEjxLQ8/SBs8ZgmcZ6FnG4FlG8CwLPcsaPGcKnuWgZzmDZznBszz0LG/wnCV4VoCeFQyeFQTPitCzosFztuBZCXpWMnhWEjwrQ8/KBs85gmcV6FnF4FlF8KwKPasaPOcKntWgZzWDZzXBszr0rG7wnCd41oCeNQyeNQTPmtCzpsFzvuBZC3rWMnjWEjxrQ8/aBs8Fgmcd6FnH4FlH8KwLPesaPBcKnvWgZz2DZz3Bsz70rG/wXCR4NoCeDQyeDQTPhtCzocFzseDZCHo2Mng2EjwbQ8/GBs8lgmcT6NnE4NlE8GwKPZsaPJcKns2gZzODZzPBszn0bG7wXCZ4toCeLQyeLQTP96Hn+wbP5YJnS+jZ0uDZUvBsBT1bGTxXCJ6toWdrg2drwfMD6PmBwXOl4NkGerYxeLYRPAPoGRg8VwmebaFnW4NnW8GzHfRsZ/BcLXi2h57tDZ7tBc8O0LODwXON4NkRenY0eHYUPDtBz04Gz7WCZ2fo2dng2Vnw7AI9uxg81wmeXaFnV4NnV8GzG/TsZvD8TfDsDj27Gzy7C549oGcPg+d6wbMn9Oxp8OwpePaCnr0Mnr8Lnr2hZ2+DZ2/Bsw/07GPw3CB49oWefQ2efQXPftCzn8HzD8GzP/Tsb/DsL3h+CD0/NHhuFDwHQM8BBs8BgudH0PMjg+efgudA6DnQ4DlQ8PwYen5s8NwkeA6CnoMMnoMEz0+g5ycGz78Ez8HQc7DBc7Dg+Sn0/NTguVnwHAI9hxg8hwien0HPzwyefwueQ6HnUIPnUMHzc+j5ucFzi+A5DHoOM3gOEzy/gJ5fGDz/ETyHQ8/hBs/hgueX0PNLg+dWwXME9Bxh8BwheH4FPb8yeP4reI6EniMNniMFz6+h59cGz22C5yjoOcrgOUrw/AZ6fmPw3C54joaeow2eowXPb6HntwbPHYLnGOg5xuA5RvD8Dnp+Z/DcKXiOhZ5jDZ5jBc/voef3Bs9dguc46DnO4DlO8PwBev5g8NwteI6HnuMNnuMFzx+h548Gzz2C5wToOcHgOUHw/Al6/mTw3Ct4ToSeEw2eEwXPn6HnzwbPfYLnJOg5yeA5SfD8BXr+YvDcL3hOhp6TDZ6TBc9foeevBs8DgucU6DnF4DlF8JwKPacaPA8KntOg5zSD5zTBczr0nG7wPCR4zoCeMwyeMwTPmdBzpsHzsOA5C3rOMnjOEjxnQ8/ZBs8jgucc6DnH4DlH8JwLPecaPI8KnvOg5zyD5zzBcz70nG/wPCZ4LoCeCwyeCwTPhdBzocHzuOC5CHouMnguEjwXQ8/FBs8TgucS6LnE4LlE8FwKPZcaPE8Knsug5zKD5zLBczn0XG7wPCV4roCeKwyeKwTPldBzpcHztOC5CnquMniuEjxXQ8/VBs8zguca6LnG4LlG8FwLPdcaPM8Knuug5zqD5zrB8zfo+ZvB85zguR56rjd4rhc8f4eevxs8zwueG6DnBoPnBsHzD+j5h8HzguC5EXpuNHhuFDz/hJ5/GjwvCp6boOcmg+cmwfMv6PmXwfOS4LkZem42eG4WPP+Gnn8bPC8Lnlug5xaD5xbB8x/o+Y/B84rguRV6bjV4bhU8/4We/xo8rwqe26DnNoPnNsFzO/TcbvC8JnjugJ47DJ47BM+d0HOnwfO64LkLeu4yeO4SPHdDz90GzxuC5x7oucfguUfw3As99xo8bwqe+6DnPoPnPsFzP/Tcb/C8JXgegJ4HDJ4HBM+D0POgwfO24HkIeh4yeB4SPA9Dz8MGzzuC5xHoecTgeUTwPAo9jxo87wqex6DnMYPnMcHzOPQ8bvC8J3iegJ4nDJ4nBM+T0POkwfO+4HkKep4yeJ4SPE9Dz9MGzweC5xnoecbgeUbwPAs9zxo8Hwqe56DnOYPnOcHzPPQ8b/B8JHhegJ4XDJ4XBM+L0POiwfOx4HkJel4yeF4SPC9Dz8sGzyeC5xXoecXgeUXwvAo9rxo8nwqe16DnNYPnNcHzOvS8bvB8JnjegJ43DJ43BM+b0POmwfO54HkLet4yeN4SPG9Dz9sGzxeC5x3oecfgeUfwvAs97xo8Xwqe96DnPYPnPcHzPvS8b/B8JXg+gJ4PDJ4PBM+H0POhw7PQ/37no//tzmjv3vX5f3f+9y5zOHcq7fC2j/+3O+O9e3v+/935+H+4M5wvwmvB8wn0fGLwfCJ4PoWeTw2ebwTPZ9DzmcHzmeD5HHo+N3i+FTxfQM8XBs8XgudL6PnS4PlO8HwFPV8ZPF8Jnq+h52uD53uF//c730DPNwbPN4LnW+j51uAZQfB8Bz3fGTzfCZ7vdWCe/70L1TOi4BmhA/OM0CF0z7Dt8LYRoWdEg2ckwTMS9Ixk8IwkeEaGnpENnpEFzyjQM4rBM4rgGRV6RjV4RhE8o0HPaAbPaIJndOgZ3eAZVfCMAT1jGDxjCJ4xoWdMg2c0wTMW9Ixl8IwleMaGnrENntEFzzjQM47BM47gGRd6xjV4xhA840HPeAbPeIJnfOgZ3+AZU/BMAD0TGDwTCJ4JoWdCg2cswTMR9Exk8EwkeCaGnokNnrEFzyTQM4nBM4ngmRR6JjV4xhE8k0HPZAbPZIJncuiZ3OAZV/BMAT1TGDxTCJ4poWdKg2c8wTMV9Exl8EwleKaGnqkNnvEFzzTQM43BM43gmRZ6pjV4JhA800HPdAbPdIJneuiZ3uCZUPDMAD0zGDwzCJ4ZoWdGg2ciwTMT9Mxk8MwkeGaGnpkNnokFzyzQM4vBM4vgmRV6ZjV4JhE8s0HPbAbPbIJnduiZ3eCZVPDMAT1zGDxzCJ45oWdOg2cywTMX9Mxl8MwleOaGnrkNnskFzzzQM4/BM4/gmRd65jV4phA880HPfAbPfIJnfuiZ3+CZUvAsAD0LGDwLCJ4FoWdBg2cqwbMQ9Cxk8CwkeBaGnoUNnqkFzyLQs4jBs4jgWRR6FjV4phE8i0HPYgbPYoJncehZ3OCZVvAsAT1LGDxLCJ4loWdJg2c6wbMU9Cxl8CwleJaGnqUNnukFzzLQs4zBs4zgWRZ6ljV4ZhA8y0HPcgbPcoJneehZ3uCZUfCsAD0rGDwrCJ4VoWdFg2cmwbMS9Kxk8KwkeFaGnpUNnpkFzyrQs4rBs4rgWRV6VjV4ZhE8q0HPagbPaoJndehZ3eCZVfCsAT1rGDxrCJ41oWdNg2c2wbMW9Kxl8KwleNaGnrUNntkFzzrQs47Bs47gWRd61jV45hA860HPegbPeoJnfehZ3+CZU/BsAD0bGDwbCJ4NoWdDg2cuwbMR9Gxk8GwkeDaGno0NnrkFzybQs4nBs4ng2RR6NjV45hE8m0HPZgbPZoJnc+jZ3OCZV/BsAT1bGDxbCJ7vQ8/3DZ75BM+W0LOlwbOl4NkKerYyeOYXPFtDz9YGz9aC5wfQ8wODZwHBsw30bGPwbCN4BtAzMHgWFDzbQs+2Bs+2gmc76NnO4FlI8GwPPdsbPNsLnh2gZweDZ2HBsyP07Gjw7Ch4doKenQyeRQTPztCzs8Gzs+DZBXp2MXgWFTy7Qs+uBs+ugmc36NnN4FlM8OwOPbsbPLsLnj2gZw+DZ3HBsyf07Gnw7Cl49oKevQyeJQTP3tCzt8Gzt+DZB3r2MXiWFDz7Qs++Bs++gmc/6NnP4FlK8OwPPfsbPPsLnh9Czw8NnqUFzwHQc4DBc4Dg+RH0/MjgWUbwHAg9Bxo8BwqeH0PPjw2eZQXPQdBzkMFzkOD5CfT8xOBZTvAcDD0HGzwHC56fQs9PDZ7lBc8h0HOIwXOI4PkZ9PzM4FlB8BwKPYcaPIcKnp9Dz88NnhUFz2HQc5jBc5jg+QX0/MLgWUnwHA49hxs8hwueX0LPLw2elQXPEdBzhMFzhOD5FfT8yuBZRfAcCT1HGjxHCp5fQ8+vDZ5VBc9R0HOUwXOU4PkN9PzG4FlN8BwNPUcbPEcLnt9Cz28NntUFzzHQc4zBc4zg+R30/M7gWUPwHAs9xxo8xwqe30PP7w2eNQXPcdBznMFznOD5A/T8weBZS/AcDz3HGzzHC54/Qs8fDZ61Bc8J0HOCwXOC4PkT9PzJ4FlH8JwIPScaPCcKnj9Dz58NnnUFz0nQc5LBc5Lg+Qv0/MXgWU/wnAw9Jxs8Jwuev0LPXw2e9QXPKdBzisFziuA5FXpONXg2EDynQc9pBs9pgud06Dnd4NlQ8JwBPWcYPGcInjOh50yDZyPBcxb0nGXwnCV4zoaesw2ejQXPOdBzjsFzjuA5F3rONXg2ETznQc95Bs95gud86Dnf4NlU8FwAPRcYPBcInguh50KDZzPBcxH0XGTwXCR4Loaeiw2ezQXPJdBzicFzieC5FHouNXi2EDyXQc9lBs9lgudy6Lnc4Pm+4LkCeq4weK4QPFdCz5UGz5aC5yroucrguUrwXA09Vxs8Wwmea6DnGoPnGsFzLfRca/BsLXiug57rDJ7rBM/foOdvBs8PBM/10HO9wXO94Pk79Pzd4NlG8NwAPTcYPDcInn9Azz8MnoHguRF6bjR4bhQ8/4Sefxo82wqem6DnJoPnJsHzL+j5l8GzneC5GXpuNnhuFjz/hp5/GzzbC55boOcWg+cWwfMf6PmPwbOD4LkVem41eG4VPP+Fnv8aPDsKntug5zaD5zbBczv03G7w7CR47oCeOwyeOwTPndBzp8Gzs+C5C3ruMnjuEjx3Q8/dBs8uguce6LnH4LlH8NwLPfcaPLsKnvug5z6D5z7Bcz/03G/w7CZ4HoCeBwyeBwTPg9DzoMGzu+B5CHoeMngeEjwPQ8/DBs8egucR6HnE4HlE8DwKPY8aPHsKnseg5zGD5zHB8zj0PG7w7CV4noCeJwyeJwTPk9DzpMGzt+B5CnqeMnieEjxPQ8/TBs8+gucZ6HnG4HlG8DwLPc8aPPsKnueg5zmD5znB8zz0PG/w7Cd4XoCeFwyeFwTPi9DzosGzv+B5CXpeMnheEjwvQ8/LBs8PBc8r0POKwfOK4HkVel41eA4QPK9Bz2sGz2uC53Xoed3g+ZHgeQN63jB43hA8b0LPmwbPgYLnLeh5y+B5S/C8DT1vGzw/FjzvQM87Bs87gudd6HnX4DlI8LwHPe8ZPO8Jnveh532D5yeC5wPo+cDg+UDwfAg9Hxo8Bwuej6DnI4PnI8HzMfR8bPD8VPB8Aj2fGDyfCJ5PoedTg+cQwfMZ9Hxm8HwmeD6Hns8Nnp8Jni+g5wuD5wvB8yX0fGnwHCp4voKerwyerwTP19DztcHzc8HzDfR8Y/B8I3i+hZ5vDZ7DBM930POdwfOd4PleR+b537tQPb8QPCN0ZJ4ROobuGbYd3jYi9Ixo8BwueEaCnpEMnpEEz8jQM7LB80vBMwr0jGLwjCJ4RoWeUQ2eIwTPaNAzmsEzmuAZHXpGN3h+JXjGgJ4xDJ4xBM+Y0DOmwXOk4BkLesYyeMYSPGNDz9gGz68FzzjQM47BM47gGRd6xjV4jhI840HPeAbPeIJnfOgZ3+D5jeCZAHomMHgmEDwTQs+EBs/Rgmci6JnI4JlI8EwMPRMbPL8VPJNAzyQGzySCZ1LomdTgOUbwTAY9kxk8kwmeyaFncoPnd4JnCuiZwuCZQvBMCT1TGjzHCp6poGcqg2cqwTM19Ext8Pxe8EwDPdMYPNMInmmhZ1qD5zjBMx30TGfwTCd4poee6Q2ePwieGaBnBoNnBsEzI/TMaPAcL3hmgp6ZDJ6ZBM/M0DOzwfNHwTML9Mxi8MwieGaFnlkNnhMEz2zQM5vBM5vgmR16Zjd4/iR45oCeOQyeOQTPnNAzp8FzouCZC3rmMnjmEjxzQ8/cBs+fBc880DOPwTOP4JkXeuY1eE4SPPNBz3wGz3yCZ37omd/g+YvgWQB6FjB4FhA8C0LPggbPyYJnIehZyOBZSPAsDD0LGzx/FTyLQM8iBs8igmdR6FnU4DlF8CwGPYsZPIsJnsWhZ3GD51TBswT0LGHwLCF4loSeJQ2e0wTPUtCzlMGzlOBZGnqWNnhOFzzLQM8yBs8ygmdZ6FnW4DlD8CwHPcsZPMsJnuWhZ3mD50zBswL0rGDwrCB4VoSeFQ2eswTPStCzksGzkuBZGXpWNnjOFjyrQM8qBs8qgmdV6FnV4DlH8KwGPasZPKsJntWhZ3WD51zBswb0rGHwrCF41oSeNQ2e8wTPWtCzlsGzluBZG3rWNnjOFzzrQM86Bs86gmdd6FnX4LlA8KwHPesZPOsJnvWhZ32D50LBswH0bGDwbCB4NoSeDQ2eiwTPRtCzkcGzkeDZGHo2NnguFjybQM8mBs8mgmdT6NnU4LlE8GwGPZsZPJsJns2hZ3OD51LBswX0bGHwbCF4vg893zd4LhM8W0LPlgbPloJnK+jZyuC5XPBsDT1bGzxbC54fQM8PDJ4rBM820LONwbON4BlAz8DguVLwbAs92xo82wqe7aBnO4PnKsGzPfRsb/BsL3h2gJ4dDJ6rBc+O0LOjwbOj4NkJenYyeK4RPDtDz84Gz86CZxfo2cXguVbw7Ao9uxo8uwqe3aBnN4PnOsGzO/TsbvDsLnj2gJ49DJ6/CZ49oWdPg2dPwbMX9Oxl8FwvePaGnr0Nnr0Fzz7Qs4/B83fBsy/07Gvw7Ct49oOe/QyeGwTP/tCzv8Gzv+D5IfT80OD5h+A5AHoOMHgOEDw/gp4fGTw3Cp4DoedAg+dAwfNj6PmxwfNPwXMQ9Bxk8BwkeH4CPT8xeG4SPAdDz8EGz8GC56fQ81OD51+C5xDoOcTgOUTw/Ax6fmbw3Cx4DoWeQw2eQwXPz6Hn5wbPvwXPYdBzmMFzmOD5BfT8wuC5RfAcDj2HGzyHC55fQs8vDZ7/CJ4joOcIg+cIwfMr6PmVwXOr4DkSeo40eI4UPL+Gnl8bPP8VPEdBz1EGz1GC5zfQ8xuD5zbBczT0HG3wHC14fgs9vzV4bhc8x0DPMQbPMYLnd9DzO4PnDsFzLPQca/AcK3h+Dz2/N3juFDzHQc9xBs9xgucP0PMHg+cuwXM89Bxv8BwveP4IPX80eO4WPCdAzwkGzwmC50/Q8yeD5x7BcyL0nGjwnCh4/gw9fzZ47hU8J0HPSQbPSYLnL9DzF4PnPsFzMvScbPCcLHj+Cj1/NXjuFzynQM8pBs8pgudU6DnV4HlA8JwGPacZPKcJntOh53SD50HBcwb0nGHwnCF4zoSeMw2ehwTPWdBzlsFzluA5G3rONngeFjznQM85Bs85gudc6DnX4HlE8JwHPecZPOcJnvOh53yD51HBcwH0XGDwXCB4LoSeCw2exwTPRdBzkcFzkeC5GHouNngeFzyXQM8lBs8lgudS6LnU4HlC8FwGPZcZPJcJnsuh53KD50nBcwX0XGHwXCF4roSeKw2epwTPVdBzlcFzleC5GnquNnieFjzXQM81Bs81guda6LnW4HlG8FwHPdcZPNcJnr9Bz98MnmcFz/XQc73Bc73g+Tv0/N3geU7w3AA9Nxg8Nwief0DPPwye5wXPjdBzo8Fzo+D5J/T80+B5QfDcBD03GTw3CZ5/Qc+/DJ4XBc/N0HOzwXOz4Pk39Pzb4HlJ8NwCPbcYPLcInv9Az38MnpcFz63Qc6vBc6vg+S/0/NfgeUXw3AY9txk8twme26HndoPnVcFzB/TcYfDcIXjuhJ47DZ7XBM9d0HOXwXOX4Lkbeu42eF4XPPdAzz0Gzz2C517oudfgeUPw3Ac99xk89wme+6HnfoPnTcHzAPQ8YPA8IHgehJ4HDZ63BM9D0POQwfOQ4HkYeh42eN4WPI9AzyMGzyOC51HoedTgeUfwPAY9jxk8jwmex6HncYPnXcHzBPQ8YfA8IXiehJ4nDZ73BM9T0POUwfOU4Hkaep42eN4XPM9AzzMGzzOC51noedbg+UDwPAc9zxk8zwme56HneYPnQ8HzAvS8YPC8IHhehJ4XDZ6PBM9L0POSwfOS4HkZel42eD4WPK9AzysGzyuC51XoedXg+UTwvAY9rxk8rwme16HndYPnU8HzBvS8YfC8IXjehJ43DZ7PBM9b0POWwfOW4Hkbet42eD4XPO9AzzsGzzuC513oedfg+ULwvAc97xk87wme96HnfYPnS8HzAfR8YPB8IHg+hJ4PDZ6vBM9H0PORwfOR4PkYej42eL4WPJ9AzycGzyeC51Po+dTg+UbwfAY9nxk8nwmez6Hnc4PnW8HzBfR8YfB8IXi+hJ4vDZ7vBM9X0POVwfOV4Pkaer42eL5X5H+/8w30fGPwfCN4voWebw2eEQTPd9DzncHzneD5Xifm+d+7UD0jCp4ROjHPCJ1C9wzbDm8bEXpGNHhGEjwjQc9IBs9Igmdk6BnZ4BlZ8IwCPaMYPKMInlGhZ1SDZxTBMxr0jGbwjCZ4Roee0Q2eUQXPGNAzhsEzhuAZE3rGNHhGEzxjQc9YBs9Ygmds6Bnb4Bld8IwDPeMYPOMInnGhZ1yDZwzBMx70jGfwjCd4xoee8Q2eMQXPBNAzgcEzgeCZEHomNHjGEjwTQc9EBs9Egmdi6JnY4Blb8EwCPZMYPJMInkmhZ1KDZxzBMxn0TGbwTCZ4JoeeyQ2ecQXPFNAzhcEzheCZEnqmNHjGEzxTQc9UBs9Ugmdq6Jna4Blf8EwDPdMYPNMInmmhZ1qDZwLBMx30TGfwTCd4poee6Q2eCQXPDNAzg8Ezg+CZEXpmNHgmEjwzQc9MBs9Mgmdm6JnZ4JlY8MwCPbMYPLMInlmhZ1aDZxLBMxv0zGbwzCZ4Zoee2Q2eSQXPHNAzh8Ezh+CZE3rmNHgmEzxzQc9cBs9cgmdu6Jnb4Jlc8MwDPfMYPPMInnmhZ16DZwrBMx/0zGfwzCd45oee+Q2eKQXPAtCzgMGzgOBZEHoWNHimEjwLQc9CBs9Cgmdh6FnY4Jla8CwCPYsYPIsInkWhZ1GDZxrBsxj0LGbwLCZ4FoeexQ2eaQXPEtCzhMGzhOBZEnqWNHimEzxLQc9SBs9Sgmdp6Fna4Jle8CwDPcsYPMsInmWhZ1mDZwbBsxz0LGfwLCd4loee5Q2eGQXPCtCzgsGzguBZEXpWNHhmEjwrQc9KBs9Kgmdl6FnZ4JlZ8KwCPasYPKsInlWhZ1WDZxbBsxr0rGbwrCZ4Voee1Q2eWQXPGtCzhsGzhuBZE3rWNHhmEzxrQc9aBs9agmdt6Fnb4Jld8KwDPesYPOsInnWhZ12DZw7Bsx70rGfwrCd41oee9Q2eOQXPBtCzgcGzgeDZEHo2NHjmEjwbQc9GBs9Ggmdj6NnY4Jlb8GwCPZsYPJsInk2hZ1ODZx7Bsxn0bGbwbCZ4NoeezQ2eeQXPFtCzhcGzheD5PvR83+CZT/BsCT1bGjxbCp6toGcrg2d+wbM19Gxt8GwteH4APT8weBYQPNtAzzYGzzaCZwA9A4NnQcGzLfRsa/BsK3i2g57tDJ6FBM/20LO9wbO94NkBenYweBYWPDtCz44Gz46CZyfo2cngWUTw7Aw9Oxs8OwueXaBnF4NnUcGzK/TsavDsKnh2g57dDJ7FBM/u0LO7wbO74NkDevYweBYXPHtCz54Gz56CZy/o2cvgWULw7A09exs8ewuefaBnH4NnScGzL/Tsa/DsK3j2g579DJ6lBM/+0LO/wbO/4Pkh9PzQ4Fla8BwAPQcYPAcInh9Bz48MnmUEz4HQc6DBc6Dg+TH0/NjgWVbwHAQ9Bxk8Bwmen0DPTwye5QTPwdBzsMFzsOD5KfT81OBZXvAcAj2HGDyHCJ6fQc/PDJ4VBM+h0HOowXOo4Pk59Pzc4FlR8BwGPYcZPIcJnl9Azy8MnpUEz+HQc7jBc7jg+SX0/NLgWVnwHAE9Rxg8RwieX0HPrwyeVQTPkdBzpMFzpOD5NfT82uBZVfAcBT1HGTxHCZ7fQM9vDJ7VBM/R0HO0wXO04Pkt9PzW4Fld8BwDPccYPMcInt9Bz+8MnjUEz7HQc6zBc6zg+T30/N7gWVPwHAc9xxk8xwmeP0DPHwyetQTP8dBzvMFzvOD5I/T80eBZW/CcAD0nGDwnCJ4/Qc+fDJ51BM+J0HOiwXOi4Pkz9PzZ4FlX8JwEPScZPCcJnr9Az18MnvUEz8nQc7LBc7Lg+Sv0/NXgWV/wnAI9pxg8pwieU6HnVINnA8FzGvScZvCcJnhOh57TDZ4NBc8Z0HOGwXOG4DkTes40eDYSPGdBz1kGz1mC52zoOdvg2VjwnAM95xg85wiec6HnXINnE8FzHvScZ/CcJ3jOh57zDZ5NBc8F0HOBwXOB4LkQei40eDYTPBdBz0UGz0WC52Loudjg2VzwXAI9lxg8lwieS6HnUoNnC8FzGfRcZvBcJnguh57LDZ7vC54roOcKg+cKwXMl9Fxp8GwpeK6CnqsMnqsEz9XQc7XBs5XguQZ6rjF4rhE810LPtQbP1oLnOui5zuC5TvD8DXr+ZvD8QPBcDz3XGzzXC56/Q8/fDZ5tBM8N0HODwXOD4PkH9PzD4BkInhuh50aD50bB80/o+afBs63guQl6bjJ4bhI8/4Kefxk82wmem6HnZoPnZsHzb+j5t8GzveC5BXpuMXhuETz/gZ7/GDw7CJ5boedWg+dWwfNf6PmvwbOj4LkNem4zeG4TPLdDz+0Gz06C5w7oucPguUPw3Ak9dxo8Owueu6DnLoPnLsFzN/TcbfDsInjugZ57DJ57BM+90HOvwbOr4LkPeu4zeO4TPPdDz/0Gz26C5wHoecDgeUDwPAg9Dxo8uwueh6DnIYPnIcHzMPQ8bPDsIXgegZ5HDJ5HBM+j0POowbOn4HkMeh4zeB4TPI9Dz+MGz16C5wnoecLgeULwPAk9Txo8ewuep6DnKYPnKcHzNPQ8bfDsI3iegZ5nDJ5nBM+z0POswbOv4HkOep4zeJ4TPM9Dz/MGz36C5wXoecHgeUHwvAg9Lxo8+wuel6DnJYPnJcHzMvS8bPD8UPC8Aj2vGDyvCJ5XoedVg+cAwfMa9Lxm8LwmeF6HntcNnh8Jnjeg5w2D5w3B8yb0vGnwHCh43oKetwyetwTP29DztsHzY8HzDvS8Y/C8I3jehZ53DZ6DBM970POewfOe4Hkfet43eH4ieD6Ang8Mng8Ez4fQ86HBc7Dg+Qh6PjJ4PhI8H0PPxwbPTwXPJ9DzicHzieD5FHo+NXgOETyfQc9nBs9ngudz6Pnc4PmZ4PkCer4weL4QPF9Cz5cGz6GC5yvo+crg+UrwfA09Xxs8Pxc830DPNwbPN4LnW+j51uA5TPB8Bz3fGTzfCZ7vdWae/70L1fMLwTNCZ+YZoXPonmHb4W0jQs+IBs/hgmck6BnJ4BlJ8IwMPSMbPL8UPKNAzygGzyiCZ1ToGdXgOULwjAY9oxk8owme0aFndIPnV4JnDOgZw+AZQ/CMCT1jGjxHCp6xoGcsg2cswTM29Ixt8Pxa8IwDPeMYPOMInnGhZ1yD5yjBMx70jGfwjCd4xoee8Q2e3wieCaBnAoNnAsEzIfRMaPAcLXgmgp6JDJ6JBM/E0DOxwfNbwTMJ9Exi8EwieCaFnkkNnmMEz2TQM5nBM5ngmRx6Jjd4fid4poCeKQyeKQTPlNAzpcFzrOCZCnqmMnimEjxTQ8/UBs/vBc800DONwTON4JkWeqY1eI4TPNNBz3QGz3SCZ3romd7g+YPgmQF6ZjB4ZhA8M0LPjAbP8YJnJuiZyeCZSfDMDD0zGzx/FDyzQM8sBs8sgmdW6JnV4DlB8MwGPbMZPLMJntmhZ3aD50+CZw7omcPgmUPwzAk9cxo8JwqeuaBnLoNnLsEzN/TMbfD8WfDMAz3zGDzzCJ55oWdeg+ckwTMf9Mxn8MwneOaHnvkNnr8IngWgZwGDZwHBsyD0LGjwnCx4FoKehQyehQTPwtCzsMHzV8GzCPQsYvAsIngWhZ5FDZ5TBM9i0LOYwbOY4FkcehY3eE4VPEtAzxIGzxKCZ0noWdLgOU3wLAU9Sxk8SwmepaFnaYPndMGzDPQsY/AsI3iWhZ5lDZ4zBM9y0LOcwbOc4FkeepY3eM4UPCtAzwoGzwqCZ0XoWdHgOUvwrAQ9Kxk8KwmelaFnZYPnbMGzCvSsYvCsInhWhZ5VDZ5zBM9q0LOawbOa4FkdelY3eM4VPGtAzxoGzxqCZ03oWdPgOU/wrAU9axk8awmetaFnbYPnfMGzDvSsY/CsI3jWhZ51DZ4LBM960LOewbOe4FkfetY3eC4UPBtAzwYGzwaCZ0Po2dDguUjwbAQ9Gxk8GwmejaFnY4PnYsGzCfRsYvBsIng2hZ5NDZ5LBM9m0LOZwbOZ4NkcejY3eC4VPFtAzxYGzxaC5/vQ832D5zLBsyX0bGnwbCl4toKerQyeywXP1tCztcGzteD5AfT8wOC5QvBsAz3bGDzbCJ4B9AwMnisFz7bQs63Bs63g2Q56tjN4rhI820PP9gbP9oJnB+jZweC5WvDsCD07Gjw7Cp6doGcng+cawbMz9Oxs8OwseHaBnl0MnmsFz67Qs6vBs6vg2Q16djN4rhM8u0PP7gbP7oJnD+jZw+D5m+DZE3r2NHj2FDx7Qc9eBs/1gmdv6Nnb4Nlb8OwDPfsYPH8XPPtCz74Gz76CZz/o2c/guUHw7A89+xs8+wueH0LPDw2efwieA6DnAIPnAMHzI+j5kcFzo+A5EHoONHgOFDw/hp4fGzz/FDwHQc9BBs9Bgucn0PMTg+cmwXMw9Bxs8BwseH4KPT81eP4leA6BnkMMnkMEz8+g52cGz82C51DoOdTgOVTw/Bx6fm7w/FvwHAY9hxk8hwmeX0DPLwyeWwTP4dBzuMFzuOD5JfT80uD5j+A5AnqOMHiOEDy/gp5fGTy3Cp4joedIg+dIwfNr6Pm1wfNfwXMU9Bxl8BwleH4DPb8xeG4TPEdDz9EGz9GC57fQ81uD53bBcwz0HGPwHCN4fgc9vzN47hA8x0LPsQbPsYLn99Dze4PnTsFzHPQcZ/AcJ3j+AD1/MHjuEjzHQ8/xBs/xgueP0PNHg+duwXMC9Jxg8JwgeP4EPX8yeO4RPCdCz4kGz4mC58/Q82eD517BcxL0nGTwnCR4/gI9fzF47hM8J0PPyQbPyYLnr9DzV4PnfsFzCvScYvCcInhOhZ5TDZ4HBM9p0HOawXOa4Dkdek43eB4UPGdAzxkGzxmC50zoOdPgeUjwnAU9Zxk8Zwmes6HnbIPnYcFzDvScY/CcI3jOhZ5zDZ5HBM950HOewXOe4Dkfes43eB4VPBdAzwUGzwWC50LoudDgeUzwXAQ9Fxk8Fwmei6HnYoPnccFzCfRcYvBcInguhZ5LDZ4nBM9l0HOZwXOZ4Lkcei43eJ4UPFdAzxUGzxWC50roudLgeUrwXAU9Vxk8Vwmeq6HnaoPnacFzDfRcY/BcI3iuhZ5rDZ5nBM910HOdwXOd4Pkb9PzN4HlW8FwPPdcbPNcLnr9Dz98NnucEzw3Qc4PBc4Pg+Qf0/MPgeV7w3Ag9Nxo8Nwqef0LPPw2eFwTPTdBzk8Fzk+D5F/T8y+B5UfDcDD03Gzw3C55/Q8+/DZ6XBM8t0HOLwXOL4PkP9PzH4HlZ8NwKPbcaPLcKnv9Cz38NnlcEz23Qc5vBc5vguR16bjd4XhU8d0DPHQbPHYLnTui50+B5TfDcBT13GTx3CZ67oedug+d1wXMP9Nxj8NwjeO6FnnsNnjcEz33Qc5/Bc5/guR967jd43hQ8D0DPAwbPA4LnQeh50OB5S/A8BD0PGTwPCZ6Hoedhg+dtwfMI9Dxi8DwieB6FnkcNnncEz2PQ85jB85jgeRx6Hjd43hU8T0DPEwbPE4LnSeh50uB5T/A8BT1PGTxPCZ6noedpg+d9wfMM9Dxj8DwjeJ6FnmcNng8Ez3PQ85zB85zgeR56njd4PhQ8L0DPCwbPC4LnReh50eD5SPC8BD0vGTwvCZ6Xoedlg+djwfMK9Lxi8LwieF6FnlcNnk8Ez2vQ85rB85rgeR16Xjd4PhU8b0DPGwbPG4LnTeh50+D5TPC8BT1vGTxvCZ63oedtg+dzwfMO9Lxj8LwjeN6FnncNni8Ez3vQ857B857geR963jd4Roj4v9/54H/1fJv+/935wOD5QPB8+L96vi7//+58aPCMKHg+gp6PDJ6PBM/H0POxwTOS4PkEej4xeD4RPJ9Cz6cGz8iC5zPo+czg+UzwfA49nxs8owieL6DnC4PnC8HzJfR8afCMKni+gp6vDJ6vBM/X0PO1wTOa4PkGer4xeL4RPN9Cz7cGz+iC5zvo+c7g+U7wfK8L8/zvXaieMQTPCF2YZ4QuoXuGbYe3jQg9Ixo8YwqekaBnJINnJMEzMvSMbPCMJXhGgZ5RDJ5RBM+o0DOqwTO24BkNekYzeEYTPKNDz+gGzziCZwzoGcPgGUPwjAk9Yxo84wqesaBnLINnLMEzNvSMbfCMJ3jGgZ5xDJ5xBM+40DOuwTO+4BkPesYzeMYTPONDz/gGzwSCZwLomcDgmUDwTAg9Exo8EwqeiaBnIoNnIsEzMfRMbPBMJHgmgZ5JDJ5JBM+k0DOpwTOx4JkMeiYzeCYTPJNDz+QGzySCZwromcLgmULwTAk9Uxo8kwqeqaBnKoNnKsEzNfRMbfBMJnimgZ5pDJ5pBM+00DOtwTO54JkOeqYzeKYTPNNDz/QGzxSCZwbomcHgmUHwzAg9Mxo8UwqemaBnJoNnJsEzM/TMbPBMJXhmgZ5ZDJ5ZBM+s0DOrwTO14JkNemYzeGYTPLNDz+wGzzSCZw7omcPgmUPwzAk9cxo80wqeuaBnLoNnLsEzN/TMbfBMJ3jmgZ55DJ55BM+80DOvwTO94JkPeuYzeOYTPPNDz/wGzwyCZwHoWcDgWUDwLAg9Cxo8MwqehaBnIYNnIcGzMPQsbPDMJHgWgZ5FDJ5FBM+i0LOowTOz4FkMehYzeBYTPItDz+IGzyyCZwnoWcLgWULwLAk9Sxo8swqepaBnKYNnKcGzNPQsbfDMJniWgZ5lDJ5lBM+y0LOswTO74FkOepYzeJYTPMtDz/IGzxyCZwXoWcHgWUHwrAg9Kxo8cwqelaBnJYNnJcGzMvSsbPDMJXhWgZ5VDJ5VBM+q0LOqwTO34FkNelYzeFYTPKtDz+oGzzyCZw3oWcPgWUPwrAk9axo88wqetaBnLYNnLcGzNvSsbfDMJ3jWgZ51DJ51BM+60LOuwTO/4FkPetYzeNYTPOtDz/oGzwKCZwPo2cDg2UDwbAg9Gxo8CwqejaBnI4NnI8GzMfRsbPAsJHg2gZ5NDJ5NBM+m0LOpwbOw4NkMejYzeDYTPJtDz+YGzyKCZwvo2cLg2ULwfB96vm/wLCp4toSeLQ2eLQXPVtCzlcGzmODZGnq2Nni2Fjw/gJ4fGDyLC55toGcbg2cbwTOAnoHBs4Tg2RZ6tjV4thU820HPdgbPkoJne+jZ3uDZXvDsAD07GDxLCZ4doWdHg2dHwbMT9Oxk8CwteHaGnp0Nnp0Fzy7Qs4vBs4zg2RV6djV4dhU8u0HPbgbPsoJnd+jZ3eDZXfDsAT17GDzLCZ49oWdPg2dPwbMX9Oxl8CwvePaGnr0Nnr0Fzz7Qs4/Bs4Lg2Rd69jV49hU8+0HPfgbPioJnf+jZ3+DZX/D8EHp+aPCsJHgOgJ4DDJ4DBM+PoOdHBs/KgudA6DnQ4DlQ8PwYen5s8KwieA6CnoMMnoMEz0+g5ycGz6qC52DoOdjgOVjw/BR6fmrwrCZ4DoGeQwyeQwTPz6DnZwbP6oLnUOg51OA5VPD8HHp+bvCsIXgOg57DDJ7DBM8voOcXBs+agudw6Dnc4Dlc8PwSen5p8KwleI6AniMMniMEz6+g51cGz9qC50joOdLgOVLw/Bp6fm3wrCN4joKeowyeowTPb6DnNwbPuoLnaOg52uA5WvD8Fnp+a/CsJ3iOgZ5jDJ5jBM/voOd3Bs/6gudY6DnW4DlW8Pween5v8GwgeI6DnuMMnuMEzx+g5w8Gz4aC53joOd7gOV7w/BF6/mjwbCR4ToCeEwyeEwTPn6DnTwbPxoLnROg50eA5UfD8GXr+bPBsInhOgp6TDJ6TBM9foOcvBs+mgudk6DnZ4DlZ8PwVev5q8GwmeE6BnlMMnlMEz6nQc6rBs7ngOQ16TjN4ThM8p0PP6QbPFoLnDOg5w+A5Q/CcCT1nGjzfFzxnQc9ZBs9Zguds6Dnb4NlS8JwDPecYPOcInnOh51yDZyvBcx70nGfwnCd4zoee8w2erQXPBdBzgcFzgeC5EHouNHh+IHgugp6LDJ6LBM/F0HOxwbON4LkEei4xeC4RPJdCz6UGz0DwXAY9lxk8lwmey6HncoNnW8FzBfRcYfBcIXiuhJ4rDZ7tBM9V0HOVwXOV4Lkaeq42eLYXPNdAzzUGzzWC51roudbg2UHwXAc91xk81wmev0HP3wyeHQXP9dBzvcFzveD5O/T83eDZSfDcAD03GDw3CJ5/QM8/DJ6dBc+N0HOjwXOj4Pkn9PzT4NlF8NwEPTcZPDcJnn9Bz78Mnl0Fz83Qc7PBc7Pg+Tf0/Nvg2U3w3AI9txg8twie/0DPfwye3QXPrdBzq8Fzq+D5L/T81+DZQ/DcBj23GTy3CZ7boed2g2dPwXMH9Nxh8NwheO6EnjsNnr0Ez13Qc5fBc5fguRt67jZ49hY890DPPQbPPYLnXui51+DZR/DcBz33GTz3CZ77oed+g2dfwfMA9Dxg8DwgeB6EngcNnv0Ez0PQ85DB85DgeRh6HjZ49hc8j0DPIwbPI4LnUeh51OD5oeB5DHoeM3geEzyPQ8/jBs8BgucJ6HnC4HlC8DwJPU8aPD8SPE9Bz1MGz1OC52noedrgOVDwPAM9zxg8zwieZ6HnWYPnx4LnOeh5zuB5TvA8Dz3PGzwHCZ4XoOcFg+cFwfMi9Lxo8PxE8LwEPS8ZPC8Jnpeh52WD52DB8wr0vGLwvCJ4XoWeVw2enwqe16DnNYPnNcHzOvS8bvAcInjegJ43DJ43BM+b0POmwfMzwfMW9Lxl8LwleN6GnrcNnkMFzzvQ847B847geRd63jV4fi543oOe9wye9wTP+9DzvsFzmOD5AHo+MHg+EDwfQs+HBs8vBM9H0PORwfOR4PkYej42eA4XPJ9AzycGzyeC51Po+dTg+aXg+Qx6PjN4PhM8n0PP5wbPEYLnC+j5wuD5QvB8CT1fGjy/EjxfQc9XBs9Xgudr6Pna4DlS8HwDPd8YPN8Inm+h51uD59eC5zvo+c7g+U7wfK8r8/zvXaieowTPCF2ZZ4SuoXuGbYe3jQg9Ixo8vxE8I0HPSAbPSIJnZOgZ2eA5WvCMAj2jGDyjCJ5RoWdUg+e3gmc06BnN4BlN8IwOPaMbPMcInjGgZwyDZwzBMyb0jGnw/E7wjAU9Yxk8YwmesaFnbIPnWMEzDvSMY/CMI3jGhZ5xDZ7fC57xoGc8g2c8wTM+9Ixv8BwneCaAngkMngkEz4TQM6HB8wfBMxH0TGTwTCR4JoaeiQ2e4wXPJNAzicEzieCZFHomNXj+KHgmg57JDJ7JBM/k0DO5wXOC4JkCeqYweKYQPFNCz5QGz58Ez1TQM5XBM5XgmRp6pjZ4ThQ800DPNAbPNIJnWuiZ1uD5s+CZDnqmM3imEzzTQ8/0Bs9JgmcG6JnB4JlB8MwIPTMaPH8RPDNBz0wGz0yCZ2bomdngOVnwzAI9sxg8swieWaFnVoPnr4JnNuiZzeCZTfDMDj2zGzynCJ45oGcOg2cOwTMn9Mxp8JwqeOaCnrkMnrkEz9zQM7fBc5rgmQd65jF45hE880LPvAbP6YJnPuiZz+CZT/DMDz3zGzxnCJ4FoGcBg2cBwbMg9Cxo8JwpeBaCnoUMnoUEz8LQs7DBc5bgWQR6FjF4FhE8i0LPogbP2YJnMehZzOBZTPAsDj2LGzznCJ4loGcJg2cJwbMk9Cxp8JwreJaCnqUMnqUEz9LQs7TBc57gWQZ6ljF4lhE8y0LPsgbP+YJnOehZzuBZTvAsDz3LGzwXCJ4VoGcFg2cFwbMi9Kxo8FwoeFaCnpUMnpUEz8rQs7LBc5HgWQV6VjF4VhE8q0LPqgbPxYJnNehZzeBZTfCsDj2rGzyXCJ41oGcNg2cNwbMm9Kxp8FwqeNaCnrUMnrUEz9rQs7bBc5ngWQd61jF41hE860LPugbP5YJnPehZz+BZT/CsDz3rGzxXCJ4NoGcDg2cDwbMh9Gxo8FwpeDaCno0Mno0Ez8bQs7HBc5Xg2QR6NjF4NhE8m0LPpgbP1YJnM+jZzODZTPBsDj2bGzzXCJ4toGcLg2cLwfN96Pm+wXOt4NkSerY0eLYUPFtBz1YGz3WCZ2vo2drg2Vrw/AB6fmDw/E3wbAM92xg82wieAfQMDJ7rBc+20LOtwbOt4NkOerYzeP4ueLaHnu0Nnu0Fzw7Qs4PBc4Pg2RF6djR4dhQ8O0HPTgbPPwTPztCzs8Gzs+DZBXp2MXhuFDy7Qs+uBs+ugmc36NnN4Pmn4NkdenY3eHYXPHtAzx4Gz02CZ0/o2dPg2VPw7AU9exk8/xI8e0PP3gbP3oJnH+jZx+C5WfDsCz37Gjz7Cp79oGc/g+ffgmd/6Nnf4Nlf8PwQen5o8NwieA6AngMMngMEz4+g50cGz38Ez4HQc6DBc6Dg+TH0/NjguVXwHAQ9Bxk8Bwmen0DPTwye/wqeg6HnYIPnYMHzU+j5qcFzm+A5BHoOMXgOETw/g56fGTy3C55DoedQg+dQwfNz6Pm5wXOH4DkMeg4zeA4TPL+Anl8YPHcKnsOh53CD53DB80vo+aXBc5fgOQJ6jjB4jhA8v4KeXxk8dwueI6HnSIPnSMHza+j5tcFzj+A5CnqOMniOEjy/gZ7fGDz3Cp6joedog+dowfNb6PmtwXOf4DkGeo4xeI4RPL+Dnt8ZPPcLnmOh51iD51jB83vo+b3B84DgOQ56jjN4jhM8f4CePxg8Dwqe46HneIPneMHzR+j5o8HzkOA5AXpOMHhOEDx/gp4/GTwPC54ToedEg+dEwfNn6PmzwfOI4DkJek4yeE4SPH+Bnr8YPI8KnpOh52SD52TB81fo+avB85jgOQV6TjF4ThE8p0LPqQbP44LnNOg5zeA5TfCcDj2nGzxPCJ4zoOcMg+cMwXMm9Jxp8DwpeM6CnrMMnrMEz9nQc7bB85TgOQd6zjF4zhE850LPuQbP04LnPOg5z+A5T/CcDz3nGzzPCJ4LoOcCg+cCwXMh9Fxo8DwreC6CnosMnosEz8XQc7HB85zguQR6LjF4LhE8l0LPpQbP84LnMui5zOC5TPBcDj2XGzwvCJ4roOcKg+cKwXMl9Fxp8LwoeK6CnqsMnqsEz9XQc7XB85LguQZ6rjF4rhE810LPtQbPy4LnOui5zuC5TvD8DXr+ZvC8Iniuh57rDZ7rBc/foefvBs+rgucG6LnB4LlB8PwDev5h8LwmeG6EnhsNnhsFzz+h558Gz+uC5yboucnguUnw/At6/mXwvCF4boaemw2emwXPv6Hn3wbPm4LnFui5xeC5RfD8B3r+Y/C8JXhuhZ5bDZ5bBc9/oee/Bs/bguc26LnN4LlN8NwOPbcbPO8Injug5w6D5w7Bcyf03GnwvCt47oKeuwyeuwTP3dBzt8HznuC5B3ruMXjuETz3Qs+9Bs/7guc+6LnP4LlP8NwPPfcbPB8Ingeg5wGD5wHB8yD0PGjwfCh4HoKehwyehwTPw9DzsMHzkeB5BHoeMXgeETyPQs+jBs/Hgucx6HnM4HlM8DwOPY8bPJ8Inieg5wmD5wnB8yT0PGnwfCp4noKepwyepwTP09DztMHzmeB5BnqeMXieETzPQs+zBs/nguc56HnO4HlO8DwPPc8bPF8Inheg5wWD5wXB8yL0vGjwfCl4XoKelwyelwTPy9DzssHzleB5BXpeMXheETyvQs+rBs/Xguc16HnN4HlN8LwOPa8bPN8Injeg5w2D5w3B8yb0vGnwfCt43oKetwyetwTP29DztsHzneB5B3reMXjeETzvQs+7Bs//fpb+f7zzHvS8Z/C8J3jeh573DZ4RBM8H0POBwfOB4PkQej40eEYUPB9Bz0cGz0eC52Po+djgGUnwfAI9nxg8nwieT6HnU4NnZMHzGfR8ZvB8Jng+h57PDZ5RBM8X0POFwfOF4PkSer40eEYVPF9Bz1cGz1eC52vo+drgGU3wfAM93xg83wieb6HnW4NndMHzHfR8Z/B8J3i+1415/vcuVM8YgmeEbswzQrfQPcO2w9tGhJ4RDZ4xBc9I0DOSwTOS4BkZekY2eMYSPKNAzygGzyiCZ1ToGdXgGVvwjAY9oxk8owme0aFndINnHMEzBvSMYfCMIXjGhJ4xDZ5xBc9Y0DOWwTOW4BkbesY2eMYTPONAzzgGzziCZ1zoGdfgGV/wjAc94xk84wme8aFnfINnAsEzAfRMYPBMIHgmhJ4JDZ4JBc9E0DORwTOR4JkYeiY2eCYSPJNAzyQGzySCZ1LomdTgmVjwTAY9kxk8kwmeyaFncoNnEsEzBfRMYfBMIXimhJ4pDZ5JBc9U0DOVwTOV4JkaeqY2eCYTPNNAzzQGzzSCZ1romdbgmVzwTAc90xk80wme6aFneoNnCsEzA/TMYPDMIHhmhJ4ZDZ4pBc9M0DOTwTOT4JkZemY2eKYSPLNAzywGzyyCZ1bomdXgmVrwzAY9sxk8swme2aFndoNnGsEzB/TMYfDMIXjmhJ45DZ5pBc9c0DOXwTOX4JkbeuY2eKYTPPNAzzwGzzyCZ17omdfgmV7wzAc98xk88wme+aFnfoNnBsGzAPQsYPAsIHgWhJ4FDZ4ZBc9C0LOQwbOQ4FkYehY2eGYSPItAzyIGzyKCZ1HoWdTgmVnwLAY9ixk8iwmexaFncYNnFsGzBPQsYfAsIXiWhJ4lDZ5ZBc9S0LOUwbOU4FkaepY2eGYTPMtAzzIGzzKCZ1noWdbgmV3wLAc9yxk8ywme5aFneYNnDsGzAvSsYPCsIHhWhJ4VDZ45Bc9K0LOSwbOS4FkZelY2eOYSPKtAzyoGzyqCZ1XoWdXgmVvwrAY9qxk8qwme1aFndYNnHsGzBvSsYfCsIXjWhJ41DZ55Bc9a0LOWwbOW4FkbetY2eOYTPOtAzzoGzzqCZ13oWdfgmV/wrAc96xk86wme9aFnfYNnAcGzAfRsYPBsIHg2hJ4NDZ4FBc9G0LORwbOR4NkYejY2eBYSPJtAzyYGzyaCZ1Po2dTgWVjwbAY9mxk8mwmezaFnc4NnEcGzBfRsYfBsIXi+Dz3fN3gWFTxbQs+WBs+Wgmcr6NnK4FlM8GwNPVsbPFsLnh9Azw8MnsUFzzbQs43Bs43gGUDPwOBZQvBsCz3bGjzbCp7toGc7g2dJwbM99Gxv8GwveHaAnh0MnqUEz47Qs6PBs6Pg2Ql6djJ4lhY8O0PPzgbPzoJnF+jZxeBZRvDsCj27Gjy7Cp7doGc3g2dZwbM79Oxu8OwuePaAnj0MnuUEz57Qs6fBs6fg2Qt69jJ4lhc8e0PP3gbP3oJnH+jZx+BZQfDsCz37Gjz7Cp79oGc/g2dFwbM/9Oxv8OwveH4IPT80eFYSPAdAzwEGzwGC50fQ8yODZ2XBcyD0HGjwHCh4fgw9PzZ4VhE8B0HPQQbPQYLnJ9DzE4NnVcFzMPQcbPAcLHh+Cj0/NXhWEzyHQM8hBs8hgudn0PMzg2d1wXMo9Bxq8BwqeH4OPT83eNYQPIdBz2EGz2GC5xfQ8wuDZ03Bczj0HG7wHC54fgk9vzR41hI8R0DPEQbPEYLnV9DzK4NnbcFzJPQcafAcKXh+DT2/NnjWETxHQc9RBs9Rguc30PMbg2ddwXM09Bxt8BwteH4LPb81eNYTPMdAzzEGzzGC53fQ8zuDZ33Bcyz0HGvwHCt4fg89vzd4NhA8x0HPcQbPcYLnD9DzB4NnQ8FzPPQcb/AcL3j+CD1/NHg2EjwnQM8JBs8JgudP0PMng2djwXMi9Jxo8JwoeP4MPX82eDYRPCdBz0kGz0mC5y/Q8xeDZ1PBczL0nGzwnCx4/go9fzV4NhM8p0DPKQbPKYLnVOg51eDZXPCcBj2nGTynCZ7Toed0g2cLwXMG9Jxh8JwheM6EnjMNnu8LnrOg5yyD5yzBczb0nG3wbCl4zoGecwyecwTPudBzrsGzleA5D3rOM3jOEzznQ8/5Bs/WgucC6LnA4LlA8FwIPRcaPD8QPBdBz0UGz0WC52Loudjg2UbwXAI9lxg8lwieS6HnUoNnIHgug57LDJ7LBM/l0HO5wbOt4LkCeq4weK4QPFdCz5UGz3aC5yroucrguUrwXA09Vxs82wuea6DnGoPnGsFzLfRca/DsIHiug57rDJ7rBM/foOdvBs+Ogud66Lne4Lle8Pwdev5u8OwkeG6AnhsMnhsEzz+g5x8Gz86C50boudHguVHw/BN6/mnw7CJ4boKemwyemwTPv6DnXwbProLnZui52eC5WfD8G3r+bfDsJnhugZ5bDJ5bBM9/oOc/Bs/ugudW6LnV4LlV8PwXev5r8OwheG6DntsMntsEz+3Qc7vBs6fguQN67jB47hA8d0LPnQbPXoLnLui5y+C5S/DcDT13Gzx7C557oOceg+cewXMv9Nxr8OwjeO6DnvsMnvsEz/3Qc7/Bs6/geQB6HjB4HhA8D0LPgwbPfoLnIeh5yOB5SPA8DD0PGzz7C55HoOcRg+cRwfMo9Dxq8PxQ8DwGPY8ZPI8Jnseh53GD5wDB8wT0PGHwPCF4noSeJw2eHwmep6DnKYPnKcHzNPQ8bfAcKHiegZ5nDJ5nBM+z0POswfNjwfMc9Dxn8DwneJ6HnucNnoMEzwvQ84LB84LgeRF6XjR4fiJ4XoKelwyelwTPy9DzssFzsOB5BXpeMXheETyvQs+rBs9PBc9r0POawfOa4Hkdel43eA4RPG9AzxsGzxuC503oedPg+ZngeQt63jJ43hI8b0PP2wbPoYLnHeh5x+B5R/C8Cz3vGjw/FzzvQc97Bs97gud96Hnf4DlM8HwAPR8YPB8Ing+h50OD5xeC5yPo+cjg+UjwfAw9Hxs8hwueT6DnE4PnE8HzKfR8avD8UvB8Bj2fGTyfCZ7Poedzg+cIwfMF9Hxh8HwheL6Eni8Nnl8Jnq+g5yuD5yvB8zX0fG3wHCl4voGebwyebwTPt9DzrcHza8HzHfR8Z/B8J3i+1515/vcuVM9RgmeE7swzQvfQPcO2w9tGhJ4RDZ7fCJ6RoGckg2ckwTMy9Ixs8BwteEaBnlEMnlEEz6jQM6rB81vBMxr0jGbwjCZ4Roee0Q2eYwTPGNAzhsEzhuAZE3rGNHh+J3jGgp6xDJ6xBM/Y0DO2wXOs4BkHesYxeMYRPONCz7gGz+8Fz3jQM57BM57gGR96xjd4jhM8E0DPBAbPBIJnQuiZ0OD5g+CZCHomMngmEjwTQ8/EBs/xgmcS6JnE4JlE8EwKPZMaPH8UPJNBz2QGz2SCZ3LomdzgOUHwTAE9Uxg8UwieKaFnSoPnT4JnKuiZyuCZSvBMDT1TGzwnCp5poGcag2cawTMt9Exr8PxZ8EwHPdMZPNMJnumhZ3qD5yTBMwP0zGDwzCB4ZoSeGQ2evwiemaBnJoNnJsEzM/TMbPCcLHhmgZ5ZDJ5ZBM+s0DOrwfNXwTMb9Mxm8MwmeGaHntkNnlMEzxzQM4fBM4fgmRN65jR4ThU8c0HPXAbPXIJnbuiZ2+A5TfDMAz3zGDzzCJ55oWdeg+d0wTMf9Mxn8MwneOaHnvkNnjMEzwLQs4DBs4DgWRB6FjR4zhQ8C0HPQgbPQoJnYehZ2OA5S/AsAj2LGDyLCJ5FoWdRg+dswbMY9Cxm8CwmeBaHnsUNnnMEzxLQs4TBs4TgWRJ6ljR4zhU8S0HPUgbPUoJnaehZ2uA5T/AsAz3LGDzLCJ5loWdZg+d8wbMc9Cxn8CwneJaHnuUNngsEzwrQs4LBs4LgWRF6VjR4LhQ8K0HPSgbPSoJnZehZ2eC5SPCsAj2rGDyrCJ5VoWdVg+diwbMa9Kxm8KwmeFaHntUNnksEzxrQs4bBs4bgWRN61jR4LhU8a0HPWgbPWoJnbehZ2+C5TPCsAz3rGDzrCJ51oWddg+dywbMe9Kxn8KwneNaHnvUNnisEzwbQs4HBs4Hg2RB6NjR4rhQ8G0HPRgbPRoJnY+jZ2OC5SvBsAj2bGDybCJ5NoWdTg+dqwbMZ9Gxm8GwmeDaHns0NnmsEzxbQs4XBs4Xg+T70fN/guVbwbAk9Wxo8WwqeraBnK4PnOsGzNfRsbfBsLXh+AD0/MHj+Jni2gZ5tDJ5tBM8AegYGz/WCZ1vo2dbg2VbwbAc92xk8fxc820PP9gbP9oJnB+jZweC5QfDsCD07Gjw7Cp6doGcng+cfgmdn6NnZ4NlZ8OwCPbsYPDcKnl2hZ1eDZ1fBsxv07Gbw/FPw7A49uxs8uwuePaBnD4PnJsGzJ/TsafDsKXj2gp69DJ5/CZ69oWdvg2dvwbMP9Oxj8NwsePaFnn0Nnn0Fz37Qs5/B82/Bsz/07G/w7C94fgg9PzR4bhE8B0DPAQbPAYLnR9DzI4PnP4LnQOg50OA5UPD8GHp+bPDcKngOgp6DDJ6DBM9PoOcnBs9/Bc/B0HOwwXOw4Pkp9PzU4LlN8BwCPYcYPIcInp9Bz88MntsFz6HQc6jBc6jg+Tn0/NzguUPwHAY9hxk8hwmeX0DPLwyeOwXP4dBzuMFzuOD5JfT80uC5S/AcAT1HGDxHCJ5fQc+vDJ67Bc+R0HOkwXOk4Pk19Pza4LlH8BwFPUcZPEcJnt9Az28MnnsFz9HQc7TBc7Tg+S30/NbguU/wHAM9xxg8xwie30HP7wye+wXPsdBzrMFzrOD5PfT83uB5QPAcBz3HGTzHCZ4/QM8fDJ4HBc/x0HO8wXO84Pkj9PzR4HlI8JwAPScYPCcInj9Bz58MnocFz4nQc6LBc6Lg+TP0/NngeUTwnAQ9Jxk8Jwmev0DPXwyeRwXPydBzssFzsuD5K/T81eB5TPCcAj2nGDynCJ5ToedUg+dxwXMa9Jxm8JwmeE6HntMNnicEzxnQc4bBc4bgORN6zjR4nhQ8Z0HPWQbPWYLnbOg52+B5SvCcAz3nGDznCJ5zoedcg+dpwXMe9Jxn8JwneM6HnvMNnmcEzwXQc4HBc4HguRB6LjR4nhU8F0HPRQbPRYLnYui52OB5TvBcAj2XGDyXCJ5LoedSg+d5wXMZ9Fxm8FwmeC6HnssNnhcEzxXQc4XBc4XguRJ6rjR4XhQ8V0HPVQbPVYLnaui52uB5SfBcAz3XGDzXCJ5roedag+dlwXMd9Fxn8FwneP4GPX8zeF4RPNdDz/UGz/WC5+/Q83eD51XBcwP03GDw3CB4/gE9/zB4XhM8N0LPjQbPjYLnn9DzT4PndcFzE/TcZPDcJHj+BT3/MnjeEDw3Q8/NBs/Nguff0PNvg+dNwXML9Nxi8NwieP4DPf8xeN4SPLdCz60Gz62C57/Q81+D523Bcxv03Gbw3CZ4boee2w2edwTPHdBzh8Fzh+C5E3ruNHjeFTx3Qc9dBs9dgudu6Lnb4HlP8NwDPfcYPPcInnuh516D533Bcx/03Gfw3Cd47oee+w2eDwTPA9DzgMHzgOB5EHoeNHg+FDwPQc9DBs9Dgudh6HnY4PlI8DwCPY8YPI8Inkeh51GD52PB8xj0PGbwPCZ4Hoeexw2eTwTPE9DzhMHzhOB5EnqeNHg+FTxPQc9TBs9Tgudp6Hna4PlM8DwDPc8YPM8Inmeh51mD53PB8xz0PGfwPCd4noee5w2eLwTPC9DzgsHzguB5EXpeNHi+FDwvQc9LBs9Lgudl6HnZ4PlK8LwCPa8YPK8Inleh51WD52vB8xr0vGbwvCZ4Xoee1w2ebwTPG9DzhsHzhuB5E3reNHi+FTxvQc9bBs9bgudt6Hnb4PlO8LwDPe8YPO8Inneh512D53uR//c770HPewbPe4Lnfeh53+AZIer/fucD6PnA4PlA8HwIPR8aPCMKno+g5yOD5yPB8zH0fGzwjCR4PoGeTwyeTwTPp9DzqcEzsuD5DHo+M3g+EzyfQ8/nBs8ogucL6PnC4PlC8HwJPV8aPKMKnq+g5yuD5yvB8zX0fG3wjCZ4voGebwyebwTPt9DzrcEzuuD5Dnq+M3i+Ezzf68E8/3sXqmcMwTNCD+YZoUfonmHb4W0jQs+IBs+Ygmck6BnJ4BlJ8IwMPSMbPGMJnlGgZxSDZxTBMyr0jGrwjC14RoOe0Qye0QTP6NAzusEzjuAZA3rGMHjGEDxjQs+YBs+4gmcs6BnL4BlL8IwNPWMbPOMJnnGgZxyDZxzBMy70jGvwjC94xoOe8Qye8QTP+NAzvsEzgeCZAHomMHgmEDwTQs+EBs+Egmci6JnI4JlI8EwMPRMbPBMJnkmgZxKDZxLBMyn0TGrwTCx4JoOeyQyeyQTP5NAzucEzieCZAnqmMHimEDxTQs+UBs+kgmcq6JnK4JlK8EwNPVMbPJMJnmmgZxqDZxrBMy30TGvwTC54poOe6Qye6QTP9NAzvcEzheCZAXpmMHhmEDwzQs+MBs+Ugmcm6JnJ4JlJ8MwMPTMbPFMJnlmgZxaDZxbBMyv0zGrwTC14ZoOe2Qye2QTP7NAzu8EzjeCZA3rmMHjmEDxzQs+cBs+0gmcu6JnL4JlL8MwNPXMbPNMJnnmgZx6DZx7BMy/0zGvwTC945oOe+Qye+QTP/NAzv8Ezg+BZAHoWMHgWEDwLQs+CBs+Mgmch6FnI4FlI8CwMPQsbPDMJnkWgZxGDZxHBsyj0LGrwzCx4FoOexQyexQTP4tCzuMEzi+BZAnqWMHiWEDxLQs+SBs+sgmcp6FnK4FlK8CwNPUsbPLMJnmWgZxmDZxnBsyz0LGvwzC54loOe5Qye5QTP8tCzvMEzh+BZAXpWMHhWEDwrQs+KBs+cgmcl6FnJ4FlJ8KwMPSsbPHMJnlWgZxWDZxXBsyr0rGrwzC14VoOe1Qye1QTP6tCzusEzj+BZA3rWMHjWEDxrQs+aBs+8gmct6FnL4FlL8KwNPWsbPPMJnnWgZx2DZx3Bsy70rGvwzC941oOe9Qye9QTP+tCzvsGzgODZAHo2MHg2EDwbQs+GBs+Cgmcj6NnI4NlI8GwMPRsbPAsJnk2gZxODZxPBsyn0bGrwLCx4NoOezQyezQTP5tCzucGziODZAnq2MHi2EDzfh57vGzyLCp4toWdLg2dLwbMV9Gxl8CwmeLaGnq0Nnq0Fzw+g5wcGz+KCZxvo2cbg2UbwDKBnYPAsIXi2hZ5tDZ5tBc920LOdwbOk4NkeerY3eLYXPDtAzw4Gz1KCZ0fo2dHg2VHw7AQ9Oxk8SwuenaFnZ4NnZ8GzC/TsYvAsI3h2hZ5dDZ5dBc9u0LObwbOs4NkdenY3eHYXPHtAzx4Gz3KCZ0/o2dPg2VPw7AU9exk8ywuevaFnb4Nnb8GzD/TsY/CsIHj2hZ59DZ59Bc9+0LOfwbOi4NkfevY3ePYXPD+Enh8aPCsJngOg5wCD5wDB8yPo+ZHBs7LgORB6DjR4DhQ8P4aeHxs8qwieg6DnIIPnIMHzE+j5icGzquA5GHoONngOFjw/hZ6fGjyrCZ5DoOcQg+cQwfMz6PmZwbO64DkUeg41eA4VPD+Hnp8bPGsInsOg5zCD5zDB8wvo+YXBs6bgORx6Djd4Dhc8v4SeXxo8awmeI6DnCIPnCMHzK+j5lcGztuA5EnqONHiOFDy/hp5fGzzrCJ6joOcog+cowfMb6PmNwbOu4Dkaeo42eI4WPL+Fnt8aPOsJnmOg5xiD5xjB8zvo+Z3Bs77gORZ6jjV4jhU8v4ee3xs8Gwie46DnOIPnOMHzB+j5g8GzoeA5HnqON3iOFzx/hJ4/GjwbCZ4ToOcEg+cEwfMn6PmTwbOx4DkRek40eE4UPH+Gnj8bPJsInpOg5ySD5yTB8xfo+YvBs6ngORl6TjZ4ThY8f4Wevxo8mwmeU6DnFIPnFMFzKvScavBsLnhOg57TDJ7TBM/p0HO6wbOF4DkDes4weM4QPGdCz5kGz/cFz1nQc5bBc5bgORt6zjZ4thQ850DPOQbPOYLnXOg51+DZSvCcBz3nGTznCZ7zoed8g2drwXMB9Fxg8FwgeC6EngsNnh8Inoug5yKD5yLBczH0XGzwbCN4LoGeSwyeSwTPpdBzqcEzEDyXQc9lBs9lgudy6Lnc4NlW8FwBPVcYPFcIniuh50qDZzvBcxX0XGXwXCV4roaeqw2e7QXPNdBzjcFzjeC5FnquNXh2EDzXQc91Bs91gudv0PM3g2dHwXM99Fxv8FwveP4OPX83eHYSPDdAzw0Gzw2C5x/Q8w+DZ2fBcyP03Gjw3Ch4/gk9/zR4dhE8N0HPTQbPTYLnX9DzL4NnV8FzM/TcbPDcLHj+DT3/Nnh2Ezy3QM8tBs8tguc/0PMfg2d3wXMr9Nxq8NwqeP4LPf81ePYQPLdBz20Gz22C53boud3g2VPw3AE9dxg8dwieO6HnToNnL8FzF/TcZfDcJXjuhp67DZ69Bc890HOPwXOP4LkXeu41ePYRPPdBz30Gz32C537oud/g2VfwPAA9Dxg8DwieB6HnQYNnP8HzEPQ8ZPA8JHgehp6HDZ79Bc8j0POIwfOI4HkUeh41eH4oeB6DnscMnscEz+PQ87jBc4DgeQJ6njB4nhA8T0LPkwbPjwTPU9DzlMHzlOB5GnqeNngOFDzPQM8zBs8zgudZ6HnW4Pmx4HkOep4zeJ4TPM9Dz/MGz0GC5wXoecHgeUHwvAg9Lxo8PxE8L0HPSwbPS4LnZeh52eA5WPC8Aj2vGDyvCJ5XoedVg+enguc16HnN4HlN8LwOPa8bPIcInjeg5w2D5w3B8yb0vGnw/EzwvAU9bxk8bwmet6HnbYPnUMHzDvS8Y/C8I3jehZ53DZ6fC573oOc9g+c9wfM+9Lxv8BwmeD6Ang8Mng8Ez4fQ86HB8wvB8xH0fGTwfCR4Poaejw2ewwXPJ9DzicHzieD5FHo+NXh+KXg+g57PDJ7PBM/n0PO5wXOE4PkCer4weL4QPF9Cz5cGz68Ez1fQ85XB85Xg+Rp6vjZ4jhQ830DPNwbPN4LnW+j51uD5teD5Dnq+M3i+Ezzf68k8/3sXqucowTNCT+YZoWfonmHb4W0jQs+IBs9vBM9I0DOSwTOS4BkZekY2eI4WPKNAzygGzyiCZ1ToGdXg+a3gGQ16RjN4RhM8o0PP6AbPMYJnDOgZw+AZQ/CMCT1jGjy/EzxjQc9YBs9Ygmds6Bnb4DlW8IwDPeMYPOMInnGhZ1yD5/eCZzzoGc/gGU/wjA894xs8xwmeCaBnAoNnAsEzIfRMaPD8QfBMBD0TGTwTCZ6JoWdig+d4wTMJ9Exi8EwieCaFnkkNnj8KnsmgZzKDZzLBMzn0TG7wnCB4poCeKQyeKQTPlNAzpcHzJ8EzFfRMZfBMJXimhp6pDZ4TBc800DONwTON4JkWeqY1eP4seKaDnukMnukEz/TQM73Bc5LgmQF6ZjB4ZhA8M0LPjAbPXwTPTNAzk8Ezk+CZGXpmNnhOFjyzQM8sBs8sgmdW6JnV4Pmr4JkNemYzeGYTPLNDz+wGzymCZw7omcPgmUPwzAk9cxo8pwqeuaBnLoNnLsEzN/TMbfCcJnjmgZ55DJ55BM+80DOvwXO64JkPeuYzeOYTPPNDz/wGzxmCZwHoWcDgWUDwLAg9Cxo8ZwqehaBnIYNnIcGzMPQsbPCcJXgWgZ5FDJ5FBM+i0LOowXO24FkMehYzeBYTPItDz+IGzzmCZwnoWcLgWULwLAk9Sxo85wqepaBnKYNnKcGzNPQsbfCcJ3iWgZ5lDJ5lBM+y0LOswXO+4FkOepYzeJYTPMtDz/IGzwWCZwXoWcHgWUHwrAg9Kxo8FwqelaBnJYNnJcGzMvSsbPBcJHhWgZ5VDJ5VBM+q0LOqwXOx4FkNelYzeFYTPKtDz+oGzyWCZw3oWcPgWUPwrAk9axo8lwqetaBnLYNnLcGzNvSsbfBcJnjWgZ51DJ51BM+60LOuwXO54FkPetYzeNYTPOtDz/oGzxWCZwPo2cDg2UDwbAg9Gxo8VwqejaBnI4NnI8GzMfRsbPBcJXg2gZ5NDJ5NBM+m0LOpwXO14NkMejYzeDYTPJtDz+YGzzWCZwvo2cLg2ULwfB96vm/wXCt4toSeLQ2eLQXPVtCzlcFzneDZGnq2Nni2Fjw/gJ4fGDx/EzzbQM82Bs82gmcAPQOD53rBsy30bGvwbCt4toOe7Qyevwue7aFne4Nne8GzA/TsYPDcIHh2hJ4dDZ4dBc9O0LOTwfMPwbMz9Oxs8OwseHaBnl0MnhsFz67Qs6vBs6vg2Q16djN4/il4doee3Q2e3QXPHtCzh8Fzk+DZE3r2NHj2FDx7Qc9eBs+/BM/e0LO3wbO34NkHevYxeG4WPPtCz74Gz76CZz/o2c/g+bfg2R969jd49hc8P4SeHxo8twieA6DnAIPnAMHzI+j5kcHzH8FzIPQcaPAcKHh+DD0/NnhuFTwHQc9BBs9Bgucn0PMTg+e/gudg6DnY4DlY8PwUen5q8NwmeA6BnkMMnkMEz8+g52cGz+2C51DoOdTgOVTw/Bx6fm7w3CF4DoOewwyewwTPL6DnFwbPnYLncOg53OA5XPD8Enp+afDcJXiOgJ4jDJ4jBM+voOdXBs/dgudI6DnS4DlS8Pwaen5t8NwjeI6CnqMMnqMEz2+g5zcGz72C52joOdrgOVrw/BZ6fmvw3Cd4joGeYwyeYwTP76DndwbP/YLnWOg51uA5VvD8Hnp+b/A8IHiOg57jDJ7jBM8foOcPBs+Dgud46Dne4Dle8PwRev5o8DwkeE6AnhMMnhMEz5+g508Gz8OC50ToOdHgOVHw/Bl6/mzwPCJ4ToKekwyekwTPX6DnLwbPo4LnZOg52eA5WfD8FXr+avA8JnhOgZ5TDJ5TBM+p0HOqwfO44DkNek4zeE4TPKdDz+kGzxOC5wzoOcPgOUPwnAk9Zxo8Twqes6DnLIPnLMFzNvScbfA8JXjOgZ5zDJ5zBM+50HOuwfO04DkPes4zeM4TPOdDz/kGzzOC5wLoucDguUDwXAg9Fxo8zwqei6DnIoPnIsFzMfRcbPA8J3gugZ5LDJ5LBM+l0HOpwfO84LkMei4zeC4TPJdDz+UGzwuC5wroucLguULwXAk9Vxo8Lwqeq6DnKoPnKsFzNfRcbfC8JHiugZ5rDJ5rBM+10HOtwfOy4LkOeq4zeK4TPH+Dnr8ZPK8Inuuh53qD53rB83fo+bvB86rguQF6bjB4bhA8/4Cefxg8rwmeG6HnRoPnRsHzT+j5p8HzuuC5CXpuMnhuEjz/gp5/GTxvCJ6boedmg+dmwfNv6Pm3wfOm4LkFem4xeG4RPP+Bnv8YPG8Jnluh51aD51bB81/o+a/B87bguQ16bjN4bhM8t0PP7QbPO4LnDui5w+C5Q/DcCT13GjzvCp67oOcug+cuwXM39Nxt8LwneO6BnnsMnnsEz73Qc6/B877guQ967jN47hM890PP/QbPB4LnAeh5wOB5QPA8CD0PGjwfCp6HoOchg+chwfMw9Dxs8HwkeB6BnkcMnkcEz6PQ86jB87HgeQx6HjN4HhM8j0PP4wbPJ4LnCeh5wuB5QvA8CT1PGjyfCp6noOcpg+cpwfM09Dxt8HwmeJ6BnmcMnmcEz7PQ86zB87ngeQ56njN4nhM8z0PP8wbPF4LnBeh5weB5QfC8CD0vGjxfCp6XoOclg+clwfMy9Lxs8HwleF6BnlcMnlcEz6vQ86rB87XgeQ16XjN4XhM8r0PP6wbPN4LnDeh5w+B5Q/C8CT1vGjzfCp63oOctg+ctwfM29Lxt8HwneN6BnncMnncEz7vQ867B871o//ud96DnPYPnPcHzPvS8b/CMIHg+gJ4PDJ4PBM+H0POhwTOi4PkIej4yeD4SPB9Dz8cGz0iC5xPo+cTg+UTwfAo9nxo8Iwuez6DnM4PnM8HzOfR8bvCMIni+gJ4vDJ4vBM+X0POlwTOq4PkKer4yeL4SPF9Dz9cGz2iC5xvo+cbg+UbwfAs93xo8owue76DnO4PnO8HzvV7M8793oXrGEDwj9GKeEXqF7hm2Hd42IvSMaPCMKXhGgp6RDJ6RBM/I0DOywTOW4BkFekYxeEYRPKNCz6gGz9iCZzToGc3gGU3wjA49oxs84wieMaBnDINnDMEzJvSMafCMK3jGgp6xDJ6xBM/Y0DO2wTOe4BkHesYxeMYRPONCz7gGz/iCZzzoGc/gGU/wjA894xs8EwieCaBnAoNnAsEzIfRMaPBMKHgmgp6JDJ6JBM/E0DOxwTOR4JkEeiYxeCYRPJNCz6QGz8SCZzLomczgmUzwTA49kxs8kwieKaBnCoNnCsEzJfRMafBMKnimgp6pDJ6pBM/U0DO1wTOZ4JkGeqYxeKYRPNNCz7QGz+SCZzromc7gmU7wTA890xs8UwieGaBnBoNnBsEzI/TMaPBMKXhmgp6ZDJ6ZBM/M0DOzwTOV4JkFemYxeGYRPLNCz6wGz9SCZzbomc3gmU3wzA49sxs80wieOaBnDoNnDsEzJ/TMafBMK3jmgp65DJ65BM/c0DO3wTOd4JkHeuYxeOYRPPNCz7wGz/SCZz7omc/gmU/wzA898xs8MwieBaBnAYNnAcGzIPQsaPDMKHgWgp6FDJ6FBM/C0LOwwTOT4FkEehYxeBYRPItCz6IGz8yCZzHoWczgWUzwLA49ixs8swieJaBnCYNnCcGzJPQsafDMKniWgp6lDJ6lBM/S0LO0wTOb4FkGepYxeJYRPMtCz7IGz+yCZznoWc7gWU7wLA89yxs8cwieFaBnBYNnBcGzIvSsaPDMKXhWgp6VDJ6VBM/K0LOywTOX4FkFelYxeFYRPKtCz6oGz9yCZzXoWc3gWU3wrA49qxs88wieNaBnDYNnDcGzJvSsafDMK3jWgp61DJ61BM/a0LO2wTOf4FkHetYxeNYRPOtCz7oGz/yCZz3oWc/gWU/wrA896xs8CwieDaBnA4NnA8GzIfRsaPAsKHg2gp6NDJ6NBM/G0LOxwbOQ4NkEejYxeDYRPJtCz6YGz8KCZzPo2czg2UzwbA49mxs8iwieLaBnC4NnC8Hzfej5vsGzqODZEnq2NHi2FDxbQc9WBs9igmdr6Nna4Nla8PwAen5g8CwueLaBnm0Mnm0EzwB6BgbPEoJnW+jZ1uDZVvBsBz3bGTxLCp7toWd7g2d7wbMD9Oxg8CwleHaEnh0Nnh0Fz07Qs5PBs7Tg2Rl6djZ4dhY8u0DPLgbPMoJnV+jZ1eDZVfDsBj27GTzLCp7doWd3g2d3wbMH9Oxh8CwnePaEnj0Nnj0Fz17Qs5fBs7zg2Rt69jZ49hY8+0DPPgbPCoJnX+jZ1+DZV/DsBz37GTwrCp79oWd/g2d/wfND6PmhwbOS4DkAeg4weA4QPD+Cnh8ZPCsLngOh50CD50DB82Po+bHBs4rgOQh6DjJ4DhI8P4Genxg8qwqeg6HnYIPnYMHzU+j5qcGzmuA5BHoOMXgOETw/g56fGTyrC55DoedQg+dQwfNz6Pm5wbOG4DkMeg4zeA4TPL+Anl8YPGsKnsOh53CD53DB80vo+aXBs5bgOQJ6jjB4jhA8v4KeXxk8awueI6HnSIPnSMHza+j5tcGzjuA5CnqOMniOEjy/gZ7fGDzrCp6joedog+dowfNb6PmtwbOe4DkGeo4xeI4RPL+Dnt8ZPOsLnmOh51iD51jB83vo+b3Bs4HgOQ56jjN4jhM8f4CePxg8Gwqe46HneIPneMHzR+j5o8GzkeA5AXpOMHhOEDx/gp4/GTwbC54ToedEg+dEwfNn6PmzwbOJ4DkJek4yeE4SPH+Bnr8YPJsKnpOh52SD52TB81fo+avBs5ngOQV6TjF4ThE8p0LPqQbP5oLnNOg5zeA5TfCcDj2nGzxbCJ4zoOcMg+cMwXMm9Jxp8Hxf8JwFPWcZPGcJnrOh52yDZ0vBcw70nGPwnCN4zoWecw2erQTPedBznsFznuA5H3rON3i2FjwXQM8FBs8FgudC6LnQ4PmB4LkIei4yeC4SPBdDz8UGzzaC5xLoucTguUTwXAo9lxo8A8FzGfRcZvBcJnguh57LDZ5tBc8V0HOFwXOF4LkSeq40eLYTPFdBz1UGz1WC52roudrg2V7wXAM91xg81wiea6HnWoNnB8FzHfRcZ/BcJ3j+Bj1/M3h2FDzXQ8/1Bs/1gufv0PN3g2cnwXMD9Nxg8NwgeP4BPf8weHYWPDdCz40Gz42C55/Q80+DZxfBcxP03GTw3CR4/gU9/zJ4dhU8N0PPzQbPzYLn39Dzb4NnN8FzC/TcYvDcInj+Az3/MXh2Fzy3Qs+tBs+tgue/0PNfg2cPwXMb9Nxm8NwmeG6HntsNnj0Fzx3Qc4fBc4fguRN67jR49hI8d0HPXQbPXYLnbui52+DZW/DcAz33GDz3CJ57oedeg2cfwXMf9Nxn8NwneO6HnvsNnn0FzwPQ84DB84DgeRB6HjR49hM8D0HPQwbPQ4LnYeh52ODZX/A8Aj2PGDyPCJ5HoedRg+eHgucx6HnM4HlM8DwOPY8bPAcInieg5wmD5wnB8yT0PGnw/EjwPAU9Txk8Twmep6HnaYPnQMHzDPQ8Y/A8I3iehZ5nDZ4fC57noOc5g+c5wfM89Dxv8BwkeF6AnhcMnhcEz4vQ86LB8xPB8xL0vGTwvCR4Xoaelw2egwXPK9DzisHziuB5FXpeNXh+Knheg57XDJ7XBM/r0PO6wXOI4HkDet4weN4QPG9Cz5sGz88Ez1vQ85bB85bgeRt63jZ4DhU870DPOwbPO4LnXeh51+D5ueB5D3reM3jeEzzvQ8/7Bs9hgucD6PnA4PlA8HwIPR8aPL8QPB9Bz0cGz0eC52Po+djgOVzwfAI9nxg8nwieT6HnU4Pnl4LnM+j5zOD5TPB8Dj2fGzxHCJ4voOcLg+cLwfMl9Hxp8PxK8HwFPV8ZPF8Jnq+h52uD50jB8w30fGPwfCN4voWebw2eXwue76DnO4PnO8Hzvd7M8793oXqOEjwj9GaeEXqH7hm2Hd42IvSMaPD8RvCMBD0jGTwjCZ6RoWdkg+dowTMK9Ixi8IwieEaFnlENnt8KntGgZzSDZzTBMzr0jG7wHCN4xoCeMQyeMQTPmNAzpsHzO8EzFvSMZfCMJXjGhp6xDZ5jBc840DOOwTOO4BkXesY1eH4veMaDnvEMnvEEz/jQM77Bc5zgmQB6JjB4JhA8E0LPhAbPHwTPRNAzkcEzkeCZGHomNniOFzyTQM8kBs8kgmdS6JnU4Pmj4JkMeiYzeCYTPJNDz+QGzwmCZwromcLgmULwTAk9Uxo8fxI8U0HPVAbPVIJnauiZ2uA5UfBMAz3TGDzTCJ5poWdag+fPgmc66JnO4JlO8EwPPdMbPCcJnhmgZwaDZwbBMyP0zGjw/EXwzAQ9Mxk8MwmemaFnZoPnZMEzC/TMYvDMInhmhZ5ZDZ6/Cp7ZoGc2g2c2wTM79Mxu8JwieOaAnjkMnjkEz5zQM6fBc6rgmQt65jJ45hI8c0PP3AbPaYJnHuiZx+CZR/DMCz3zGjynC575oGc+g2c+wTM/9Mxv8JwheBaAngUMngUEz4LQs6DBc6bgWQh6FjJ4FhI8C0PPwgbPWYJnEehZxOBZRPAsCj2LGjxnC57FoGcxg2cxwbM49Cxu8JwjeJaAniUMniUEz5LQs6TBc67gWQp6ljJ4lhI8S0PP0gbPeYJnGehZxuBZRvAsCz3LGjznC57loGc5g2c5wbM89Cxv8FwgeFaAnhUMnhUEz4rQs6LBc6HgWQl6VjJ4VhI8K0PPygbPRYJnFehZxeBZRfCsCj2rGjwXC57VoGc1g2c1wbM69Kxu8FwieNaAnjUMnjUEz5rQs6bBc6ngWQt61jJ41hI8a0PP2gbPZYJnHehZx+BZR/CsCz3rGjyXC571oGc9g2c9wbM+9Kxv8FwheDaAng0Mng0Ez4bQs6HBc6Xg2Qh6NjJ4NhI8G0PPxgbPVYJnE+jZxODZRPBsCj2bGjxXC57NoGczg2czwbM59Gxu8FwjeLaAni0Mni0Ez/eh5/sGz7WCZ0vo2dLg2VLwbAU9Wxk81wmeraFna4Nna8HzA+j5gcHzN8GzDfRsY/BsI3gG0DMweK4XPNtCz7YGz7aCZzvo2c7g+bvg2R56tjd4thc8O0DPDgbPDYJnR+jZ0eDZUfDsBD07GTz/EDw7Q8/OBs/OgmcX6NnF4LlR8OwKPbsaPLsKnt2gZzeD55+CZ3fo2d3g2V3w7AE9exg8NwmePaFnT4NnT8GzF/TsZfD8S/DsDT17Gzx7C559oGcfg+dmwbMv9Oxr8OwrePaDnv0Mnn8Lnv2hZ3+DZ3/B80Po+aHBc4vgOQB6DjB4DhA8P4KeHxk8/xE8B0LPgQbPgYLnx9DzY4PnVsFzEPQcZPAcJHh+Aj0/MXj+K3gOhp6DDZ6DBc9PoeenBs9tgucQ6DnE4DlE8PwMen5m8NwueA6FnkMNnkMFz8+h5+cGzx2C5zDoOczgOUzw/AJ6fmHw3Cl4Doeeww2ewwXPL6HnlwbPXYLnCOg5wuA5QvD8Cnp+ZfDcLXiOhJ4jDZ4jBc+voefXBs89guco6DnK4DlK8PwGen5j8NwreI6GnqMNnqMFz2+h57cGz32C5xjoOcbgOUbw/A56fmfw3C94joWeYw2eYwXP76Hn9wbPA4LnOOg5zuA5TvD8AXr+YPA8KHiOh57jDZ7jBc8foeePBs9DgucE6DnB4DlB8PwJev5k8DwseE6EnhMNnhMFz5+h588GzyOC5yToOcngOUnw/AV6/mLwPCp4Toaekw2ekwXPX6HnrwbPY4LnFOg5xeA5RfCcCj2nGjyPC57ToOc0g+c0wXM69Jxu8DwheM6AnjMMnjMEz5nQc6bB86TgOQt6zjJ4zhI8Z0PP2QbPU4LnHOg5x+A5R/CcCz3nGjxPC57zoOc8g+c8wXM+9Jxv8DwjeC6AngsMngsEz4XQc6HB86zguQh6LjJ4LhI8F0PPxQbPc4LnEui5xOC5RPBcCj2XGjzPC57LoOcyg+cywXM59Fxu8LwgeK6AnisMnisEz5XQc6XB86LguQp6rjJ4rhI8V0PP1QbPS4LnGui5xuC5RvBcCz3XGjwvC57roOc6g+c6wfM36PmbwfOK4Lkeeq43eK4XPH+Hnr8bPK8Knhug5waD5wbB8w/o+YfB85rguRF6bjR4bhQ8/4Sefxo8rwuem6DnJoPnJsHzL+j5l8HzhuC5GXpuNnhuFjz/hp5/GzxvCp5boOcWg+cWwfMf6PmPwfOW4LkVem41eG4VPP+Fnv8aPG8Lntug5zaD5zbBczv03G7wvCN47oCeOwyeOwTPndBzp8HzruC5C3ruMnjuEjx3Q8/dBs97guce6LnH4LlH8NwLPfcaPO8Lnvug5z6D5z7Bcz/03G/wfCB4HoCeBwyeBwTPg9DzoMHzoeB5CHoeMngeEjwPQ8/DBs9HgucR6HnE4HlE8DwKPY8aPB8Lnseg5zGD5zHB8zj0PG7wfCJ4noCeJwyeJwTPk9DzpMHzqeB5CnqeMnieEjxPQ8/TBs9ngucZ6HnG4HlG8DwLPc8aPJ8Lnueg5zmD5znB8zz0PG/wfCF4XoCeFwyeFwTPi9DzosHzpeB5CXpeMnheEjwvQ8/LBs9XgucV6HnF4HlF8LwKPa8aPF8Lnteg5zWD5zXB8zr0vG7wfCN43oCeNwyeNwTPm9DzpsHzreB5C3reMnjeEjxvQ8/bBs93gucd6HnH4HlH8LwLPe8aPN+L/r/feQ963jN43hM870PP+w7PzP/7nQ96/6//jRAt7J3/vYsZzp1KO7ztw//5zohxw9758H+4M5wvQgTB8xH0fGTwfCR4Poaejw2eEQXPJ9DzicHzieD5FHo+NXhGEjyfQc9nBs9ngudz6Pnc4BlZ8HwBPV8YPF8Ini+h50uDZxTB8xX0fGXwfCV4voaerw2eUQXPN9DzjcHzjeD5Fnq+NXhGEzzfQc93Bs93gud7fZjnf+9C9YwueEbowzwj9AndM2w7vG1E6BnR4BlD8IwEPSMZPCMJnpGhZ2SDZ0zBMwr0jGLwjCJ4RoWeUQ2esQTPaNAzmsEzmuAZHXpGN3jGFjxjQM8YBs8YgmdM6BnT4BlH8IwFPWMZPGMJnrGhZ2yDZ1zBMw70jGPwjCN4xoWecQ2e8QTPeNAznsEznuAZH3rGN3jGFzwTQM8EBs8EgmdC6JnQ4JlA8EwEPRMZPBMJnomhZ2KDZ0LBMwn0TGLwTCJ4JoWeSQ2eiQTPZNAzmcEzmeCZHHomN3gmFjxTQM8UBs8UgmdK6JnS4JlE8EwFPVMZPFMJnqmhZ2qDZ1LBMw30TGPwTCN4poWeaQ2eyQTPdNAzncEzneCZHnqmN3gmFzwzQM8MBs8MgmdG6JnR4JlC8MwEPTMZPDMJnpmhZ2aDZ0rBMwv0zGLwzCJ4ZoWeWQ2eqQTPbNAzm8Ezm+CZHXpmN3imFjxzQM8cBs8cgmdO6JnT4JlG8MwFPXMZPHMJnrmhZ26DZ1rBMw/0zGPwzCN45oWeeQ2e6QTPfNAzn8Ezn+CZH3rmN3imFzwLQM8CBs8CgmdB6FnQ4JlB8CwEPQsZPAsJnoWhZ2GDZ0bBswj0LGLwLCJ4FoWeRQ2emQTPYtCzmMGzmOBZHHoWN3hmFjxLQM8SBs8SgmdJ6FnS4JlF8CwFPUsZPEsJnqWhZ2mDZ1bBswz0LGPwLCN4loWeZQ2e2QTPctCznMGznOBZHnqWN3hmFzwrQM8KBs8KgmdF6FnR4JlD8KwEPSsZPCsJnpWhZ2WDZ07Bswr0rGLwrCJ4VoWeVQ2euQTPatCzmsGzmuBZHXpWN3jmFjxrQM8aBs8agmdN6FnT4JlH8KwFPWsZPGsJnrWhZ22DZ17Bsw70rGPwrCN41oWedQ2e+QTPetCznsGznuBZH3rWN3jmFzwbQM8GBs8GgmdD6NnQ4FlA8GwEPRsZPBsJno2hZ2ODZ0HBswn0bGLwbCJ4NoWeTQ2ehQTPZtCzmcGzmeDZHHo2N3gWFjxbQM8WBs+w7fC27/dhnv+9C9WziODZsg/zbNkndM+Wgmcr6NnK4FlU8GwNPVsbPFsLnh9Azw8MnsUEzzbQs43Bs43gGUDPwOBZXPBsCz3bGjzbCp7toGc7g2cJwbM99Gxv8GwveHaAnh0MniUFz47Qs6PBs6Pg2Ql6djJ4lhI8O0PPzgbPzoJnF+jZxeBZWvDsCj27Gjy7Cp7doGc3g2cZwbM79Oxu8OwuePaAnj0MnmUFz57Qs6fBs6fg2Qt69jJ4lhM8e0PP3gbP3oJnH+jZx+BZXvDsCz37Gjz7Cp79oGc/g2cFwbM/9Oxv8OwveH4IPT80eFYUPAdAzwEGzwGC50fQ8yODZyXBcyD0HGjwHCh4fgw9PzZ4VhY8B0HPQQbPQYLnJ9DzE4NnFcFzMPQcbPAcLHh+Cj0/NXhWFTyHQM8hBs8hgudn0PMzg2c1wXMo9Bxq8BwqeH4OPT83eFYXPIdBz2EGz2GC5xfQ8wuDZw3Bczj0HG7wHC54fgk9vzR41hQ8R0DPEQbPEYLnV9DzK4NnLcFzJPQcafAcKXh+DT2/NnjWFjxHQc9RBs9Rguc30PMbg2cdwXM09Bxt8BwteH4LPb81eNYVPMdAzzEGzzGC53fQ8zuDZz3Bcyz0HGvwHCt4fg89vzd41hc8x0HPcQbPcYLnD9DzB4NnA8FzPPQcb/AcL3j+CD1/NHg2FDwnQM8JBs8JgudP0PMng2cjwXMi9Jxo8JwoeP4MPX82eDYWPCdBz0kGz0mC5y/Q8xeDZxPBczL0nGzwnCx4/go9fzV4NhU8p0DPKQbPKYLnVOg51eDZTPCcBj2nGTynCZ7Toed0g2dzwXMG9Jxh8JwheM6EnjMNni0Ez1nQc5bBc5bgORt6zjZ4vi94zoGecwyecwTPudBzrsGzpeA5D3rOM3jOEzznQ8/5Bs9WgucC6LnA4LlA8FwIPRcaPFsLnoug5yKD5yLBczH0XGzw/EDwXAI9lxg8lwieS6HnUoNnG8FzGfRcZvBcJnguh57LDZ6B4LkCeq4weK4QPFdCz5UGz7aC5yroucrguUrwXA09Vxs82wmea6DnGoPnGsFzLfRca/BsL3iug57rDJ7rBM/foOdvBs8Ogud66Lne4Lle8Pwdev5u8OwoeG6AnhsMnhsEzz+g5x8Gz06C50boudHguVHw/BN6/mnw7Cx4boKemwyemwTPv6DnXwbPLoLnZui52eC5WfD8G3r+bfDsKnhugZ5bDJ5bBM9/oOc/Bs9ugudW6LnV4LlV8PwXev5r8OwueG6DntsMntsEz+3Qc7vBs4fguQN67jB47hA8d0LPnQbPnoLnLui5y+C5S/DcDT13Gzx7CZ57oOceg+cewXMv9Nxr8OwteO6DnvsMnvsEz/3Qc7/Bs4/geQB6HjB4HhA8D0LPgwbPvoLnIeh5yOB5SPA8DD0PGzz7CZ5HoOcRg+cRwfMo9Dxq8OwveB6DnscMnscEz+PQ87jB80PB8wT0PGHwPCF4noSeJw2eAwTPU9DzlMHzlOB5GnqeNnh+JHiegZ5nDJ5nBM+z0POswXOg4HkOep4zeJ4TPM9Dz/MGz48FzwvQ84LB84LgeRF6XjR4DhI8L0HPSwbPS4LnZeh52eD5ieB5BXpeMXheETyvQs+rBs/Bguc16HnN4HlN8LwOPa8bPD8VPG9AzxsGzxuC503oedPgOUTwvAU9bxk8bwmet6HnbYPnZ4LnHeh5x+B5R/C8Cz3vGjyHCp73oOc9g+c9wfM+9Lxv8Pxc8HwAPR8YPB8Ing+h50OD5zDB8xH0fGTwfCR4Poaejw2eXwieT6DnE4PnE8HzKfR8avAcLng+g57PDJ7PBM/n0PO5wfNLwfMF9Hxh8HwheL6Eni8NniMEz1fQ85XB85Xg+Rp6vjZ4fiV4voGebwyebwTPt9DzrcFzpOD5Dnq+M3i+Ezzf68s8/3sXqufXgmeEvswzQt/QPcO2w9tGhJ4RDZ6jBM9I0DOSwTOS4BkZekY2eH4jeEaBnlEMnlEEz6jQM6rBc7TgGQ16RjN4RhM8o0PP6AbPbwXPGNAzhsEzhuAZE3rGNHiOETxjQc9YBs9Ygmds6Bnb4Pmd4BkHesYxeMYRPONCz7gGz7GCZzzoGc/gGU/wjA894xs8vxc8E0DPBAbPBIJnQuiZ0OA5TvBMBD0TGTwTCZ6JoWdig+cPgmcS6JnE4JlE8EwKPZMaPMcLnsmgZzKDZzLBMzn0TG7w/FHwTAE9Uxg8UwieKaFnSoPnBMEzFfRMZfBMJXimhp6pDZ4/CZ5poGcag2cawTMt9Exr8JwoeKaDnukMnukEz/TQM73B82fBMwP0zGDwzCB4ZoSeGQ2ekwTPTNAzk8Ezk+CZGXpmNnj+InhmgZ5ZDJ5ZBM+s0DOrwXOy4JkNemYzeGYTPLNDz+wGz18FzxzQM4fBM4fgmRN65jR4ThE8c0HPXAbPXIJnbuiZ2+A5VfDMAz3zGDzzCJ55oWdeg+c0wTMf9Mxn8MwneOaHnvkNntMFzwLQs4DBs4DgWRB6FjR4zhA8C0HPQgbPQoJnYehZ2OA5U/AsAj2LGDyLCJ5FoWdRg+cswbMY9Cxm8CwmeBaHnsUNnrMFzxLQs4TBs4TgWRJ6ljR4zhE8S0HPUgbPUoJnaehZ2uA5V/AsAz3LGDzLCJ5loWdZg+c8wbMc9Cxn8CwneJaHnuUNnvMFzwrQs4LBs4LgWRF6VjR4LhA8K0HPSgbPSoJnZehZ2eC5UPCsAj2rGDyrCJ5VoWdVg+ciwbMa9Kxm8KwmeFaHntUNnosFzxrQs4bBs4bgWRN61jR4LhE8a0HPWgbPWoJnbehZ2+C5VPCsAz3rGDzrCJ51oWddg+cywbMe9Kxn8KwneNaHnvUNnssFzwbQs4HBs4Hg2RB6NjR4rhA8G0HPRgbPRoJnY+jZ2OC5UvBsAj2bGDybCJ5NoWdTg+cqwbMZ9Gxm8GwmeDaHns0NnqsFzxbQs4XBs4Xg+T70fN/guUbwbAk9Wxo8WwqeraBnK4PnWsGzNfRsbfBsLXh+AD0/MHiuEzzbQM82Bs82gmcAPQOD52+CZ1vo2dbg2VbwbAc92xk81wue7aFne4Nne8GzA/TsYPD8XfDsCD07Gjw7Cp6doGcng+cGwbMz9Oxs8OwseHaBnl0Mnn8Inl2hZ1eDZ1fBsxv07Gbw3Ch4doee3Q2e3QXPHtCzh8HzT8GzJ/TsafDsKXj2gp69DJ6bBM/e0LO3wbO34NkHevYxeP4lePaFnn0Nnn0Fz37Qs5/Bc7Pg2R969jd49hc8P4SeHxo8/xY8B0DPAQbPAYLnR9DzI4PnFsFzIPQcaPAcKHh+DD0/Nnj+I3gOgp6DDJ6DBM9PoOcnBs+tgudg6DnY4DlY8PwUen5q8PxX8BwCPYcYPIcInp9Bz88MntsEz6HQc6jBc6jg+Tn0/NzguV3wHAY9hxk8hwmeX0DPLwyeOwTP4dBzuMFzuOD5JfT80uC5U/AcAT1HGDxHCJ5fQc+vDJ67BM+R0HOkwXOk4Pk19Pza4Llb8BwFPUcZPEcJnt9Az28MnnsEz9HQc7TBc7Tg+S30/NbguVfwHAM9xxg8xwie30HP7wye+wTPsdBzrMFzrOD5PfT83uC5X/AcBz3HGTzHCZ4/QM8fDJ4HBM/x0HO8wXO84Pkj9PzR4HlQ8JwAPScYPCcInj9Bz58MnocEz4nQc6LBc6Lg+TP0/NngeVjwnAQ9Jxk8Jwmev0DPXwyeRwTPydBzssFzsuD5K/T81eB5VPCcAj2nGDynCJ5ToedUg+cxwXMa9Jxm8JwmeE6HntMNnscFzxnQc4bBc4bgORN6zjR4nhA8Z0HPWQbPWYLnbOg52+B5UvCcAz3nGDznCJ5zoedcg+cpwXMe9Jxn8JwneM6HnvMNnqcFzwXQc4HBc4HguRB6LjR4nhE8F0HPRQbPRYLnYui52OB5VvBcAj2XGDyXCJ5LoedSg+c5wXMZ9Fxm8FwmeC6HnssNnucFzxXQc4XBc4XguRJ6rjR4XhA8V0HPVQbPVYLnaui52uB5UfBcAz3XGDzXCJ5roedag+clwXMd9Fxn8FwneP4GPX8zeF4WPNdDz/UGz/WC5+/Q83eD5xXBcwP03GDw3CB4/gE9/zB4XhU8N0LPjQbPjYLnn9DzT4PnNcFzE/TcZPDcJHj+BT3/MnheFzw3Q8/NBs/Nguff0PNvg+cNwXML9Nxi8NwieP4DPf8xeN4UPLdCz60Gz62C57/Q81+D5y3Bcxv03Gbw3CZ4boee2w2etwXPHdBzh8Fzh+C5E3ruNHjeETx3Qc9dBs9dgudu6Lnb4HlX8NwDPfcYPPcInnuh516D5z3Bcx/03Gfw3Cd47oee+w2e9wXPA9DzgMHzgOB5EHoeNHg+EDwPQc9DBs9Dgudh6HnY4PlQ8DwCPY8YPI8Inkeh51GD5yPB8xj0PGbwPCZ4Hoeexw2ejwXPE9DzhMHzhOB5EnqeNHg+ETxPQc9TBs9Tgudp6Hna4PlU8DwDPc8YPM8Inmeh51mD5zPB8xz0PGfwPCd4noee5w2ezwXPC9DzgsHzguB5EXpeNHi+EDwvQc9LBs9Lgudl6HnZ4PlS8LwCPa8YPK8Inleh51WD5yvB8xr0vGbwvCZ4Xoee1w2erwXPG9DzhsHzhuB5E3reNHi+ETxvQc9bBs9bgudt6Hnb4PlW8LwDPe8YPO8Inneh512D5zvB8x70vGfwvCd43oee9w2e72X53+98AD0fGDwfCJ4PoedDg2cEwfMR9Hxk8HwkeD6Gno8NnhEFzyfQ84nB84ng+RR6PjV4RhI8n0HPZwbPZ4Lnc+j53OAZWfB8AT1fGDxfCJ4voedLg2cUwfMV9Hxl8HwleL6Gnq8NnlEFzzfQ843B843g+RZ6vjV4RhM830HPdwbPd4Lne/2Y53/vQvWMLnhG6Mc8I/QL3TNsO7xtROgZ0eAZQ/CMBD0jGTwjCZ6RoWdkg2dMwTMK9Ixi8IwieEaFnlENnrEEz2jQM5rBM5rgGR16Rjd4xhY8Y0DPGAbPGIJnTOgZ0+AZR/CMBT1jGTxjCZ6xoWdsg2dcwTMO9Ixj8IwjeMaFnnENnvEEz3jQM57BM57gGR96xjd4xhc8E0DPBAbPBIJnQuiZ0OCZQPBMBD0TGTwTCZ6JoWdig2dCwTMJ9Exi8EwieCaFnkkNnokEz2TQM5nBM5ngmRx6Jjd4JhY8U0DPFAbPFIJnSuiZ0uCZRPBMBT1TGTxTCZ6poWdqg2dSwTMN9Exj8EwjeKaFnmkNnskEz3TQM53BM53gmR56pjd4Jhc8M0DPDAbPDIJnRuiZ0eCZQvDMBD0zGTwzCZ6ZoWdmg2dKwTML9Mxi8MwieGaFnlkNnqkEz2zQM5vBM5vgmR16Zjd4phY8c0DPHAbPHIJnTuiZ0+CZRvDMBT1zGTxzCZ65oWdug2dawTMP9Mxj8MwjeOaFnnkNnukEz3zQM5/BM5/gmR965jd4phc8C0DPAgbPAoJnQehZ0OCZQfAsBD0LGTwLCZ6FoWdhg2dGwbMI9Cxi8CwieBaFnkUNnpkEz2LQs5jBs5jgWRx6Fjd4ZhY8S0DPEgbPEoJnSehZ0uCZRfAsBT1LGTxLCZ6loWdpg2dWwbMM9Cxj8CwjeJaFnmUNntkEz3LQs5zBs5zgWR56ljd4Zhc8K0DPCgbPCoJnRehZ0eCZQ/CsBD0rGTwrCZ6VoWdlg2dOwbMK9Kxi8KwieFaFnlUNnrkEz2rQs5rBs5rgWR16Vjd45hY8a0DPGgbPGoJnTehZ0+CZR/CsBT1rGTxrCZ61oWdtg2dewbMO9Kxj8KwjeNaFnnUNnvkEz3rQs57Bs57gWR961jd45hc8G0DPBgbPBoJnQ+jZ0OBZQPBsBD0bGTwbCZ6NoWdjg2dBwbMJ9Gxi8GwieDaFnk0NnoUEz2bQs5nBs5ng2Rx6Njd4FhY8W0DPFgbPFoLn+9DzfYNnEcGzJfRsafBsKXi2gp6tDJ5FBc/W0LO1wbO14PkB9PzA4FlM8GwDPdsYPNsIngH0DAyexQXPttCzrcGzreDZDnq2M3iWEDzbQ8/2Bs/2gmcH6NnB4FlS8OwIPTsaPDsKnp2gZyeDZynBszP07Gzw7Cx4doGeXQyepQXPrtCzq8Gzq+DZDXp2M3iWETy7Q8/uBs/ugmcP6NnD4FlW8OwJPXsaPHsKnr2gZy+DZznBszf07G3w7C149oGefQye5QXPvtCzr8Gzr+DZD3r2M3hWEDz7Q8/+Bs/+gueH0PNDg2dFwXMA9Bxg8BwgeH4EPT8yeFYSPAdCz4EGz4GC58fQ82ODZ2XBcxD0HGTwHCR4fgI9PzF4VhE8B0PPwQbPwYLnp9DzU4NnVcFzCPQcYvAcInh+Bj0/M3hWEzyHQs+hBs+hgufn0PNzg2d1wXMY9Bxm8BwmeH4BPb8weNYQPIdDz+EGz+GC55fQ80uDZ03BcwT0HGHwHCF4fgU9vzJ41hI8R0LPkQbPkYLn19Dza4NnbcFzFPQcZfAcJXh+Az2/MXjWETxHQ8/RBs/Rgue30PNbg2ddwXMM9Bxj8BwjeH4HPb8zeNYTPMdCz7EGz7GC5/fQ83uDZ33Bcxz0HGfwHCd4/gA9fzB4NhA8x0PP8QbP8YLnj9DzR4NnQ8FzAvScYPCcIHj+BD1/Mng2EjwnQs+JBs+JgufP0PNng2djwXMS9Jxk8JwkeP4CPX8xeDYRPCdDz8kGz8mC56/Q81eDZ1PBcwr0nGLwnCJ4ToWeUw2ezQTPadBzmsFzmuA5HXpON3g2FzxnQM8ZBs8ZgudM6DnT4NlC8JwFPWcZPGcJnrOh52yD5/uC5xzoOcfgOUfwnAs95xo8Wwqe86DnPIPnPMFzPvScb/BsJXgugJ4LDJ4LBM+F0HOhwbO14LkIei4yeC4SPBdDz8UGzw8EzyXQc4nBc4nguRR6LjV4thE8l0HPZQbPZYLncui53OAZCJ4roOcKg+cKwXMl9Fxp8GwreK6CnqsMnqsEz9XQc7XBs53guQZ6rjF4rhE810LPtQbP9oLnOui5zuC5TvD8DXr+ZvDsIHiuh57rDZ7rBc/foefvBs+OgucG6LnB4LlB8PwDev5h8OwkeG6EnhsNnhsFzz+h558Gz86C5yboucnguUnw/At6/mXw7CJ4boaemw2emwXPv6Hn3wbProLnFui5xeC5RfD8B3r+Y/DsJnhuhZ5bDZ5bBc9/oee/Bs/uguc26LnN4LlN8NwOPbcbPHsInjug5w6D5w7Bcyf03Gnw7Cl47oKeuwyeuwTP3dBzt8Gzl+C5B3ruMXjuETz3Qs+9Bs/eguc+6LnP4LlP8NwPPfcbPPsIngeg5wGD5wHB8yD0PGjw7Ct4HoKehwyehwTPw9DzsMGzn+B5BHoeMXgeETyPQs+jBs/+gucx6HnM4HlM8DwOPY8bPD8UPE9AzxMGzxOC50noedLgOUDwPAU9Txk8Twmep6HnaYPnR4LnGeh5xuB5RvA8Cz3PGjwHCp7noOc5g+c5wfM89Dxv8PxY8LwAPS8YPC8Inheh50WD5yDB8xL0vGTwvCR4Xoaelw2enwieV6DnFYPnFcHzKvS8avAcLHheg57XDJ7XBM/r0PO6wfNTwfMG9Lxh8LwheN6EnjcNnkMEz1vQ85bB85bgeRt63jZ4fiZ43oGedwyedwTPu9DzrsFzqOB5D3reM3jeEzzvQ8/7Bs/PBc8H0POBwfOB4PkQej40eA4TPB9Bz0cGz0eC52Po+djg+YXg+QR6PjF4PhE8n0LPpwbP4YLnM+j5zOD5TPB8Dj2fGzy/FDxfQM8XBs8XgudL6PnS4DlC8HwFPV8ZPF8Jnq+h52uD51eC5xvo+cbg+UbwfAs93xo8Rwqe76DnO4PnO8Hzvf7M8793oXp+LXhG6M88I/QP3TNsO7xtROgZ0eA5SvCMBD0jGTwjCZ6RoWdkg+c3gmcU6BnF4BlF8IwKPaMaPEcLntGgZzSDZzTBMzr0jG7w/FbwjAE9Yxg8YwieMaFnTIPnGMEzFvSMZfCMJXjGhp6xDZ7fCZ5xoGccg2ccwTMu9Ixr8BwreMaDnvEMnvEEz/jQM77B83vBMwH0TGDwTCB4JoSeCQ2e4wTPRNAzkcEzkeCZGHomNnj+IHgmgZ5JDJ5JBM+k0DOpwXO84JkMeiYzeCYTPJNDz+QGzx8FzxTQM4XBM4XgmRJ6pjR4ThA8U0HPVAbPVIJnauiZ2uD5k+CZBnqmMXimETzTQs+0Bs+Jgmc66JnO4JlO8EwPPdMbPH8WPDNAzwwGzwyCZ0bomdHgOUnwzAQ9Mxk8MwmemaFnZoPnL4JnFuiZxeCZRfDMCj2zGjwnC57ZoGc2g2c2wTM79Mxu8PxV8MwBPXMYPHMInjmhZ06D5xTBMxf0zGXwzCV45oaeuQ2eUwXPPNAzj8Ezj+CZF3rmNXhOEzzzQc98Bs98gmd+6Jnf4Dld8CwAPQsYPAsIngWhZ0GD5wzBsxD0LGTwLCR4FoaehQ2eMwXPItCziMGziOBZFHoWNXjOEjyLQc9iBs9igmdx6Fnc4Dlb8CwBPUsYPEsIniWhZ0mD5xzBsxT0LGXwLCV4loaepQ2ecwXPMtCzjMGzjOBZFnqWNXjOEzzLQc9yBs9ygmd56Fne4Dlf8KwAPSsYPCsInhWhZ0WD5wLBsxL0rGTwrCR4VoaelQ2eCwXPKtCzisGziuBZFXpWNXguEjyrQc9qBs9qgmd16Fnd4LlY8KwBPWsYPGsInjWhZ02D5xLBsxb0rGXwrCV41oaetQ2eSwXPOtCzjsGzjuBZF3rWNXguEzzrQc96Bs96gmd96Fnf4Llc8GwAPRsYPBsIng2hZ0OD5wrBsxH0bGTwbCR4NoaejQ2eKwXPJtCzicGzieDZFHo2NXiuEjybQc9mBs9mgmdz6Nnc4Lla8GwBPVsYPFsInu9Dz/cNnmsEz5bQs6XBs6Xg2Qp6tjJ4rhU8W0PP1gbP1oLn/7FCV2Fble0WhqW7u0FAREREREREQERERERERKS7u2vS3SAi3d3d3d3d3d21Dve+tfX943rH3B7PvO7jrAg9Kxo8lwmelaBnJYNnJcGzMvSsbPBcLnhWgZ5VDJ5VBM+q0LOqwXOF4FkNelYzeFYTPKtDz+oGz5WCZw3oWcPgWUPwrAk9axo8VwmetaBnLYNnLcGzNvSsbfBcLXjWgZ51DJ51BM+60LOuwXON4FkPetYzeNYTPOtDz/oGz7WCZwPo2cDg2UDwbAg9Gxo81wmejaBnI4NnI8GzMfRsbPBcL3g2gZ5NDJ5NBM+m0LOpwXOD4NkMejYzeDYTPJtDz+YGz42CZwvo2cLg2ULwbAk9Wxo8NwmeraBnK4NnK8GzNfRsbfDcLHi2gZ5tDJ5tBM+20LOtwXOL4NkOerYzeLYTPNtDz/YGz62CZwfo2cHg2UHw7Ag9Oxo8twmenaBnJ4NnJ8EzgJ6BwXO74NkZenY2eHYWPLtAzy4Gzx2CZ1fo2dXg2VXw7AY9uxk8dwqe3aFnd4Nnd8GzB/TsYfDcJXj2hJ49DZ49Bc9e0LOXwXO34NkbevY2ePYWPPtAzz4Gzz2CZ1/o2dfg2Vfw7Ac9+xk89wqe/aFnf4Nnf8FzAPQcYPDcJ3gOhJ4DDZ4DBc9B0HOQwXO/4DkYeg42eA4WPIdAzyEGzwOC51DoOdTgOVTwHAY9hxk8Dwqew6HncIPncMHzb+j5t8HzkOA5AnqOMHiOEDz/gZ7/GDwPC54joedIg+dIwfNf6PmvwfOI4DkKeo4yeI4SPEdDz9EGz6OC5xjoOcbgOUbwHAs9xxo8jwme46DnOIPnOMFzPPQcb/A8LnhOgJ4TDJ4TBM+J0HOiwfOE4DkJek4yeE4SPCdDz8kGz5OC5xToOcXgOUXwnAo9pxo8Twme06DnNIPnNMFzOvScbvA8LXjOgJ4zDJ4zBM+Z0HOmwfOM4DkLes4yeM4SPGdDz9kGz7OC5xzoOcfgOUfwnAs95xo8zwme86DnPIPnPMFzPvScb/A8L3gugJ4LDJ4LBM+F0HOhwfOC4LkIei4yeC4SPBdDz8UGz4uC5xLoucTguUTwXAo9lxo8Lwmey6DnMoPnMsFzOfRcbvC8LHiugJ4rDJ4rBM+V0HOlwfOK4LkKeq4yeK4SPFdDz9UGz6uC5xroucbguUbwXAs91xo8rwme66DnOoPnOsFzPfRcb/C8LnhugJ4bDJ4bBM+N0HOjwfOG4LkJem4yeG4SPDdDz80Gz5uC5xboucXguUXw3Ao9txo8bwme26DnNoPnNsFzO/TcbvC8LXjugJ47DJ47BM+d0HOnwfOO4LkLeu4yeO4SPHdDz90Gz7uC5x7oucfguUfw3As99xo87wme+6DnPoPnPsFzP/Tcb/C8L3gegJ4HDJ4HBM+D0POgwfOB4HkIeh4yeB4SPA9Dz8MGz4eC5xHoecTgeUTwPAo9jxo8Hwmex6DnMYPnMcHzOPQ8bvB8LHiegJ4nDJ4nBM+T0POkwfOJ4HkKep4yeJ4SPE9Dz9MGz6eC5xnoecbgeUbwPAs9zxo8nwme56DnOYPnOcHzPPQ8b/B8LnhegJ4XDJ4XBM+L0POiwfOF4HkJel4yeF4SPC9Dz8sGz5eC5xXoecXgeUXwvAo9rxo8Xwme16DnNYPnNcHzOvS8bvB8LXjegJ43DJ43BM+b0POmwfON4HkLet4yeN4SPG9Dz9sGz7eC5x3oecfgeUfwvAs97xo83wme96DnPYPnPcHzPvS8b/B874P//c4H0POBwfOB4PkQej40eEYQPB9Bz0cGz0eC52Po+djgGVHwfAI9nxg8nwieT6HnU4NnJMHzGfR8ZvB8Jng+h57PDZ6RBc8X0POFwfOF4PkSer40eEYRPF9Bz1cGz1eC52vo+drgGVXwfAM93xg83wieb6HnW4NnNMHzHfR8Z/B8J3i+15x5/vcuVM/ogmeE5swzQvPQPcO2w9tGhJ4RDZ4xBM9I0DOSwTOS4BkZekY2eMYUPKNAzygGzyiCZ1ToGdXgGUvwjAY9oxk8owme0aFndINnbMEzBvSMYfCMIXjGhJ4xDZ5xBM9Y0DOWwTOW4BkbesY2eMYVPONAzzgGzziCZ1zoGdfgGU/wjAc94xk84wme8aFnfINnfMEzAfRMYPBMIHgmhJ4JDZ4JBM9E0DORwTOR4JkYeiY2eCYUPJNAzyQGzySCZ1LomdTgmUjwTAY9kxk8kwmeyaFncoNnYsEzBfRMYfBMIXimhJ4pDZ5JBM9U0DOVwTOV4JkaeqY2eCYVPNNAzzQGzzSCZ1romdbgmUzwTAc90xk80wme6aFneoNncsEzA/TMYPDMIHi+Dz3fN3imEDwzQs+MBs+Mgmcm6JnJ4JlS8MwMPTMbPDMLnh9Azw8MnqkEzyzQM4vBM4vg+SH0/NDgmVrwzAo9sxo8swqeH0HPjwyeaQTPbNAzm8Ezm+D5MfT82OCZVvDMDj2zGzyzC56fQM9PDJ7pBM8c0DOHwTOH4Pkp9PzU4Jle8MwJPXMaPHMKnp9Bz88MnhkEz1zQM5fBM5fg+Tn0/Nzg+b7gmRt65jZ45hY8v4CeXxg8MwqeeaBnHoNnHsHzS+j5pcEzk+CZF3rmNXjmFTy/gp5fGTwzC575oGc+g2c+wfNr6Pm1wfMDwTM/9Mxv8MwveH4DPb8xeGYRPAtAzwIGzwKCZ0HoWdDg+aHgWQh6FjJ4FhI8v4We3xo8swqehaFnYYNnYcHzO+j5ncHzI8GzCPQsYvAsInh+Dz2/N3hmEzyLQs+iBs+igucP0PMHg+fHgmcx6FnM4FlM8PwRev5o8MwueBaHnsUNnsUFz5+g508Gz08EzxLQs4TBs4Tg+TP0/NngmUPwLAk9Sxo8Swqev0DPXwyenwqepaBnKYNnKcHzV+j5q8Ezp+BZGnqWNniWFjx/g56/GTw/EzzLQM8yBs8ygufv0PN3g2cuwbMs9Cxr8CwreP4BPf8weH4ueJaDnuUMnuUEzz+h558Gz9yCZ3noWd7gWV7w/At6/mXw/ELwrAA9Kxg8KwieFaFnRYNnHsGzEvSsZPCsJHhWhp6VDZ5fCp5VoGcVg2cVwbMq9Kxq8MwreFaDntUMntUEz+rQs7rB8yvBswb0rGHwrCF41oSeNQ2e+QTPWtCzlsGzluBZG3rWNnh+LXjWgZ51DJ51BM+60LOuwTO/4FkPetYzeNYTPOtDz/oGz28EzwbQs4HBs4Hg2RB6NjR4FhA8G0HPRgbPRoJnY+jZ2OBZUPBsAj2bGDybCJ5NoWdTg2chwbMZ9Gxm8GwmeDaHns0Nnt8Kni2gZwuDZwvBsyX0bGnwLCx4toKerQyerQTP1tCztcHzO8GzDfRsY/BsI3i2hZ5tDZ5FBM920LOdwbOd4NkeerY3eH4veHaAnh0Mnh0Ez47Qs6PBs6jg2Ql6djJ4dhI8A+gZGDx/EDw7Q8/OBs/OgmcX6NnF4FlM8OwKPbsaPLsKnt2gZzeD54+CZ3fo2d3g2V3w7AE9exg8iwuePaFnT4NnT8GzF/TsZfD8SfDsDT17Gzx7C559oGcfg2cJwbMv9Oxr8OwrePaDnv0Mnj8Lnv2hZ3+DZ3/BcwD0HGDwLCl4DoSeAw2eAwXPQdBzkMHzF8FzMPQcbPAcLHgOgZ5DDJ6lBM+h0HOowXOo4DkMeg4zeP4qeA6HnsMNnsMFz7+h598Gz9KC5wjoOcLgOULw/Ad6/mPw/E3wHAk9Rxo8Rwqe/0LPfw2eZQTPUdBzlMFzlOA5GnqONnj+LniOgZ5jDJ5jBM+x0HOswbOs4DkOeo4zeI4TPMdDz/EGzz8EzwnQc4LBc4LgORF6TjR4lhM8J0HPSQbPSYLnZOg52eD5p+A5BXpOMXhOETynQs+pBs/yguc06DnN4DlN8JwOPacbPP8SPGdAzxkGzxmC50zoOdPgWUHwnAU9Zxk8Zwmes6HnbINnRcFzDvScY/CcI3jOhZ5zDZ6VBM950HOewXOe4Dkfes43eFYWPBdAzwUGzwWC50LoudDgWUXwXAQ9Fxk8Fwmei6HnYoNnVcFzCfRcYvBcInguhZ5LDZ7VBM9l0HOZwXOZ4Lkcei43eFYXPFdAzxUGzxWC50roudLgWUPwXAU9Vxk8Vwmeq6HnaoNnTcFzDfRcY/BcI3iuhZ5rDZ61BM910HOdwXOd4Lkeeq43eNYWPDdAzw0Gzw2C50boudHgWUfw3AQ9Nxk8Nwmem6HnZoNnXcFzC/TcYvDcInhuhZ5bDZ71BM9t0HObwXOb4Lkdem43eNYXPHdAzx0Gzx2C507oudPg2UDw3AU9dxk8dwmeu6HnboNnQ8FzD/TcY/DcI3juhZ57DZ6NBM990HOfwXOf4Lkfeu43eDYWPA9AzwMGzwOC50HoedDg2UTwPAQ9Dxk8Dwmeh6HnYYNnU8HzCPQ8YvA8IngehZ5HDZ7NBM9j0POYwfOY4Hkceh43eDYXPE9AzxMGzxOC50noedLg2ULwPAU9Txk8Twmep6HnaYNnS8HzDPQ8Y/A8I3iehZ5nDZ6tBM9z0POcwfOc4Hkeep43eLYWPC9AzwsGzwuC50XoedHg2UbwvAQ9Lxk8Lwmel6HnZYNnW8HzCvS8YvC8InhehZ5XDZ7tBM9r0POawfOa4Hkdel43eLYXPG9AzxsGzxuC503oedPg2UHwvAU9bxk8bwmet6HnbYNnR8HzDvS8Y/C8I3jehZ53DZ6dBM970POewfOe4Hkfet43eAaC5wPo+cDg+UDwfAg9Hxo8Owuej6DnI4PnI8HzMfR8bPDsIng+gZ5PDJ5PBM+n0POpwbOr4PkMej4zeD4TPJ9Dz+cGz26C5wvo+cLg+ULwfAk9Xxo8uwuer6DnK4PnK8HzNfR8bfDsIXi+gZ5vDJ5vBM+30POtwbOn4PkOer4zeL4TPN9rwTz/exeqZy/BM0IL5hmhReieYdvhbSNCz4gGz96CZyToGcngGUnwjAw9Ixs8+wieUaBnFINnFMEzKvSMavDsK3hGg57RDJ7RBM/o0DO6wbOf4BkDesYweMYQPGNCz5gGz/6CZyzoGcvgGUvwjA09Yxs8BwiecaBnHINnHMEzLvSMa/AcKHjGg57xDJ7xBM/40DO+wXOQ4JkAeiYweCYQPBNCz4QGz8GCZyLomcjgmUjwTAw9Exs8hwieSaBnEoNnEsEzKfRMavAcKngmg57JDJ7JBM/k0DO5wXOY4JkCeqYweKYQPFNCz5QGz+GCZyromcrgmUrwTA09Uxs8/xY800DPNAbPNIJnWuiZ1uA5QvBMBz3TGTzTCZ7poWd6g+c/gmcG6JnB4JlB8Hwfer5v8BwpeGaEnhkNnhkFz0zQM5PB81/BMzP0zGzwzCx4fgA9PzB4jhI8s0DPLAbPLILnh9DzQ4PnaMEzK/TMavDMKnh+BD0/MniOETyzQc9sBs9sgufH0PNjg+dYwTM79Mxu8MwueH4CPT8xeI4TPHNAzxwGzxyC56fQ81OD53jBMyf0zGnwzCl4fgY9PzN4ThA8c0HPXAbPXILn59Dzc4PnRMEzN/TMbfDMLXh+AT2/MHhOEjzzQM88Bs88gueX0PNLg+dkwTMv9Mxr8MwreH4FPb8yeE4RPPNBz3wGz3yC59fQ82uD51TBMz/0zG/wzC94fgM9vzF4ThM8C0DPAgbPAoJnQehZ0OA5XfAsBD0LGTwLCZ7fQs9vDZ4zBM/C0LOwwbOw4Pkd9PzO4DlT8CwCPYsYPIsInt9Dz+8NnrMEz6LQs6jBs6jg+QP0/MHgOVvwLAY9ixk8iwmeP0LPHw2ecwTP4tCzuMGzuOD5E/T8yeA5V/AsAT1LGDxLCJ4/Q8+fDZ7zBM+S0LOkwbOk4PkL9PzF4Dlf8CwFPUsZPEsJnr9Cz18NngsEz9LQs7TBs7Tg+Rv0/M3guVDwLAM9yxg8ywiev0PP3w2eiwTPstCzrMGzrOD5B/T8w+C5WPAsBz3LGTzLCZ5/Qs8/DZ5LBM/y0LO8wbO84PkX9PzL4LlU8KwAPSsYPCsInhWhZ0WD5zLBsxL0rGTwrCR4VoaelQ2eywXPKtCzisGziuBZFXpWNXiuEDyrQc9qBs9qgmd16Fnd4LlS8KwBPWsYPGsInjWhZ02D5yrBsxb0rGXwrCV41oaetQ2eqwXPOtCzjsGzjuBZF3rWNXiuETzrQc96Bs96gmd96Fnf4LlW8GwAPRsYPBsIng2hZ0OD5zrBsxH0bGTwbCR4NoaejQ2e6wXPJtCzicGzieDZFHo2NXhuEDybQc9mBs9mgmdz6Nnc4LlR8GwBPVsYPFsIni2hZ0uD5ybBsxX0bGXwbCV4toaerQ2emwXPNtCzjcGzjeDZFnq2NXhuETzbQc92Bs92gmd76Nne4LlV8OwAPTsYPDsInh2hZ0eD5zbBsxP07GTw7CR4BtAzMHhuFzw7Q8/OBs/OgmcX6NnF4LlD8OwKPbsaPLsKnt2gZzeD507Bszv07G7w7C549oCePQyeuwTPntCzp8Gzp+DZC3r2MnjuFjx7Q8/eBs/egmcf6NnH4LlH8OwLPfsaPPsKnv2gZz+D517Bsz/07G/w7C94DoCeAwye+wTPgdBzoMFzoOA5CHoOMnjuFzwHQ8/BBs/BgucQ6DnE4HlA8BwKPYcaPIcKnsOg5zCD50HBczj0HG7wHC54/g09/zZ4HhI8R0DPEQbPEYLnP9DzH4PnYcFzJPQcafAcKXj+Cz3/NXgeETxHQc9RBs9Rgudo6Dna4HlU8BwDPccYPMcInmOh51iD5zHBcxz0HGfwHCd4joee4w2exwXPCdBzgsFzguA5EXpONHieEDwnQc9JBs9Jgudk6DnZ4HlS8JwCPacYPKcInlOh51SD5ynBcxr0nGbwnCZ4Toee0w2epwXPGdBzhsFzhuA5E3rONHieETxnQc9ZBs9Zguds6Dnb4HlW8JwDPecYPOcInnOh51yD5znBcx70nGfwnCd4zoee8w2e5wXPBdBzgcFzgeC5EHouNHheEDwXQc9FBs9Fgudi6LnY4HlR8FwCPZcYPJcInkuh51KD5yXBcxn0XGbwXCZ4Loeeyw2elwXPFdBzhcFzheC5EnquNHheETxXQc9VBs9Vgudq6Lna4HlV8FwDPdcYPNcInmuh51qD5zXBcx30XGfwXCd4roee6w2e1wXPDdBzg8Fzg+C5EXpuNHjeEDw3Qc9NBs9Ngudm6LnZ4HlT8NwCPbcYPLcInluh51aD5y3Bcxv03Gbw3CZ4boee2w2etwXPHdBzh8Fzh+C5E3ruNHjeETx3Qc9dBs9dgudu6Lnb4HlX8NwDPfcYPPcInnuh516D5z3Bcx/03Gfw3Cd47oee+w2e9wXPA9DzgMHzgOB5EHoeNHg+EDwPQc9DBs9Dgudh6HnY4PlQ8DwCPY8YPI8Inkeh51GD5yPB8xj0PGbwPCZ4Hoeexw2ejwXPE9DzhMHzhOB5EnqeNHg+ETxPQc9TBs9Tgudp6Hna4PlU8DwDPc8YPM8Inmeh51mD5zPB8xz0PGfwPCd4noee5w2ezwXPC9DzgsHzguB5EXpeNHi+EDwvQc9LBs9Lgudl6HnZ4PlS8LwCPa8YPK8Inleh51WD5yvB8xr0vGbwvCZ4Xoee1w2erwXPG9DzhsHzhuB5E3reNHi+ETxvQc9bBs9bgudt6Hnb4PlW8LwDPe8YPO8Inneh512D5zvB8x70vGfwvCd43oee9w2e72X53+98AD0fGDwfCJ4PoedDg2cEwfMR9Hxk8HwkeD6Gno8NnhEFzyfQ84nB84ng+RR6PjV4RhI8n0HPZwbPZ4Lnc+j53OAZWfB8AT1fGDxfCJ4voedLg2cUwfMV9Hxl8HwleL6Gnq8NnlEFzzfQ843B843g+RZ6vjV4RhM830HPdwbPd4Lney2Z53/vQvWMLnhGaMk8I7QM3TNsO7xtROgZ0eAZQ/CMBD0jGTwjCZ6RoWdkg2dMwTMK9Ixi8IwieEaFnlENnrEEz2jQM5rBM5rgGR16Rjd4xhY8Y0DPGAbPGIJnTOgZ0+AZR/CMBT1jGTxjCZ6xoWdsg2dcwTMO9Ixj8IwjeMaFnnENnvEEz3jQM57BM57gGR96xjd4xhc8E0DPBAbPBIJnQuiZ0OCZQPBMBD0TGTwTCZ6JoWdig2dCwTMJ9Exi8EwieCaFnkkNnokEz2TQM5nBM5ngmRx6Jjd4JhY8U0DPFAbPFIJnSuiZ0uCZRPBMBT1TGTxTCZ6poWdqg2dSwTMN9Exj8EwjeKaFnmkNnskEz3TQM53BM53gmR56pjd4Jhc8M0DPDAbPDILn+9DzfYNnCsEzI/TMaPDMKHhmgp6ZDJ4pBc/M0DOzwTOz4PkB9PzA4JlK8MwCPbMYPLMInh9Czw8NnqkFz6zQM6vBM6vg+RH0/MjgmUbwzAY9sxk8swmeH0PPjw2eaQXP7NAzu8Ezu+D5CfT8xOCZTvDMAT1zGDxzCJ6fQs9PDZ7pBc+c0DOnwTOn4PkZ9PzM4JlB8MwFPXMZPHMJnp9Dz88Nnu8LnrmhZ26DZ27B8wvo+YXBM6PgmQd65jF45hE8v4SeXxo8MwmeeaFnXoNnXsHzK+j5lcEzs+CZD3rmM3jmEzy/hp5fGzw/EDzzQ8/8Bs/8guc30PMbg2cWwbMA9Cxg8CwgeBaEngUNnh8KnoWgZyGDZyHB81vo+a3BM6vgWRh6FjZ4FhY8v4Oe3xk8PxI8i0DPIgbPIoLn99Dze4NnNsGzKPQsavAsKnj+AD1/MHh+LHgWg57FDJ7FBM8foeePBs/sgmdx6Fnc4Flc8PwJev5k8PxE8CwBPUsYPEsInj9Dz58NnjkEz5LQs6TBs6Tg+Qv0/MXg+angWQp6ljJ4lhI8f4Wevxo8cwqepaFnaYNnacHzN+j5m8HzM8GzDPQsY/AsI3j+Dj1/N3jmEjzLQs+yBs+ygucf0PMPg+fngmc56FnO4FlO8PwTev5p8MwteJaHnuUNnuUFz7+g518Gzy8EzwrQs4LBs4LgWRF6VjR45hE8K0HPSgbPSoJnZehZ2eD5peBZBXpWMXhWETyrQs+qBs+8gmc16FnN4FlN8KwOPasbPL8SPGtAzxoGzxqCZ03oWdPgmU/wrAU9axk8awmetaFnbYPn14JnHehZx+BZR/CsCz3rGjzzC571oGc9g2c9wbM+9Kxv8PxG8GwAPRsYPBsIng2hZ0ODZwHBsxH0bGTwbCR4NoaejQ2eBQXPJtCzicGzieDZFHo2NXgWEjybQc9mBs9mgmdz6Nnc4Pmt4NkCerYweLYQPFtCz5YGz8KCZyvo2crg2UrwbA09Wxs8vxM820DPNgbPNoJnW+jZ1uBZRPBsBz3bGTzbCZ7toWd7g+f3gmcH6NnB4NlB8OwIPTsaPIsKnp2gZyeDZyfBM4CegcHzB8GzM/TsbPDsLHh2gZ5dDJ7FBM+u0LOrwbOr4NkNenYzeP4oeHaHnt0Nnt0Fzx7Qs4fBs7jg2RN69jR49hQ8e0HPXgbPnwTP3tCzt8Gzt+DZB3r2MXiWEDz7Qs++Bs++gmc/6NnP4Pmz4NkfevY3ePYXPAdAzwEGz5KC50DoOdDgOVDwHAQ9Bxk8fxE8B0PPwQbPwYLnEOg5xOBZSvAcCj2HGjyHCp7DoOcwg+evgudw6Dnc4Dlc8Pwbev5t8CwteI6AniMMniMEz3+g5z8Gz98Ez5HQc6TBc6Tg+S/0/NfgWUbwHAU9Rxk8Rwmeo6HnaIPn74LnGOg5xuA5RvAcCz3HGjzLCp7joOc4g+c4wXM89Bxv8PxD8JwAPScYPCcInhOh50SDZznBcxL0nGTwnCR4Toaekw2efwqeU6DnFIPnFMFzKvScavAsL3hOg57TDJ7TBM/p0HO6wfMvwXMG9Jxh8JwheM6EnjMNnhUEz1nQc5bBc5bgORt6zjZ4VhQ850DPOQbPOYLnXOg51+BZSfCcBz3nGTznCZ7zoed8g2dlwXMB9Fxg8FwgeC6EngsNnlUEz0XQc5HBc5HguRh6LjZ4VhU8l0DPJQbPJYLnUui51OBZTfBcBj2XGTyXCZ7Loedyg2d1wXMF9Fxh8FwheK6EnisNnjUEz1XQc5XBc5XguRp6rjZ41hQ810DPNQbPNYLnWui51uBZS/BcBz3XGTzXCZ7roed6g2dtwXMD9Nxg8NwgeG6EnhsNnnUEz03Qc5PBc5PguRl6bjZ41hU8t0DPLQbPLYLnVui51eBZT/DcBj23GTy3CZ7boed2g2d9wXMH9Nxh8NwheO6EnjsNng0Ez13Qc5fBc5fguRt67jZ4NhQ890DPPQbPPYLnXui51+DZSPDcBz33GTz3CZ77oed+g2djwfMA9Dxg8DwgeB6EngcNnk0Ez0PQ85DB85DgeRh6HjZ4NhU8j0DPIwbPI4LnUeh51ODZTPA8Bj2PGTyPCZ7Hoedxg2dzwfME9Dxh8DwheJ6EnicNni0Ez1PQ85TB85TgeRp6njZ4thQ8z0DPMwbPM4LnWeh51uDZSvA8Bz3PGTzPCZ7noed5g2drwfMC9Lxg8LwgeF6EnhcNnm0Ez0vQ85LB85LgeRl6XjZ4thU8r0DPKwbPK4LnVeh51eDZTvC8Bj2vGTyvCZ7Xoed1g2d7wfMG9Lxh8LwheN6EnjcNnh0Ez1vQ85bB85bgeRt63jZ4dhQ870DPOwbPO4LnXeh51+DZSfC8Bz3vGTzvCZ73oed9g2cgeD6Ang8Mng8Ez4fQ86HBs7Pg+Qh6PjJ4PhI8H0PPxwbPLoLnE+j5xOD5RPB8Cj2fGjy7Cp7PoOczg+czwfM59Hxu8OwmeL6Ani8Mni8Ez5fQ86XBs7vg+Qp6vjJ4vhI8X0PP1wbPHoLnG+j5xuD5RvB8Cz3fGjx7Cp7voOc7g+c7wfO9Vszzv3ehevYSPCO0Yp4RWoXuGbYd3jYi9Ixo8OwteEaCnpEMnpEEz8jQM7LBs4/gGQV6RjF4RhE8o0LPqAbPvoJnNOgZzeAZTfCMDj2jGzz7CZ4xoGcMg2cMwTMm9Ixp8OwveMaCnrEMnrEEz9jQM7bBc4DgGQd6xjF4xhE840LPuAbPgYJnPOgZz+AZT/CMDz3jGzwHCZ4JoGcCg2cCwTMh9Exo8BwseCaCnokMnokEz8TQM7HBc4jgmQR6JjF4JhE8k0LPpAbPoYJnMuiZzOCZTPBMDj2TGzyHCZ4poGcKg2cKwTMl9Exp8BwueKaCnqkMnqkEz9TQM7XB82/BMw30TGPwTCN4poWeaQ2eIwTPdNAzncEzneCZHnqmN3j+I3hmgJ4ZDJ4ZBM/3oef7Bs+RgmdG6JnR4JlR8MwEPTMZPP8VPDNDz8wGz8yC5wfQ8wOD5yjBMwv0zGLwzCJ4fgg9PzR4jhY8s0LPrAbPrILnR9DzI4PnGMEzG/TMZvDMJnh+DD0/NniOFTyzQ8/sBs/sgucn0PMTg+c4wTMH9Mxh8MwheH4KPT81eI4XPHNCz5wGz5yC52fQ8zOD5wTBMxf0zGXwzCV4fg49Pzd4ThQ8c0PP3AbP3ILnF9DzC4PnJMEzD/TMY/DMI3h+CT2/NHhOFjzzQs+8Bs+8gudX0PMrg+cUwTMf9Mxn8MwneH4NPb82eE4VPPNDz/wGz/yC5zfQ8xuD5zTBswD0LGDwLCB4FoSeBQ2e0wXPQtCzkMGzkOD5LfT81uA5Q/AsDD0LGzwLC57fQc/vDJ4zBc8i0LOIwbOI4Pk99Pze4DlL8CwKPYsaPIsKnj9Azx8MnrMFz2LQs5jBs5jg+SP0/NHgOUfwLA49ixs8iwueP0HPnwyecwXPEtCzhMGzhOD5M/T82eA5T/AsCT1LGjxLCp6/QM9fDJ7zBc9S0LOUwbOU4Pkr9PzV4LlA8CwNPUsbPEsLnr9Bz98MngsFzzLQs4zBs4zg+Tv0/N3guUjwLAs9yxo8ywqef0DPPwyeiwXPctCznMGznOD5J/T80+C5RPAsDz3LGzzLC55/Qc+/DJ5LBc8K0LOCwbOC4FkRelY0eC4TPCtBz0oGz0qCZ2XoWdnguVzwrAI9qxg8qwieVaFnVYPnCsGzGvSsZvCsJnhWh57VDZ4rBc8a0LOGwbOG4FkTetY0eK4SPGtBz1oGz1qCZ23oWdvguVrwrAM96xg86wiedaFnXYPnGsGzHvSsZ/CsJ3jWh571DZ5rBc8G0LOBwbOB4NkQejY0eK4TPBtBz0YGz0aCZ2Po2djguV7wbAI9mxg8mwieTaFnU4PnBsGzGfRsZvBsJng2h57NDZ4bBc8W0LOFwbOF4NkSerY0eG4SPFtBz1YGz1aCZ2vo2drguVnwbAM92xg82wiebaFnW4PnFsGzHfRsZ/BsJ3i2h57tDZ5bBc8O0LODwbOD4NkRenY0eG4TPDtBz04Gz06CZwA9A4PndsGzM/TsbPDsLHh2gZ5dDJ47BM+u0LOrwbOr4NkNenYzeO4UPLtDz+4Gz+6CZw/o2cPguUvw7Ak9exo8ewqevaBnL4PnbsGzN/TsbfDsLXj2gZ59DJ57BM++0LOvwbOv4NkPevYzeO4VPPtDz/4Gz/6C5wDoOcDguU/wHAg9Bxo8Bwqeg6DnIIPnfsFzMPQcbPAcLHgOgZ5DDJ4HBM+h0HOowXOo4DkMeg4zeB4UPIdDz+EGz+GC59/Q82+D5yHBcwT0HGHwHCF4/gM9/zF4HhY8R0LPkQbPkYLnv9DzX4PnEcFzFPQcZfAcJXiOhp6jDZ5HBc8x0HOMwXOM4DkWeo41eB4TPMdBz3EGz3GC53joOd7geVzwnAA9Jxg8JwieE6HnRIPnCcFzEvScZPCcJHhOhp6TDZ4nBc8p0HOKwXOK4DkVek41eJ4SPKdBz2kGz2mC53ToOd3geVrwnAE9Zxg8ZwieM6HnTIPnGcFzFvScZfCcJXjOhp6zDZ5nBc850HOOwXOO4DkXes41eJ4TPOdBz3kGz3mC53zoOd/geV7wXAA9Fxg8FwieC6HnQoPnBcFzEfRcZPBcJHguhp6LDZ4XBc8l0HOJwXOJ4LkUei41eF4SPJdBz2UGz2WC53LoudzgeVnwXAE9Vxg8VwieK6HnSoPnFcFzFfRcZfBcJXiuhp6rDZ5XBc810HONwXON4LkWeq41eF4TPNdBz3UGz3WC53roud7geV3w3AA9Nxg8NwieG6HnRoPnDcFzE/TcZPDcJHhuhp6bDZ43Bc8t0HOLwXOL4LkVem41eN4SPLdBz20Gz22C53boud3geVvw3AE9dxg8dwieO6HnToPnHcFzF/TcZfDcJXjuhp67DZ53Bc890HOPwXOP4LkXeu41eN4TPPdBz30Gz32C537oud/geV/wPAA9Dxg8DwieB6HnQYPnA8HzEPQ8ZPA8JHgehp6HDZ4PBc8j0POIwfOI4HkUeh41eD4SPI9Bz2MGz2OC53Hoedzg+VjwPAE9Txg8TwieJ6HnSYPnE8HzFPQ8ZfA8JXiehp6nDZ5PBc8z0POMwfOM4HkWep41eD4TPM9Bz3MGz3OC53noed7g+VzwvAA9Lxg8LwieF6HnRYPnC8HzEvS8ZPC8JHhehp6XDZ4vBc8r0POKwfOK4HkVel41eL4SPK9Bz2sGz2uC53Xoed3g+VrwvAE9bxg8bwieN6HnTYPnG8HzFvS8ZfC8JXjehp63DZ5vBc870POOwfOO4HkXet51eGb93++897/dGe3d2/Tvhb3zv3eZwrlTaYe3vf+/3Rnv3euC/+/O+//DneF8Ed4Jng+g5wOD5wPB8yH0fGjwfO+j//3OR9DzkcHzkeD5GHo+NnhGEDyfQM8nBs8ngudT6PnU4BlR8HwGPZ8ZPJ8Jns+h53ODZyTB8wX0fGHwfCF4voSeLw2ekQXPV9DzlcHzleD5Gnq+NnhGETzfQM83Bs83gudb6PnW4BlV8HwHPd8ZPN8Jnu+1Zp7/vQvVM5rgGaE184zQOnTPsO3wthGhZ0SDZ3TBMxL0jGTwjCR4RoaekQ2eMQTPKNAzisEziuAZFXpGNXjGFDyjQc9oBs9ogmd06Bnd4BlL8IwBPWMYPGMInjGhZ0yDZ2zBMxb0jGXwjCV4xoaesQ2ecQTPONAzjsEzjuAZF3rGNXjGFTzjQc94Bs94gmd86Bnf4BlP8EwAPRMYPBMIngmhZ0KDZ3zBMxH0TGTwTCR4JoaeiQ2eCQTPJNAzicEzieCZFHomNXgmFDyTQc9kBs9kgmdy6Jnc4JlI8EwBPVMYPFMInimhZ0qDZ2LBMxX0TGXwTCV4poaeqQ2eSQTPNNAzjcEzjeCZFnqmNXgmFTzTQc90Bs90gmd66Jne4JlM8MwAPTMYPDMInu9Dz/cNnskFz4zQM6PBM6PgmQl6ZjJ4phA8M0PPzAbPzILnB9DzA4NnSsEzC/TMYvDMInh+CD0/NHimEjyzQs+sBs+sgudH0PMjg2dqwTMb9Mxm8MwmeH4MPT82eKYRPLNDz+wGz+yC5yfQ8xODZ1rBMwf0zGHwzCF4fgo9PzV4phM8c0LPnAbPnILnZ9DzM4NnesEzF/TMZfDMJXh+Dj0/N3hmEDxzQ8/cBs/cgucX0PMLg+f7gmce6JnH4JlH8PwSen5p8MwoeOaFnnkNnnkFz6+g51cGz0yCZz7omc/gmU/w/Bp6fm3wzCx45oee+Q2e+QXPb6DnNwbPDwTPAtCzgMGzgOBZEHoWNHhmETwLQc9CBs9Cgue30PNbg+eHgmdh6FnY4FlY8PwOen5n8MwqeBaBnkUMnkUEz++h5/cGz48Ez6LQs6jBs6jg+QP0/MHgmU3wLAY9ixk8iwmeP0LPHw2eHwuexaFncYNnccHzJ+j5k8Ezu+BZAnqWMHiWEDx/hp4/Gzw/ETxLQs+SBs+Sgucv0PMXg2cOwbMU9Cxl8CwleP4KPX81eH4qeJaGnqUNnqUFz9+g528Gz5yCZxnoWcbgWUbw/B16/m7w/EzwLAs9yxo8ywqef0DPPwyeuQTPctCznMGznOD5J/T80+D5ueBZHnqWN3iWFzz/gp5/GTxzC54VoGcFg2cFwbMi9Kxo8PxC8KwEPSsZPCsJnpWhZ2WDZx7Bswr0rGLwrCJ4VoWeVQ2eXwqe1aBnNYNnNcGzOvSsbvDMK3jWgJ41DJ41BM+a0LOmwfMrwbMW9Kxl8KwleNaGnrUNnvkEzzrQs47Bs47gWRd61jV4fi141oOe9Qye9QTP+tCzvsEzv+DZAHo2MHg2EDwbQs+GBs9vBM9G0LORwbOR4NkYejY2eBYQPJtAzyYGzyaCZ1Po2dTgWVDwbAY9mxk8mwmezaFnc4NnIcGzBfRsYfBsIXi2hJ4tDZ7fCp6toGcrg2crwbM19Gxt8CwseLaBnm0Mnm0Ez7bQs63B8zvBsx30bGfwbCd4toee7Q2eRQTPDtCzg8Gzg+DZEXp2NHh+L3h2gp6dDJ6dBM8AegYGz6KCZ2fo2dng2Vnw7AI9uxg8fxA8u0LPrgbProJnN+jZzeBZTPDsDj27Gzy7C549oGcPg+ePgmdP6NnT4NlT8OwFPXsZPIsLnr2hZ2+DZ2/Bsw/07GPw/Enw7As9+xo8+wqe/aBnP4NnCcGzP/Tsb/DsL3gOgJ4DDJ4/C54DoedAg+dAwXMQ9Bxk8CwpeA6GnoMNnoMFzyHQc4jB8xfBcyj0HGrwHCp4DoOewwyepQTP4dBzuMFzuOD5N/T82+D5q+A5AnqOMHiOEDz/gZ7/GDxLC54joedIg+dIwfNf6PmvwfM3wXMU9Bxl8BwleI6GnqMNnmUEzzHQc4zBc4zgORZ6jjV4/i54joOe4wye4wTP8dBzvMGzrOA5AXpOMHhOEDwnQs+JBs8/BM9J0HOSwXOS4DkZek42eJYTPKdAzykGzymC51ToOdXg+afgOQ16TjN4ThM8p0PP6QbP8oLnDOg5w+A5Q/CcCT1nGjz/EjxnQc9ZBs9Zguds6Dnb4FlB8JwDPecYPOcInnOh51yDZ0XBcx70nGfwnCd4zoee8w2elQTPBdBzgcFzgeC5EHouNHhWFjwXQc9FBs9Fgudi6LnY4FlF8FwCPZcYPJcInkuh51KDZ1XBcxn0XGbwXCZ4Loeeyw2e1QTPFdBzhcFzheC5EnquNHhWFzxXQc9VBs9Vgudq6Lna4FlD8FwDPdcYPNcInmuh51qDZ03Bcx30XGfwXCd4roee6w2etQTPDdBzg8Fzg+C5EXpuNHjWFjw3Qc9NBs9Ngudm6LnZ4FlH8NwCPbcYPLcInluh51aDZ13Bcxv03Gbw3CZ4boee2w2e9QTPHdBzh8Fzh+C5E3ruNHjWFzx3Qc9dBs9dgudu6Lnb4NlA8NwDPfcYPPcInnuh516DZ0PBcx/03Gfw3Cd47oee+w2ejQTPA9DzgMHzgOB5EHoeNHg2FjwPQc9DBs9Dgudh6HnY4NlE8DwCPY8YPI8Inkeh51GDZ1PB8xj0PGbwPCZ4Hoeexw2ezQTPE9DzhMHzhOB5EnqeNHg2FzxPQc9TBs9Tgudp6Hna4NlC8DwDPc8YPM8Inmeh51mDZ0vB8xz0PGfwPCd4noee5w2erQTPC9DzgsHzguB5EXpeNHi2FjwvQc9LBs9Lgudl6HnZ4NlG8LwCPa8YPK8Inleh51WDZ1vB8xr0vGbwvCZ4Xoee1w2e7QTPG9DzhsHzhuB5E3reNHi2FzxvQc9bBs9bgudt6Hnb4NlB8LwDPe8YPO8Inneh512DZ0fB8x70vGfwvCd43oee9w2enQTPB9DzgcHzgeD5EHo+NHgGgucj6PnI4PlI8HwMPR8bPDsLnk+g5xOD5xPB8yn0fGrw7CJ4PoOezwyezwTP59DzucGzq+D5Anq+MHi+EDxfQs+XBs9ugucr6PnK4PlK8HwNPV8bPLsLnm+g5xuD5xvB8y30fGvw7CF4voOe7wye7wTP99owz//eherZU/CM0IZ5RmgTumfYdnjbiNAzosGzl+AZCXpGMnhGEjwjQ8/IBs/egmcU6BnF4BlF8IwKPaMaPPsIntGgZzSDZzTBMzr0jG7w7Ct4xoCeMQyeMQTPmNAzpsGzn+AZC3rGMnjGEjxjQ8/YBs/+gmcc6BnH4BlH8IwLPeMaPAcInvGgZzyDZzzBMz70jG/wHCh4JoCeCQyeCQTPhNAzocFzkOCZCHomMngmEjwTQ8/EBs/BgmcS6JnE4JlE8EwKPZMaPIcInsmgZzKDZzLBMzn0TG7wHCp4poCeKQyeKQTPlNAzpcFzmOCZCnqmMnimEjxTQ8/UBs/hgmca6JnG4JlG8EwLPdMaPP8WPNNBz3QGz3SCZ3romd7gOULwzAA9Mxg8Mwie70PP9w2e/wieGaFnRoNnRsEzE/TMZPAcKXhmhp6ZDZ6ZBc8PoOcHBs9/Bc8s0DOLwTOL4Pkh9PzQ4DlK8MwKPbMaPLMKnh9Bz48MnqMFz2zQM5vBM5vg+TH0/NjgOUbwzA49sxs8swuen0DPTwyeYwXPHNAzh8Ezh+D5KfT81OA5TvDMCT1zGjxzCp6fQc/PDJ7jBc9c0DOXwTOX4Pk59Pzc4DlB8MwNPXMbPHMLnl9Azy8MnhMFzzzQM4/BM4/g+SX0/NLgOUnwzAs98xo88wqeX0HPrwyekwXPfNAzn8Ezn+D5NfT82uA5RfDMDz3zGzzzC57fQM9vDJ5TBc8C0LOAwbOA4FkQehY0eE4TPAtBz0IGz0KC57fQ81uD53TBszD0LGzwLCx4fgc9vzN4zhA8i0DPIgbPIoLn99Dze4PnTMGzKPQsavAsKnj+AD1/MHjOEjyLQc9iBs9igueP0PNHg+dswbM49Cxu8CwueP4EPX8yeM4RPEtAzxIGzxKC58/Q82eD51zBsyT0LGnwLCl4/gI9fzF4zhM8S0HPUgbPUoLnr9DzV4PnfMGzNPQsbfAsLXj+Bj1/M3guEDzLQM8yBs8ygufv0PN3g+dCwbMs9Cxr8CwreP4BPf8weC4SPMtBz3IGz3KC55/Q80+D52LBszz0LG/wLC94/gU9/zJ4LhE8K0DPCgbPCoJnRehZ0eC5VPCsBD0rGTwrCZ6VoWdlg+cywbMK9Kxi8KwieFaFnlUNnssFz2rQs5rBs5rgWR16Vjd4rhA8a0DPGgbPGoJnTehZ0+C5UvCsBT1rGTxrCZ61oWdtg+cqwbMO9Kxj8KwjeNaFnnUNnqsFz3rQs57Bs57gWR961jd4rhE8G0DPBgbPBoJnQ+jZ0OC5VvBsBD0bGTwbCZ6NoWdjg+c6wbMJ9Gxi8GwieDaFnk0NnusFz2bQs5nBs5ng2Rx6Njd4bhA8W0DPFgbPFoJnS+jZ0uC5UfBsBT1bGTxbCZ6toWdrg+cmwbMN9Gxj8GwjeLaFnm0NnpsFz3bQs53Bs53g2R56tjd4bhE8O0DPDgbPDoJnR+jZ0eC5VfDsBD07GTw7CZ4B9AwMntsEz87Qs7PBs7Pg2QV6djF4bhc8u0LPrgbProJnN+jZzeC5Q/DsDj27Gzy7C549oGcPg+dOwbMn9Oxp8OwpePaCnr0MnrsEz97Qs7fBs7fg2Qd69jF47hY8+0LPvgbPvoJnP+jZz+C5R/DsDz37Gzz7C54DoOcAg+dewXMg9Bxo8BwoeA6CnoMMnvsEz8HQc7DBc7DgOQR6DjF47hc8h0LPoQbPoYLnMOg5zOB5QPAcDj2HGzyHC55/Q8+/DZ4HBc8R0HOEwXOE4PkP9PzH4HlI8BwJPUcaPEcKnv9Cz38NnocFz1HQc5TBc5TgORp6jjZ4HhE8x0DPMQbPMYLnWOg51uB5VPAcBz3HGTzHCZ7joed4g+cxwXMC9Jxg8JwgeE6EnhMNnscFz0nQc5LBc5LgORl6TjZ4nhA8p0DPKQbPKYLnVOg51eB5UvCcBj2nGTynCZ7Toed0g+cpwXMG9Jxh8JwheM6EnjMNnqcFz1nQc5bBc5bgORt6zjZ4nhE850DPOQbPOYLnXOg51+B5VvCcBz3nGTznCZ7zoed8g+c5wXMB9Fxg8FwgeC6EngsNnucFz0XQc5HBc5HguRh6LjZ4XhA8l0DPJQbPJYLnUui51OB5UfBcBj2XGTyXCZ7Loedyg+clwXMF9Fxh8FwheK6EnisNnpcFz1XQc5XBc5XguRp6rjZ4XhE810DPNQbPNYLnWui51uB5VfBcBz3XGTzXCZ7roed6g+c1wXMD9Nxg8NwgeG6EnhsNntcFz03Qc5PBc5PguRl6bjZ43hA8t0DPLQbPLYLnVui51eB5U/DcBj23GTy3CZ7boed2g+ctwXMH9Nxh8NwheO6EnjsNnrcFz13Qc5fBc5fguRt67jZ43hE890DPPQbPPYLnXui51+B5V/DcBz33GTz3CZ77oed+g+c9wfMA9Dxg8DwgeB6EngcNnvcFz0PQ85DB85DgeRh6HjZ4PhA8j0DPIwbPI4LnUeh51OD5UPA8Bj2PGTyPCZ7Hoedxg+cjwfME9Dxh8DwheJ6EnicNno8Fz1PQ85TB85TgeRp6njZ4PhE8z0DPMwbPM4LnWeh51uD5VPA8Bz3PGTzPCZ7noed5g+czwfMC9Lxg8LwgeF6EnhcNns8Fz0vQ85LB85LgeRl6XjZ4vhA8r0DPKwbPK4LnVeh51eD5UvC8Bj2vGTyvCZ7Xoed1g+crwfMG9Lxh8LwheN6EnjcNnq8Fz1vQ85bB85bgeRt63jZ4vhE870DPOwbPO4LnXeh51+D5VvC8Bz3vGTzvCZ73oed9g+c7wfMB9Hxg8HwgeD6Eng8Nnu9l+9/vfAQ9Hxk8Hwmej6HnY4NnBMHzCfR8YvB8Ing+hZ5PDZ4RBc9n0POZwfOZ4Pkcej43eEYSPF9AzxcGzxeC50vo+dLgGVnwfAU9Xxk8Xwmer6Hna4NnFMHzDfR8Y/B8I3i+hZ5vDZ5RBc930POdwfOd4PleW+b537tQPaMJnhHaMs8IbUP3DNsObxsRekY0eEYXPCNBz0gGz0iCZ2ToGdngGUPwjAI9oxg8owieUaFnVINnTMEzGvSMZvCMJnhGh57RDZ6xBM8Y0DOGwTOG4BkTesY0eMYWPGNBz1gGz1iCZ2zoGdvgGUfwjAM94xg84wiecaFnXINnXMEzHvSMZ/CMJ3jGh57xDZ7xBM8E0DOBwTOB4JkQeiY0eMYXPBNBz0QGz0SCZ2LomdjgmUDwTAI9kxg8kwieSaFnUoNnQsEzGfRMZvBMJngmh57JDZ6JBM8U0DOFwTOF4JkSeqY0eCYWPFNBz1QGz1SCZ2romdrgmUTwTAM90xg80wieaaFnWoNnUsEzHfRMZ/BMJ3imh57pDZ7JBM8M0DODwTOD4Pk+9Hzf4Jlc8MwIPTMaPDMKnpmgZyaDZwrBMzP0zGzwzCx4fgA9PzB4phQ8s0DPLAbPLILnh9DzQ4NnKsEzK/TMavDMKnh+BD0/MnimFjyzQc9sBs9sgufH0PNjg2cawTM79Mxu8MwueH4CPT8xeKYVPHNAzxwGzxyC56fQ81ODZzrBMyf0zGnwzCl4fgY9PzN4phc8c0HPXAbPXILn59Dzc4NnBsEzN/TMbfDMLXh+AT2/MHi+L3jmgZ55DJ55BM8voeeXBs+Mgmde6JnX4JlX8PwKen5l8MwkeOaDnvkMnvkEz6+h59cGz8yCZ37omd/gmV/w/AZ6fmPw/EDwLAA9Cxg8CwieBaFnQYNnFsGzEPQsZPAsJHh+Cz2/NXh+KHgWhp6FDZ6FBc/voOd3Bs+sgmcR6FnE4FlE8Pween5v8PxI8CwKPYsaPIsKnj9Azx8MntkEz2LQs5jBs5jg+SP0/NHg+bHgWRx6Fjd4Fhc8f4KePxk8swueJaBnCYNnCcHzZ+j5s8HzE8GzJPQsafAsKXj+Aj1/MXjmEDxLQc9SBs9Sguev0PNXg+engmdp6Fna4Fla8PwNev5m8MwpeJaBnmUMnmUEz9+h5+8Gz88Ez7LQs6zBs6zg+Qf0/MPgmUvwLAc9yxk8ywmef0LPPw2enwue5aFneYNnecHzL+j5l8Ezt+BZAXpWMHhWEDwrQs+KBs8vBM9K0LOSwbOS4FkZelY2eOYRPKtAzyoGzyqCZ1XoWdXg+aXgWQ16VjN4VhM8q0PP6gbPvIJnDehZw+BZQ/CsCT1rGjy/EjxrQc9aBs9agmdt6Fnb4JlP8KwDPesYPOsInnWhZ12D59eCZz3oWc/gWU/wrA896xs88wueDaBnA4NnA8GzIfRsaPD8RvBsBD0bGTwbCZ6NoWdjg2cBwbMJ9Gxi8GwieDaFnk0NngUFz2bQs5nBs5ng2Rx6Njd4FhI8W0DPFgbPFoJnS+jZ0uD5reDZCnq2Mni2EjxbQ8/WBs/Cgmcb6NnG4NlG8GwLPdsaPL8TPNtBz3YGz3aCZ3vo2d7gWUTw7AA9Oxg8OwieHaFnR4Pn94JnJ+jZyeDZSfAMoGdg8CwqeHaGnp0Nnp0Fzy7Qs4vB8wfBsyv07Grw7Cp4doOe3QyexQTP7tCzu8Gzu+DZA3r2MHj+KHj2hJ49DZ49Bc9e0LOXwbO44NkbevY2ePYWPPtAzz4Gz58Ez77Qs6/Bs6/g2Q969jN4lhA8+0PP/gbP/oLnAOg5wOD5s+A5EHoONHgOFDwHQc9BBs+Sgudg6DnY4DlY8BwCPYcYPH8RPIdCz6EGz6GC5zDoOczgWUrwHA49hxs8hwuef0PPvw2evwqeI6DnCIPnCMHzH+j5j8GztOA5EnqONHiOFDz/hZ7/Gjx/EzxHQc9RBs9Rgudo6Dna4FlG8BwDPccYPMcInmOh51iD5++C5zjoOc7gOU7wHA89xxs8ywqeE6DnBIPnBMFzIvScaPD8Q/CcBD0nGTwnCZ6Toedkg2c5wXMK9Jxi8JwieE6FnlMNnn8KntOg5zSD5zTBczr0nG7wLC94zoCeMwyeMwTPmdBzpsHzL8FzFvScZfCcJXjOhp6zDZ4VBM850HOOwXOO4DkXes41eFYUPOdBz3kGz3mC53zoOd/gWUnwXAA9Fxg8FwieC6HnQoNnZcFzEfRcZPBcJHguhp6LDZ5VBM8l0HOJwXOJ4LkUei41eFYVPJdBz2UGz2WC53LoudzgWU3wXAE9Vxg8VwieK6HnSoNndcFzFfRcZfBcJXiuhp6rDZ41BM810HONwXON4LkWeq41eNYUPNdBz3UGz3WC53roud7gWUvw3AA9Nxg8NwieG6HnRoNnbcFzE/TcZPDcJHhuhp6bDZ51BM8t0HOLwXOL4LkVem41eNYVPLdBz20Gz22C53boud3gWU/w3AE9dxg8dwieO6HnToNnfcFzF/TcZfDcJXjuhp67DZ4NBM890HOPwXOP4LkXeu41eDYUPPdBz30Gz32C537oud/g2UjwPAA9Dxg8DwieB6HnQYNnY8HzEPQ8ZPA8JHgehp6HDZ5NBM8j0POIwfOI4HkUeh41eDYVPI9Bz2MGz2OC53Hoedzg2UzwPAE9Txg8TwieJ6HnSYNnc8HzFPQ8ZfA8JXiehp6nDZ4tBM8z0POMwfOM4HkWep41eLYUPM9Bz3MGz3OC53noed7g2UrwvAA9Lxg8LwieF6HnRYNna8HzEvS8ZPC8JHhehp6XDZ5tBM8r0POKwfOK4HkVel41eLYVPK9Bz2sGz2uC53Xoed3g2U7wvAE9bxg8bwieN6HnTYNne8HzFvS8ZfC8JXjehp63DZ4dBM870POOwfOO4HkXet41eHYUPO9Bz3sGz3uC533oed/g2UnwfAA9Hxg8HwieD6HnQ4NnIHg+gp6PDJ6PBM/H0POxwbOz4PkEej4xeD4RPJ9Cz6cGzy6C5zPo+czg+UzwfA49nxs8uwqeL6DnC4PnC8HzJfR8afDsJni+gp6vDJ6vBM/X0PO1wbO74PkGer4xeL4RPN9Cz7cGzx6C5zvo+c7g+U7wfK8d8/zvXaiePQXPCO2YZ4R2oXuGbYe3jQg9Ixo8ewmekaBnJINnJMEzMvSMbPDsLXhGgZ5RDJ5RBM+o0DOqwbOP4BkNekYzeEYTPKNDz+gGz76CZwzoGcPgGUPwjAk9Yxo8+wmesaBnLINnLMEzNvSMbfDsL3jGgZ5xDJ5xBM+40DOuwXOA4BkPesYzeMYTPONDz/gGz4GCZwLomcDgmUDwTAg9Exo8BwmeiaBnIoNnIsEzMfRMbPAcLHgmgZ5JDJ5JBM+k0DOpwXOI4JkMeiYzeCYTPJNDz+QGz6GCZwromcLgmULwTAk9Uxo8hwmeqaBnKoNnKsEzNfRMbfAcLnimgZ5pDJ5pBM+00DOtwfNvwTMd9Exn8EwneKaHnukNniMEzwzQM4PBM4Pg+T70fN/g+Y/gmRF6ZjR4ZhQ8M0HPTAbPkYJnZuiZ2eCZWfD8AHp+YPD8V/DMAj2zGDyzCJ4fQs8PDZ6jBM+s0DOrwTOr4PkR9PzI4Dla8MwGPbMZPLMJnh9Dz48NnmMEz+zQM7vBM7vg+Qn0/MTgOVbwzAE9cxg8cwien0LPTw2e4wTPnNAzp8Ezp+D5GfT8zOA5XvDMBT1zGTxzCZ6fQ8/PDZ4TBM/c0DO3wTO34PkF9PzC4DlR8MwDPfMYPPMInl9Czy8NnpMEz7zQM6/BM6/g+RX0/MrgOVnwzAc98xk88wmeX0PPrw2eUwTP/NAzv8Ezv+D5DfT8xuA5VfAsAD0LGDwLCJ4FoWdBg+c0wbMQ9Cxk8CwkeH4LPb81eE4XPAtDz8IGz8KC53fQ8zuD5wzBswj0LGLwLCJ4fg89vzd4zhQ8i0LPogbPooLnD9DzB4PnLMGzGPQsZvAsJnj+CD1/NHjOFjyLQ8/iBs/igudP0PMng+ccwbME9Cxh8CwheP4MPX82eM4VPEtCz5IGz5KC5y/Q8xeD5zzBsxT0LGXwLCV4/go9fzV4zhc8S0PP0gbP0oLnb9DzN4PnAsGzDPQsY/AsI3j+Dj1/N3guFDzLQs+yBs+ygucf0PMPg+ciwbMc9Cxn8CwneP4JPf80eC4WPMtDz/IGz/KC51/Q8y+D5xLBswL0rGDwrCB4VoSeFQ2eSwXPStCzksGzkuBZGXpWNnguEzyrQM8qBs8qgmdV6FnV4Llc8KwGPasZPKsJntWhZ3WD5wrBswb0rGHwrCF41oSeNQ2eKwXPWtCzlsGzluBZG3rWNniuEjzrQM86Bs86gmdd6FnX4Lla8KwHPesZPOsJnvWhZ32D5xrBswH0bGDwbCB4NoSeDQ2eawXPRtCzkcGzkeDZGHo2NniuEzybQM8mBs8mgmdT6NnU4Lle8GwGPZsZPJsJns2hZ3OD5wbBswX0bGHwbCF4toSeLQ2eGwXPVtCzlcGzleDZGnq2NnhuEjzbQM82Bs82gmdb6NnW4LlZ8GwHPdsZPNsJnu2hZ3uD5xbBswP07GDw7CB4doSeHQ2eWwXPTtCzk8Gzk+AZQM/A4LlN8OwMPTsbPDsLnl2gZxeD53bBsyv07Grw7Cp4doOe3QyeOwTP7tCzu8Gzu+DZA3r2MHjuFDx7Qs+eBs+egmcv6NnL4LlL8OwNPXsbPHsLnn2gZx+D527Bsy/07Gvw7Ct49oOe/QyeewTP/tCzv8Gzv+A5AHoOMHjuFTwHQs+BBs+Bgucg6DnI4LlP8BwMPQcbPAcLnkOg5xCD537Bcyj0HGrwHCp4DoOewwyeBwTP4dBzuMFzuOD5N/T82+B5UPAcAT1HGDxHCJ7/QM9/DJ6HBM+R0HOkwXOk4Pkv9PzX4HlY8BwFPUcZPEcJnqOh52iD5xHBcwz0HGPwHCN4joWeYw2eRwXPcdBznMFznOA5HnqON3geEzwnQM8JBs8JgudE6DnR4Hlc8JwEPScZPCcJnpOh52SD5wnBcwr0nGLwnCJ4ToWeUw2eJwXPadBzmsFzmuA5HXpON3ieEjxnQM8ZBs8ZgudM6DnT4Hla8JwFPWcZPGcJnrOh52yD5xnBcw70nGPwnCN4zoWecw2eZwXPedBznsFznuA5H3rON3ieEzwXQM8FBs8FgudC6LnQ4Hle8FwEPRcZPBcJnouh52KD5wXBcwn0XGLwXCJ4LoWeSw2eFwXPZdBzmcFzmeC5HHouN3heEjxXQM8VBs8VgudK6LnS4HlZ8FwFPVcZPFcJnquh52qD5xXBcw30XGPwXCN4roWeaw2eVwXPddBzncFzneC5HnquN3heEzw3QM8NBs8NgudG6LnR4Hld8NwEPTcZPDcJnpuh52aD5w3Bcwv03GLw3CJ4boWeWw2eNwXPbdBzm8Fzm+C5HXpuN3jeEjx3QM8dBs8dgudO6LnT4Hlb8NwFPXcZPHcJnruh526D5x3Bcw/03GPw3CN47oWeew2edwXPfdBzn8Fzn+C5H3ruN3jeEzwPQM8DBs8DgudB6HnQ4Hlf8DwEPQ8ZPA8Jnoeh52GD5wPB8wj0PGLwPCJ4HoWeRw2eDwXPY9DzmMHzmOB5HHoeN3g+EjxPQM8TBs8TgudJ6HnS4PlY8DwFPU8ZPE8Jnqeh52mD5xPB8wz0PGPwPCN4noWeZw2eTwXPc9DznMHznOB5HnqeN3g+EzwvQM8LBs8LgudF6HnR4Plc8LwEPS8ZPC8Jnpeh52WD5wvB8wr0vGLwvCJ4XoWeVw2eLwXPa9DzmsHzmuB5HXpeN3i+EjxvQM8bBs8bgudN6HnT4Pla8LwFPW8ZPG8Jnreh522HZ47//c477f7X/0b4f3f+9y5mOHcq7fC2d//nOyP+vzvv/g93hvNFeCN43oOe9wye9wTP+9DzvsHzreD5AHo+MHg+EDwfQs+HBs93gucj6PnI4PlI8HwMPR8bPN/79H+/8wn0fGLwfCJ4PoWeTw2eEQTPZ9DzmcHzmeD5HHo+N3hGFDxfQM8XBs8XgudL6PnS4BlJ8HwFPV8ZPF8Jnq+h52uDZ2TB8w30fGPwfCN4voWebw2eUQTPd9DzncHzneD5Xnvm+d+7UD2jCp4R2jPPCO1D9wzbDm8bEXpGNHhGEzwjQc9IBs9Igmdk6BnZ4Bld8IwCPaMYPKMInlGhZ1SDZwzBMxr0jGbwjCZ4Roee0Q2eMQXPGNAzhsEzhuAZE3rGNHjGEjxjQc9YBs9Ygmds6Bnb4Blb8IwDPeMYPOMInnGhZ1yDZxzBMx70jGfwjCd4xoee8Q2ecQXPBNAzgcEzgeCZEHomNHjGEzwTQc9EBs9Egmdi6JnY4Blf8EwCPZMYPJMInkmhZ1KDZwLBMxn0TGbwTCZ4JoeeyQ2eCQXPFNAzhcEzheCZEnqmNHgmEjxTQc9UBs9Ugmdq6Jna4JlY8EwDPdMYPNMInmmhZ1qDZxLBMx30TGfwTCd4poee6Q2eSQXPDNAzg8Ezg+D5PvR83+CZTPDMCD0zGjwzCp6ZoGcmg2dywTMz9Mxs8MwseH4APT8weKYQPLNAzywGzyyC54fQ80ODZ0rBMyv0zGrwzCp4fgQ9PzJ4phI8s0HPbAbPbILnx9DzY4NnasEzO/TMbvDMLnh+Aj0/MXimETxzQM8cBs8cguen0PNTg2dawTMn9Mxp8MwpeH4GPT8zeKYTPHNBz1wGz1yC5+fQ83ODZ3rBMzf0zG3wzC14fgE9vzB4ZhA880DPPAbPPILnl9DzS4Pn+4JnXuiZ1+CZV/D8Cnp+ZfDMKHjmg575DJ75BM+voefXBs9Mgmd+6Jnf4Jlf8PwGen5j8MwseBaAngUMngUEz4LQs6DB8wPBsxD0LGTwLCR4fgs9vzV4ZhE8C0PPwgbPwoLnd9DzO4Pnh4JnEehZxOBZRPD8Hnp+b/DMKngWhZ5FDZ5FBc8foOcPBs+PBM9i0LOYwbOY4Pkj9PzR4JlN8CwOPYsbPIsLnj9Bz58Mnh8LniWgZwmDZwnB82fo+bPBM7vgWRJ6ljR4lhQ8f4Gevxg8PxE8S0HPUgbPUoLnr9DzV4NnDsGzNPQsbfAsLXj+Bj1/M3h+KniWgZ5lDJ5lBM/foefvBs+cgmdZ6FnW4FlW8PwDev5h8PxM8CwHPcsZPMsJnn9Czz8NnrkEz/LQs7zBs7zg+Rf0/Mvg+bngWQF6VjB4VhA8K0LPigbP3IJnJehZyeBZSfCsDD0rGzy/EDyrQM8qBs8qgmdV6FnV4JlH8KwGPasZPKsJntWhZ3WD55eCZw3oWcPgWUPwrAk9axo88wqetaBnLYNnLcGzNvSsbfD8SvCsAz3rGDzrCJ51oWddg2c+wbMe9Kxn8KwneNaHnvUNnl8Lng2gZwODZwPBsyH0bGjwzC94NoKejQyejQTPxtCzscHzG8GzCfRsYvBsIng2hZ5NDZ4FBM9m0LOZwbOZ4NkcejY3eBYUPFtAzxYGzxaCZ0vo2dLgWUjwbAU9Wxk8WwmeraFna4Pnt4JnG+jZxuDZRvBsCz3bGjwLC57toGc7g2c7wbM99Gxv8PxO8OwAPTsYPDsInh2hZ0eDZxHBsxP07GTw7CR4BtAzMHh+L3h2hp6dDZ6dBc8u0LOLwbOo4NkVenY1eHYVPLtBz24Gzx8Ez+7Qs7vBs7vg2QN69jB4FhM8e0LPngbPnoJnL+jZy+D5o+DZG3r2Nnj2Fjz7QM8+Bs/igmdf6NnX4NlX8OwHPfsZPH8SPPtDz/4Gz/6C5wDoOcDgWULwHAg9Bxo8Bwqeg6DnIIPnz4LnYOg52OA5WPAcAj2HGDxLCp5DoedQg+dQwXMY9Bxm8PxF8BwOPYcbPIcLnn9Dz78NnqUEzxHQc4TBc4Tg+Q/0/Mfg+avgORJ6jjR4jhQ8/4We/xo8Swueo6DnKIPnKMFzNPQcbfD8TfAcAz3HGDzHCJ5joedYg2cZwXMc9Bxn8BwneI6HnuMNnr8LnhOg5wSD5wTBcyL0nGjwLCt4ToKekwyekwTPydBzssHzD8FzCvScYvCcInhOhZ5TDZ7lBM9p0HOawXOa4Dkdek43eP4peM6AnjMMnjMEz5nQc6bBs7zgOQt6zjJ4zhI8Z0PP2QbPvwTPOdBzjsFzjuA5F3rONXhWEDznQc95Bs95gud86Dnf4FlR8FwAPRcYPBcInguh50KDZyXBcxH0XGTwXCR4Loaeiw2elQXPJdBzicFzieC5FHouNXhWETyXQc9lBs9lgudy6Lnc4FlV8FwBPVcYPFcIniuh50qDZzXBcxX0XGXwXCV4roaeqw2e1QXPNdBzjcFzjeC5FnquNXjWEDzXQc91Bs91gud66Lne4FlT8NwAPTcYPDcInhuh50aDZy3BcxP03GTw3CR4boaemw2etQXPLdBzi8Fzi+C5FXpuNXjWETy3Qc9tBs9tgud26Lnd4FlX8NwBPXcYPHcInjuh506DZz3Bcxf03GXw3CV47oaeuw2e9QXPPdBzj8Fzj+C5F3ruNXg2EDz3Qc99Bs99gud+6Lnf4NlQ8DwAPQ8YPA8Ingeh50GDZyPB8xD0PGTwPCR4Hoaehw2ejQXPI9DziMHziOB5FHoeNXg2ETyPQc9jBs9jgudx6Hnc4NlU8DwBPU8YPE8Inieh50mDZzPB8xT0PGXwPCV4noaepw2ezQXPM9DzjMHzjOB5FnqeNXi2EDzPQc9zBs9zgud56Hne4NlS8LwAPS8YPC8Inheh50WDZyvB8xL0vGTwvCR4Xoaelw2erQXPK9DzisHziuB5FXpeNXi2ETyvQc9rBs9rgud16Hnd4NlW8LwBPW8YPG8Injeh502DZzvB8xb0vGXwvCV43oaetw2e7QXPO9DzjsHzjuB5F3reNXh2EDzvQc97Bs97gud96Hnf4NlR8HwAPR8YPB8Ing+h50ODZyfB8xH0fGTwfCR4Poaejw2egeD5BHo+MXg+ETyfQs+nBs/Ogucz6PnM4PlM8HwOPZ8bPLsIni+g5wuD5wvB8yX0fGnw7Cp4voKerwyerwTP19DztcGzm+D5Bnq+MXi+ETzfQs+3Bs/uguc76PnO4PlO8HyvA/P8712onj0EzwgdmGeEDqF7hm2Ht40IPSMaPHsKnpGgZySDZyTBMzL0jGzw7CV4RoGeUQyeUQTPqNAzqsGzt+AZDXpGM3hGEzyjQ8/oBs8+gmcM6BnD4BlD8IwJPWMaPPsKnrGgZyyDZyzBMzb0jG3w7Cd4xoGecQyecQTPuNAzrsGzv+AZD3rGM3jGEzzjQ8/4Bs8BgmcC6JnA4JlA8EwIPRMaPAcKnomgZyKDZyLBMzH0TGzwHCR4JoGeSQyeSQTPpNAzqcFzsOCZDHomM3gmEzyTQ8/kBs8hgmcK6JnC4JlC8EwJPVMaPIcKnqmgZyqDZyrBMzX0TG3wHCZ4poGeaQyeaQTPtNAzrcFzuOCZDnqmM3imEzzTQ8/0Bs+/Bc8M0DODwTOD4Pk+9Hzf4DlC8MwIPTMaPDMKnpmgZyaD5z+CZ2bomdngmVnw/AB6fmDwHCl4ZoGeWQyeWQTPD6HnhwbPfwXPrNAzq8Ezq+D5EfT8yOA5SvDMBj2zGTyzCZ4fQ8+PDZ6jBc/s0DO7wTO74PkJ9PzE4DlG8MwBPXMYPHMInp9Cz08NnmMFz5zQM6fBM6fg+Rn0/MzgOU7wzAU9cxk8cwmen0PPzw2e4wXP3NAzt8Ezt+D5BfT8wuA5QfDMAz3zGDzzCJ5fQs8vDZ4TBc+80DOvwTOv4PkV9PzK4DlJ8MwHPfMZPPMJnl9Dz68NnpMFz/zQM7/BM7/g+Q30/MbgOUXwLAA9Cxg8CwieBaFnQYPnVMGzEPQsZPAsJHh+Cz2/NXhOEzwLQ8/CBs/Cgud30PM7g+d0wbMI9Cxi8CwieH4PPb83eM4QPItCz6IGz6KC5w/Q8weD50zBsxj0LGbwLCZ4/gg9fzR4zhI8i0PP4gbP4oLnT9DzJ4PnbMGzBPQsYfAsIXj+DD1/NnjOETxLQs+SBs+Sgucv0PMXg+dcwbMU9Cxl8CwleP4KPX81eM4TPEtDz9IGz9KC52/Q8zeD53zBswz0LGPwLCN4/g49fzd4LhA8y0LPsgbPsoLnH9DzD4PnQsGzHPQsZ/AsJ3j+CT3/NHguEjzLQ8/yBs/ygudf0PMvg+diwbMC9Kxg8KwgeFaEnhUNnksEz0rQs5LBs5LgWRl6VjZ4LhU8q0DPKgbPKoJnVehZ1eC5TPCsBj2rGTyrCZ7VoWd1g+dywbMG9Kxh8KwheNaEnjUNnisEz1rQs5bBs5bgWRt61jZ4rhQ860DPOgbPOoJnXehZ1+C5SvCsBz3rGTzrCZ71oWd9g+dqwbMB9Gxg8GwgeDaEng0NnmsEz0bQs5HBs5Hg2Rh6NjZ4rhU8m0DPJgbPJoJnU+jZ1OC5TvBsBj2bGTybCZ7NoWdzg+d6wbMF9Gxh8GwheLaEni0NnhsEz1bQs5XBs5Xg2Rp6tjZ4bhQ820DPNgbPNoJnW+jZ1uC5SfBsBz3bGTzbCZ7toWd7g+dmwbMD9Oxg8OwgeHaEnh0NnlsEz07Qs5PBs5PgGUDPwOC5VfDsDD07Gzw7C55doGcXg+c2wbMr9Oxq8OwqeHaDnt0MntsFz+7Qs7vBs7vg2QN69jB47hA8e0LPngbPnoJnL+jZy+C5U/DsDT17Gzx7C559oGcfg+cuwbMv9Oxr8OwrePaDnv0MnrsFz/7Qs7/Bs7/gOQB6DjB47hE8B0LPgQbPgYLnIOg5yOC5V/AcDD0HGzwHC55DoOcQg+c+wXMo9Bxq8BwqeA6DnsMMnvsFz+HQc7jBc7jg+Tf0/NvgeUDwHAE9Rxg8Rwie/0DPfwyeBwXPkdBzpMFzpOD5L/T81+B5SPAcBT1HGTxHCZ6joedog+dhwXMM9Bxj8BwjeI6FnmMNnkcEz3HQc5zBc5zgOR56jjd4HhU8J0DPCQbPCYLnROg50eB5TPCcBD0nGTwnCZ6Toedkg+dxwXMK9Jxi8JwieE6FnlMNnicEz2nQc5rBc5rgOR16Tjd4nhQ8Z0DPGQbPGYLnTOg50+B5SvCcBT1nGTxnCZ6zoedsg+dpwXMO9Jxj8JwjeM6FnnMNnmcEz3nQc57Bc57gOR96zjd4nhU8F0DPBQbPBYLnQui50OB5TvBcBD0XGTwXCZ6Loedig+d5wXMJ9Fxi8FwieC6FnksNnhcEz2XQc5nBc5nguRx6Ljd4XhQ8V0DPFQbPFYLnSui50uB5SfBcBT1XGTxXCZ6roedqg+dlwXMN9Fxj8FwjeK6FnmsNnlcEz3XQc53Bc53guR56rjd4XhU8N0DPDQbPDYLnRui50eB5TfDcBD03GTw3CZ6boedmg+d1wXML9Nxi8NwieG6FnlsNnjcEz23Qc5vBc5vguR16bjd43hQ8d0DPHQbPHYLnTui50+B5S/DcBT13GTx3CZ67oedug+dtwXMP9Nxj8NwjeO6FnnsNnncEz33Qc5/Bc5/guR967jd43hU8D0DPAwbPA4LnQeh50OB5T/A8BD0PGTwPCZ6Hoedhg+d9wfMI9Dxi8DwieB6FnkcNng8Ez2PQ85jB85jgeRx6Hjd4PhQ8T0DPEwbPE4LnSeh50uD5SPA8BT1PGTxPCZ6noedpg+djwfMM9Dxj8DwjeJ6FnmcNnk8Ez3PQ85zB85zgeR56njd4PhU8L0DPCwbPC4LnReh50eD5TPC8BD0vGTwvCZ6Xoedlg+dzwfMK9Lxi8LwieF6FnlcNni8Ez2vQ85rB85rgeR16Xjd4vhQ8b0DPGwbPG4LnTeh50+D5SvC8BT1vGTxvCZ63oedtg+drwfMO9Lxj8LwjeN6FnncNnm8Ez3vQ857B857geR963jd4vhU8H0DPBwbPB4LnQ+j50OD5TvB8BD0fGTwfCZ6Poedjg+d7Of/3O59AzycGzyeC51Po+dTgGUHwfAY9nxk8nwmez6Hnc4NnRMHzBfR8YfB8IXi+hJ4vDZ6RBM9X0POVwfOV4Pkaer42eEYWPN9AzzcGzzeC51vo+dbgGUXwfAc93xk83wme73Vknv+9C9UzquAZoSPzjNAxdM+w7fC2EaFnRINnNMEzEvSMZPCMJHhGhp6RDZ7RBc8o0DOKwTOK4BkVekY1eMYQPKNBz2gGz2iCZ3ToGd3gGVPwjAE9Yxg8YwieMaFnTINnLMEzFvSMZfCMJXjGhp6xDZ6xBc840DOOwTOO4BkXesY1eMYRPONBz3gGz3iCZ3zoGd/gGVfwTAA9Exg8EwieCaFnQoNnPMEzEfRMZPBMJHgmhp6JDZ7xBc8k0DOJwTOJ4JkUeiY1eCYQPJNBz2QGz2SCZ3LomdzgmVDwTAE9Uxg8UwieKaFnSoNnIsEzFfRMZfBMJXimhp6pDZ6JBc800DONwTON4JkWeqY1eCYRPNNBz3QGz3SCZ3romd7gmVTwzAA9Mxg8Mwie70PP9w2eyQTPjNAzo8Ezo+CZCXpmMngmFzwzQ8/MBs/MgucH0PMDg2cKwTML9Mxi8MwieH4IPT80eKYUPLNCz6wGz6yC50fQ8yODZyrBMxv0zGbwzCZ4fgw9PzZ4phY8s0PP7AbP7ILnJ9DzE4NnGsEzB/TMYfDMIXh+Cj0/NXimFTxzQs+cBs+cgudn0PMzg2c6wTMX9Mxl8MwleH4OPT83eKYXPHNDz9wGz9yC5xfQ8wuDZwbBMw/0zGPwzCN4fgk9vzR4vi945oWeeQ2eeQXPr6DnVwbPjIJnPuiZz+CZT/D8Gnp+bfDMJHjmh575DZ75Bc9voOc3Bs/MgmcB6FnA4FlA8CwIPQsaPD8QPAtBz0IGz0KC57fQ81uDZxbBszD0LGzwLCx4fgc9vzN4fih4FoGeRQyeRQTP76Hn9wbPrIJnUehZ1OBZVPD8AXr+YPD8SPAsBj2LGTyLCZ4/Qs8fDZ7ZBM/i0LO4wbO44PkT9PzJ4Pmx4FkCepYweJYQPH+Gnj8bPLMLniWhZ0mDZ0nB8xfo+YvB8xPBsxT0LGXwLCV4/go9fzV45hA8S0PP0gbP0oLnb9DzN4Pnp4JnGehZxuBZRvD8HXr+bvDMKXiWhZ5lDZ5lBc8/oOcfBs/PBM9y0LOcwbOc4Pkn9PzT4JlL8CwPPcsbPMsLnn9Bz78Mnp8LnhWgZwWDZwXBsyL0rGjwzC14VoKelQyelQTPytCzssHzC8GzCvSsYvCsInhWhZ5VDZ55BM9q0LOawbOa4FkdelY3eH4peNaAnjUMnjUEz5rQs6bBM6/gWQt61jJ41hI8a0PP2gbPrwTPOtCzjsGzjuBZF3rWNXjmEzzrQc96Bs96gmd96Fnf4Pm14NkAejYweDYQPBtCz4YGz/yCZyPo2cjg2UjwbAw9Gxs8vxE8m0DPJgbPJoJnU+jZ1OBZQPBsBj2bGTybCZ7NoWdzg2dBwbMF9Gxh8GwheLaEni0NnoUEz1bQs5XBs5Xg2Rp6tjZ4fit4toGebQyebQTPttCzrcGzsODZDnq2M3i2EzzbQ8/2Bs/vBM8O0LODwbOD4NkRenY0eBYRPDtBz04Gz06CZwA9A4Pn94JnZ+jZ2eDZWfDsAj27GDyLCp5doWdXg2dXwbMb9Oxm8PxB8OwOPbsbPLsLnj2gZw+DZzHBsyf07Gnw7Cl49oKevQyePwqevaFnb4Nnb8GzD/TsY/AsLnj2hZ59DZ59Bc9+0LOfwfMnwbM/9Oxv8OwveA6AngMMniUEz4HQc6DBc6DgOQh6DjJ4/ix4Doaegw2egwXPIdBziMGzpOA5FHoONXgOFTyHQc9hBs9fBM/h0HO4wXO44Pk39Pzb4FlK8BwBPUcYPEcInv9Az38Mnr8KniOh50iD50jB81/o+a/Bs7TgOQp6jjJ4jhI8R0PP0QbP3wTPMdBzjMFzjOA5FnqONXiWETzHQc9xBs9xgud46Dne4Pm74DkBek4weE4QPCdCz4kGz7KC5yToOcngOUnwnAw9Jxs8/xA8p0DPKQbPKYLnVOg51eBZTvCcBj2nGTynCZ7Toed0g+efgucM6DnD4DlD8JwJPWcaPMsLnrOg5yyD5yzBczb0nG3w/EvwnAM95xg85wiec6HnXINnBcFzHvScZ/CcJ3jOh57zDZ4VBc8F0HOBwXOB4LkQei40eFYSPBdBz0UGz0WC52LoudjgWVnwXAI9lxg8lwieS6HnUoNnFcFzGfRcZvBcJnguh57LDZ5VBc8V0HOFwXOF4LkSeq40eFYTPFdBz1UGz1WC52roudrgWV3wXAM91xg81wiea6HnWoNnDcFzHfRcZ/BcJ3iuh57rDZ41Bc8N0HODwXOD4LkRem40eNYSPDdBz00Gz02C52boudngWVvw3AI9txg8twieW6HnVoNnHcFzG/TcZvDcJnhuh57bDZ51Bc8d0HOHwXOH4LkTeu40eNYTPHdBz10Gz12C527oudvgWV/w3AM99xg89wiee6HnXoNnA8FzH/TcZ/DcJ3juh577DZ4NBc8D0POAwfOA4HkQeh40eDYSPA9Bz0MGz0OC52Hoedjg2VjwPAI9jxg8jwieR6HnUYNnE8HzGPQ8ZvA8Jngeh57HDZ5NBc8T0POEwfOE4HkSep40eDYTPE9Bz1MGz1OC52noedrg2VzwPAM9zxg8zwieZ6HnWYNnC8HzHPQ8Z/A8J3ieh57nDZ4tBc8L0POCwfOC4HkRel40eLYSPC9Bz0sGz0uC52Xoedng2VrwvAI9rxg8rwieV6HnVYNnG8HzGvS8ZvC8Jnheh57XDZ5tBc8b0POGwfOG4HkTet40eLYTPG9Bz1sGz1uC523oedvg2V7wvAM97xg87wied6HnXYNnB8HzHvS8Z/C8J3jeh573DZ4dBc8H0POBwfOB4PkQej40eHYSPB9Bz0cGz0eC52Po+djgGQieT6DnE4PnE8HzKfR8avDsLHg+g57PDJ7PBM/n0PO5wbOL4PkCer4weL4QPF9Cz5cGz66C5yvo+crg+UrwfA09Xxs8uwmeb6DnG4PnG8HzLfR8a/DsLni+g57vDJ7vBM/3OjHP/96F6tlD8IzQiXlG6BS6Z9h2eNuI0DOiwbOn4BkJekYyeEYSPCNDz8gGz16CZxToGcXgGUXwjAo9oxo8ewue0aBnNINnNMEzOvSMbvDsI3jGgJ4xDJ4xBM+Y0DOmwbOv4BkLesYyeMYSPGNDz9gGz36CZxzoGcfgGUfwjAs94xo8+wue8aBnPINnPMEzPvSMb/AcIHgmgJ4JDJ4JBM+E0DOhwXOg4JkIeiYyeCYSPBNDz8QGz0GCZxLomcTgmUTwTAo9kxo8BwueyaBnMoNnMsEzOfRMbvAcInimgJ4pDJ4pBM+U0DOlwXOo4JkKeqYyeKYSPFNDz9QGz2GCZxromcbgmUbwTAs90xo8hwue6aBnOoNnOsEzPfRMb/D8W/DMAD0zGDwzCJ7vQ8/3DZ4jBM+M0DOjwTOj4JkJemYyeP4jeGaGnpkNnpkFzw+g5wcGz5GCZxbomcXgmUXw/BB6fmjw/FfwzAo9sxo8swqeH0HPjwyeowTPbNAzm8Ezm+D5MfT82OA5WvDMDj2zGzyzC56fQM9PDJ5jBM8c0DOHwTOH4Pkp9PzU4DlW8MwJPXMaPHMKnp9Bz88MnuMEz1zQM5fBM5fg+Tn0/NzgOV7wzA09cxs8cwueX0DPLwyeEwTPPNAzj8Ezj+D5JfT80uA5UfDMCz3zGjzzCp5fQc+vDJ6TBM980DOfwTOf4Pk19Pza4DlZ8MwPPfMbPPMLnt9Az28MnlMEzwLQs4DBs4DgWRB6FjR4ThU8C0HPQgbPQoLnt9DzW4PnNMGzMPQsbPAsLHh+Bz2/M3hOFzyLQM8iBs8iguf30PN7g+cMwbMo9Cxq8CwqeP4APX8weM4UPItBz2IGz2KC54/Q80eD5yzBszj0LG7wLC54/gQ9fzJ4zhY8S0DPEgbPEoLnz9DzZ4PnHMGzJPQsafAsKXj+Aj1/MXjOFTxLQc9SBs9Sguev0PNXg+c8wbM09Cxt8CwteP4GPX8zeM4XPMtAzzIGzzKC5+/Q83eD5wLBsyz0LGvwLCt4/gE9/zB4LhQ8y0HPcgbPcoLnn9DzT4PnIsGzPPQsb/AsL3j+BT3/MnguFjwrQM8KBs8KgmdF6FnR4LlE8KwEPSsZPCsJnpWhZ2WD51LBswr0rGLwrCJ4VoWeVQ2eywTPatCzmsGzmuBZHXpWN3guFzxrQM8aBs8agmdN6FnT4LlC8KwFPWsZPGsJnrWhZ22D50rBsw70rGPwrCN41oWedQ2eqwTPetCznsGznuBZH3rWN3iuFjwbQM8GBs8GgmdD6NnQ4LlG8GwEPRsZPBsJno2hZ2OD51rBswn0bGLwbCJ4NoWeTQ2e6wTPZtCzmcGzmeDZHHo2N3iuFzxbQM8WBs8WgmdL6NnS4LlB8GwFPVsZPFsJnq2hZ2uD50bBsw30bGPwbCN4toWebQ2emwTPdtCzncGzneDZHnq2N3huFjw7QM8OBs8OgmdH6NnR4LlF8OwEPTsZPDsJngH0DAyeWwXPztCzs8Gzs+DZBXp2MXhuEzy7Qs+uBs+ugmc36NnN4Lld8OwOPbsbPLsLnj2gZw+D5w7Bsyf07Gnw7Cl49oKevQyeOwXP3tCzt8Gzt+DZB3r2MXjuEjz7Qs++Bs++gmc/6NnP4Llb8OwPPfsbPPsLngOg5wCD5x7BcyD0HGjwHCh4DoKegwyeewXPwdBzsMFzsOA5BHoOMXjuEzyHQs+hBs+hgucw6DnM4Llf8BwOPYcbPIcLnn9Dz78NngcEzxHQc4TBc4Tg+Q/0/MfgeVDwHAk9Rxo8Rwqe/0LPfw2ehwTPUdBzlMFzlOA5GnqONngeFjzHQM8xBs8xgudY6DnW4HlE8BwHPccZPMcJnuOh53iD51HBcwL0nGDwnCB4ToSeEw2exwTPSdBzksFzkuA5GXpONngeFzynQM8pBs8pgudU6DnV4HlC8JwGPacZPKcJntOh53SD50nBcwb0nGHwnCF4zoSeMw2epwTPWdBzlsFzluA5G3rONnieFjznQM85Bs85gudc6DnX4HlG8JwHPecZPOcJnvOh53yD51nBcwH0XGDwXCB4LoSeCw2e5wTPRdBzkcFzkeC5GHouNnieFzyXQM8lBs8lgudS6LnU4HlB8FwGPZcZPJcJnsuh53KD50XBcwX0XGHwXCF4roSeKw2elwTPVdBzlcFzleC5GnquNnheFjzXQM81Bs81guda6LnW4HlF8FwHPdcZPNcJnuuh53qD51XBcwP03GDw3CB4boSeGw2e1wTPTdBzk8Fzk+C5GXpuNnheFzy3QM8tBs8tgudW6LnV4HlD8NwGPbcZPLcJntuh53aD503Bcwf03GHw3CF47oSeOw2etwTPXdBzl8Fzl+C5G3ruNnjeFjz3QM89Bs89gude6LnX4HlH8NwHPfcZPPcJnvuh536D513B8wD0PGDwPCB4HoSeBw2e9wTPQ9DzkMHzkOB5GHoeNnjeFzyPQM8jBs8jgudR6HnU4PlA8DwGPY8ZPI8Jnseh53GD50PB8wT0PGHwPCF4noSeJw2ejwTPU9DzlMHzlOB5GnqeNng+FjzPQM8zBs8zgudZ6HnW4PlE8DwHPc8ZPM8Jnueh53mD51PB8wL0vGDwvCB4XoSeFw2ezwTPS9DzksHzkuB5GXpeNng+FzyvQM8rBs8rgudV6HnV4PlC8LwGPa8ZPK8Jnteh53WD50vB8wb0vGHwvCF43oSeNw2erwTPW9DzlsHzluB5G3reNni+FjzvQM87Bs87gudd6HnX4PlG8LwHPe8ZPO8Jnveh532D51vB8wH0fGDwfCB4PoSeDw2e7wTPR9DzkcHzkeD5GHo+Nni+99n/fucT6PnE4PlE8HwKPZ8aPCMIns+g5zOD5zPB8zn0fG7wjCh4voCeLwyeLwTPl9DzpcEzkuD5Cnq+Mni+EjxfQ8/XBs/Igucb6PnG4PlG8HwLPd8aPKMInu+g5zuD5zvB872Aef73LlTPqIJnhIB5RghC9wzbDm8bMWCeEYPQPaMJnpEC5hkpCN0zbDu8beSAeUYOQveMLnhGCZhnlCB0z7Dt8LZRA+YZNQjdM4bgGS1gntGC0D3DtsPbRg+YZ/QgdM+YgmeMgHnGCEL3DNsObxszYJ4xg9A9YwmesQLmGSsI3TNsO7xt7IB5xg5C94wteMYJmGecIHTPsO3wtnED5hk3CN0zjuAZL2Ce8YLQPcO2w9vGD5hn/CB0z7iCZ4KAeSYIQvcM2w5vmzBgngmD0D3jCZ6JAuaZKAjdM2w7vG3igHkmDkL3jC94JgmYZ5IgdM+w7fC2SQPmmTQI3TOB4JksYJ7JgtA9w7bD2yYPmGfyIHTPhIJnioB5pghC9wzbDm+bMmCeKYPQPRMJnqkC5pkqCN0zbDu8beqAeaYOQvdMLHimCZhnmiB0z7Dt8LZpA+aZNgjdM4ngmS5gnumC0D3DtsPbpg+YZ/ogdM+kgmeGgHlmCEL3DNsOb/t+wDzfD0L3TCZ4ZgyYZ8YgdM+w7fC2mQLmmSkI3TO54Jk5YJ6Zg9A9w7bD234QMM8PgtA9UwieWQLmmSUI3TNsO7zthwHz/DAI3TOl4Jk1YJ5Zg9A9w7bD234UMM+PgtA9Uwme2QLmmS0I3TNsO7ztxwHz/DgI3TO14Jk9YJ7Zg9A9w7bD234SMM9PgtA90wieOQLmmSMI3TNsO7ztpwHz/DQI3TOt4JkzYJ45g9A9w7bD234WMM/PgtA90wmeuQLmmSsI3TNsO7zt5wHz/DwI3TO94Jk7YJ65g9A9w7bD234RMM8vgtA9MwieeQLmmScI3TNsO7ztlwHz/DII3fN9wTNvwDzzBqF7hm2Ht/0qYJ5fBaF7ZhQ88wXMM18QumfYdnjbrwPm+XUQumcmwTN/wDzzB6F7hm2Ht/0mYJ7fBKF7ZhY8CwTMs0AQumfYdnjbggHzLBiE7vmB4FkoYJ6FgtA9w7bD234bMM9vg9A9swiehQPmWTgI3TNsO7ztdwHz/C4I3fNDwbNIwDyLBKF7hm2Ht/0+YJ7fB6F7ZhU8iwbMs2gQumfYdnjbHwLm+UMQuudHgmexgHkWC0L3DNsOb/tjwDx/DEL3zCZ4Fg+YZ/EgdM+w7fC2PwXM86cgdM+PBc8SAfMsEYTuGbYd3vbngHn+HITumV3wLBkwz5JB6J5h2+FtfwmY5y9B6J6fCJ6lAuZZKgjdM2w7vO2vAfP8NQjdM4fgWTpgnqWD0D3DtsPb/hYwz9+C0D0/FTzLBMyzTBC6Z9h2eNvfA+b5exC6Z07Bs2zAPMsGoXuGbYe3/SNgnn8EoXt+JniWC5hnuSB0z7Dt8LZ/BszzzyB0z1yCZ/mAeZYPQvcM2w5v+1fAPP8KQvf8XPCsEDDPCkHonmHb4W0rBsyzYhC6Z27Bs1LAPCsFoXuGbYe3rRwwz8pB6J5fCJ5VAuZZJQjdM2w7vG3VgHlWDUL3zCN4VguYZ7UgdM+w7fC21QPmWT0I3fNLwbNGwDxrBKF7hm2Ht60ZMM+aQeieeQXPWgHzrBWE7hm2Hd62dsA8awehe34leNYJmGedIHTPsO3wtnUD5lk3CN0zn+BZL2Ce9YLQPcO2w9vWD5hn/SB0z68FzwYB82wQhO4Zth3etmHAPBsGoXvmFzwbBcyzURC6Z9h2eNvGAfNsHITu+Y3g2SRgnk2C0D3DtsPbNg2YZ9MgdM8CgmezgHk2C0L3DNsOb9s8YJ7Ng9A9CwqeLQLm2SII3TNsO7xty4B5tgxC9ywkeLYKmGerIHTPsO3wtq0D5tk6CN3zW8GzTcA82wShe4Zth7dtGzDPtkHonoUFz3YB82wXhO4Zth3etn3APNsHoXt+J3h2CJhnhyB0z7Dt8LYdA+bZMQjds4jg2Slgnp2C0D3DtsPbBgHzDILQPb8XPDsHzLNzELpn2HZ42y4B8+wShO5ZVPDsGjDPrkHonmHb4W27BcyzWxC65w+CZ/eAeXYPQvcM2w5v2yNgnj2C0D2LCZ49A+bZMwjdM2w7vG2vgHn2CkL3/FHw7B0wz95B6J5h2+Ft+wTMs08QumdxwbNvwDz7BqF7hm2Ht+0XMM9+QeiePwme/QPm2T8I3TNsO7ztgIB5DghC9ywheA4MmOfAIHTPsO3wtoMC5jkoCN3zZ8FzcMA8Bwehe4Zth7cdEjDPIUHoniUFz6EB8xwahO4Zth3edljAPIcFoXv+IngOD5jn8CB0z7Dt8LZ/B8zz7yB0z1KC54iAeY4IQvcM2w5v+0/APP8JQvf8VfAcGTDPkUHonmHb4W3/DZjnv0HonqUFz1EB8xwVhO4Zth3ednTAPEcHoXv+JniOCZjnmCB0z7Dt8LZjA+Y5Ngjds4zgOS5gnuOC0D3DtsPbjg+Y5/ggdM/fBc8JAfOcEITuGbYd3nZiwDwnBqF7lhU8JwXMc1IQumfYdnjbyQHznByE7vmH4DklYJ5TgtA9w7bD204NmOfUIHTPcoLntIB5TgtC9wzbDm87PWCe04PQPf8UPGcEzHNGELpn2HZ425kB85wZhO5ZXvCcFTDPWUHonmHb4W1nB8xzdhC651+C55yAec4JQvcM2w5vOzdgnnOD0D0rCJ7zAuY5LwjdM2w7vO38gHnOD0L3rCh4LgiY54IgdM+w7fC2CwPmuTAI3bOS4LkoYJ6LgtA9w7bD2y4OmOfiIHTPyoLnkoB5LglC9wzbDm+7NGCeS4PQPasInssC5rksCN0zbDu87fKAeS4PQvesKniuCJjniiB0z7Dt8LYrA+a5Mgjds5rguSpgnquC0D3DtsPbrg6Y5+ogdM/qgueagHmuCUL3DNsOb7s2YJ5rg9A9awie6wLmuS4I3TNsO7zt+oB5rg9C96wpeG4ImOeGIHTPsO3wthsD5rkxCN2zluC5KWCem4LQPcO2w9tuDpjn5iB0z9qC55aAeW4JQvcM2w5vuzVgnluD0D3rCJ7bAua5LQjdM2w7vO32gHluD0L3rCt47giY544gdM+w7fC2OwPmuTMI3bOe4LkrYJ67gtA9w7bD2+4OmOfuIHTP+oLnnoB57glC9wzbDm+7N2Cee4PQPRsInvsC5rkvCN0zbDu87f6Aee4PQvdsKHgeCJjngSB0z7Dt8LYHA+Z5MAjds5HgeShgnoeC0D3DtsPbHg6Y5+EgdM/GgueRgHkeCUL3DNsOb3s0YJ5Hg9A9mwiexwLmeSwI3TNsO7zt8YB5Hg9C92wqeJ4ImOeJIHTPsO3wticD5nkyCN2zmeB5KmCep4LQPcO2w9ueDpjn6SB0z+aC55mAeZ4JQvcM2w5vezZgnmeD0D1bCJ7nAuZ5LgjdM2w7vO35gHmeD0L3bCl4XgiY54UgdM+w7fC2FwPmeTEI3bOV4HkpYJ6XgtA9w7bD214OmOflIHTP1oLnlYB5XglC9wzbDm97NWCeV4PQPdsIntcC5nktCN0zbDu87fWAeV4PQvdsK3jeCJjnjSB0z7Dt8LY3A+Z5Mwjds53geStgnreC0D3DtsPb3g6Y5+0gdM/2guedgHneCUL3DNsOb3s3YJ53g9A9Owie9wLmeS8I3TNsO7zt/YB53g9C9+woeD4ImOeDIHTPsO3wtg8D5vkwCN2zk+D5KGCej4LQPcO2w9s+Dpjn4yB0z0DwfBIwzydB6J5h2+FtnwbM82kQumdnwfNZwDyfBaF7hm2Ht30eMM/nQeieXQTPFwHzfBGE7hm2Hd72ZcA8Xwahe3YVPF8FzPNVELpn2HZ429cB83wdhO7ZTfB8EzDPN0HonmHb4W3fBszzbRC6Z3fB813APN8FoXuGbYe3fa8z8/zvXaiePQTPCJ2ZZ4TOoXuGbYe3jQg9Ixo8ewqekaBnJINnJMEzMvSMbPDsJXhGgZ5RDJ5RBM+o0DOqwbO34BkNekYzeEYTPKNDz+gGzz6CZwzoGcPgGUPwjAk9Yxo8+wqesaBnLINnLMEzNvSMbfDsJ3jGgZ5xDJ5xBM+40DOuwbO/4BkPesYzeMYTPONDz/gGzwGCZwLomcDgmUDwTAg9Exo8BwqeiaBnIoNnIsEzMfRMbPAcJHgmgZ5JDJ5JBM+k0DOpwXOw4JkMeiYzeCYTPJNDz+QGzyGCZwromcLgmULwTAk9Uxo8hwqeqaBnKoNnKsEzNfRMbfAcJnimgZ5pDJ5pBM+00DOtwXO44JkOeqYzeKYTPNNDz/QGz78FzwzQM4PBM4Pg+T70fN/gOULwzAg9Mxo8MwqemaBnJoPnP4JnZuiZ2eCZWfD8AHp+YPAcKXhmgZ5ZDJ5ZBM8PoeeHBs9/Bc+s0DOrwTOr4PkR9PzI4DlK8MwGPbMZPLMJnh9Dz48NnqMFz+zQM7vBM7vg+Qn0/MTgOUbwzAE9cxg8cwien0LPTw2eYwXPnNAzp8Ezp+D5GfT8zOA5TvDMBT1zGTxzCZ6fQ8/PDZ7jBc/c0DO3wTO34PkF9PzC4DlB8MwDPfMYPPMInl9Czy8NnhMFz7zQM6/BM6/g+RX0/MrgOUnwzAc98xk88wmeX0PPrw2ekwXP/NAzv8Ezv+D5DfT8xuA5RfAsAD0LGDwLCJ4FoWdBg+dUwbMQ9Cxk8CwkeH4LPb81eE4TPAtDz8IGz8KC53fQ8zuD53TBswj0LGLwLCJ4fg89vzd4zhA8i0LPogbPooLnD9DzB4PnTMGzGPQsZvAsJnj+CD1/NHjOEjyLQ8/iBs/igudP0PMng+dswbME9Cxh8CwheP4MPX82eM4RPEtCz5IGz5KC5y/Q8xeD51zBsxT0LGXwLCV4/go9fzV4zhM8S0PP0gbP0oLnb9DzN4PnfMGzDPQsY/AsI3j+Dj1/N3guEDzLQs+yBs+ygucf0PMPg+dCwbMc9Cxn8CwneP4JPf80eC4SPMtDz/IGz/KC51/Q8y+D52LBswL0rGDwrCB4VoSeFQ2eSwTPStCzksGzkuBZGXpWNnguFTyrQM8qBs8qgmdV6FnV4LlM8KwGPasZPKsJntWhZ3WD53LBswb0rGHwrCF41oSeNQ2eKwTPWtCzlsGzluBZG3rWNniuFDzrQM86Bs86gmdd6FnX4LlK8KwHPesZPOsJnvWhZ32D52rBswH0bGDwbCB4NoSeDQ2eawTPRtCzkcGzkeDZGHo2NniuFTybQM8mBs8mgmdT6NnU4LlO8GwGPZsZPJsJns2hZ3OD53rBswX0bGHwbCF4toSeLQ2eGwTPVtCzlcGzleDZGnq2NnhuFDzbQM82Bs82gmdb6NnW4LlJ8GwHPdsZPNsJnu2hZ3uD52bBswP07GDw7CB4doSeHQ2eWwTPTtCzk8Gzk+AZQM/A4LlV8OwMPTsbPDsLnl2gZxeD5zbBsyv07Grw7Cp4doOe3Qye2wXP7tCzu8Gzu+DZA3r2MHjuEDx7Qs+eBs+egmcv6NnL4LlT8OwNPXsbPHsLnn2gZx+D5y7Bsy/07Gvw7Ct49oOe/QyeuwXP/tCzv8Gzv+A5AHoOMHjuETwHQs+BBs+Bgucg6DnI4LlX8BwMPQcbPAcLnkOg5xCD5z7Bcyj0HGrwHCp4DoOewwye+wXP4dBzuMFzuOD5N/T82+B5QPAcAT1HGDxHCJ7/QM9/DJ4HBc+R0HOkwXOk4Pkv9PzX4HlI8BwFPUcZPEcJnqOh52iD52HBcwz0HGPwHCN4joWeYw2eRwTPcdBznMFznOA5HnqON3geFTwnQM8JBs8JgudE6DnR4HlM8JwEPScZPCcJnpOh52SD53HBcwr0nGLwnCJ4ToWeUw2eJwTPadBzmsFzmuA5HXpON3ieFDxnQM8ZBs8ZgudM6DnT4HlK8JwFPWcZPGcJnrOh52yD52nBcw70nGPwnCN4zoWecw2eZwTPedBznsFznuA5H3rON3ieFTwXQM8FBs8FgudC6LnQ4HlO8FwEPRcZPBcJnouh52KD53nBcwn0XGLwXCJ4LoWeSw2eFwTPZdBzmcFzmeC5HHouN3heFDxXQM8VBs8VgudK6LnS4HlJ8FwFPVcZPFcJnquh52qD52XBcw30XGPwXCN4roWeaw2eVwTPddBzncFzneC5HnquN3heFTw3QM8NBs8NgudG6LnR4HlN8NwEPTcZPDcJnpuh52aD53XBcwv03GLw3CJ4boWeWw2eNwTPbdBzm8Fzm+C5HXpuN3jeFDx3QM8dBs8dgudO6LnT4HlL8NwFPXcZPHcJnruh526D523Bcw/03GPw3CN47oWeew2edwTPfdBzn8Fzn+C5H3ruN3jeFTwPQM8DBs8DgudB6HnQ4HlP8DwEPQ8ZPA8Jnoeh52GD533B8wj0PGLwPCJ4HoWeRw2eDwTPY9DzmMHzmOB5HHoeN3g+FDxPQM8TBs8TgudJ6HnS4PlI8DwFPU8ZPE8Jnqeh52mD52PB8wz0PGPwPCN4noWeZw2eTwTPc9DznMHznOB5HnqeN3g+FTwvQM8LBs8LgudF6HnR4PlM8LwEPS8ZPC8Jnpeh52WD53PB8wr0vGLwvCJ4XoWeVw2eLwTPa9DzmsHzmuB5HXpeN3i+FDxvQM8bBs8bgudN6HnT4PlK8LwFPW8ZPG8Jnreh522D52vB8w70vGPwvCN43oWedw2ebwTPe9DznsHznuB5H3reN3i+FTwfQM8HBs8HgudD6PnQ4PlO8HwEPR8ZPB8Jno+h52OD53u5/vc7n0DPJwbPJ4LnU+j51OAZQfB8Bj2fGTyfCZ7Poedzg2dEwfMF9Hxh8HwheL6Eni8NnpEEz1fQ85XB85Xg+Rp6vjZ4RhY830DPNwbPN4LnW+j51uAZRfB8Bz3fGTzfCZ7vdWGe/70L1TOq4BmhC/OM0CV0z7Dt8LYRoWdEg2c0wTMS9Ixk8IwkeEaGnpENntEFzyjQM4rBM4rgGRV6RjV4xhA8o0HPaAbPaIJndOgZ3eAZU/CMAT1jGDxjCJ4xoWdMg2cswTMW9Ixl8IwleMaGnrENnrEFzzjQM47BM47gGRd6xjV4xhE840HPeAbPeIJnfOgZ3+AZV/BMAD0TGDwTCJ4JoWdCg2c8wTMR9Exk8EwkeCaGnokNnvEFzyTQM4nBM4ngmRR6JjV4JhA8k0HPZAbPZIJncuiZ3OCZUPBMAT1TGDxTCJ4poWdKg2ciwTMV9Exl8EwleKaGnqkNnokFzzTQM43BM43gmRZ6pjV4JhE800HPdAbPdIJneuiZ3uCZVPDMAD0zGDwzCJ7vQ8/3DZ7JBM+M0DOjwTOj4JkJemYyeCYXPDNDz8wGz8yC5wfQ8wODZwrBMwv0zGLwzCJ4fgg9PzR4phQ8s0LPrAbPrILnR9DzI4NnKsEzG/TMZvDMJnh+DD0/NnimFjyzQ8/sBs/sgucn0PMTg2cawTMH9Mxh8MwheH4KPT81eKYVPHNCz5wGz5yC52fQ8zODZzrBMxf0zGXwzCV4fg49Pzd4phc8c0PP3AbP3ILnF9DzC4NnBsEzD/TMY/DMI3h+CT2/NHi+L3jmhZ55DZ55Bc+voOdXBs+Mgmc+6JnP4JlP8Pwaen5t8MwkeOaHnvkNnvkFz2+g5zcGz8yCZwHoWcDgWUDwLAg9Cxo8PxA8C0HPQgbPQoLnt9DzW4NnFsGzMPQsbPAsLHh+Bz2/M3h+KHgWgZ5FDJ5FBM/voef3Bs+sgmdR6FnU4FlU8PwBev5g8PxI8CwGPYsZPIsJnj9Czx8NntkEz+LQs7jBs7jg+RP0/Mng+bHgWQJ6ljB4lhA8f4aePxs8swueJaFnSYNnScHzF+j5i8HzE8GzFPQsZfAsJXj+Cj1/NXjmEDxLQ8/SBs/Sgudv0PM3g+engmcZ6FnG4FlG8Pwdev5u8MwpeJaFnmUNnmUFzz+g5x8Gz88Ez3LQs5zBs5zg+Sf0/NPgmUvwLA89yxs8ywuef0HPvwyenwueFaBnBYNnBcGzIvSsaPDMLXhWgp6VDJ6VBM/K0LOywfMLwbMK9Kxi8KwieFaFnlUNnnkEz2rQs5rBs5rgWR16Vjd4fil41oCeNQyeNQTPmtCzpsEzr+BZC3rWMnjWEjxrQ8/aBs+vBM860LOOwbOO4FkXetY1eOYTPOtBz3oGz3qCZ33oWd/g+bXg2QB6NjB4NhA8G0LPhgbP/IJnI+jZyODZSPBsDD0bGzy/ETybQM8mBs8mgmdT6NnU4FlA8GwGPZsZPJsJns2hZ3ODZ0HBswX0bGHwbCF4toSeLQ2ehQTPVtCzlcGzleDZGnq2Nnh+K3i2gZ5tDJ5tBM+20LOtwbOw4NkOerYzeLYTPNtDz/YGz+8Ezw7Qs4PBs4Pg2RF6djR4FhE8O0HPTgbPToJnAD0Dg+f3gmdn6NnZ4NlZ8OwCPbsYPIsKnl2hZ1eDZ1fBsxv07Gbw/EHw7A49uxs8uwuePaBnD4NnMcGzJ/TsafDsKXj2gp69DJ4/Cp69oWdvg2dvwbMP9Oxj8CwuePaFnn0Nnn0Fz37Qs5/B8yfBsz/07G/w7C94DoCeAwyeJQTPgdBzoMFzoOA5CHoOMnj+LHgOhp6DDZ6DBc8h0HOIwbOk4DkUeg41eA4VPIdBz2EGz18Ez+HQc7jBc7jg+Tf0/NvgWUrwHAE9Rxg8Rwie/0DPfwyevwqeI6HnSIPnSMHzX+j5r8GztOA5CnqOMniOEjxHQ8/RBs/fBM8x0HOMwXOM4DkWeo41eJYRPMdBz3EGz3GC53joOd7g+bvgOQF6TjB4ThA8J0LPiQbPsoLnJOg5yeA5SfCcDD0nGzz/EDynQM8pBs8pgudU6DnV4FlO8JwGPacZPKcJntOh53SD55+C5wzoOcPgOUPwnAk9Zxo8ywues6DnLIPnLMFzNvScbfD8S/CcAz3nGDznCJ5zoedcg2cFwXMe9Jxn8JwneM6HnvMNnhUFzwXQc4HBc4HguRB6LjR4VhI8F0HPRQbPRYLnYui52OBZWfBcAj2XGDyXCJ5LoedSg2cVwXMZ9Fxm8FwmeC6HnssNnlUFzxXQc4XBc4XguRJ6rjR4VhM8V0HPVQbPVYLnaui52uBZXfBcAz3XGDzXCJ5roedag2cNwXMd9Fxn8FwneK6HnusNnjUFzw3Qc4PBc4PguRF6bjR41hI8N0HPTQbPTYLnZui52eBZW/DcAj23GDy3CJ5boedWg2cdwXMb9Nxm8NwmeG6HntsNnnUFzx3Qc4fBc4fguRN67jR41hM8d0HPXQbPXYLnbui52+BZX/DcAz33GDz3CJ57oedeg2cDwXMf9Nxn8NwneO6HnvsNng0FzwPQ84DB84DgeRB6HjR4NhI8D0HPQwbPQ4LnYeh52ODZWPA8Aj2PGDyPCJ5HoedRg2cTwfMY9Dxm8DwmeB6HnscNnk0FzxPQ84TB84TgeRJ6njR4NhM8T0HPUwbPU4Lnaeh52uDZXPA8Az3PGDzPCJ5noedZg2cLwfMc9Dxn8DwneJ6HnucNni0FzwvQ84LB84LgeRF6XjR4thI8L0HPSwbPS4LnZeh52eDZWvC8Aj2vGDyvCJ5XoedVg2cbwfMa9Lxm8LwmeF6HntcNnm0FzxvQ84bB84bgeRN63jR4thM8b0HPWwbPW4Lnbeh52+DZXvC8Az3vGDzvCJ53oeddg2cHwfMe9Lxn8LwneN6HnvcNnh0FzwfQ84HB84Hg+RB6PjR4dhI8H0HPRwbPR4LnY+j52OAZCJ5PoOcTg+cTwfMp9Hxq8OwseD6Dns8Mns8Ez+fQ87nBs4vg+QJ6vjB4vhA8X0LPlwbProLnK+j5yuD5SvB8DT1fGzy7CZ5voOcbg+cbwfMt9Hxr8OwueL6Dnu8Mnu8Ez/e6Ms//3oXq2UPwjNCVeUboGrpn2HZ424jQM6LBs6fgGQl6RjJ4RhI8I0PPyAbPXoJnFOgZxeAZRfCMCj2jGjx7C57RoGc0g2c0wTM69Ixu8OwjeMaAnjEMnjEEz5jQM6bBs6/gGQt6xjJ4xhI8Y0PP2AbPfoJnHOgZx+AZR/CMCz3jGjz7C57xoGc8g2c8wTM+9Ixv8BwgeCaAngkMngkEz4TQM6HBc6DgmQh6JjJ4JhI8E0PPxAbPQYJnEuiZxOCZRPBMCj2TGjwHC57JoGcyg2cywTM59Exu8BwieKaAnikMnikEz5TQM6XBc6jgmQp6pjJ4phI8U0PP1AbPYYJnGuiZxuCZRvBMCz3TGjyHC57poGc6g2c6wTM99Exv8Pxb8MwAPTMYPDMInu9Dz/cNniMEz4zQM6PBM6PgmQl6ZjJ4/iN4ZoaemQ2emQXPD6DnBwbPkYJnFuiZxeCZRfD8EHp+aPD8V/DMCj2zGjyzCp4fQc+PDJ6jBM9s0DObwTOb4Pkx9PzY4Dla8MwOPbMbPLMLnp9Az08MnmMEzxzQM4fBM4fg+Sn0/NTgOVbwzAk9cxo8cwqen0HPzwye4wTPXNAzl8Ezl+D5OfT83OA5XvDMDT1zGzxzC55fQM8vDJ4TBM880DOPwTOP4Pkl9PzS4DlR8MwLPfMaPPMKnl9Bz68MnpMEz3zQM5/BM5/g+TX0/NrgOVnwzA898xs88wue30DPbwyeUwTPAtCzgMGzgOBZEHoWNHhOFTwLQc9CBs9Cgue30PNbg+c0wbMw9Cxs8CwseH4HPb8zeE4XPItAzyIGzyKC5/fQ83uD5wzBsyj0LGrwLCp4/gA9fzB4zhQ8i0HPYgbPYoLnj9DzR4PnLMGzOPQsbvAsLnj+BD1/MnjOFjxLQM8SBs8SgufP0PNng+ccwbMk9Cxp8CwpeP4CPX8xeM4VPEtBz1IGz1KC56/Q81eD5zzBszT0LG3wLC14/gY9fzN4zhc8y0DPMgbPMoLn79Dzd4PnAsGzLPQsa/AsK3j+AT3/MHguFDzLQc9yBs9yguef0PNPg+ciwbM89Cxv8CwveP4FPf8yeC4WPCtAzwoGzwqCZ0XoWdHguUTwrAQ9Kxk8KwmelaFnZYPnUsGzCvSsYvCsInhWhZ5VDZ7LBM9q0LOawbOa4FkdelY3eC4XPGtAzxoGzxqCZ03oWdPguULwrAU9axk8awmetaFnbYPnSsGzDvSsY/CsI3jWhZ51DZ6rBM960LOewbOe4FkfetY3eK4WPBtAzwYGzwaCZ0Po2dDguUbwbAQ9Gxk8GwmejaFnY4PnWsGzCfRsYvBsIng2hZ5NDZ7rBM9m0LOZwbOZ4NkcejY3eK4XPFtAzxYGzxaCZ0vo2dLguUHwbAU9Wxk8WwmeraFna4PnRsGzDfRsY/BsI3i2hZ5tDZ6bBM920LOdwbOd4NkeerY3eG4WPDtAzw4Gzw6CZ0fo2dHguUXw7AQ9Oxk8OwmeAfQMDJ5bBc/O0LOzwbOz4NkFenYxeG4TPLtCz64Gz66CZzfo2c3guV3w7A49uxs8uwuePaBnD4PnDsGzJ/TsafDsKXj2gp69DJ47Bc/e0LO3wbO34NkHevYxeO4SPPtCz74Gz76CZz/o2c/guVvw7A89+xs8+wueA6DnAIPnHsFzIPQcaPAcKHgOgp6DDJ57Bc/B0HOwwXOw4DkEeg4xeO4TPIdCz6EGz6GC5zDoOczguV/wHA49hxs8hwuef0PPvw2eBwTPEdBzhMFzhOD5D/T8x+B5UPAcCT1HGjxHCp7/Qs9/DZ6HBM9R0HOUwXOU4Dkaeo42eB4WPMdAzzEGzzGC51joOdbgeUTwHAc9xxk8xwme46HneIPnUcFzAvScYPCcIHhOhJ4TDZ7HBM9J0HOSwXOS4DkZek42eB4XPKdAzykGzymC51ToOdXgeULwnAY9pxk8pwme06HndIPnScFzBvScYfCcIXjOhJ4zDZ6nBM9Z0HOWwXOW4Dkbes42eJ4WPOdAzzkGzzmC51zoOdfgeUbwnAc95xk85wme86HnfIPnWcFzAfRcYPBcIHguhJ4LDZ7nBM9F0HORwXOR4LkYei42eJ4XPJdAzyUGzyWC51LoudTgeUHwXAY9lxk8lwmey6HncoPnRcFzBfRcYfBcIXiuhJ4rDZ6XBM9V0HOVwXOV4Lkaeq42eF4WPNdAzzUGzzWC51roudbgeUXwXAc91xk81wme66HneoPnVcFzA/TcYPDcIHhuhJ4bDZ7XBM9N0HOTwXOT4LkZem42eF4XPLdAzy0Gzy2C51boudXgeUPw3AY9txk8twme26HndoPnTcFzB/TcYfDcIXjuhJ47DZ63BM9d0HOXwXOX4Lkbeu42eN4WPPdAzz0Gzz2C517oudfgeUfw3Ac99xk89wme+6HnfoPnXcHzAPQ8YPA8IHgehJ4HDZ73BM9D0POQwfOQ4HkYeh42eN4XPI9AzyMGzyOC51HoedTg+UDwPAY9jxk8jwmex6HncYPnQ8HzBPQ8YfA8IXiehJ4nDZ6PBM9T0POUwfOU4Hkaep42eD4WPM9AzzMGzzOC51noedbg+UTwPAc9zxk8zwme56HneYPnU8HzAvS8YPC8IHhehJ4XDZ7PBM9L0POSwfOS4HkZel42eD4XPK9AzysGzyuC51XoedXg+ULwvAY9rxk8rwme16HndYPnS8HzBvS8YfC8IXjehJ43HZ65//c7b/1vd0Z79zb9/7vzv3eZwrlTaYe3vf2/3Rnv3euC/+/O2//DneF8EV4Jnneg5x2D5x3B8y70vGvwfC143oOe9wye9wTP+9DzvsHzjeD5AHo+MHg+EDwfQs+HBs+3gucj6PnI4PlI8HwMPR8bPN8Jnk+g5xOD5xPB8yn0fGrwfO+L//3OZ9DzmcHzmeD5HHo+N3hGEDxfQM8XBs8XgudL6PnS4BlR8HwFPV8ZPF8Jnq+h52uDZyTB8w30fGPwfCN4voWebw2ekQXPd9DzncHzneD5Xjfm+d+7UD2jCJ4RujHPCN1C9wzbDm8bEXpGNHhGFTwjQc9IBs9Igmdk6BnZ4BlN8IwCPaMYPKMInlGhZ1SDZ3TBMxr0jGbwjCZ4Roee0Q2eMQTPGNAzhsEzhuAZE3rGNHjGFDxjQc9YBs9Ygmds6Bnb4BlL8IwDPeMYPOMInnGhZ1yDZ2zBMx70jGfwjCd4xoee8Q2ecQTPBNAzgcEzgeCZEHomNHjGFTwTQc9EBs9Egmdi6JnY4BlP8EwCPZMYPJMInkmhZ1KDZ3zBMxn0TGbwTCZ4JoeeyQ2eCQTPFNAzhcEzheCZEnqmNHgmFDxTQc9UBs9Ugmdq6Jna4JlI8EwDPdMYPNMInmmhZ1qDZ2LBMx30TGfwTCd4poee6Q2eSQTPDNAzg8Ezg+D5PvR83+CZVPDMCD0zGjwzCp6ZoGcmg2cywTMz9Mxs8MwseH4APT8weCYXPLNAzywGzyyC54fQ80ODZwrBMyv0zGrwzCp4fgQ9PzJ4phQ8s0HPbAbPbILnx9DzY4NnKsEzO/TMbvDMLnh+Aj0/MXimFjxzQM8cBs8cguen0PNTg2cawTMn9Mxp8MwpeH4GPT8zeKYVPHNBz1wGz1yC5+fQ83ODZzrBMzf0zG3wzC14fgE9vzB4phc880DPPAbPPILnl9DzS4NnBsEzL/TMa/DMK3h+BT2/Mni+L3jmg575DJ75BM+voefXBs+Mgmd+6Jnf4Jlf8PwGen5j8MwkeBaAngUMngUEz4LQs6DBM7PgWQh6FjJ4FhI8v4We3xo8PxA8C0PPwgbPwoLnd9DzO4NnFsGzCPQsYvAsInh+Dz2/N3h+KHgWhZ5FDZ5FBc8foOcPBs+sgmcx6FnM4FlM8PwRev5o8PxI8CwOPYsbPIsLnj9Bz58MntkEzxLQs4TBs4Tg+TP0/Nng+bHgWRJ6ljR4lhQ8f4Gevxg8swuepaBnKYNnKcHzV+j5q8HzE8GzNPQsbfAsLXj+Bj1/M3jmEDzLQM8yBs8ygufv0PN3g+engmdZ6FnW4FlW8PwDev5h8MwpeJaDnuUMnuUEzz+h558Gz88Ez/LQs7zBs7zg+Rf0/MvgmUvwrAA9Kxg8KwieFaFnRYPn54JnJehZyeBZSfCsDD0rGzxzC55VoGcVg2cVwbMq9Kxq8PxC8KwGPasZPKsJntWhZ3WDZx7Bswb0rGHwrCF41oSeNQ2eXwqetaBnLYNnLcGzNvSsbfDMK3jWgZ51DJ51BM+60LOuwfMrwbMe9Kxn8KwneNaHnvUNnvkEzwbQs4HBs4Hg2RB6NjR4fi14NoKejQyejQTPxtCzscEzv+DZBHo2MXg2ETybQs+mBs9vBM9m0LOZwbOZ4NkcejY3eBYQPFtAzxYGzxaCZ0vo2dLgWVDwbAU9Wxk8WwmeraFna4NnIcGzDfRsY/BsI3i2hZ5tDZ7fCp7toGc7g2c7wbM99Gxv8CwseHaAnh0Mnh0Ez47Qs6PB8zvBsxP07GTw7CR4BtAzMHgWETw7Q8/OBs/OgmcX6NnF4Pm94NkVenY1eHYVPLtBz24Gz6KCZ3fo2d3g2V3w7AE9exg8fxA8e0LPngbPnoJnL+jZy+BZTPDsDT17Gzx7C559oGcfg+ePgmdf6NnX4NlX8OwHPfsZPIsLnv2hZ3+DZ3/BcwD0HGDw/EnwHAg9Bxo8Bwqeg6DnIINnCcFzMPQcbPAcLHgOgZ5DDJ4/C55DoedQg+dQwXMY9Bxm8CwpeA6HnsMNnsMFz7+h598Gz18EzxHQc4TBc4Tg+Q/0/MfgWUrwHAk9Rxo8Rwqe/0LPfw2evwqeo6DnKIPnKMFzNPQcbfAsLXiOgZ5jDJ5jBM+x0HOswfM3wXMc9Bxn8BwneI6HnuMNnmUEzwnQc4LBc4LgORF6TjR4/i54ToKekwyekwTPydBzssGzrOA5BXpOMXhOETynQs+pBs8/BM9p0HOawXOa4Dkdek43eJYTPGdAzxkGzxmC50zoOdPg+afgOQt6zjJ4zhI8Z0PP2QbP8oLnHOg5x+A5R/CcCz3nGjz/EjznQc95Bs95gud86Dnf4FlB8FwAPRcYPBcInguh50KDZ0XBcxH0XGTwXCR4Loaeiw2elQTPJdBzicFzieC5FHouNXhWFjyXQc9lBs9lgudy6Lnc4FlF8FwBPVcYPFcIniuh50qDZ1XBcxX0XGXwXCV4roaeqw2e1QTPNdBzjcFzjeC5FnquNXhWFzzXQc91Bs91gud66Lne4FlD8NwAPTcYPDcInhuh50aDZ03BcxP03GTw3CR4boaemw2etQTPLdBzi8Fzi+C5FXpuNXjWFjy3Qc9tBs9tgud26Lnd4FlH8NwBPXcYPHcInjuh506DZ13Bcxf03GXw3CV47oaeuw2e9QTPPdBzj8Fzj+C5F3ruNXjWFzz3Qc99Bs99gud+6Lnf4NlA8DwAPQ8YPA8Ingeh50GDZ0PB8xD0PGTwPCR4Hoaehw2ejQTPI9DziMHziOB5FHoeNXg2FjyPQc9jBs9jgudx6Hnc4NlE8DwBPU8YPE8Inieh50mDZ1PB8xT0PGXwPCV4noaepw2ezQTPM9DzjMHzjOB5FnqeNXg2FzzPQc9zBs9zgud56Hne4NlC8LwAPS8YPC8Inheh50WDZ0vB8xL0vGTwvCR4Xoaelw2erQTPK9DzisHziuB5FXpeNXi2FjyvQc9rBs9rgud16Hnd4NlG8LwBPW8YPG8Injeh502DZ1vB8xb0vGXwvCV43oaetw2e7QTPO9DzjsHzjuB5F3reNXi2FzzvQc97Bs97gud96Hnf4NlB8HwAPR8YPB8Ing+h50ODZ0fB8xH0fGTwfCR4Poaejw2enQTPJ9DzicHzieD5FHo+NXgGgucz6PnM4PlM8HwOPZ8bPDsLni+g5wuD5wvB8yX0fGnw7CJ4voKerwyerwTP19DztcGzq+D5Bnq+MXi+ETzfQs+3Bs9uguc76PnO4PlO8HyvO/P8712ont0FzwjdmWeE7qF7hm2Ht40IPSMaPHsInpGgZySDZyTBMzL0jGzw7Cl4RoGeUQyeUQTPqNAzqsGzl+AZDXpGM3hGEzyjQ8/oBs/egmcM6BnD4BlD8IwJPWMaPPsInrGgZyyDZyzBMzb0jG3w7Ct4xoGecQyecQTPuNAzrsGzn+AZD3rGM3jGEzzjQ8/4Bs/+gmcC6JnA4JlA8EwIPRMaPAcInomgZyKDZyLBMzH0TGzwHCh4JoGeSQyeSQTPpNAzqcFzkOCZDHomM3gmEzyTQ8/kBs/BgmcK6JnC4JlC8EwJPVMaPIcInqmgZyqDZyrBMzX0TG3wHCp4poGeaQyeaQTPtNAzrcFzmOCZDnqmM3imEzzTQ8/0Bs/hgmcG6JnB4JlB8Hwfer5v8Pxb8MwIPTMaPDMKnpmgZyaD5wjBMzP0zGzwzCx4fgA9PzB4/iN4ZoGeWQyeWQTPD6HnhwbPkYJnVuiZ1eCZVfD8CHp+ZPD8V/DMBj2zGTyzCZ4fQ8+PDZ6jBM/s0DO7wTO74PkJ9PzE4Dla8MwBPXMYPHMInp9Cz08NnmMEz5zQM6fBM6fg+Rn0/MzgOVbwzAU9cxk8cwmen0PPzw2e4wTP3NAzt8Ezt+D5BfT8wuA5XvDMAz3zGDzzCJ5fQs8vDZ4TBM+80DOvwTOv4PkV9PzK4DlR8MwHPfMZPPMJnl9Dz68NnpMEz/zQM7/BM7/g+Q30/MbgOVnwLAA9Cxg8CwieBaFnQYPnFMGzEPQsZPAsJHh+Cz2/NXhOFTwLQ8/CBs/Cgud30PM7g+c0wbMI9Cxi8CwieH4PPb83eE4XPItCz6IGz6KC5w/Q8weD5wzBsxj0LGbwLCZ4/gg9fzR4zhQ8i0PP4gbP4oLnT9DzJ4PnLMGzBPQsYfAsIXj+DD1/NnjOFjxLQs+SBs+Sgucv0PMXg+ccwbMU9Cxl8CwleP4KPX81eM4VPEtDz9IGz9KC52/Q8zeD5zzBswz0LGPwLCN4/g49fzd4zhc8y0LPsgbPsoLnH9DzD4PnAsGzHPQsZ/AsJ3j+CT3/NHguFDzLQ8/yBs/ygudf0PMvg+ciwbMC9Kxg8KwgeFaEnhUNnosFz0rQs5LBs5LgWRl6VjZ4LhE8q0DPKgbPKoJnVehZ1eC5VPCsBj2rGTyrCZ7VoWd1g+cywbMG9Kxh8KwheNaEnjUNnssFz1rQs5bBs5bgWRt61jZ4rhA860DPOgbPOoJnXehZ1+C5UvCsBz3rGTzrCZ71oWd9g+cqwbMB9Gxg8GwgeDaEng0NnqsFz0bQs5HBs5Hg2Rh6NjZ4rhE8m0DPJgbPJoJnU+jZ1OC5VvBsBj2bGTybCZ7NoWdzg+c6wbMF9Gxh8GwheLaEni0NnusFz1bQs5XBs5Xg2Rp6tjZ4bhA820DPNgbPNoJnW+jZ1uC5UfBsBz3bGTzbCZ7toWd7g+cmwbMD9Oxg8OwgeHaEnh0NnpsFz07Qs5PBs5PgGUDPwOC5RfDsDD07Gzw7C55doGcXg+dWwbMr9Oxq8OwqeHaDnt0MntsEz+7Qs7vBs7vg2QN69jB4bhc8e0LPngbPnoJnL+jZy+C5Q/DsDT17Gzx7C559oGcfg+dOwbMv9Oxr8OwrePaDnv0MnrsEz/7Qs7/Bs7/gOQB6DjB47hY8B0LPgQbPgYLnIOg5yOC5R/AcDD0HGzwHC55DoOcQg+dewXMo9Bxq8BwqeA6DnsMMnvsEz+HQc7jBc7jg+Tf0/NvguV/wHAE9Rxg8Rwie/0DPfwyeBwTPkdBzpMFzpOD5L/T81+B5UPAcBT1HGTxHCZ6joedog+chwXMM9Bxj8BwjeI6FnmMNnocFz3HQc5zBc5zgOR56jjd4HhE8J0DPCQbPCYLnROg50eB5VPCcBD0nGTwnCZ6Toedkg+cxwXMK9Jxi8JwieE6FnlMNnscFz2nQc5rBc5rgOR16Tjd4nhA8Z0DPGQbPGYLnTOg50+B5UvCcBT1nGTxnCZ6zoedsg+cpwXMO9Jxj8JwjeM6FnnMNnqcFz3nQc57Bc57gOR96zjd4nhE8F0DPBQbPBYLnQui50OB5VvBcBD0XGTwXCZ6Loedig+c5wXMJ9Fxi8FwieC6FnksNnucFz2XQc5nBc5nguRx6Ljd4XhA8V0DPFQbPFYLnSui50uB5UfBcBT1XGTxXCZ6roedqg+clwXMN9Fxj8FwjeK6FnmsNnpcFz3XQc53Bc53guR56rjd4XhE8N0DPDQbPDYLnRui50eB5VfDcBD03GTw3CZ6boedmg+c1wXML9Nxi8NwieG6FnlsNntcFz23Qc5vBc5vguR16bjd43hA8d0DPHQbPHYLnTui50+B5U/DcBT13GTx3CZ67oedug+ctwXMP9Nxj8NwjeO6FnnsNnrcFz33Qc5/Bc5/guR967jd43hE8D0DPAwbPA4LnQeh50OB5V/A8BD0PGTwPCZ6Hoedhg+c9wfMI9Dxi8DwieB6FnkcNnvcFz2PQ85jB85jgeRx6Hjd4PhA8T0DPEwbPE4LnSeh50uD5UPA8BT1PGTxPCZ6noedpg+cjwfMM9Dxj8DwjeJ6FnmcNno8Fz3PQ85zB85zgeR56njd4PhE8L0DPCwbPC4LnReh50eD5VPC8BD0vGTwvCZ6Xoedlg+czwfMK9Lxi8LwieF6FnlcNns8Fz2vQ85rB85rgeR16Xjd4vhA8b0DPGwbPG4LnTeh50+D5UvC8BT1vGTxvCZ63oedtg+crwfMO9Lxj8LwjeN6FnncNnq8Fz3vQ857B857geR963jd4vhE8H0DPBwbPB4LnQ+j50OD5VvB8BD0fGTwfCZ6Poedjg+c7wfMJ9Hxi8HwieD6Fnk8Nnu/l+d/vfAY9nxk8nwmez6Hnc4NnBMHzBfR8YfB8IXi+hJ4vDZ4RBc9X0POVwfOV4Pkaer42eEYSPN9AzzcGzzeC51vo+dbgGVnwfAc93xk83wme7/Vgnv+9C9UziuAZoQfzjNAjdM+w7fC2EaFnRINnVMEzEvSMZPCMJHhGhp6RDZ7RBM8o0DOKwTOK4BkVekY1eEYXPKNBz2gGz2iCZ3ToGd3gGUPwjAE9Yxg8YwieMaFnTINnTMEzFvSMZfCMJXjGhp6xDZ6xBM840DOOwTOO4BkXesY1eMYWPONBz3gGz3iCZ3zoGd/gGUfwTAA9Exg8EwieCaFnQoNnXMEzEfRMZPBMJHgmhp6JDZ7xBM8k0DOJwTOJ4JkUeiY1eMYXPJNBz2QGz2SCZ3LomdzgmUDwTAE9Uxg8UwieKaFnSoNnQsEzFfRMZfBMJXimhp6pDZ6JBM800DONwTON4JkWeqY1eCYWPNNBz3QGz3SCZ3romd7gmUTwzAA9Mxg8Mwie70PP9w2eSQXPjNAzo8Ezo+CZCXpmMngmEzwzQ8/MBs/MgucH0PMDg2dywTML9Mxi8MwieH4IPT80eKYQPLNCz6wGz6yC50fQ8yODZ0rBMxv0zGbwzCZ4fgw9PzZ4phI8s0PP7AbP7ILnJ9DzE4NnasEzB/TMYfDMIXh+Cj0/NXimETxzQs+cBs+cgudn0PMzg2dawTMX9Mxl8MwleH4OPT83eKYTPHNDz9wGz9yC5xfQ8wuDZ3rBMw/0zGPwzCN4fgk9vzR4ZhA880LPvAbPvILnV9DzK4Pn+4JnPuiZz+CZT/D8Gnp+bfDMKHjmh575DZ75Bc9voOc3Bs9MgmcB6FnA4FlA8CwIPQsaPDMLnoWgZyGDZyHB81vo+a3B8wPBszD0LGzwLCx4fgc9vzN4ZhE8i0DPIgbPIoLn99Dze4Pnh4JnUehZ1OBZVPD8AXr+YPDMKngWg57FDJ7FBM8foeePBs+PBM/i0LO4wbO44PkT9PzJ4JlN8CwBPUsYPEsInj9Dz58Nnh8LniWhZ0mDZ0nB8xfo+YvBM7vgWQp6ljJ4lhI8f4Wevxo8PxE8S0PP0gbP0oLnb9DzN4NnDsGzDPQsY/AsI3j+Dj1/N3h+KniWhZ5lDZ5lBc8/oOcfBs+cgmc56FnO4FlO8PwTev5p8PxM8CwPPcsbPMsLnn9Bz78MnrkEzwrQs4LBs4LgWRF6VjR4fi54VoKelQyelQTPytCzssEzt+BZBXpWMXhWETyrQs+qBs8vBM9q0LOawbOa4FkdelY3eOYRPGtAzxoGzxqCZ03oWdPg+aXgWQt61jJ41hI8a0PP2gbPvIJnHehZx+BZR/CsCz3rGjy/EjzrQc96Bs96gmd96Fnf4JlP8GwAPRsYPBsIng2hZ0OD59eCZyPo2cjg2UjwbAw9Gxs88wueTaBnE4NnE8GzKfRsavD8RvBsBj2bGTybCZ7NoWdzg2cBwbMF9Gxh8GwheLaEni0NngUFz1bQs5XBs5Xg2Rp6tjZ4FhI820DPNgbPNoJnW+jZ1uD5reDZDnq2M3i2EzzbQ8/2Bs/CgmcH6NnB4NlB8OwIPTsaPL8TPDtBz04Gz06CZwA9A4NnEcGzM/TsbPDsLHh2gZ5dDJ7fC55doWdXg2dXwbMb9Oxm8CwqeHaHnt0Nnt0Fzx7Qs4fB8wfBsyf07Gnw7Cl49oKevQyexQTP3tCzt8Gzt+DZB3r2MXj+KHj2hZ59DZ59Bc9+0LOfwbO44NkfevY3ePYXPAdAzwEGz58Ez4HQc6DBc6DgOQh6DjJ4lhA8B0PPwQbPwYLnEOg5xOD5s+A5FHoONXgOFTyHQc9hBs+Sgudw6Dnc4Dlc8Pwbev5t8PxF8BwBPUcYPEcInv9Az38MnqUEz5HQc6TBc6Tg+S/0/Nfg+avgOQp6jjJ4jhI8R0PP0QbP0oLnGOg5xuA5RvAcCz3HGjx/EzzHQc9xBs9xgud46Dne4FlG8JwAPScYPCcInhOh50SD5++C5yToOcngOUnwnAw9Jxs8ywqeU6DnFIPnFMFzKvScavD8Q/CcBj2nGTynCZ7Toed0g2c5wXMG9Jxh8JwheM6EnjMNnn8KnrOg5yyD5yzBczb0nG3wLC94zoGecwyecwTPudBzrsHzL8FzHvScZ/CcJ3jOh57zDZ4VBM8F0HOBwXOB4LkQei40eFYUPBdBz0UGz0WC52LoudjgWUnwXAI9lxg8lwieS6HnUoNnZcFzGfRcZvBcJnguh57LDZ5VBM8V0HOFwXOF4LkSeq40eFYVPFdBz1UGz1WC52roudrgWU3wXAM91xg81wiea6HnWoNndcFzHfRcZ/BcJ3iuh57rDZ41BM8N0HODwXOD4LkRem40eNYUPDdBz00Gz02C52boudngWUvw3AI9txg8twieW6HnVoNnbcFzG/TcZvDcJnhuh57bDZ51BM8d0HOHwXOH4LkTeu40eNYVPHdBz10Gz12C527oudvgWU/w3AM99xg89wiee6HnXoNnfcFzH/TcZ/DcJ3juh577DZ4NBM8D0POAwfOA4HkQeh40eDYUPA9Bz0MGz0OC52Hoedjg2UjwPAI9jxg8jwieR6HnUYNnY8HzGPQ8ZvA8Jngeh57HDZ5NBM8T0POEwfOE4HkSep40eDYVPE9Bz1MGz1OC52noedrg2UzwPAM9zxg8zwieZ6HnWYNnc8HzHPQ8Z/A8J3ieh57nDZ4tBM8L0POCwfOC4HkRel40eLYUPC9Bz0sGz0uC52Xoedng2UrwvAI9rxg8rwieV6HnVYNna8HzGvS8ZvC8Jnheh57XDZ5tBM8b0POGwfOG4HkTet40eLYVPG9Bz1sGz1uC523oedvg2U7wvAM97xg87wied6HnXYNne8HzHvS8Z/C8J3jeh573DZ4dBM8H0POBwfOB4PkQej40eHYUPB9Bz0cGz0eC52Po+djg2UnwfAI9nxg8nwieT6HnU4NnIHg+g57PDJ7PBM/n0PO5wbOz4PkCer4weL4QPF9Cz5cGzy6C5yvo+crg+UrwfA09Xxs8uwqeb6DnG4PnG8HzLfR8a/DsJni+g57vDJ7vBM/3ejLP/96F6tld8IzQk3lG6Bm6Z9h2eNuI0DOiwbOH4BkJekYyeEYSPCNDz8gGz56CZxToGcXgGUXwjAo9oxo8ewme0aBnNINnNMEzOvSMbvDsLXjGgJ4xDJ4xBM+Y0DOmwbOP4BkLesYyeMYSPGNDz9gGz76CZxzoGcfgGUfwjAs94xo8+wme8aBnPINnPMEzPvSMb/DsL3gmgJ4JDJ4JBM+E0DOhwXOA4JkIeiYyeCYSPBNDz8QGz4GCZxLomcTgmUTwTAo9kxo8BwmeyaBnMoNnMsEzOfRMbvAcLHimgJ4pDJ4pBM+U0DOlwXOI4JkKeqYyeKYSPFNDz9QGz6GCZxromcbgmUbwTAs90xo8hwme/8fbW0DHdXTrtm1mW7Iks6WWJTMzMzMzMzMzMzMzMzMzMzMzM9unnFTy7+QkUc3ePZbfq1v7nrMsz6yp79st544RPxf36eeGffqBfTpd3KfTDfscD/bp7+I+/d2wT3+wz3gu7jOeG/Y5AewzwMV9BrhhnwFgn4Eu7jPQDfucCPYZ38V9xnfDPuODfSZwcZ8J3LDPSWCfCV3cZ0I37DMh2GciF/eZyA37nAz2mdjFfSZ2wz4Tg30mcXGfSdywzylgn0ld3GdSN+wzKdhnMhf3mcwN+5wK9pncxX0md8M+k4N9pnBxnyncsM9pYJ8pXdxnSjfsMyXYZyoX95nKDfucDvaZ2sV9pnbDPlODfaZxcZ9p3LDPGWCfaV3cZ1o37DMt2Gc6F/eZzg37nAn2md7FfaZ3wz7Tg31mcHGfGdywz1lgnxld3GdGN+wzI9hnJhf3mckN+5wN9pnZxX1mdsM+M4N9ZnFxn1ncsM85YJ9ZXdxnVjfsMyvYZzYX95nNDfucC/aZ3cV9ZnfDPrODfeZwcZ853LDPeWCfOV3cZ0437DMn2GcuF/eZyw37nA/2mdvFfeZ2wz5zg33mcXGfedywzwVgn3ld3GdeN+wzL9hnPhf3mc8N+1wI9pnfxX3md8M+84N9FnBxnwXcsM9FYJ8FXdxnQTfssyDYZyEX91nIDftcDPZZ2MV9FnbDPguDfRZxcZ9F3LDPJWCfRV3cZ1E37LMo2GcxF/dZzA37XAr2WdzFfRZ3wz6Lg32WcHGfJdywz2VgnyVd3GdJN+yzJNhnKRf3WcoN+1wO9lnaxX2WdsM+S4N9lnFxn2XcsM8VYJ9lXdxnWTfssyzYZzkX91nODftcCfZZ3sV9lnfDPsuDfVZwcZ8V3LDPVWCfFV3cZ0U37LMi2GclF/dZyQ37XA32WdnFfVZ2wz4rg31WcXGfVdywzzVgn1Vd3GdVN+yzKthnNRf3Wc0N+1wL9lndxX1Wd8M+q4N91nBxnzXcsM91YJ81XdxnTTfssybYZy0X91nLDftcD/ZZ28V91nbDPmuDfdZxcZ913LDPDWCfdV3cZ1037LMu2Gc9F/dZzw373Aj2Wd/FfdZ3wz7rg302cHGfDdywz01gnw1d3GdDN+yzIdhnIxf32cgN+9wM9tnYxX02dsM+G4N9NnFxn03csM8tYJ9NXdxnUzfssynYZzMX99nMDfvcCvbZ3MV9NnfDPpuDfbZwcZ8t3LDPbWCfLV3cZ0s37LMl2GcrF/fZyg373A722drFfbZ2wz5bg322cXGfbdywzx1gn21d3GdbN+yzLdhnOxf32c4N+9wJ9tnexX22d8M+24N9dnBxnx3csM9dYJ8dXdxnRzfssyPYZycX99nJDfvcDfbZ2cV9dnbDPjuDfXZxcZ9d3LDPPWCfXV3cZ1c37LMr2Gc3F/fZzQ373Av22d3FfXZ3wz67g332cHGfPdywz31gnz1d3GdPN+yzJ9hnLxf32csN+9wP9tnbxX32dsM+e4N99nFxn33csM8DYJ99XdxnXzfssy/YZz8X99nPDfs8CPbZ38V99nfDPvuDfQ5wcZ8D3LDPQ2CfA13c50A37HMg2OcgF/c5yA37PAz2OdjFfQ52wz4Hg30OcXGfQ9ywzyNgn0Nd3OdQN+xzKNjnMBf3OcwN+zwK9jncxX0Od8M+h4N9jnBxnyPcsM9jYJ8jXdznSDfscyTY5ygX9znKDfs8DvY52sV9jnbDPkeDfY5xcZ9j3LDPE2CfY13c51g37HMs2Oc4F/c5zg37PAn2Od7FfY53wz7Hg31OcHGfE9ywz1NgnxNd3OdEN+xzItjnJBf3OckN+zwN9jnZxX1OdsM+J4N9TnFxn1PcsM8zYJ9TXdznVDfscyrY5zQX9znNDfs8C/Y53cV9TnfDPqeDfc5wcZ8z3LDPc2CfM13c50w37HMm2OcsF/c5yw37PA/2OdvFfc52wz5ng33OcXGfc9ywzwtgn3Nd3OdcN+xzLtjnPBf3Oc8N+7wI9jnfxX3Od8M+54N9LnBxnwvcsM9LYJ8LXdznQjfscyHY5yIX97nIDfu8DPa52MV9LnbDPheDfS5xcZ9L3LDPK2CfS13c51I37HMp2OcyF/e5zA37vAr2udzFfS53wz6Xg32ucHGfK9ywz2tgnytd3OdKN+xzJdjnKhf3ucoN+7wO9rnaxX2udsM+V4N9rnFxn2vcsM8bYJ9rXdznWjfscy3Y5zoX97nODfu8Cfa53sV9rnfDPteDfW5wcZ8b3LDPW2CfG13c50Y37HMj2OcmF/e5yQ37vA32udnFfW52wz43g31ucXGfW9ywzztgn1td3OdWN+xzK9jnNhf3uc0N+7wL9rndxX1ud8M+t4N97nBxnzvcsM97YJ87XdznTjfscyfY5y4X97nLDfu8D/a528V97nbDPneDfe5xcZ973LDPB2Cfe13c51437HMv2Oc+F/e5zw37fAj2ud/Ffe53wz73g30ecHGfB9ywz0dgnwdd3OdBN+zzINjnIRf3ecgN+3wM9nnYxX0edsM+D4N9HnFxn0fcsM8nYJ9HXdznUTfs8yjY5zEX93nMDft8CvZ53MV9HnfDPo+DfZ5wcZ8n3LDPZ2CfJ13c50k37PMk2OcpF/d5yg37fA72edrFfZ52wz5Pg32ecXGfZ9ywzxdgn2dd3OdZN+zzLNjnORf3ec4N+3wJ9nnexX2ed8M+z4N9XnBxnxfcsM9XYJ8XXdznRTfs8yLY5yUX93nJDft8DfZ52cV9XnbDPi+DfV5xcZ9X3LDPN2CfV13c51U37PMq2Oc1F/d5zQ37fAv2ed3FfV53wz6vg33ecHGfN9ywz3dgnzdd3OdNN+zzJtjnLRf3ecsN+3wP9nnbxX3edsM+b4N93nFxn3fcsM8PYJ93XdznXTfs8y7Y5z0X93nPDfv8CPZ538V93nfDPu+DfT5wcZ8P3LDPT2CfD13c50M37PMh2OcjF/f56B84Q/yNM4hfwYJFNecMFs1otu+rYGqfsYwZbPEHB/zBAX9wIf4QgD8E4A8hxB8S8IcE/CGF+EMB/lCAP5QQf2jAHxrwhxbiDwP4wwD+MEL8YQF/WMAfVog/HOAPB/jDCfGHB/zhAX94If4IgD8C4I8gxB8R8EcE/BGF+CMB/kiAP5IQf2TAHxnwRxbijwL4owD+KEL8HoDfA/B7CPF7An5PwO8pxB8V8EcF/FGF+L0Avxfg9xLi9wb83oDfW4jfB/D7AH4fIf5ogD8a4I8mxB8d8EcH/NGF+GMA/hiAP4YQf0zAHxPwxxTijwX4YwH+WEL8sQF/bMAfW4g/DuCPA/jjCPHHBfxxAX9cIX5fwO8L+H2F+P0Avx/g9xPidwJ+J+B3CvH7A35/wO8vxB8P8McD/PGE+AMAfwDgDxDiDwT8gYA/UIg/PuCPD/jjC/EnAPwJAH8CIf6EgD8h4E8oxJ8I8CcC/ImE+BMD/sSAP7EQfxLAnwTwJxHiTwr4kwL+pEL8yQB/MsCfTIg/OeBPDviTC/GnAPwpAH8KIf6UgD8l4E8pxJ8K8KcC/KmE+FMD/tSAP7UQfxrAnwbwpxHiTwv40wL+tEL86QB/OsCfTog/PeBPD/jTC/FnAPwZAH8GIf6MgD8j4M8oxJ8J8GcC/JmE+DMD/syAP7MQfxbAnwXwZxHizwr4swL+rEL82QB/NsCfTYg/O+DPDvizC/HnAPw5AH8OIf6cgD8n4M8pxJ8L8OcC/LmE+HMD/tyAP7cQfx7Anwfw5xHizwv48wL+vEL8+QB/PsCfT4g/P+DPD/jzC/EXAPwFAH8BIf6CgL8g4C8oxF8I8BcC/IWE+AsD/sKAv7AQfxHAXwTwFxHiLwr4iwL+okL8xQB/McBfTIi/OOAvDviLC/GXAPwlAH8JIf6SgL8k4C8pxF8K8JcC/KWE+EsD/tKAv7QQfxnAXwbwlxHiLwv4ywL+skL85QB/OcBfToi/POAvD/jLC/FXAPwVAH8FIf6KgL8i4K8oxF8J8FcC/JWE+CsD/sqAv7IQfxXAXwXwVxHirwr4qwL+qkL81QB/NcBfTYi/OuCvDvirC/HXAPw1AH8NIf6agL8m4K8pxF8L8NcC/LWE+GsD/tqAv7YQfx3AXwfw1xHirwv46wL+ukL89QB/PcBfT4i/PuCvD/jrC/E3APwNAH8DIf6GgL8h4G8oxN8I8DcC/I2E+BsD/saAv7EQfxPA3wTwNxHibwr4mwL+pkL8zQB/M8DfTIi/OeBvDvibC/G3APwtAH8LIf6WgL8l4G8pxN8K8LcC/K2E+FsD/taAv7UQfxvA3wbwtxHibwv42wL+tkL87QB/O8DfToi/PeBvD/jbC/F3APwdAH8HIf6OgL8j4O8oxN8J8HcC/J2E+DsD/s6Av7MQfxfA3wXwdxHi7wr4uwL+rkL83QB/N8DfTYi/O+DvDvi7C/H3APw9AH8PIf6egL8n4O8pxN8L8PcC/L2E+HsD/t6Av7cQfx/A3wfw9xHi7wv4+wL+vkL8/QB/P8DfT4i/P+DvD/j7C/EPAPwDAP8AIf6BgH8g4B8oxD8I8A8C/IOE+AcD/sGAf7AQ/xDAPwTwDxHiHwr4hwL+oUL8wwD/MMA/TIh/OOAfDviHC/GPAPwjAP8IIf6RgH8k4B8pxD8K8I8C/KOE+EcD/tGAf7QQ/xjAPwbwjxHiHwv4xwL+sUL84wD/OMA/Toh/POAfD/jHC/FPAPwTAP8EIf6JgH8i4J8oxD8J8E8C/JOE+CcD/smAf7IQ/xTAPwXwTxHinwr4pwL+qUL80wD/NMA/TYh/OuCfDvinC/HPAPwzAP8MIf6ZgH8m4J8pxD8L8M8C/LOE+GcD/tmAf7YQ/xzAPwfwzxHinwv45wL+uUL88wD/PMA/T4h/PuCfD/jnC/EvAPwLAP8CIf6FgH8h4F8oxL8I8C8C/IuE+BcD/sWAf7EQ/xLAvwTwLxHiXwr4lwL+pUL8ywD/MsC/TIh/OeBfDviXC/GvAPwrAP8KIf6VgH8l4F8pxL8K8K8C/KuE+FcD/tWAf7UQ/xrAvwbwrxHiXwv41wL+tUL86wD/OsC/Toh/PeBfD/jXC/FvAPwbAP8GIf6NgH8j4N8oxL8J8G8C/JuE+DcD/s2Af7MQ/xbAvwXwbxHi3wr4twL+rUL82wD/NsC/TYh/O+DfDvi3C/HvAPw7AP8OIf6dgH8n4N8pxL8L8O8C/LuE+HcD/t2Af7cQ/x7Avwfw7xHi3wv49wL+vUL8+wD/PsC/T4h/P+DfD/j3C/EfAPwHAP8BIf6DgP8g4D8oxH8I8B8C/IeE+A8D/sOA/7AQ/xHAfwTwHxHiPwr4jwL+o0L8xwD/McB/TIj/OOA/DviPC/GfAPwnAP8JIf6TgP8k4D8pxH8K8J8C/KeE+E8D/tOA/7QQ/xnAfwbwnxHiPwv4zwL+s0L85wD/OcB/Toj/POA/D/jPC/FfAPwXAP8FIf6LgP8i4L8oxH8J8F8C/JeE+C8D/suA/7IQ/xXAfwXwXxHivwr4rwL+q0L81wD/NcB/TYj/OuC/DvivC/HfAPw3AP8NIf6bgP8m4L8pxH8L8N8C/LeE+G8D/tuA/7YQ/x3Afwfw3xHivwv47wL+u0L89wD/PcB/T4j/PuC/D/jvC/E/APwPAP8DIf6HgP8h4H8oxP8I8D8C/I+E+B8D/seA/7EQ/xPA/wTwPxHifwr4nwL+p0L8zwD/M8D/TIj/OeB/DvifC/G/APwvAP8LIf6XgP8l4H8pxP8K8L8C/K+E+F8D/teA/7UQ/xvA/wbwvxHifwv43wL+t0L87wD/O8D/Toj/PeB/D/jfC/F/APwfAP8HIf6PgP8j4P8oxP8J8H8C/J+E+D8D/s+A/7MQ/xfA/wXwfxHi/wr4vwL+r0L83wD/N8D/TYj/O+D/Dvi/C/H/APw/AP8PIf6fgP8n4P8pxO/wMud3RDfnd8SW4Q8G+IMB/mBC/MEBf3DAH1yIPwTgDwH4QwjxhwT8IQF/SCH+UIA/FOAPJcQfGvCHBvyhhfjDAP4wgD+MEH9YwB8W8IcV4g8H+MMB/nBC/OEBf3jAH16IPwLgjwD4IwjxRwT8EQF/RCH+SIA/EuCPJMQfGfBHBvyRhfijAP4ogD+KEL8H4PcA/B5C/J6A3xPwewrxRwX8UQF/VCF+L8DvBfi9hPi9Ab834PcW4vcB/D6A30eIPxrgjwb4ownxRwf80QF/dCH+GIA/BuCPIcQfE/DHBPwxhfhjAf5YgD+WEH9swB8b8McW4o8D+OMA/jhC/HEBf1zAH1eI3xfw+wJ+XyF+P8DvB/j9hPidgN8J+J1C/P6A3x/w+wvxxwP88QB/PCH+AMAfAPgDhPgDAX8g4A8U4o8P+OMD/vhC/AkAfwLAn0CIPyHgTwj4EwrxJwL8iQB/IiH+xIA/MeBPLMSfBPAnAfxJhPiTAv6kgD+pEH8ywJ8M8CcT4k8O+JMD/uRC/CkAfwrAn0KIPyXgTwn4UwrxpwL8qQB/KiH+1IA/NeBPLcSfBvCnAfxphPjTAv60gD+tEH86wJ8O8KcT4k8P+NMD/vRC/BkAfwbAn0GIPyPgzwj4MwrxZwL8mQB/JiH+zIA/M+DPLMSfBfBnAfxZhPizAv6sgD+rEH82wJ8N8GcT4s8O+LMD/uxC/DkAfw7An0OIPyfgzwn4cwrx5wL8uQB/LiH+3IA/N+DPLcSfB/DnAfx5hPjzAv68gD+vEH8+wJ8P8OcT4s8P+PMD/vxC/AUAfwHAX0CIvyDgLwj4CwrxFwL8hQB/ISH+woC/MOAvLMRfBPAXAfxFhPiLAv6igL+oEH8xwF8M8BcT4i8O+IsD/uJC/CUAfwnAX0KIvyTgLwn4SwrxlwL8pQB/KSH+0oC/NOAvLcRfBvCXAfxlhPjLAv6ygL+sEH85wF8O8JcT4i8P+MsD/vJC/BUAfwXAX0GIvyLgrwj4KwrxVwL8lQB/JSH+yoC/MuCvLMRfBfBXAfxVhPirAv6qgL+qEH81wF8N8FcT4q8O+KsD/upC/DUAfw3AX0OIvybgrwn4awrx1wL8tQB/LSH+2oC/NuCvLcRfB/DXAfx1hPjrAv66gL+uEH89wF8P8NcT4q8P+OsD/vpC/A0AfwPA30CIvyHgbwj4GwrxNwL8jQB/IyH+xoC/MeBvLMTfBPA3AfxNhPibAv6mgL+pEH8zwN8M8DcT4m8O+JsD/uZC/C0AfwvA30KIvyXgbwn4WwrxtwL8rQB/KyH+1oC/NeBvLcTfBvC3AfxthPjbAv62gL+tEH87wN8O8LcT4m8P+NsD/vZC/B0AfwfA30GIvyPg7wj4OwrxdwL8nQB/JyH+zoC/M+DvLMTfBfB3AfxdhPi7Av6ugL+rEH83wN8N8HcT4u8O+LsD/u5C/D0Afw/A30OIvyfg7wn4ewrx9wL8vQB/LyH+3oC/N+DvLcTfB/D3Afx9hPj7Av6+gL+vEH8/wN8P8PcT4u8P+PsD/v5C/AMA/wDAP0CIfyDgHwj4BwrxDwL8gwD/ICH+wYB/MOAfLMQ/BPAPAfxDhPiHAv6hgH+oEP8wwD8M8A8T4h8O+IcD/uFC/CMA/wjAP0KIfyTgHwn4RwrxjwL8owD/KCH+0YB/NOAfLcQ/BvCPAfxjhPjHAv6xgH+sEP84wD8O8I8T4h8P+McD/vFC/BMA/wTAP0GIfyLgnwj4JwrxTwL8kwD/JCH+yYB/MuCfLMQ/BfBPAfxThPinAv6pgH+qEP80wD8N8E8T4p8O+KcD/ulC/DMA/wzAP0OIfybgnwn4ZwrxzwL8swD/LCH+2YB/NuCfLcQ/B/DPAfxzhPjnAv65gH+uEP88wD8P8M8T4p8P+OcD/vlC/AsA/wLAv0CIfyHgXwj4FwrxLwL8iwD/IiH+xYB/MeBfLMS/BPAvAfxLhPiXAv6lgH+pEP8ywL8M8C8T4l8O+JcD/uVC/CsA/wrAv0KIfyXgXwn4VwrxrwL8qwD/KiH+1YB/NeBfLcS/BvCvAfxrhPjXAv61gH+tEP86wL8O8K8T4l8P+NcD/vVC/BsA/wbAv0GIfyPg3wj4NwrxbwL8mwD/JiH+zYB/M+DfLMS/BfBvAfxbhPi3Av6tgH+rEP82wL8N8G8T4t8O+LcD/u1C/DsA/w7Av0OIfyfg3wn4dwrx7wL8uwD/LiH+3YB/N+DfLcS/B/DvAfx7hPj3Av69gH+vEP8+wL8P8O8T4t8P+PcD/v1C/AcA/wHAf0CI/yDgPwj4DwrxHwL8hwD/ISH+w4D/MOA/LMR/BPAfAfxHhPiPAv6jgP+oEP8xwH8M8B8T4j8O+I8D/uNC/CcA/wnAf0KI/yTgPwn4TwrxnwL8pwD/KSH+04D/NOA/LcR/BvCfAfxnhPjPAv6zgP+sEP85wH8O8J8T4j8P+M8D/vNC/BcA/wXAf0GI/yLgvwj4LwrxXwL8lwD/JSH+y4D/MuC/LMR/BfBfAfxXhPivAv6rgP+qEP81wH8N8F8T4r8O+K8D/utC/DcA/w3Af0OI/ybgvwn4bwrx3wL8twD/LSH+24D/NuC/LcR/B/DfAfx3hPjvAv67gP+uEP89wH8P8N8T4r8P+O8D/vtC/A8A/wPA/0CI/yHgfwj4HwrxPwL8jwD/IyH+x4D/MeB/LMT/BPA/AfxPhPifAv6ngP+pEP8zwP8M8D8T4n8O+J8D/udC/C8A/wvA/0KI/yXgfwn4XwrxvwL8rwD/KyH+14D/NeB/LcT/BvC/AfxvhPjfAv63gP+tEP87wP8O8L8T4n8P+N8D/vdC/B8A/wfA/0GI/yPg/wj4PwrxfwL8nwD/JyH+z4D/M+D/LMT/BfB/AfxfhPi/Av6vgP+rEP83wP8N8H8T4v8O+L8D/u9C/D8A/w/A/0OI/yfg/wn4fwrxO7zN+R0xzPkdcWT4g0U15w9myh9ilyOYEH9wwB8c8AcX4g8B+EMA/hBC/CEBf0jAH1KIPxTgDwX4Qwnxhwb8oQF/aCH+MIA/DOAPI8QfFvCHBfxhhfjDAf5wgD+cEH94wB8e8IcX4o8A+CMA/ghC/BEBf0TAH1GIPxLgjwT4IwnxRwb8kQF/ZCH+KIA/CuCPIsTvAfg9AL+HEL8n4PcE/J5C/FEBf1TAH1WI3wvwewF+LyF+b8DvDfi9hfh9AL8P4PcR4o8G+KMB/mhC/NEBf3TAH12IPwbgjwH4YwjxxwT8MQF/TCH+WIA/FuCPJcQfG/DHBvyxhfjjAP44gD+OEH9cwB8X8McV4vcF/L6A31eI3w/w+wF+PyF+J+B3An6nEL8/4PcH/P5C/PEAfzzAH0+IPwDwBwD+ACH+QMAfCPgDhfjjA/74gD++EH8CwJ8A8CcQ4k8I+BMC/oRC/IkAfyLAn0iIPzHgTwz4EwvxJwH8SQB/EiH+pIA/KeBPKsSfDPAnA/zJhPiTA/7kgD+5EH8KwJ8C8KcQ4k8J+FMC/pRC/KkAfyrAn0qIPzXgTw34UwvxpwH8aQB/GiH+tIA/LeBPK8SfDvCnA/zphPjTA/70gD+9EH8GwJ8B8GcQ4s8I+DMC/oxC/JkAfybAn0mIPzPgzwz4MwvxZwH8WQB/FiH+rIA/K+DPKsSfDfBnA/zZhPizA/7sgD+7EH8OwJ8D8OcQ4s8J+HMC/pxC/LkAfy7An0uIPzfgzw34cwvx5wH8eQB/HiH+vIA/L+DPK8SfD/DnA/z5hPjzA/78gD+/EH8BwF8A8BcQ4i8I+AsC/oJC/IUAfyHAX0iIvzDgLwz4CwvxFwH8RQB/ESH+ooC/KOAvKsRfDPAXA/zFhPiLA/7igL+4EH8JwF8C8JcQ4i8J+EsC/pJC/KUAfynAX0qIvzTgLw34SwvxlwH8ZQB/GSH+soC/LOAvK8RfDvCXA/zlhPjLA/7ygL+8EH8FwF8B8FcQ4q8I+CsC/opC/JUAfyXAX0mIvzLgrwz4KwvxVwH8VQB/FSH+qoC/KuCvKsRfDfBXA/zVhPirA/7qgL+6EH8NwF8D8NcQ4q8J+GsC/ppC/LUAfy3AX0uIvzbgrw34awvx1wH8dQB/HSH+uoC/LuCvK8RfD/DXA/z1hPjrA/76gL++EH8DwN8A8DcQ4m8I+BsC/oZC/I0AfyPA30iIvzHgbwz4GwvxNwH8TQB/EyH+poC/KeBvKsTfDPA3A/zNhPibA/7mgL+5EH8LwN8C8LcQ4m8J+FsC/pZC/K0AfyvA30qIvzXgbw34WwvxtwH8bQB/GyH+toC/LeBvK8TfDvC3A/zthPjbA/72gL+9EH8HwN8B8HcQ4u8I+DsC/o5C/J0AfyfA30mIvzPg7wz4OwvxdwH8XQB/FyH+roC/K+DvKsTfDfB3A/zdhPi7A/7ugL+7EH8PwN8D8PcQ4u8J+HsC/p5C/L0Afy/A30uIvzfg7w34ewvx9wH8fQB/HyH+voC/L+DvK8TfD/D3A/z9hPj7A/7+gL+/EP8AwD8A8A8Q4h8I+AcC/oFC/IMA/yDAP0iIfzDgHwz4BwvxDwH8QwD/ECH+oYB/KOAfKsQ/DPAPA/zDhPiHA/7hgH+4EP8IwD8C8I8Q4h8J+EcC/pFC/KMA/yjAP0qIfzTgHw34RwvxjwH8YwD/GCH+sYB/LOAfK8Q/DvCPA/zjhPjHA/7xgH+8EP8EwD8B8E8Q4p8I+CcC/olC/JMA/yTAP0mIfzLgnwz4JwvxTwH8UwD/FCH+qYB/KuCfKsQ/DfBPA/zThPinA/7pgH+6EP8MwD8D8M8Q4p8J+GcC/plC/LMA/yzAP0uIfzbgnw34ZwvxzwH8cwD/HCH+uYB/LuCfK8Q/D/DPA/zzhPjnA/75gH++EP8CwL8A8C8Q4l8I+BcC/oVC/IsA/yLAv0iIfzHgXwz4FwvxLwH8SwD/EiH+pYB/KeBfKsS/DPAvA/zLhPiXA/7lgH+5EP8KwL8C8K8Q4l8J+FcC/pVC/KsA/yrAv0qIfzXgXw34VwvxrwH8awD/GiH+tYB/LeBfK8S/DvCvA/zrhPjXA/71gH+9EP8GwL8B8G8Q4t8I+DcC/o1C/JsA/ybAv0mIfzPg3wz4NwvxbwH8WwD/FiH+rYB/K+DfKsS/DfBvA/zbhPi3A/7tgH+7EP8OwL8D8O8Q4t8J+HcC/p1C/LsA/y7Av0uIfzfg3w34dwvx7wH8ewD/HiH+vYB/L+DfK8S/D/DvA/z7hPj3A/79gH+/EP8BwH8A8B8Q4j8I+A8C/oNC/IcA/yHAf0iI/zDgPwz4DwvxHwH8RwD/ESH+o4D/KOA/KsR/DPAfA/zHhPiPA/7jgP+4EP8JwH8C8J8Q4j8J+E8C/pNC/KcA/ynAf0qI/zTgPw34TwvxnwH8ZwD/GSH+s4D/LOA/K8R/DvCfA/znhPjPA/7zgP+8EP8FwH8B8F8Q4r8I+C8C/otC/JcA/yXAf0mI/zLgvwz4LwvxXwH8VwD/FSH+q4D/KuC/KsR/DfBfA/zXhPivA/7rgP+6EP8NwH8D8N8Q4r8J+G8C/ptC/LcA/y3Af0uI/zbgvw34bwvx3wH8dwD/HSH+u4D/LuC/K8R/D/DfA/z3hPjvA/77gP++EP8DwP8A8D8Q4n8I+B8C/odC/I8A/yPA/0iI/zHgfwz4HwvxPwH8TwD/EyH+p4D/KeB/KsT/DPA/A/zPhPifA/7ngP+5EP8LwP8C8L8Q4n8J+F8C/pdC/K8A/yvA/0qI/zXgfw34XwvxvwH8bwD/GyH+t4D/LeB/K8T/DvC/A/zvhPjfA/73gP+9EP8HwP8B8H8Q4v8I+D8C/o9C/J8A/yfA/0mI/zPg/wz4PwvxfwH8XwD/FyH+r4D/K+D/KsT/DfB/A/zfhPi/A/7vgP+7EP8PwP8D8P8Q4v8J+H8C/p9C/A4vc35HTHN+R1wZ/mCAPxjgDybEHxzwBwf8wYX4QwD+EIA/hBB/SMAfEvCHFOIPBfhDAf5QQvyhAX9owB9aiD8M4A8D+MMI8YcF/GEBf1gh/nCAPxzgDyfEHx7whwf84YX4IwD+CIA/ghB/RMAfEfBHFOKPBPgjAf5IQvyRAX9kwB9ZiD8K4I8C+KMI8XsAfg/A7yHE7wn4PQG/pxB/VMAfFfBHFeL3AvxegN9LiN8b8HsDfm8hfh/A7wP4fYT4owH+aIA/mhB/dMAfHfBHF+KPAfhjAP4YQvwxAX9MwB9TiD8W4I8F+GMJ8ccG/LEBf2wh/jiAPw7gjyPEHxfwxwX8cYX4fQG/L+D3FeL3A/x+gN9PiN8J+J2A3ynE7w/4/QG/vxB/PMAfD/DHE+IPAPwBgD9AiD8Q8AcC/kAh/viAPz7gjy/EnwDwJwD8CYT4EwL+hIA/oRB/IsCfCPAnEuJPDPgTA/7EQvxJAH8SwJ9EiD8p4E8K+JMK8ScD/MkAfzIh/uSAPzngTy7EnwLwpwD8KYT4UwL+lIA/pRB/KsCfCvCnEuJPDfhTA/7UQvxpAH8awJ9GiD8t4E8L+NMK8acD/OkAfzoh/vSAPz3gTy/EnwHwZwD8GYT4MwL+jIA/oxB/JsCfCfBnEuLPDPgzA/7MQvxZAH8WwJ9FiD8r4M8K+LMK8WcD/NkAfzYh/uyAPzvgzy7EnwPw5wD8OYT4cwL+nIA/pxB/LsCfC/DnEuLPDfhzA/7cQvx5AH8ewJ9HiD8v4M8L+PMK8ecD/PkAfz4h/vyAPz/gzy/EXwDwFwD8BYT4CwL+goC/oBB/IcBfCPAXEuIvDPgLA/7CQvxFAH8RwF9EiL8o4C8K+IsK8RcD/MUAfzEh/uKAvzjgLy7EXwLwlwD8JYT4SwL+koC/pBB/KcBfCvCXEuIvDfhLA/7SQvxlAH8ZwF9GiL8s4C8L+MsK8ZcD/OUAfzkh/vKAvzzgLy/EXwHwVwD8FYT4KwL+ioC/ohB/JcBfCfBXEuKvDPgrA/7KQvxVAH8VwF9FiL8q4K8K+KsK8VcD/NUAfzUh/uqAvzrgry7EXwPw1wD8NYT4awL+moC/phB/LcBfC/DXEuKvDfhrA/7aQvx1AH8dwF9HiL8u4K8L+OsK8dcD/PUAfz0h/vqAvz7gry/E3wDwNwD8DYT4GwL+hoC/oRB/I8DfCPA3EuJvDPgbA/7GQvxNAH8TwN9EiL8p4G8K+JsK8TcD/M0AfzMh/uaAvzngby7E3wLwtwD8LYT4WwL+loC/pRB/K8DfCvC3EuJvDfhbA/7WQvxtAH8bwN9GiL8t4G8L+NsK8bcD/O0Afzsh/vaAvz3gby/E3wHwdwD8HYT4OwL+joC/oxB/J8DfCfB3EuLvDPg7A/7OQvxdAH8XwN9FiL8r4O8K+LsK8XcD/N0Afzch/u6Avzvg7y7E3wPw9wD8PYT4ewL+noC/pxB/L8DfC/D3EuLvDfh7A/7eQvx9AH8fwN9HiL8v4O8L+PsK8fcD/P0Afz8h/v6Avz/g7y/EPwDwDwD8A4T4BwL+gYB/oBD/IMA/CPAPEuIfDPgHA/7BQvxDAP8QwD9EiH8o4B8K+IcK8Q8D/MMA/zAh/uGAfzjgHy7EPwLwjwD8I4T4RwL+kYB/pBD/KMA/CvCPEuIfDfhHA/7RQvxjAP8YwD9GiH8s4B8L+McK8Y8D/OMA/zgh/vGAfzzgHy/EPwHwTwD8E4T4JwL+iYB/ohD/JMA/CfBPEuKfDPgnA/7JQvxTAP8UwD9FiH8q4J8K+KcK8U8D/NMA/zQh/umAfzrgny7EPwPwzwD8M4T4ZwL+mYB/phD/LMA/C/DPEuKfDfhnA/7ZQvxzAP8cwD9HiH8u4J8L+OcK8c8D/PMA/zwh/vmAfz7gny/EvwDwLwD8C4T4FwL+hYB/oRD/IsC/CPAvEuJfDPgXA/7FQvxLAP8SwL9EiH8p4F8K+JcK8S8D/MsA/zIh/uWAfzngXy7EvwLwrwD8K4T4VwL+lYB/pRD/KsC/CvCvEuJfDfhXA/7VQvxrAP8awL9GiH8t4F8L+NcK8a8D/OsA/zoh/vWAfz3gXy/EvwHwbwD8G4T4NwL+jYB/oxD/JsC/CfBvEuLfDPg3A/7NQvxbAP8WwL9FiH8r4N8K+LcK8W8D/NsA/zYh/u2Afzvg3y7EvwPw7wD8O4T4dwL+nYB/pxD/LsC/C/DvEuLfDfh3A/7dQvx7AP8ewL9HiH8v4N8L+PcK8e8D/PsA/z4h/v2Afz/g3y/EfwDwHwD8B4T4DwL+g4D/oBD/IcB/CPAfEuI/DPgPA/7DQvxHAP8RwH9EiP8o4D8K+I8K8R8D/McA/zEh/uOA/zjgPy7EfwLwnwD8J4T4TwL+k4D/pBD/KcB/CvCfEuI/DfhPA/7TQvxnAP8ZwH9GiP8s4D8L+M8K8Z8D/OcA/zkh/vOA/zzgPy/EfwHwXwD8F4T4LwL+i4D/ohD/JcB/CfBfEuK/DPgvA/7LQvxXAP8VwH9FiP8q4L8K+K8K8V8D/NcA/zUh/uuA/zrgvy7EfwPw3wD8N4T4bwL+m4D/phD/LcB/C/DfEuK/DfhvA/7bQvx3AP8dwH9HiP8u4L8L+O8K8d8D/PcA/z0h/vuA/z7gvy/E/wDwPwD8D4T4HwL+h4D/oRD/I8D/CPA/EuJ/DPgfA/7HQvxPAP8TwP9EiP8p4H8K+J8K8T8D/M8A/zMh/ueA/zngfy7E/wLwvwD8L4T4XwL+l4D/pRD/K8D/CvC/EuJ/DfhfA/7XQvxvAP8bwP9GiP8t4H8L+N8K8b8D/O8A/zsh/veA/z3gfy/E/wHwfwD8H4T4PwL+j4D/oxD/J8D/CfB/EuL/DPg/A/7PQvxfAP8XwP9FiP8r4P8K+L8K8X8D/N8A/zch/u+A/zvg/y7E/wPw/wD8P4T4fwL+n4D/pxC/w9uc3xHLnN/h6xp/sL/xB/l3OgP//c+J6Li3v+D7yD2if3v9afD6E6Gs/7swf/tz/vqn/zOX85//x//vV3DHvzP9/TeEcASxJ8tvCOkw2envvyGU0ezvvyG0A/wd1F/27fGf/4f1F913GIf5vsM6zPcdzmG+7/AO831HcJjvO6ID/J2Z0L4jOcz3Hdlhvu8oDvN9ezjM9+3pMN93VAf4Oz6w718kv1yGtJD96qNf9xN9P9X3r6/7x9xz9fxCnZfqvBr4V9iw+nb+9R/B8W+/vBzm3rwd5t58HObeogU1a/kN0Y1mf/8NMcDsi4Hg74FczBR1E9Nh7iaWw9xNbIe5mzgOczdxHeb79gWzL4GbN0Ju/BzmbpwOczf+DnM38RzmbgIc5vsOBLOvgJu3Nrvxue7C1/p+o++3lm58p57fq/NBnY82uzG+w9xxAoe544QOc8eJgpq1/IbERrO//4YkYPY9cPxJKH9JHeZukjnM3SR3mLtJ4TB3k9Jhvu9UYPYDcPNZyE1qh7mbNA5zN2kd5m7SOczdpHeY7zsDmP0I3Hyx2Y3vdBd+0vdnfX+xdONX9fxNne/q/LDZjRkd5o4zOcwdZ3aYO84S1KzlN2Q1mv39N2QDs9+A459C+cvuMHeTw2HuJqfD3E0uh7mb3A7zfecBs9+BG8cgGTd5HeZu8jnM3eR3mLsp4DB3U9Bhvu9CYPYHcBMMuPmnbvyqu/Cnvn+5Dqa/7h9zwdVziF//d3VCDforLHVc2GHuuIjD3HFRh7njYkHNWn5DcaPZ339DCTAbYpC549BC+SvpMHdTymHuprTD3E0Zh7mbsg7zfZcDsyGBmzBCbso7zN1UcJi7qegwd1PJYe6mssN831XAbCjgJqzNbgyuuzC0vsPoO6ylG8Op5/DqRFAnos1urOowd1zNYe64usPccY2gZi2/oabR7O+/oRaYDQ8cRxLKX22HuZs6DnM3dR3mbuo5zN3Ud5jvuwGYjQDcRBZy09Bh7qaRw9xNY4e5myYOczdNHeb7bgZmIwI3UWx2YzjdhZH0HVnfUSzd6KGePdWJqo6XzW5s7jB33MJh7rilw9xxq6BmLb+htdHs77+hDZj1BI69hfLX1mHupp3D3E17h7mbDg5zNx0d5vvuBGajAjc+Qm46O8zddHGYu+nqMHfTzWHuprvDfN89wKwXcBPNZjd66C701rePvqNZujG6eo6hTkx1Ytnsxp4Oc8e9HOaOezvMHfcJatbyG/oazf7+G/qB2RjAcWyh/PV3mLsZ4DB3M9Bh7maQw9zNYIf5voeA2ZjATRwhN0Md5m6GOczdDHeYuxnhMHcz0mG+71FgNhZwE9dmN0bXXRhb33H0HdfSjb7q2e/Xn6OOv81uHO0wdzzGYe54rMPc8bigZi2/YbzR7O+/YQKY9QOO4wnlb6LD3M0kh7mbyQ5zN1Mc5m6mOsz3PQ3MOoGbACE30x3mbmY4zN3MdJi7meUwdzPbYb7vOWDWH7gJtNmNvroL4+k7QN+Blm6Mr54TqJNQnUQ2u3Guw9zxPIe54/kOc8cLgpq1/IaFRrO//4ZFYDYBcJxYKH+LHeZuljjM3Sx1mLtZ5jB3s9xhvu8VYDYhcJNEyM1Kh7mbVQ5zN6sd5m7WOMzdrHWY73sdmE0E3CS12Y3xdRcm1ncSfSe1dGMy9ZxcnRTqpLTZjesd5o43OMwdb3SYO94U1KzlN2w2mv39N2wBs8mB41RC+dvqMHezzWHuZrvD3M0Oh7mbnQ7zfe8CsymAm9RCbnY7zN3scZi72eswd7PPYe5mv8N83wfAbErgJo3NbkymuzCVvlPrO42lG9Oq53TqpFcng81uPOgwd3zIYe74sMPc8ZGgZi2/4ajR7O+/4RiYTQccZxTK33GHuZsTDnM3Jx3mbk45zN2cdpjv+wyYTQ/cZBJyc9Zh7uacw9zNeYe5mwsOczcXHeb7vgRmMwA3mW12Y1rdhRn1nUnfmS3dmEU9Z1UnmzrZbXbjZYe54ysOc8dXHeaOrwU1a/kN141mf/8NN8BsVuA4h1D+bjrM3dxymLu57TB3c8dh7uauw3zf98BsNuAmp5Cb+w5zNw8c5m4eOszdPHKYu3nsMN/3EzCbHbjJZbMbs+guzKHvnPrOZenG3Oo5jzp51clnsxufOswdP3OYO37uMHf8IqhZy294aTT7+294BWbzAMf5hfL32mHu5o3D3M1bh7mbdw5zN+8d5vv+AGbzAjcFhNx8dJi7+eQwd/PZYe7mi8PczVeH+b6/gdl8wE1Bm92YW3dhfn0X0HdBSzcWUs+F1SmiTlGb3fjdYe74h8Pc8U+HueNfz/85a/kNwYxmfx8NDmYLA8fFhPIXIpi5m5DBzN2ECmbuJjRwEwbsOyyYLQLcFBdyEw64CQ/cRABuIgI3kcC+I4PZosBNCZvdWEh3YTF9F9d3CUs3llTPpdQprU4Zm90YBTj2AI49geOowLEX8OYNZksBx2WF8ucD3EQDbqIDNzGAm5hg37HAbGngppyQm9jATRzgJi5w4wvc+IF9O8FsGeCmvM1uLKm7sKy+y+m7vKUbK6jniupUUqeyzW70B47jAccBwHEgcBwfeEsAZisCx1WE8pcQuEkE3CQGbpIAN0nBvpOB2UrATVUhN8mBmxTATUrgJhVwkxrsOw2YrQzcVLPZjRV0F1bRd1V9V7N0Y3X1XEOdmurUstmNaYHjdMBxeuA4A3CcEXjLBGZrAMe1hfKXGbjJAtxkBW6yATfZwb5zgNmawE0dITc5gZtcwE1u4CYPcJMX7DsfmK0F3NS12Y3VdRfW1ncdfde1dGM99VxfnQbqNLTZjfmB4wLAcUHguBBwXBh4KwJm6wPHjYTyVxS4KQbcFAduSgA3JcG+S4HZBsBNYyE3pYGbMsBNWeCmHHBTHuy7AphtCNw0sdmN9XQXNtJ3Y303sXRjU/XcTJ3m6rSw2Y0VgeNKwHFl4LgKcFwVeKsGZpsBxy2F8lcduKkB3NQEbmoBN7XBvuuA2ebATSshN3WBm3rATX3gpgFw0xDsuxGYbQHctLbZjU11F7bUdyt9t7Z0Yxv13Fadduq0t9mNjYHjJsBxU+C4GXDcnHgDs22B4w5C+WsJ3LQCbloDN22Am7Zg3+3ILHDTUchNe+CmA3DTEbjpBNx0BvvuAmbbAzedbHZjG92FHfTdUd+dLN3YWT13UaerOt1sdmNX4LgbcNwdOO4BHPcE3nqR7wfguLtQ/noDN32Am77ATT/gpj/Y9wAw2xW46SHkZiBwMwi4GQzcDAFuhoJ9DwOz3YCbnja7sbPuwu767qHvnpZu7KWee6vTR52+NrtxOHA8AjgeCRyPAo5HA29jwGxv4LifUP7GAjfjgJvxwM0E4GYi2PckMNsHuOkv5GYycDMFuJkK3EwDbqaDfc8As32BmwE2u7GX7sJ++u6v7wGWbhyongepM1idITa7cSZwPAs4ng0czwGO5wJv88DsIOB4qFD+5gM3C4CbhcDNIuBmMdj3EjA7GLgZJuRmKXCzDLhZDtysAG5Wgn2vArNDgJvhNrtxoO7Cofoepu/hlm4coZ5HqjNKndE2u3E1cLwGOF4LHK8DjtcDbxvA7EjgeIxQ/jYCN5uAm83AzRbgZivY9zYwOwq4GSvkZjtwswO42Qnc7AJudoN97wGzo4GbcTa7cYTuwjH6HqvvcZZuHK+eJ6gzUZ1JNrtxL3C8DzjeDxwfAI4PAm+HwOwE4HiyUP4OAzdHgJujwM0x4OY42PcJMDsRuJki5OYkcHMKuDkN3JwBbs6CfZ8Ds5OAm6k2u3G87sLJ+p6i76mWbpymnqerM0OdmTa78TxwfAE4vggcXwKOLwNvV8DsdOB4llD+rgI314Cb68DNDeDmJtj3LTA7A7iZLeTmNnBzB7i5C9zcA27ug30/ALMzgZs5Nrtxmu7CWfqere85lm6cq57nqTNfnQU2u/EhcPwIOH4MHD8Bjp8Cb8/A7DzgeKFQ/p4DNy+Am5fAzSvg5jXY9xswOx+4WSTk5i1w8w64eQ/cfABuPoJ9fwKzC4CbxTa7ca7uwoX6XqTvxZZuXKKel6qzTJ3lNrvxM3D8BTj+Chx/A46/A28/wOxS4HiFi/n7w5/zr3+0499+/QRuHMHN/1mXgX/WlUJdEyy4+T9r8ODm34chgpt/H4YMbv59GArsOzSYXQ7crLLZNUt0t6zQ90p9r7J0zWr1vEadteqss9k1YYDjsMBxOOA4PHAcAXiLCGbXAMfrhfIXCbiJDNxEAW48gBtPsO+oYHYtcLNByI0XcOMN3PgAN9GAm+hg3zHA7DrgZqPNblytu3C9vjfoe6OlGzep583qbFFnq81ujAkcxwKOYwPHcYDjuMCbL5jdDBxvE8qfH3DjBG78gZt4wE0A2HcgmN0C3GwXchMfuEkA3CQEbhIBN4nBvpOA2a3AzQ6b3bhJd+E2fW/X9w5LN+5Uz7vU2a3OHpvdmBQ4TgYcJweOUwDHKYG3VGB2F3C8Vyh/qYGbNMBNWuAmHXCTHuw7A5jdDdzsE3KTEbjJBNxkBm6yADdZwb6zgdk9wM1+m924U3fhXn3v0/d+SzceUM8H1TmkzmGb3ZgdOM4BHOcEjnMBx7mBtzxg9iBwfEQof3mBm3zATX7gpgBwUxDsuxCYPQTcHBVyUxi4KQLcFAVuigE3xcG+S4DZw8DNMZvdeEB34RF9H9X3MUs3HlfPJ9Q5qc4pm91YEjguBRyXBo7LAMdlgbdyYPYEcHxaKH/lgZsKwE1F4KYScFMZ7LsKmD0J3JwRclMVuKkG3FQHbmoANzXBvmuB2VPAzVmb3Xhcd+FpfZ/R91lLN55Tz+fVuaDORZvdWBs4rgMc1wWO6wHH9YG3BmD2PHB8SSh/DYGbRsBNY+CmCXDTFOy7GZi9ANxcFnLTHLhpAdy0BG5aATetwb7bgNmLwM0Vm914TnfhJX1f1vcVSzdeVc/X1Lmuzg2b3dgWOG4HHLcHjjsAxx2Bt05g9hpwfFMof52Bmy7ATVfgphtw0x3suweYvQ7c3BJy0xO46QXc9AZu+gA3fcG++4HZG8DNbZvdeFV34U1939L3bUs33lHPd9W5p859m93YHzgeABwPBI4HAceDgbchYPYucPxAKH9DgZthwM1w4GYEcDMS7HsUmL0H3DwUcjMauBkD3IwFbsYBN+PBvieA2fvAzSOb3XhHd+EDfT/U9yNLNz5Wz0/UearOM5vdOBE4ngQcTwaOpwDHU4G3aWD2CXD8XCh/04GbGcDNTOBmFnAzG+x7Dph9Cty8EHIzF7iZB9zMB24WADcLwb4XgdlnwM1Lm934WHfhc32/0PdLSze+Us+v1Xmjzlub3bgYOF4CHC8FjpcBx8uBtxVg9jVw/E4ofyuBm1XAzWrgZg1wsxbsex2YfQPcvBdysx642QDcbARuNgE3m8G+t4DZt8DNB5vd+Ep34Tt9v9f3B0s3flTPn9T5rM4Xm924FTjeBhxvB453AMc7gbddYPYTcPxVKH+7gZs9wM1e4GYfcLMf7PsAmP0M3HwTcnMQuDkE3BwGbo4AN0fBvo+B2S/AzXeb3fhRd+FXfX/T93dLN/5Qzz9/deJg9b8b/FdY6vg4cHwCOD4JHJ8Cjk8Db2fA7E/gOPhgmfydBW7OATfngZsLwM1FsO9LYNYx2NxNCCE3l4GbK8DNVeDmGnBznfz7FTAbDLgJCdz8Uzf+0F34K3+/7hD6/vV1/5gLpZ5DqxNGnbA2u/EmcHwLOL4NHN8Bju+Sv8MHs6GB43BC+bsP3DwAbh4CN4+Am8fk73fBbBjgJryQm6fAzTPg5jlw8wK4eQn2/QrMhgVuItjsxlC6C8PpO7y+I1i6MaJ6jqROZHWi2OzG18DxG+D4LXD8Djh+D7x9ALORgGMPofx9BG4+ATefgZsvwM1XsO9vYDYycOMp5OY7cPMDuPkJ3DhCmLsJFsJ838HBbBTgJqrNboyou9BD3576jmrpRi/17K2OjzrRbHZjiBDmjkOGMHccKoS549DAcRjgLSyY9QaOowvlLxxwEx64iQDcRARuIoF9RwazPsBNDCE3UYAbD+DGE7iJCtx4kSyA2WjATUyb3eiluzC6vmPoO6alG2Op59jqxFEnrs1u9AGOowHH0YHjGMBxTOAtFpiNDRz7CuUvNnATB7iJC9z4Ajd+YN9OMBsHuPETcuMP3MQDbgKAm0DgJj7YdwIwGxe4cdrsxli6C3317advp6Ub/dVzPHUC1Am02Y0JgeNEwHFi4DgJcJwUeEsGZuMBx/GF8pccuEkB3KQEblIBN6nBvtOA2QDgJoGQm7TATTrgJj1wkwG4yQj2nQnMBgI3CW12o7/uwvj6TqDvhJZuTKSeE6uTRJ2kNrsxM3CcBTjOChxnA46zA285wGxi4DiZUP5yAje5gJvcwE0e4CYv2Hc+MJsEuEku5CY/cFMAuCkI3BQCbgqDfRcBs0mBmxQ2uzGR7sJk+k6u7xSWbkypnlOpk1qdNDa7sShwXAw4Lg4clwCOSwJvpcBsKuA4rVD+SgM3ZYCbssBNOeCmPNh3BTCbGrhJJ+SmInBTCbipDNxUAW6qgn1XI5//gZv0Nrsxpe7CtPpOp+/0lm7MoJ4zqpNJncw2u7E6cFwDOK4JHNcCjmsDb3XAbEbgOItQ/uoCN/WAm/rATQPgpiHYdyPyMx5wk1XITWPgpglw0xS4aQbcNAf7bgFmMwM32Wx2YwbdhVn0nVXf2SzdmF0951Anpzq5bHZjS+C4FXDcGjhuAxy3Bd7akZ+/gePcQvlrD9x0AG46AjedgJvOYN9dwGxO4CaPkJuuwE034KY7cNMDuOkJ9t0LzOYCbvLa7Mbsugtz6zuPvvNaujGfes6vTgF1Ctrsxt7AcR/guC9w3A847g+8DQCz+YHjQkL5GwjcDAJuBgM3Q4CboWDfw8BsAeCmsJCb4cDNCOBmJHAzCrgZDfY9BswWBG6K2OzGfLoLC+m7sL6LWLqxqHoupk5xdUrY7MaxwPE44Hg8cDwBOJ4IvE0Cs8WA45JC+ZsM3EwBbqYCN9OAm+lg3zPAbHHgppSQm5nAzSzgZjZwMwe4mQv2PQ/MlgBuStvsxqK6C0vqu5S+S1u6sYx6LqtOOXXK2+zG+cDxAuB4IXC8CDheDLwtAbNlgeMKQvlbCtwsA26WAzcrgJuVYN+rwGw54KaikJvVwM0a4GYtcLMOuFkP9r0BzJYHbirZ7MYyugsr6LuivitZurGyeq6iTlV1qtnsxo3A8SbgeDNwvAU43gq8bQOzVYDj6kL52w7c7ABudgI3u4Cb3WDfe8BsVeCmhpCbvcDNPuBmP3BzALg5CPZ9iPw7beCmps1urKy7sLq+a+i7pqUba6nn2urUUaeuzW48DBwfAY6PAsfHgOPjwNsJMFsbOK4nlL+TwM0p4OY0cHMGuDkL9n2O/L83AG7qC7k5D9xcAG4uAjeXgJvLYN9XwGxd4KaBzW6spbuwnr7r67uBpRsbqudG6jRWp4nNbrwKHF8Djq8DxzeA45vA2y3y/6YEOG4qlL/bwM0d4OYucHMPuLkP9v0AzDYGbpoJuXkI3DwCbh4DN0+Am6dg38/AbBPgprnNbmyou7Cpvpvpu7mlG1uo55bqtFKntc1ufA4cvwCOXwLHr4Dj18DbGzDbEjhuI5S/t8DNO+DmPXDzAbj5CPb9Ccy2Am7aCrn5DNx8AW6+AjffgJvvYN8/wGxr4KadzW5sobuwjb7b6rudpRvbq+cO6nRUp9PfuvGPGedf/xEc//brJ3D864s7HUa/gnUAO+ss9P0cLKT5P2vwkObfzyFCmn8/hwxp/v0cCuw7NJjtCNx0EXITBrgJC9yEA27CAzcRwL4jgtlOwE1Xm13TXndLZ3130XdXS9d0U8/d1emhTk+bn8MiAceRgeMowLEHcOwJvEUFs92B415C+fMCbryBGx/gJhpwEx3sOwaY7QHc9BZyExO4iQXcxAZu4gA3ccG+fcFsT+Cmj81u7Ka7sJe+e+u7j6Ub+6rnfur0V2eAzW70A46dwLE/cBwPOA4A3gLBbD/geKBQ/uIDNwmAm4TATSLgJjHYdxIw2x+4GSTkJilwkwy4SQ7cpABuUoJ9pwKzA4CbwTa7sa/uwoH6HqTvwZZuHKKeh6ozTJ3hNrsxNXCcBjhOCxynA47TA28ZwOxQ4HiEUP4yAjeZgJvMwE0W4CYr2Hc2MDsMuBkp5CY7cJMDuMkJ3OQCbnKDfecBs8OBm1E2u3GI7sIR+h6p71GWbhytnseoM1adcTa7MS9wnA84zg8cFwCOCwJvhcDsGOB4vFD+CgM3RYCbosBNMeCmONh3CTA7FriZIOSmJHBTCrgpDdyUAW7Kgn2XA7PjgJuJNrtxtO7C8fqeoO+Jlm6cpJ4nqzNFnak2u7E8cFwBOK4IHFcCjisDb1XA7GTgeJpQ/qoCN9WAm+rATQ3gpibYdy0wOwW4mS7kpjZwUwe4qQvc1ANu6oN9NwCzU4GbGTa7cZLuwmn6nq7vGZZunKmeZ6kzW505NruxIXDcCDhuDBw3AY6bAm/NwOws4HiuUP6aAzctgJuWwE0r4KY12HcbMDsbuJkn5KYtcNMOuGkP3HQAbjqSf/cMZucAN/NtduNM3YVz9T1P3/Mt3bhAPS9UZ5E6i212Y2fguAtw3BU47gYcdyf/fhPMLgSOlwjlrydw0wu46Q3c9AFu+pJ/9wVmFwE3S4Xc9AduBgA3A4GbQcDNYLDvIWB2MXCzzGY3LtBduETfS/W9zNKNy9XzCnVWqrPKZjcOBY6HAcfDgeMRwPFI4G0UmF0BHK8Wyt9o4GYMcDMWuBkH3IwH+54AZlcCN2uE3EwEbiYBN5OBmynAzVSw72lgdhVws9ZmNy7XXbha32v0vdbSjevU83p1Nqiz0WY3TgeOZwDHM4HjWcDxbPJ5H8yuB443CeVvLnAzD7iZD9wsAG4Wks+CYHYDcLNZyM1i4GYJcLMUuFkG3CwnnxPA7EbgZovNblynu3CTvjfre4ulG7eq523qbFdnh81uXAkcrwKOVwPHa4DjtcDbOjC7DTjeKZS/9cDNBuBmI3CzCbjZDPa9BcxuB252CbnZCtxsA262Azc7gJudYN+7wOwO4Ga3zW7cqrtwp7536Xu3pRv3qOe96uxTZ7/NbtwNHO8BjvcCx/uA4/3A2wEwuxc4PiCUv4PAzSHg5jBwcwS4OQr2fQzM7gNuDgq5OQ7cnABuTgI3p4Cb02DfZ8DsfuDmkM1u3KO78IC+D+r7kKUbD6vnI+ocVeeYzW48CxyfA47PA8cXgOOLwNslMHsEOD4ulL/LwM0V4OYqcHMNuLkO9n0DzB4Fbk4IubkJ3NwCbm4DN3eAm7tg3/fIOw64OWmzGw/rLjyu7xP6PmnpxlPq+bQ6Z9Q5a7Mb7wPHD4Djh8DxI+D4MfD2BMyeBo7PCeXvKXDzDLh5Dty8AG5egn2/Ip9jgJvzQm5eAzdvgJu3wM074OY92PcHMHsWuLlgsxtP6S48p+/z+r5g6caL6vmSOpfVuWKzGz8Cx5+A48/A8Rfg+Cvw9o18xgSOrwrl7ztw8wO4+QncOEKZuwkWynzfwcHsZeDmmpCbEKHM3YQMZe4mVChzN6GBmzBg32HB7BXg5rrNbryou/Cqvq/p+7qlG2+o55vq3FLnts1uDAcchweOIwDHEYHjSMBbZDB7Ezi+I5S/KMCNB3DjCdxEBW68wL69wewt4OaukBsf4CYacBMduIkB3MQE+44FZm8DN/dsduMN3YV39H1X3/cs3XhfPT9Q56E6j2x2Y2zgOA5wHBc49gWO/YA3J5h9ABw/FsqfP3ATD7gJAG4CgZv4YN8JwOxD4OaJkJuEwE0i4CYxcJMEuEkK9p0MzD4Cbp7a7Mb7ugsf6/uJvp9auvGZen6uzgt1XtrsxuTAcQrgOCVwnAo4Tg28pQGzz4HjV0L5SwvcpANu0gM3GYCbjGDfmcDsC+DmtZCbzMBNFuAmK3CTDbjJDvadA8y+BG7e2OzGZ7oLX+n7tb7fWLrxrXp+p857dT7Y7MacwHEu4Dg3cJwHOM4LvOUDs++A449C+csP3BQAbgoCN4WAm8Jg30XA7Hvg5pOQm6LATTHgpjhwUwK4KQn2XQrMfgBuPtvsxre6Cz/q+5O+P1u68Yt6/qrON3W+2+zG0sBxGeC4LHBcDjguD7xVALNfgeMfQvmrCNxUAm4qAzdVgJuqYN/VwOw34OankJvqwE0N4KYmcFMLuKkN9l0HzH4HbhxD7HXjF92FP/T9U9+/vu6fc+o5uDohfv3PhvwVljquCxzXA47rA8cNgOOGwFsj8u9Nh5g7DgUcW39RN42BmybATVPgphlw0xzsuwWYDQHchBZy0xK4aQXctAZu2gA3bcG+24HZkMBNGJvd+Kv3ft2h9B1a32Es3RhWPYdTJ7w6EWx2Y3vguANw3BE47gQcdwbeuoDZcMBxRKH8dQVuugE33YGbHsBNT7DvXmA2PHATSchNb+CmD3DTF7jpB9z0B/seAGYjADeRbXZjWN2FEfUdSd+RLd0YRT17qOOpTlSb3TgQOB4EHA8GjocAx0OBt2Fg1gM49hLK33DgZgRwMxK4GQXcjAb7HgNmPYEbbyE3Y4GbccDNeOBmAnAzEex7EpiNCtz42OzGKLoLvfTtrW8fSzdGU8/R1YmhTkyb3TgZOJ4CHE8FjqcBx9OBtxlgNjpwHEsofzOBm1nAzWzgZg5wMxfsex6YjQHcxBZyMx+4WQDcLARuFgE3i8G+l4DZmMBNHJvdGE13YSx9x9Z3HEs3xlXPvur4/fqzbHbjUuB4GXC8HDheARyvBN5WgVlf4NhfKH+rgZs1wM1a4GYdcLMe7HsDmPUDbuIJudkI3GwCbjYDN1uAm61g39vArBO4CbDZjXF1F/rrO56+AyzdGKie46uTQJ2ENrtxO3C8AzjeCRzvAo53A297wGx84DiRUP72Ajf7gJv9wM0B4OYg2PchMJsAuEks5OYwcHMEuDkK3BwDbo6DfZ8AswmBmyQ2uzFQd2EifSfWdxJLNyZVz8nUSa5OCpvdeBI4PgUcnwaOzwDHZ4G3c2A2GXCcUih/54GbC8DNReDmEnBzGez7CphNDtykEnJzFbi5BtxcB25uADc3wb5vgdkUwE1qm92YVHdhSn2n0ndqSzemUc9p1UmnTnqb3XgbOL4DHN8Fju8Bx/eBtwdgNi1wnEEofw+Bm0fAzWPg5glw8xTs+xmYTQfcZBRy8xy4eQHcvARuXgE3r8G+34DZ9MBNJpvdmEZ3YQZ9Z9R3Jks3ZlbPWdTJqk42m934Fjh+Bxy/B44/AMcfgbdPYDYLcJxdKH+fgZsvwM1X4OYbcPMd7PsHmM0K3ORw0c0f2XL+9Y92/Nuvn8CNI7T5P2s28M+a02bXZNbdkl3fOfSd09I1udRzbnXyqJPXZtcEC22+s+Chzb+fQ4Q2/34OGdr8+zkU8BYazOYGjvMJdU0Y4CYscBMOuAkP3EQA+44IZvMAN/mF3EQCbiIDN1GAGw/gxhPsOyqYzQvcFLDZjbl0F+bTd359F7B0Y0H1XEidwuoUsdmNXsCxN3DsAxxHA46jA28xwGwh4LioUP5iAjexgJvYwE0c4CYu2LcvmC0M3BQTcuMH3DiBG3/gJh5wEwD2HQhmiwA3xW12Y0HdhUX1XUzfxS3dWEI9l1SnlDqlbXZjfOA4AXCcEDhOBBwnBt6SgNmSwHEZofwlBW6SATfJgZsUwE1KsO9UYLYUcFNWyE1q4CYNcJMWuEkH3KQH+84AZksDN+VsdmMJ3YVl9F1W3+Us3VhePVdQp6I6lWx2Y0bgOBNwnBk4zgIcZyV/FwJmKwDHlYXylx24yQHc5ARucgE3ucnPyWC2InBTRchNXuAmH3CTH7gpANwUJD9DgdlKwE1Vm91YXndhZX1X0XdVSzdWU8/V1amhTk2b3VgYOC4CHBcFjosBx8WBtxJgtjpwXEsofyWBm1LATWngpgxwUxbsuxyYrQHc1BZyUx64qQDcVARuKgE3lcG+q4DZmsBNHZvdWE13YS1919Z3HUs31lXP9dSpr04Dm91YFTiuBhxXB45rAMc1gbdaYLYecNxQKH+1gZs6wE1d4KYecFMf7LsBmK0P3DQSctMQuGkE3DQGbpoAN03BvpsRj8BNY5vdWFd3YUN9N9J3Y0s3NlHPTdVppk5zm93YHDhuARy3BI5bAcetgbc2YLYpcNxCKH9tgZt2wE174KYDcNMR7LsTySpw01LITWfgpgtw0xW46QbcdAf77gFmmwM3rWx2YxPdhS303VLfrSzd2Fo9t1GnrTrtbHZjT+C4F3DcGzjuAxz3Bd76kR4FjtsL5a8/cDMAuBkI3AwCbgaDfQ8Bs22Bmw5CboYCN8OAm+HAzQjgZiTY9ygw2w646WizG1vrLmyv7w767mjpxk7qubM6XdTparMbRwPHY4DjscDxOOB4PPA2Acx2Bo67CeVvInAzCbiZDNxMAW6mgn1PA7NdgJvuQm6mAzczgJuZwM0s4GY22PccMNsVuOlhsxs76S7spu/u+u5h6cae6rmXOr3V6WOzG+cCx/OA4/nA8QLgeCHwtgjM9gKO+wrlbzFwswS4WQrcLANuloN9rwCzvYGbfkJuVgI3q4Cb1cDNGuBmLdj3OjDbB7jpb7Mbe+ou7Kvvfvrub+nGAep5oDqD1BlssxvXA8cbgOONwPEm4Hgz8LYFzA4EjocI5W8rcLMNuNkO3OwAbnaCfe8Cs4OAm6FCbnYDN3uAm73AzT7gZj/Y9wEwOxi4GWazGwfoLhyi76H6HmbpxuHqeYQ6I9UZZbMbDwLHh4Djw8DxEeD4KPB2DMyOAI5HC+XvOHBzArg5CdycAm5Og32fAbMjgZsxQm7OAjfngJvzwM0F4OYi2Pcl8neTwM1Ym904XHfhaH2P0fdYSzeOU8/j1ZmgzkSb3XgZOL4CHF8Fjq8Bx9eBtxtgdjxwPEkofzeBm1vAzW3g5g5wcxfs+x75e2PgZrKQm/vAzQPg5iFw8wi4eQz2/QTMTgRuptjsxnG6Cyfpe7K+p1i6cap6nqbOdHVm2OzGp8DxM+D4OXD8Ajh+Cby9Iv9uADieKZS/18DNG+DmLXDzDrh5D/b9AcxOB25mCbn5CNx8Am4+AzdfgJuvYN/fwOwM4Ga2zW6cqrtwpr5n6Xu2pRvnqOe56sxTZ77NbvwOHP8Ajn8Cx44w5o6DGc3+PhoczM4FjhcI5S9EGHM3IcOYuwkVxtxNaOAmDNh3WDA7D7hZKOQmHHATHriJANxEBG4igX1HBrPzgZtFNrtxju7CBfpeqO9Flm5crJ6XqLNUnWU2uzEKcOwBHHsCx1GBYy/gzRvMLgGOlwvlzwe4iQbcRAduYgA3McG+Y4HZpcDNCiE3sYGbOMBNXODGF7jxA/t2gtllwM1Km924WHfhcn2v0PdKSzeuUs+r1Vmjzlqb3egPHMcDjgOA40DgOD7wlgDMrgaO1wnlLyFwkwi4SQzcJAFukoJ9JwOza4Cb9UJukgM3KYCblMBNKuAmNdh3GjC7FrjZYLMbV+kuXKfv9freYOnGjep5kzqb1dlisxvTAsfpgOP0wHEG4Dgj8JYJzG4CjrcK5S8zcJMFuMkK3GQDbrKDfecAs5uBm21CbnICN7mAm9zATR7gJi/Ydz4wuwW42W6zGzfqLtyq72363m7pxh3qeac6u9TZbbMb8wPHBYDjgsBxIeC4MPBWBMzuBI73COWvKHBTDLgpDtyUAG5Kgn2XArO7gJu9Qm5KAzdlgJuywE054KY82HcFMLsbuNlnsxt36C7co++9+t5n6cb96vmAOgfVOWSzGysCx5WA48rAcRXguCrwVg3MHgCODwvlrzpwUwO4qQnc1AJuaoN91wGzB4GbI0Ju6gI39YCb+sBNA+CmIdh3IzB7CLg5arMb9+suPKzvI/o+aunGY+r5uDon1DlpsxsbA8dNgOOmwHEz4Lg58NYCzB4Hjk8J5a8lcNMKuGkN3LQBbtqCfbcDsyeAm9NCbtoDNx2Am47ATSfgpjPYdxcwexK4OWOzG4/pLjyl79P6PmPpxrPq+Zw659W5YLMbuwLH3YDj7sBxD+C4J/DWC8yeA44vCuWvN3DTB7jpC9z0A276g30PALPngZtLQm4GAjeDgJvBwM0Q4GYo2PcwMHsBuLlssxvP6i68qO9L+r5s6cYr6vmqOtfUuW6zG4cDxyOA45HA8SjgeDTwNgbMXgWObwjlbyxwMw64GQ/cTABuJoJ9TwKz14Cbm0JuJgM3U4CbqcDNNOBmOtj3DDB7Hbi5ZbMbr+guvKHvm/q+ZenG2+r5jjp31blnsxtnAsezgOPZwPEc4Hgu8DYPzN4Bju8L5W8+cLMAuFkI3CwCbhaDfS8Bs3eBmwdCbpYCN8uAm+XAzQrgZiXY9yowew+4eWizG2/rLryv7wf6fmjpxkfq+bE6T9R5arMbVwPHa4DjtcDxOuB4PfC2Acw+Bo6fCeVvI3CzCbjZDNxsAW62gn1vA7NPgJvnQm62Azc7gJudwM0u4GY32PceMPsUuHlhsxsf6S58pu/n+n5h6caX6vmVOq/VeWOzG/cCx/uA4/3A8QHg+CD5d2hg9hVw/FYof4eBmyPAzVHg5hhwc5z8+xUw+xq4eSfk5iRwcwq4OQ3cnAFuzpK/ewezb4Cb9za78aXuwrf6fqfv95Zu/KCeP6rzSZ3PNrvxPHB8ATi+CBxfAo4vA29XwOxH4PiLUP6uAjfXgJvrwM0N4OYm2PctMPsJuPkq5OY2cHMHuLkL3NwDbu6DfT8As5+Bm282u/GD7sIv+v6q72+Wbvyunn+o8/NXLw79Kyx1/BA4fgQcPwaOnwDHT4G3Z2D2B3AcbKhM/p4DNy+Am5fAzSvg5jX5vAFmfwI3wYXcvAVu3gE374GbD8DNR/IuArOOoeZuQgA3/9SN33UX/srfrzu4vn993T/mQqrnUOqEVieMzW78DBx/AY6/AsffgOPvpO/AbCjgOKyL+fvDn/Ovf7Tj3379BG5+iXc6jH4FCw3+WcPZ/H4Oqb9/w+o7nL7DWL6fw6vnCOpEVCfS376fg+vbachrnQ1qDxGGGs/+9TdCpsj/8eeknFO5bsy0c6f9CL11efguflus/7swf/tz/vqn/wNXWPPvl+BhzbMcIqx5lkOGNc9yKPI9G9Z831FczCfddxiw77Bg3+HAvsODfUcA+44I9u1hsyMiD/3fP9KvO4r+v3tYOsJTPUdVx0sdb5vvvEjAW2TgLQrw5gG8eQJvUckseA/4CH3m9AJuvIEbH+AmGnATHew7Bpj1Am6iCbmJCdzEAm5iAzdxgJu4YN++YNYbuIlusxs9dRf66DuavqNbujGGeo6pTix1YtvsRj/g2Akc+wPH8YDjAOAtEMzGBI7jCOUvPnCTALhJCNwkAm4Sg30nAbOxgJu4Qm6SAjfJgJvkwE0K4CYl2HcqMBsbuPG12Y0xdBfG0XdcfftautHv15+hjr868Wx2Y2rgOA1wnBY4TgccpwfeMoBZJ3AcIJS/jMBNJuAmM3CTBbjJCvadDcz6AzeBQm6yAzc5gJucwE0u4CY32HceMBsPuIlvsxv9dBcG6DtQ3/Et3ZhAPSdUJ5E6iW12Y17gOB9wnB84LgAcFwTeCoHZhMBxEqH8FQZuigA3RYGbYsBNcbDvEmA2EXCTVMhNSeCmFHBTGrgpA9yUBfsuB2YTAzfJbHZjAt2FSfSdVN/JLN2YXD2nUCelOqlsdmN54LgCcFwROK4EHFcG3qqA2RTAcWqh/FUFbqoBN9WBmxrATU2w71pgNiVwk0bITW3gpg5wUxe4qQfc1Af7bkB+/gZu0trsxuS6C1PrO42+01q6MZ16Tq9OBnUy2uzGhsBxI+C4MXDcBDhuCrw1A7PpgeNMQvlrDty0AG5aAjetgJvWYN9tyN+NADeZhdy0BW7aATftgZsOwE1HsO9OYDYjcJPFZjem012YSd+Z9Z3F0o1Z1XM2dbKrk8NmN3YGjrsAx12B427AcXfgrQf5+y/gOKdQ/noCN72Am97ATR/gpi/Ydz8wmx24ySXkpj9wMwC4GQjcDAJuBoN9DwGzOYCb3Da7Mavuwpz6zqXv3JZuzKOe86qTT538NrtxKHA8DDgeDhyPAI5HAm+jwGxe4LiAUP5GAzdjgJuxwM044GY82PcEMJsPuCko5GYicDMJuJkM3EwBbqaCfU8Ds/mBm0I2uzGP7sIC+i6o70KWbiysnouoU1SdYja7cTpwPAM4ngkczwKOZwNvc8BsEeC4uFD+5gI384Cb+cDNAuBmIdj3IjBbFLgpIeRmMXCzBLhZCtwsA26Wg32vALPFgJuSNruxsO7C4vouoe+Slm4spZ5Lq1NGnbI2u3ElcLwKOF4NHK8BjtcCb+vAbGnguJxQ/tYDNxuAm43AzSbgZjPY9xYwWwa4KS/kZitwsw242Q7c7ABudoJ97wKzZYGbCja7sZTuwnL6Lq/vCpZurKieK6lTWZ0qNrtxN3C8BzjeCxzvA473A28HwGwl4LiqUP4OAjeHgJvDwM0R4OYo2PcxMFsZuKkm5OY4cHMCuDkJ3JwCbk6DfZ8Bs1WAm+o2u7Gi7sKq+q6m7+qWbqyhnmuqU0ud2ja78SxwfA44Pg8cXwCOLwJvl8BsTeC4jlD+LgM3V4Cbq8DNNeDmOtj3DTBbC7ipK+TmJnBzC7i5DdzcAW7ugn3fA7O1gZt6Nruxhu7COvquq+96lm6sr54bqNNQnUY2u/E+cPwAOH4IHD8Cjh8Db0/AbAPguLFQ/p4CN8+Am+fAzQvg5iXY9ysw2xC4aSLk5jVw8wa4eQvcvANu3oN9fwCzjYCbpja7sb7uwsb6bqLvppZubKaem6vTQp2WNrvxI3D8CTj+DBx/AY6/Am/fwGxz4LiVUP6+Azc/gJufwI0jnLmbYOHM9x0czLYAbloLuQkRztxNyHDmbkKFM3cTGrgJA/YdFsy2BG7a2OzGZroLW+m7tb7bWLqxrXpup057dTrY7MZwwHF44DgCcBwROI4EvEUGs+2A445C+YsC3HgAN57ATVTgxgvs2xvMtgduOgm58QFuogE30YGbGMBNTLDvWGC2A3DT2WY3ttVd2FHfnfTd2dKNXdRzV3W6qdPdZjfGBo7jAMdxgWNf4NgPeHOC2a7AcQ+h/PkDN/GAmwDgJhC4iQ/2nQDMdgNuegq5SQjcJAJuEgM3SYCbpGDfycBsd+Cml81u7KK7sIe+e+q7l6Ube6vnPur0VaefzW5MDhynAI5TAsepgOPUwFsaMNsHOO4vlL+0wE064CY9cJMBuMkI9p0JzPYFbgYIuckM3GQBbrICN9mAm+xg3znAbD/gZqDNbuytu7C/vgfoe6ClGwep58HqDFFnqM1uzAkc5wKOcwPHeYDjvMBbPjA7GDgeJpS//MBNAeCmIHBTCLgpDPZdBMwOAW6GC7kpCtwUA26KAzclgJuSYN+lwOxQ4GaEzW4cpLtwmL6H63uEpRtHqudR6oxWZ4zNbiwNHJcBjssCx+WA4/LAWwUwOwo4HiuUv4rATSXgpjJwUwW4qQr2XQ3MjgZuxgm5qQ7c1ABuagI3tYCb2mDfdcDsGOBmvM1uHKm7cKy+x+l7vKUbJ6jniepMUmeyzW6sCxzXA47rA8cNgOOGwFsjMDsROJ4ilL/GwE0T4KYpcNMMuGlO/t0zmJ0E3EwVctMSuGkF3LQGbtoAN23Jv5cEs5OBm2k2u3GC7sIp+p6q72mWbpyunmeoM1OdWTa7sT1w3AE47ggcdwKOOwNvXcDsDOB4tlD+ugI33YCb7sBND+CmJ9h3LzA7E7iZI+SmN3DTB7jpC9z0A276g30PALOzgJu5Nrtxuu7C2fqeo++5lm6cp57nq7NAnYU2u3EgcDwIOB4MHA8BjocCb8PA7HzgeJFQ/oYDNyOAm5HAzSjgZjT5WQzMLgBuFgu5GQvcjANuxgM3E4CbieRzOphdCNwssdmN83QXLtL3Yn0vsXTjUvW8TJ3l6qyw2Y2TgeMpwPFU4HgacDydfBYEs8uA45VC+ZsJ3MwCbmYDN3OAm7lg3/PA7HLgZpWQm/nAzQLgZiFwswi4WQz2vQTMrgBuVtvsxqW6C1fqe5W+V1u6cY16XqvOOnXW2+zGpcDxMuB4OXC8AjheCbytArNrgeMNQvlbDdysAW7WAjfrgJv1YN8bwOw64GajkJuNwM0m4GYzcLMFuNkK9r0NzK4HbjbZ7MY1ugs36HujvjdZunGzet6izlZ1ttnsxu3A8Q7geCdwvAs43g287QGzW4Dj7UL52wvc7ANu9gM3B4Cbg2Dfh8DsVuBmh5Cbw8DNEeDmKHBzDLg5DvZ9gvQocLPTZjdu1l24Xd879L3T0o271PNudfaos9dmN54Ejk8Bx6eB4zPA8Vng7RyY3Q0c7xPK33ng5gJwcxG4uQTcXAb7vkLeccDNfiE3V4Gba8DNdeDmBnBzE+z7FpjdC9wcsNmNu3QX7tP3fn0fsHTjQfV8SJ3D6hyx2Y23geM7wPFd4PgecHwfeHtAPscAx0eF8vcQuHkE3DwGbp4AN0/Bvp+B2cPAzTEhN8+BmxfAzUvg5hVw8xrs+w2YPQLcHLfZjQd1Fx7V9zF9H7d04wn1fFKdU+qcttmNb4Hjd8Dxe+D4A3D8EXj7BGZPAsdnhPL3Gbj5Atx8BW6+ATffwb5/gNlTwM1ZF938kS3nX/9ox7/9+gncOMKb/7OeBv+s52x2zQndLWf0fVbf5yxdc149X1DnojqXbHZNsPDmOwse3vz7OUR48+/nkOHNv59DAW+hwewF4PiyUNeEAW7CAjfhgJvwwE0EsO+IYPYicHNFyE0k4CYycBMFuPEAbjzBvqOC2UvAzVWb3Xhed+FlfV/R91VLN15Tz9fVuaHOTZvd6AUcewPHPsBxNOA4OvAWA8xeB45vCeUvJnATC7iJDdzEAW7ign37gtkbwM1tITd+wI0TuPEHbuIBNwFg34Fg9iZwc8dmN17TXXhL37f1fcfSjXfV8z117qvzwGY3xgeOEwDHCYHjRMBxYuAtCZi9Bxw/FMpfUuAmGXCTHLhJAdykBPtOBWbvAzePhNykBm7SADdpgZt0wE16sO8MYPYBcPPYZjfe1V34UN+P9P3Y0o1P1PNTdZ6p89xmN2YEjjMBx5mB4yzAcVbgLRuYfQocvxDKX3bgJgdwkxO4yQXc5Ab7zgNmnwE3L4Xc5AVu8gE3+YGbAsBNQbDvQmD2OXDzymY3PtFd+ELfL/X9ytKNr9XzG3XeqvPOZjcWBo6LAMdFgeNiwHFx4K0EmH0DHL8Xyl9J4KYUcFMauCkD3JQF+y4HZt8CNx+E3JQHbioANxWBm0rATWWw7ypg9h1w89FmN77WXfhe3x/0/dHSjZ/U82d1vqjz1WY3VgWOqwHH1YHjGsBxTeCtFpj9DBx/E8pfbeCmDnBTF7ipB9zUB/tuAGa/ADffhdw0BG4aATeNgZsmwE1TsO9mYPYrcPPDZjd+0l34Td/f9f3D0o0/f/XhMPU/Vyf4sL/CUsfNgeMWwHFL4LgVcNwaeGsDZn/t84/ZoByHGCaTv7bATTvgpj1w0wG46Qj23QnMBgNuQgq56QzcdAFuugI33YCb7mDfPcBscOAmFHDzT934U3fhr/z9ukPq+9fX/WMutHoOo05YdcLZ7MaewHEv4Lg3cNwHOO4LvPUDs2GA4/BC+esP3AwAbgYCN4OAm8Fg30PAbFjgJoKQm6HAzTDgZjhwMwK4GQn2PQrMhgNuItrsxtC6C8PrO4K+I1q6MZJ6jqxOFHU8bHbjaOB4DHA8FjgeBxyPB94mgNnIwLGnUP4mAjeTgJvJwM0U4GYq2Pc0MBsFuIkq5GY6cDMDuJkJ3MwCbmaDfc8Bsx7AjZfNboyku9BT31H17WXpRm/17KNONHWi2+zGucDxPOB4PnC8ADheCLwtArM+wHEMofwtBm6WADdLgZtlwM1ysO8VYDYacBNTyM1K4GYVcLMauFkD3KwF+14HZqMDN7FsdqO37sIY+o6p71iWboytnuOoE1cdX5vduB443gAcbwSONwHHm4G3LWA2DnDsJ5S/rcDNNuBmO3CzA7jZCfa9C8zGBW6cQm52Azd7gJu9wM0+4GY/2PcBMOsL3Pjb7MbYugv99O3Ut7+lG+Op5wB1AtWJb7MbDwLHh4Djw8DxEeD4KPB2DMwGAMcJhPJ3HLg5AdycBG5OATenwb7PgNlA4CahkJuzwM054OY8cHMBuLkI9n0JzMYHbhLZ7MZ4ugsT6DuhvhNZujGxek6iTlJ1ktnsxsvA8RXg+CpwfA04vg683QCzSYDj5EL5uwnc3AJubgM3d4Cbu2Df98BsUuAmhZCb+8DNA+DmIXDzCLh5DPb9BMwmA25S2uzGxLoLk+s7hb5TWroxlXpOrU4addLa7ManwPEz4Pg5cPwCOH4JvL0Cs6mB43RC+XsN3LwBbt4CN++Am/dg3x/AbBrgJr2Qm4/AzSfg5jNw8wW4+Qr2/Q3MpgVuMtjsxlS6C9PpO72+M1i6MaN6zqROZnWy2OzG78DxD+D4J3DsiGDuOJjR7O+jwcFsJuA4q1D+QkQwdxMygrmbUBHM3YQGbsKAfYcFs5mBm2xCbsIBN+GBmwjATUTgJhLYd2QwmwW4yW6zGzPqLsyq72z6zm7pxhzqOac6udTJbbMbowDHHsCxJ3AcFTj2At68wWxO4DiPUP58gJtowE104CYGcBMT7DsWmM0F3OQVchMbuIkD3MQFbnyBGz+wbyeYzQ3c5LPZjTl0F+bRd15957N0Y371XECdguoUstmN/sBxPOA4ADgOBI7jA28JwGwB4LiwUP4SAjeJgJvEwE0S4CYp2HcyMFsQuCki5CY5cJMCuEkJ3KQCblKDfacBs4WAm6I2uzG/7sLC+i6i76KWbiymnourU0Kdkja7MS1wnA44Tg8cZwCOM5Kfk8FsceC4lFD+MgM3WYCbrMBNNuAmO9h3DjBbArgpLeQmJ3CTC7jJDdzkAW7ygn3nA7MlgZsyNruxmO7CUvoure8ylm4sq57LqVNenQo2uzE/cFwAOC4IHBcCjgsDb0XAbDnguKJQ/ooCN8WAm+LATQngpiTYdykwWx64qSTkpjRwUwa4KQvclANuyoN9VyCzwE1lm91YVndhRX1X0ndlSzdWUc9V1ammTnWb3VgROK4EHFcGjqsAx1WBt2pgtipwXEMof9WBmxrATU3gphZwUxvsuw7xCNzUFHJTF7ipB9zUB24aADcNwb4bgdnqwE0tm91YRXdhDX3X1HctSzfWVs911KmrTj2b3dgYOG4CHDcFjpsBx82BtxYkq8BxfaH8tQRuWgE3rYGbNsBNW7DvdmC2LnDTQMhNe+CmA3DTEbjpBNx0BvvuAmbrATcNbXZjbd2F9fXdQN8NLd3YSD03VqeJOk1tdmNX4LgbcNwdOO4BHPcE3nqB2cbAcTOh/PUGbvoAN32Bm37ATX+w7wFgtglw01zIzUDgZhBwMxi4GQLcDAX7HgZmmwI3LWx2YyPdhc303VzfLSzd2FI9t1KntTptbHbjcOB4BHA8EjgeBRyPBt7GgNlWwHFbofyNBW7GATfjgZsJwM1EsO9JYLY1cNNOyM1k4GYKcDMVuJkG3EwH+54BZtsAN+1tdmNL3YVt9d1O3+0t3dhBPXdUp5M6nW1240zgeBZwPBs4ngMczwXe5oHZjsBxF6H8zQduFgA3C4GbRcDNYrDvJWC2E3DTVcjNUuBmGXCzHLhZAdysBPteBWY7AzfdbHZjB92FXfTdVd/dLN3YXT33UKenOr1sduNq4HgNcLwWOF4HHK8H3jaA2R7AcW+h/G0EbjYBN5uBmy3AzVaw721gtidw00fIzXbgZgdwsxO42QXc7Ab73kP+3gq46WuzG7vrLuyt7z767mvpxn7qub86A9QZaLMb9wLH+4Dj/cDxAeD4IPB2CMz2B44HCeXvMHBzBLg5CtwcA26Og32fIH83CdwMFnJzErg5BdycBm7OADdnwb7PgdmBwM0Qm93YT3fhIH0P1vcQSzcOVc/D1Bmuzgib3XgeOL4AHF8Eji8Bx5eBtyvk75+B45FC+bsK3FwDbq4DNzeAm5tg37fA7HDgZpSQm9vAzR3g5i5wcw+4uQ/2/QDMjgBuRtvsxqG6C0fqe5S+R1u6cYx6HqvOOHXG2+zGh8DxI+D4MXD8BDh+Crw9A7NjgeMJQvl7Dty8AG5eAjevgJvXYN9vwOw44GaikJu3wM074OY9cPMBuPkI9v0JzI4HbibZ7MYxugsn6HuividZunGyep6izlR1ptnsxs/A8Rfg+Ctw/A04/g68/QCzU4Dj6S7m7w9/zr/+0Y5/+/UTuPn1jeR0GP0KNhX8s84Q6ppgEc3/WYNHNP8+DBHR/PswZETz78NQYN+hwew04Gamza6ZrLtlur5n6HumpWtmqefZ6sxRZ67NrgkDHIcFjsMBx+GB4wjAW0QwOxs4nieUv0jATWTgJgpw4wHceIJ9RwWzc4Cb+UJuvIAbb+DGB7iJBtxEB/uOAWbnAjcLbHbjLN2F8/Q9X98LLN24UD0vUmexOktsdmNM4DgWcBwbOI4DHMcF3nzB7CLgeKlQ/vyAGydw4w/cxANuAsC+A8HsYuBmmZCb+MBNAuAmIXCTCLhJDPadBMwuAW6W2+zGhboLl+p7mb6XW7pxhXpeqc4qdVbb7MakwHEy4Dg5cJwCOE4JvKUCsyuB4zVC+UsN3KQBbtICN+mAm/Rg3xnA7CrgZq2Qm4zATSbgJjNwkwW4yQr2nQ3MrgZu1tnsxhW6C9foe62+11m6cb163qDORnU22ezG7MBxDuA4J3CcCzjODbzlAbMbgOPNQvnLC9zkA27yAzcFgJuCYN+FwOxG4GaLkJvCwE0R4KYocFMMuCkO9l0CzG4Cbrba7Mb1ugs363uLvrdaunGbet6uzg51dtrsxpLAcSnguDRwXAY4Lgu8lQOz24HjXUL5Kw/cVABuKgI3lYCbymDfVcDsDuBmt5CbqsBNNeCmOnBTA7ipCfZdC8zuBG722OzGbboLd+l7t773WLpxr3rep85+dQ7Y7MbawHEd4LgucFwPOK4PvDUAs/uA44NC+WsI3DQCbhoDN02Am6Zg383A7H7g5pCQm+bATQvgpiVw0wq4aQ323QbMHgBuDtvsxr26Cw/q+5C+D1u68Yh6PqrOMXWO2+zGtsBxO+C4PXDcATjuCLx1ArNHgeMTQvnrDNx0AW66AjfdgJvuYN89wOwx4OakkJuewE0v4KY3cNMHuOkL9t0PzB4Hbk7Z7MYjugtP6Pukvk9ZuvG0ej6jzll1ztnsxv7A8QDgeCBwPAg4Hgy8DQGzZ4Dj80L5GwrcDANuhgM3I4CbkWDfo8DsWeDmgpCb0cDNGOBmLHAzDrgZD/Y9AcyeA24u2uzG07oLz+v7gr4vWrrxknq+rM4Vda7a7MaJwPEk4HgycDwFOJ4KvE0Ds5eB42tC+ZsO3MwAbmYCN7OAm9lg33PA7BXg5rqQm7nAzTzgZj5wswC4WQj2vQjMXgVubtjsxku6C6/p+7q+b1i68aZ6vqXObXXu2OzGxcDxEuB4KXC8DDheDrytALO3gOO7QvlbCdysAm5WAzdrgJu1YN/rwOxt4OaekJv1wM0G4GYjcLMJuNkM9r0FzN4Bbu7b7Mabugvv6vuevu9buvGBen6oziN1Htvsxq3A8TbgeDtwvAM43gm87QKzD4HjJ0L52w3c7AFu9gI3+4Cb/WDfB8DsI+DmqZCbg8DNIeDmMHBzBLg5CvZ9DMw+Bm6e2ezGB7oLn+j7qb6fWbrxuXp+oc5LdV7Z7MbjwPEJ4PgkcHwKOD4NvJ0Bsy+A49dC+TsL3JwDbs4DNxeAm4tg35fA7Evg5o2Qm8vAzRXg5ipwcw24uQ72fQPMvgJu3trsxue6C1/r+42+31q68Z16fq/OB3U+2uzGm8DxLeD4NnB8Bzi+C7zdA7PvgeNPQvm7D9w8AG4eAjePgJvHYN9PwOwH4OazkJunwM0z4OY5cPMCuHlJ+g7MfgRuvtjsxne6Cz/p+7O+v1i68at6/qbOd3V+2OzG18DxG+D4LXD8Djh+TzIFZr8Bxz+F8vcRuPkE3HwGbr4AN1/JvsHsd+DGMVzGzXfg5gdw8xO4cUQydxMskvm+g4PZH8BNMODmn7rxq+7Cn/r+5TqY/rp/zAVXzyF+/d/VCTX8r7DUcYhI5o5DRjJ3HCqSuePQwHEY4C0smA0x3NxxaKH8hQNuwgM3EYCbiMBNJLDvyGA2JHATRshNFODGA7jxBG6iAjdeYN/eYDYUcBPWZjcG110YWt9h9B3W0o3h1HN4dSKoE9FmN/oAx9GA4+jAcQzgOCbwFgvMhgeOIwnlLzZwEwe4iQvc+AI3fmDfTjAbAbiJLOTGH7iJB9wEADeBwE18sO8EYDYicBPFZjeG010YSd+R9R3F0o0e6tlTnajqeNnsxoTAcSLgODFwnAQ4Tgq8JQOznsCxt1D+kgM3KYCblMBNKuAmNdh3GjAbFbjxEXKTFrhJB9ykB24yADcZwb4zgVkv4CaazW700F3orW8ffUezdGN09RxDnZjqxLLZjZmB4yzAcVbgOBtwnB14ywFmYwDHsYXylxO4yQXc5AZu8gA3ecG+84HZmMBNHCE3+YGbAsBNQeCmEHBTGOy7CPnZDLiJa7Mbo+sujK3vOPqOa+lGX/Xs9+vPUcffZjcWBY6LAcfFgeMSwHFJ4K0UmPUDjuMJ5a80cFMGuCkL3JQDbsqDfVcgP38DNwFCbioCN5WAm8rATRXgpirYdzUw6w/cBNrsRl/dhfH0HaDvQEs3xlfPCdRJqE4im91YHTiuARzXBI5rAce1gbc65O9YgOPEQvmrC9zUA27qAzcNgJuGYN+NwGxC4CaJkJvGwE0T4KYpcNMMuGkO9t0CzCYCbpLa7Mb4ugsT6zuJvpNaujGZek6uTgp1UtrsxpbAcSvguDVw3AY4bgu8tQOzyYHjVEL5aw/cdABuOgI3nYCbzmDfXcBsCuAmtZCbrsBNN+CmO3DTA7jpCfbdC8ymBG7S2OzGZLoLU+k7tb7TWLoxrXpOp056dTLY7MbewHEf4LgvcNwPOO4PvA0As+mA44xC+RsI3AwCbgYDN0OAm6Fg38PAbHrgJpOQm+HAzQjgZiRwMwq4GQ32PQbMZgBuMtvsxrS6CzPqO5O+M1u6MYt6zqpONnWy2+zGscDxOOB4PHA8ATieCLxNArNZgeMcQvmbDNxMAW6mAjfTgJvpYN8zwGw24CankJuZwM0s4GY2cDMHuJkL9j0PzGYHbnLZ7MYsugtz6DunvnNZujG3es6jTl518tnsxvnA8QLgeCFwvAg4Xgy8LQGzeYDj/EL5WwrcLANulgM3K4CblWDfq8BsXuCmgJCb1cDNGuBmLXCzDrhZD/a9AczmA24K2uzG3LoL8+u7gL4LWrqxkHourE4RdYra7MaNwPEm4HgzcLwFON4KvG0Ds4WB42JC+dsO3OwAbnYCN7uAm91g33vAbBHgpriQm73AzT7gZj9wcwC4OQj2fQjMFgVuStjsxkK6C4vpu7i+S1i6saR6LqVOaXXK2OzGw8DxEeD4KHB8DDg+DrydALOlgOOyQvk7CdycAm5OAzdngJuzYN/nwGxp4KackJvzwM0F4OYicHMJuLkM9n0FzJYBbsrb7MaSugvL6rucvstburGCeq6oTiV1KtvsxqvA8TXg+DpwfAM4vgm83QKzFYHjKkL5uw3c3AFu7gI394Cb+2DfD8BsJeCmqpCbh8DNI+DmMXDzBLh5Cvb9DMxWBm6q2ezGCroLq+i7qr6rWbqxunquoU5NdWrZ7MbnwPEL4PglcPwKOH4NvL0BszWA49pC+XsL3LwDbt4DNx+Am49g35/AbE3gpo6Qm8/AzRfg5itw8w24+Q72/QPM1gJu6trsxuq6C2vru46+61q6sZ56rq9OA3Ua/q0b/5hx/vUfwfFvv34Cx47I5jurD3bWSOj7OVhk83/W4JHNv59DRDb/fg4Z2fz7ORTYd2gw2wC4aSzkJgxwExa4CQfchAduIoB9RwSzDYGbJja7pp7ulkb6bqzvJpauaaqem6nTXJ0WNj+HRQKOIwPHUYBjD+DYE3iLCmabAccthfLnBdx4Azc+wE004CY62HcMMNscuGkl5CYmcBMLuIkN3MQBbuKCffuC2RbATWub3dhUd2FLfbfSd2tLN7ZRz23VaadOe5vd6AccO4Fjf+A4HnAcALwFgtm2wHEHofzFB24SADcJgZtEwE1isO8kYLYdcNNRyE1S4CYZcJMcuEkB3KQE+04FZtsDN51sdmMb3YUd9N1R350s3dhZPXdRp6s63Wx2Y2rgOA1wnBY4TgccpwfeMoDZLsBxd6H8ZQRuMgE3mYGbLMBNVrDvbGC2K3DTQ8hNduAmB3CTE7jJBdzkBvvOA2a7ATc9bXZjZ92F3fXdQ989Ld3YSz33VqePOn1tdmNe4DgfcJwfOC4AHBcE3gqB2d7AcT+h/BUGbooAN0WBm2LATXGw7xJgtg9w01/ITUngphRwUxq4KQPclAX7Lgdm+wI3A2x2Yy/dhf303V/fAyzdOFA9D1JnsDpDbHZjeeC4AnBcETiuBBxXBt6qgNlBwPFQofxVBW6qATfVgZsawE1NsO9aYHYwcDNMyE1t4KYOcFMXuKkH3NQn/+4LzA4Bbobb7MaBuguH6nuYvodbunGEeh6pzih1RtvsxobAcSPguDFw3AQ4bkr+/QqYHQkcjxHKX3PgpgVw0xK4aQXctAb7bgNmRwE3Y4XctAVu2gE37YGbDsBNR7DvTmB2NHAzzmY3jtBdOEbfY/U9ztKN49XzBHUmqjPJZjd2Bo67AMddgeNuwHF34K0HmJ0AHE8Wyl9P4KYXcNMbuOkD3PQF++4HZicCN1OE3PQHbgYANwOBm0HAzWDyWRDMTgJuptrsxvG6Cyfre4q+p1q6cZp6nq7ODHVm2uzGocDxMOB4OHA8AjgeST5vgNnpwPEsofyNBm7GADdjgZtxwM148i4CszOAm9lCbiYCN5OAm8nAzRTgZirY9zQwOxO4mWOzG6fpLpyl79n6nmPpxrnqeZ4689VZYLMbpwPHM4DjmcDxLOB4NvA2B8zOA44XCuVvLnAzD7iZD9wsAG4Wgn0vArPzgZtFQm4WAzdLgJulwM0y4GY52PcKMLsAuFlssxvn6i5cqO9F+l5s6cYl6nmpOsvUWW6zG1cCx6uA49XA8RrgeC3wtg7MLgWOVwjlbz1wswG42QjcbAJuNoN9bwGzy4CblUJutgI324Cb7cDNDuBmJ9j3LjC7HLhZZbMbl+guXKHvlfpeZenG1ep5jTpr1Vlnsxt3A8d7gOO9wPE+4Hg/8HYAzK4BjtcL5e8gcHMIuDkM3BwBbo6CfR8Ds2uBmw1Cbo4DNyeAm5PAzSng5jTY9xny+QO42WizG1frLlyv7w363mjpxk3qebM6W9TZarMbzwLH54Dj88DxBeD4IvB2CcxuBo63CeXvMnBzBbi5CtxcA26ug33fIJ8xgZvtQm5uAje3gJvbwM0d4OYu2Pc9MLsVuNlhsxs36S7cpu/t+t5h6cad6nmXOrvV2WOzG+8Dxw+A44fA8SPg+DHw9oT8HAEc7xXK31Pg5hlw8xy4eQHcvAT7fgVmdwM3+4TcvAZu3gA3b4Gbd8DNe7DvD2B2D3Cz32Y37tRduFff+/S939KNB9TzQXUOqXPYZjd+BI4/AcefgeMvwPFX4O0bmD0IHB8Ryt934OYHcPMTuHFEMXcTLIr5voOD2UPAzVEhNyGimLsJGcXcTago5m5CAzdhwL7DgtnDwM0xm914QHfhEX0f1fcxSzceV88n1Dmpzimb3RgOOA4PHEcAjiMCx5GAt8hg9gRwfFoof1GAGw/gxhO4iQrceIF9e4PZk8DNGSE3PsBNNOAmOnATA7iJCfYdC8yeAm7O2uzG47oLT+v7jL7PWrrxnHo+r84FdS7a7MbYwHEc4DgucOwLHPsBb04wex44viSUP3/gJh5wEwDcBAI38cG+E4DZC8DNZSE3CYGbRMBNYuAmCXCTFOw7GZi9CNxcsdmN53QXXtL3ZX1fsXTjVfV8TZ3r6tyw2Y3JgeMUwHFK4DgVcJwaeEsDZq8BxzeF8pcWuEkH3KQHbjIANxnBvjOB2evAzS0hN5mBmyzATVbgJhtwkx3sOweYvQHc3LbZjVd1F97U9y1937Z04x31fFede+rct9mNOYHjXMBxbuA4D3CcF3jLB2bvAscPhPKXH7gpANwUBG4KATeFwb6LgNl7wM1DITdFgZtiwE1x4KYEcFMS7LsUmL0P3Dyy2Y13dBc+0PdDfT+ydONj9fxEnafqPLPZjaWB4zLAcVnguBxwXB54qwBmnwDHz4XyVxG4qQTcVAZuqgA3VcG+q4HZp8DNCyE31YGbGsBNTeCmFnBTG+y7Dph9Bty8tNmNj3UXPtf3C32/tHTjK/X8Wp036ry12Y11geN6wHF94LgBcNwQeGsEZl8Dx++E8tcYuGkC3DQFbpoBN83BvluA2TfAzXshNy2Bm1bATWvgpg1w0xbsux2YfQvcfLDZja90F77T93t9f7B040f1/Emdz+p8sdmN7YHjDsBxR+C4E3DcGXjrAmY/AcdfhfLXFbjpBtx0B256ADc9wb57gdnPwM03ITe9gZs+wE1f4KYfcNMf7HsAmP0C3Hy32Y0fdRd+1fc3fX+3dOMP9fzzVyeOUP+7EX+FpY4HAseDgOPBwPEQ4Hgo8DYMzP4EjoOPkMnfcOBmBHAzErgZBdyMBvseA2YdI8zdhBByMxa4GQfcjAduJgA3E8G+J4HZYMBNSODmn7rxh+7CX/n7dYfQ96+v+8dcKPUcWp0w6oS12Y2TgeMpwPFU4HgacDwdeJsBZkMDx+GE8jcTuJkF3MwGbuYAN3PBvueB2TDATXghN/OBmwXAzULgZhFwsxjsewmYDQvcRLDZjaF0F4bTd3h9R7B0Y0T1HEmdyOpEsdmNS4HjZcDxcuB4BXC8EnhbBWYjAcceQvlbDdysAW7WAjfrgJv1YN8bwGxk4MZTyM1G4GYTcLMZuNkC3GwF+94GZqMAN1FtdmNE3YUe+vbUd1RLN3qpZ291fNSJZrMbtwPHO4DjncDxLuB4N/C2B8x6A8fRhfK3F7jZB9zsB24OADcHwb4PgVkf4CaGkJvDwM0R4OYocHMMuDkO9n0CzEYDbmLa7EYv3YXR9R1D3zEt3RhLPcdWJ446cW1240ng+BRwfBo4PgMcnwXezoHZ2MCxr1D+zgM3F4Cbi8DNJeDmMtj3FTAbB7jxE3JzFbi5BtxcB25uADc3wb5vgdm4wI3TZjfG0l3oq28/fTst3eivnuOpE6BOoM1uvA0c3wGO7wLH94Dj+8DbAzAbDziOL5S/h8DNI+DmMXDzBLh5Cvb9DMwGADcJhNw8B25eADcvgZtXwM1rsO83YDYQuElosxv9dRfG13cCfSe0dGMi9ZxYnSTqJLXZjW+B43fA8Xvg+ANw/BF4+wRmEwPHyYTy9xm4+QLcfAVuvgE338G+f4DZJMBNchfd/JEt51//aMe//foJ3Pz605wOo1/BkoJ/1hQ2uyaR7pZk+k6u7xSWrkmpnlOpk1qdNH/rmuj6djosX/S//uGi/mUPHv81G/yvs//5pUNE/ft+//1Lh/x/s//+pUNF/Qdv//KlQ//T7L986TBR//n74Z++dNh/mf2nLx0u6r9+n/2/Lx0+qnlfRIj6X9+/f/3SEf9z9q9fOlLUIHJh+dKRg5q1fOkoQc7+70t7GMz+8aU9TWb1l45qNvvbl/YynP31pb2NZ9XfRYLZVKB30lpmgzk8/vP/t/6ifREN9EV00BcxQF/EBH0RC/RFbNAXcUBfxAV94Qv6wg/0hRP0hT/oi3igLwJAXwSCvogP+iIB6IuEoC8Sgb5IDDogCZhNDfoinVBfJAV9kQz0RXLQFylAX6QEfZEK9EVq0BdpQF+kBX2RDvRFetAXGUBfZAR9kQn0RWbQF1lAX2QFfZEN9EV20Bc5QAfkBLNpQF+kB33xTz/XpNQ/x6TVdzp9p7f8XJNBPWdUJ5M6mW3+XJML9E5u0Dt5QO/kBb2TD/ROftA7BUDvFAS9Uwj0TmHQO0VA7xQFvVMM9E5x0DslQO+UBL1TCvROadA7ZUDvlAVdUg7MZgS9k0Xoc0p50BcVQF9UBH1RCfRFZdAXVUBfVAV9UQ30RXXQFzVAX9QEfVEL9EVt0Bd1QF/UBX1RD/RFfdAXDUBfNAR90Qh0QGMwmwn0RVahvmgC+qIp6ItmoC+ag75oAfqiJeiLVqAvWoO+aAP6oi3oi3agL9qDvugA+qIj6ItOoC86g77oAvqiK+iLbqAvuoMO6AFmM4O+yGbz55oM+ueYLPrOqu9slp9rsqvnHOrkVCeXzZ9reoLe6QV6pzfonT6gd/qC3ukHeqc/6J0BoHcGgt4ZBHpnMOidIaB3hoLeGQZ6ZzjonRGgd0aC3hkFemc06J0xoEvGgtkcoHdyC31OGQf6YjzoiwmgLyaCvpgE+mIy6IspoC+mgr6YBvpiOuiLGaAvZoK+mAX6YjboizmgL+aCvpgH+mI+6IsFoC8Wgg5YRP6uFvRFHqG+WAz6Ygnoi6WgL5aBvlgO+mIF6IuVoC9Wgb5YDfpiDeiLtaAv1oG+WA/6YgPoi42gLzaBvtgM+mIL6IutoC+2gQ7YDmZzgb7Ia/Pnmuz655jc+s6j77yWn2vyqef86hRQp6DNn2t2gN7ZCXpnF+id3aB39oDe2Qt6Zx/onf2gdw6A3jkIeucQ6J3DoHeOgN45CnrnGOid46B3ToDeOQl65xTondOgS86A2fygdwoJfU45C/riHOiL86AvLoC+uAj64hLoi8ugL66AvrgK+uIa6IvroC9ugL64CfriFuiL26Av7oC+uAv64h7oi/ugLx6ADngIZguAvigs1BePQF88Bn3xBPTFU9AXz0BfPAd98QL0xUvQF69AX7wGffEG9MVb0BfvQF+8B33xAfTFR9AXn0BffAZ98QX0xVfQAd/AbEHQF0Vs/lyTT/8cU0jfhfVdxPJzTVH1XEyd4uqUsPlzzXfQOz9A7/wEvePwMu+dYF7mvRPcy7x3QniZ905IL/PeCeVl3juhvcx7J4yXee+E9TLvnXBe5r0TPqhZy5eOEOTs/750RIPZP750JJNZ/aUjm83+9qWjGM7++tIexrOOYJ5gthjonZJCn1Oiepn3hZeXeV94e5n3hQ/oi2igL6KDvogB+iIm6ItYoC9ig76IA/oiLugLX9AXfqAvnKAv/EFfxAN9EQD6IhD0RXzQAQnAbHHQF6WE+iIh6ItEoC8Sg75IAvoiKeiLZKAvkoO+SAH6IiXoi1SgL1KDvkgD+iIt6It0oC/Sg77IAPoiI+iLTKAvMoO+yAI6ICuYLQH6orTNn2uK6p9jSuq7lL5LW36uKaOey6pTTp3yNn+uyQZ6JzvonRygd3KC3skFeic36J08oHfygt7JB3onP+idAqB3CoLeKQR6pzDonSKgd4qC3ikGeqc46J0SoHdKgi4pBWbLgt6pIPQ5pTToizKgL8qCvigH+qI86IsKoC8qgr6oBPqiMuiLKqAvqoK+qAb6ojroixqgL2qCvqgF+qI26Is6oC/qgr6oBzqgPpgtB/qiolBfNAB90RD0RSPQF41BXzQBfdEU9EUz0BfNQV+0AH3REvRFK9AXrUFftAF90Rb0RTvQF+1BX3QAfdER9EUn0BedQQd0AbPlQV9UsvlzTRn9c0wFfVfUdyXLzzWV1XMVdaqqU83mzzVdQe90A73THfROD9A7PUHv9AK90xv0Th/QO31B7/QDvdMf9M4A0DsDQe8MAr0zGPTOENA7Q0HvDAO9Mxz0zgjQJSPBbBXQO9WFPqeMAn0xGvTFGNAXY0FfjAN9MR70xQTQFxNBX0wCfTEZ9MUU0BdTQV9MA30xHfTFDNAXM0FfzAJ9MRv0xRzQF3NBB8wDs1VBX9QQ6ov5oC8WgL5YCPpiEeiLxaAvloC+WAr6Yhnoi+WgL1aAvlgJ+mIV6IvVoC/WgL5YC/piHeiL9aAvNoC+2Aj6YhPogM1gthroi5o2f66prH+Oqa7vGvquafm5ppZ6rq1OHXXq2vy5Zgvona2gd7aB3tkOemcH6J2doHd2gd7ZDXpnD+idvaB39oHe2Q965wDonYOgdw6B3jkMeucI6J2joHeOgd45DrrkBJitDXqnntDnlJOgL06BvjgN+uIM6IuzoC/Ogb44D/riAuiLi6AvLoG+uAz64groi6ugL66BvrgO+uIG6IuboC9ugb64DfriDuiAu2C2DuiL+kJ9cQ/0xX3QFw9AXzwEffEI9MVj0BdPQF88BX3xDPTFc9AXL0BfvAR98Qr0xWvQF29AX7wFffEO9MV70BcfQF98BB3wCczWBX3RwObPNbX0zzH19F1f3w0sP9c0VM+N1GmsTpO//VwTXt9Oh+WL/sevz6B3voDe+Qp65xvone+gd36A3vkJesfhbf690wh87zQVetcE8zZ3Htzb3HkIb3PnIb3NnYfyNnce2tvceRhvc+dhvc3fNeG8zd814b3N3zURvM3fNRG9zd81kYL6frZ86chBfu//70tHMcjJH1/awyRT+kt7muXvty8d1TCrv760l3GuPRzeoAN8wGxj0BfNpP6bRaAvooO+iAH6Iiboi1igL2KDvogD+iIu6Atf0Bd+oC+coC/8QV/EA30RAPoiEPRFfNAXCUBfJAR9kQj0RWLQAUnAbBPQF81tfjZtqD+LNtV3M303t3w2baGeW6rTSp3WNv/OPSnonWSgd5KD3kkBeicl6J1UoHdSg95JA3onLeiddKB30oPeyQB6JyPonUygdzKD3skCeicr6J1soHeyg97JAbokJ5htCXqnjdDnlFygL3KDvsgD+iIv6It8oC/yg74oAPqiIOiLQqAvCoO+KAL6oijoi2KgL4qDvigB+qIk6ItSoC9Kg74oA/qiLOiAcmC2FeiLtlL/zSLQFxVAX1QEfVEJ9EVl0BdVQF9UBX1RDfRFddAXNUBf1AR9UQv0RW3QF3VAX9QFfVEP9EV90BcNQF80BH3RiPzdBphtDfqinc2fa1ron2Pa6LutvttZfq5pr547qNNRnU42f65pAnqnKeidZqB3moPeaQF6pyXonVagd1qD3mkDeqct6J12oHfag97pAHqnI+idTqB3OoPe6QJ6pyvonW6gd7qDLukBZjuA3uks9DmlJ+iLXqAveoO+6AP6oi/oi36gL/qDvhgA+mIg6ItBoC8Gg74YAvpiKOiLYaAvhoO+GAH6YiToi1GgL0aDvhgDOmAsmO0I+qKL1H+zCPTFeNAXE0BfTAR9MQn0xWTQF1NAX0wFfTEN9MV00BczQF/MBH0xC/TFbNAXc0BfzAV9MQ/0xXzQFwtAXywEHbAIzHYCfdHV5s817fXPMZ313UXfXS0/13RTz93V6aFOT5s/1ywGvbME9M5S0DvLQO8sB72zAvTOStA7q0DvrAa9swb0zlrQO+tA76wHvbMB9M5G0DubQO9sBr2zBfTOVtA720CXbAez3UHv9BL6nLID9MVO0Be7QF/sBn2xB/TFXtAX+0Bf7Ad9cQD0xUHQF4dAXxwGfXEE9MVR0BfHQF8cB31xAvTFSdAXp0BfnAYdcIb8nQnoi95S/80i0BfnQF+cB31xAfTFRdAXl0BfXAZ9cQX0xVXQF9dAX1wHfXED9MVN0Be3QF/cBn1xB/TFXdAX90Bf3Ad98QB0wEMw2xP0RR+bP9d00z/H9NJ3b333sfxc01c991OnvzoDbP5c8wj0zmPQO09A7zwFvfMM9M5z0DsvQO+8BL3zCvTOa9A7b0DvvAW98w70znvQOx9A73wEvfMJ9M5n0DtfQO98BV3yDcz2A70zUOhzynfQFz9AX/wEfeHwMe+LYD7mfRHcx7wvQviY90VIH/O+COVj3hehfcz7IoyPeV+E9THvi3A+5n0RPqhZy5eOEOTs/750RIPZP750JJNZ/aUjm83+9qWjGM7++tIexrOOYJ5gtj/oi0FS/80iH/O+8PIx7wtvH/O+8AF9EQ30RXTQFzFAX8QEfREL9EVs0BdxQF/EBX3hC/rCD/SFE/SFP+iLeKAvAkBfBIK+iA86IAGYHQD6YrDNn2v66p9jBup7kL4HW36uGaKeh6ozTJ3hNn+uSQh6JxHoncSgd5KA3kkKeicZ6J3koHdSgN5JCXonFeid1KB30oDeSQt6Jx3onfSgdzKA3skIeicT6J3MoHeygC7JCmaHgt4ZIfQ5JRvoi+ygL3KAvsgJ+iIX6IvcoC/ygL7IC/oiH+iL/KAvCoC+KAj6ohDoi8KgL4qAvigK+qIY6IvioC9KgL4oCTqgFJgdBvpipNR/swj0RRnQF2VBX5QDfVEe9EUF0BcVQV9UAn1RGfRFFdAXVUFfVAN9UR30RQ3QFzVBX9QCfVEb9EUd0Bd1QV/UAx1QH8wOB30xyubPNUP0zzEj9D1S36MsP9eMVs9j1BmrzjibP9c0AL3TEPROI9A7jUHvNAG90xT0TjPQO81B77QAvdMS9E4r0DutQe+0Ab3TFvROO9A77UHvdAC90xH0TifQO51Bl3QBs2NA74wX+pzSFfRFN9AX3UFf9AB90RP0RS/QF71BX/QBfdEX9EU/0Bf9QV8MAH0xEPTFINAXg0FfDAF9MRT0xTDQF8NBX4wAHTASzI4FfTFB6r9ZBPpiNOiLMaAvxoK+GAf6YjzoiwmgLyaCvpgE+mIy6IspoC+mgr6YBvpiOuiLGaAvZoK+mAX6YjboizmgL+aCDpgHZseBvpho8+ea0frnmPH6nqDviZafayap58nqTFFnqs2fa+aD3lkAemch6J1FoHcWg95ZAnpnKeidZaB3loPeWQF6ZyXonVWgd1aD3lkDemct6J11oHfWg97ZAHpnI+idTaBLNoPZyaB3pgl9TtkC+mIr6IttoC+2g77YAfpiJ+iLXaAvdoO+2AP6Yi/oi32gL/aDvjgA+uIg6ItDoC8Og744AvriKOiLY6AvjoMOOAFmp4C+mC713ywCfXEK9MVp0BdnQF+cBX1xDvTFedAXF0BfXAR9cQn0xWXQF1dAX1wFfXEN9MV10Bc3QF/cBH1xC/TFbdAXd0AH3AWzU0FfzLD5c80k/XPMNH1P1/cMy881M9XzLHVmqzPH5s8190Dv3Ae98wD0zkPQO49A7zwGvfME9M5T0DvPQO88B73zAvTOS9A7r0DvvAa98wb0zlvQO+9A77wHvfMB9M5H0CWfwOws0DtzXfycgv+bRaAvvoC++Ar64hvoi++gL36AvvgJ+sIRzdz5bOB8novO/fXt/PNPdfw3lIeV/7+Hg/9l9r+HQ3iYf3+E/Nvsfw2H+vvsfwyH9jD/Xgrz/2f/dTjsP8z+23A4D/Pvu/D/OPvPwxH+efYfhyN6mL/TIv3b7D8MR/7X2f8/HMXD/P3n8R+zfx/2/K/Zvw1H9TB/V3r99+xfhr2DmLUO+wQ1axmOFuTs/4ajBz3753AMg9k/hmOazOrhWEazvw/HNpv9bTiO4eyv4bims2rY13jWEcwPzM4BPT/fMqu+8f/z1z/9TDFT/wwxV9/z9D3f8jPFAvW8UJ1F6iz+288U9H3hBO8Lf/C+iAfeFwHgfREI3hfxwfsiAXhfJATvi0TgfZEYvC+SgPdFUvC+SAbeF8nB+yIFeF+kBO+LVOB9kRq8L9KA90Va8L5IB94X6cH7IgN4X2QE74tM4H2RGbwvsoD3RVbwvsgG3hfZwTsgB5hdCN4XS8D7wvqH0J7PCXo+F+j53KDn84Cezwt6Ph/o+fyg5wuAni8Ier4Q6PnCoOeLgJ4vCnq+GOj54qDnS4CeLwl6vhTo+dKg58uAni8Ler4c6PnyoOcrgJ6vCHq+Euj5yqDnq4Cerwp6vhro7upgdhHo+aVCPV8D9HxN0PO1QM/XBj1fB/R8XdDz9UDP1wc93wD0fEPQ841AzzcGPd8E9HxT0PPNQM83Bz3fAvR8S9DzrUDPtwY93wb0fFvQ8+1Az7cHPd8B9HxH0POdQM93Bj3fBfR8V9Dd3cDsYtDzy2z+/c8C/fc9S/S9VN/LLH//s1w9r1BnpTqrbP79T3fwvugB3hc9wfuiF3hf9Abviz7gfdEXvC/6gfdFf/C+GADeFwPB+2IQeF8MBu+LIeB9MRS8L4aB98Vw8L4YAd4XI8H7YhR4X4wG74sx4H0xFrwvxoH3xXjwvpgA3hcTwftiEnhfTAbviyngHTAVzK4A74vVQj8XTAM9Px30/AzQ8zNBz88CPT8b9Pwc0PNzQc/PAz0/H/T8AtDzC0HPLwI9vxj0/BLQ80tBzy8DPb8c9PwK0PMrQc+vAj2/GvT8GtDza0HPrwM9vx70/AbQ8xtBz28CPb8ZdPcWMLsS9PwaoZ7fCnp+G+j57aDnd4Ce3wl6fhfo+d2g5/eAnt8Len4f6Pn9oOcPgJ4/CHr+EOj5w6Dnj4CePwp6/hjo+eOg50+Anj8Jev4U6PnToOfPgJ4/C3r+HOj586DnL4Cevwh6/hLo7stgdhXo+bU2//5nuf77ntX6XqPvtZa//1mnnters0GdjTb//ucKeF9cBe+La+B9cR28L26A98VN8L64Bd4Xt8H74g54X9wF74t74H1xH7wvHoD3xUPwvngE3hePwfviCXhfPAXvi2fgffEcvC9egPfFS/C+eAXeF6/B++INeF+8Be+Ld+B98R68Lz6A98VH8A74BGbXg/fFJqGfCz6Dnv8Cev4r6PlvoOe/g57/AXr+J+h5h6d5zwfzNO/54J7mPR/C07znQ3qa93woT/OeD+1p3vNhPM17Pqynec+H8zTv+fCe5j0fwdO85yN6mvd8pKBmLcORg5z933CUoGf/HPYwmP1j2NNkVg9HNZr9fdjLbPa3YW/D2V/DPqazajia8awjWHQwuwH0/Gahno/had7zMT3Nez6Wp3nPx/Y07/k4nuY9H9fTvOd9Pc173g/0vBP0vD/o+Xig5wNAzweCno8Pej4B6PmEoOcTgZ5PDHo+Cej5pKDnk4GeTw56PgXo+ZSg51OBnk8Nej4N6Pm0oOfTgZ5PD7o7A5jdCHp+i82//1mn/75nk74363uL5e9/tqrnbepsV2eHzb//yQjeF5nA+yIzeF9kAe+LrOB9kQ28L7KD90UO8L7ICd4XucD7Ijd4X+QB74u84H2RD7wv8oP3RQHwvigI3heFwPuiMHhfFAHvi6LgfVEMvC+Kg/dFCfC+KAneF6XA+6I0eF+UAe+LsuB9UQ68A8qD2W3gfbFT6OeCCqDnK4KerwR6vjLo+Sqg56uCnq8Ger466PkaoOdrgp6vBXq+Nuj5OqDn64Kerwd6vj7o+Qag5xuCnm8Eer4x6PkmoOebgp5vBnq+Oej5FqDnW4KebwV6vjXo+Tag59uC7m4HZreDnt8l1PPtQc93AD3fEfR8J9DznUHPdwE93xX0fDfQ891Bz/cAPd8T9Hwv0PO9Qc/3AT3fF/R8P9Dz/UHPDwA9PxD0/CDQ84NBzw8BPT8U9Pww0PPDQc+PAD0/EvT8KNDzo0HPjwHdPRbM7gA9v9vm3/9s1X/fs1Pfu/S92/L3P3vU81519qmz3+bf/4wD74vx4H0xAbwvJoL3xSTwvpgM3hdTwPtiKnhfTAPvi+ngfTEDvC9mgvfFLPC+mA3eF3PA+2IueF/MA++L+eB9sQC8LxaC98Ui8L5YDN4XS8D7Yil4XywD74vl4H2xArwvVoL3xSrwvlgN3gFrwOxe8L44IPRzwVrQ8+tAz68HPb8B9PxG0PObQM9vBj2/BfT8VtDz20DPbwc9vwP0/E7Q87tAz+8GPb8H9Pxe0PP7QM/vBz1/APT8QdDzh0DPHwY9fwT0/FHQ88dAzx8HPX8C9PxJ0POnQHefBrP7QM8fFOr5M6Dnz4KePwd6/jzo+Qug5y+Cnr8Eev4y6PkroOevgp6/Bnr+Ouj5G6Dnb4KevwV6/jbo+Tug5++Cnr8Hev4+6PkHoOcfgp5/BHr+Mej5J6Dnn4KefwZ6/jno+Reg51+C7n4FZveDnj9k8+9/9ui/7zmg74P6PmT5+5/D6vmIOkfVOfa3v/+Jqm+nw/JF/+PXa/C+eAPeF2/B++IdeF+8B++LD+B98RG8Lz6B98Vn8L74At4XX8H74ht4X3wH74sf4H3xE7wvfn0T/9vs33/rEZDN4y5+BqP/naZgvn/h9/iv2eC+5jkJ4fv3vfz7lw7pa/69H8r3H/b9L186tK/593MY33/2+E9fOqyv+fdoON9//f74f186vK/5910E3//6vvvrl47oa/7ZI5JvEN/Pli8dOahZy5eOEuTs/760h8HsH1/a02RWf+moZrO/fWkvw9lfX9rb17wDfMDsUdAXJ4T+e5LRQF9EB30RA/RFTNAXsUBfxAZ9EQf0RVzQF76gL/xAXzhBX/iDvogH+iIA9EUg6Iv4oC8SgL5ICPoiEeiLxKADkoDZY6AvTtr870ke1p/1j+v7hL5PWj77n1LPp9U5o85Zm/89yaSgd5KB3kkOeicF6J2UoHdSgd5JDXonDeidtKB30oHeSQ96JwPonYygdzKB3skMeicL6J2soHeygd7JDnonB+iSnGD2NOidc0KfU3KBvsgN+iIP6Iu8oC/ygb7ID/qiAOiLgqAvCoG+KAz6ogjoi6KgL4qBvigO+qIE6IuSoC9Kgb4oDfqiDOiLsqADyoHZM6Avzgv1RXnQFxVAX1QEfVEJ9EVl0BdVQF9UBX1RDfRFddAXNUBf1AR9UQv0RW3QF3VAX9QFfVEP9EV90BcNQF80BH3RCHRAYzB7FvTFBZs/15zSP8ec0/d5fV+w/FxzUT1fUueyOlds/lzTBPROU9A7zUDvNAe90wL0TkvQO61A77QGvdMG9E5b0DvtQO+0B73TAfROR9A7nUDvdAa90wX0TlfQO91A73QHXdIDzF4CvXNV6HNKT9AXvUBf9AZ90Qf0RV/QF/1AX/QHfTEA9MVA0BeDQF8MBn0xBPTFUNAXw0BfDAd9MQL0xUjQF6NAX4wGfTEGdMBYMHsZ9MU1ob4YB/piPOiLCaAvJoK+mAT6YjLoiymgL6aCvpgG+mI66IsZoC9mgr6YBfpiNuiLOaAv5oK+mAf6Yj7oiwWgLxaCDlgEZq+Avrhu8+eai/rnmKv6vqbv65afa26o55vq3FLnts2faxaD3lkCemcp6J1loHeWg95ZAXpnJeidVaB3VoPeWQN6Zy3onXWgd9aD3tkAemcj6J1NoHc2g97ZAnpnK+idbaBLtoPZm6B37gh9TtkB+mIn6ItdoC92g77YA/piL+iLfaAv9oO+OAD64iDoi0OgLw6DvjgC+uIo6ItjoC+Og744AfriJOiLU6AvToMOOANmb4G+uCvUF2dBX5wDfXEe9MUF0BcXQV9cAn1xGfTFFdAXV0FfXAN9cR30xQ3QFzdBX9wCfXEb9MUd0Bd3QV/cA31xH/TFA9ABD8HsbdAX92z+XHND/xxzR9939X3P8nPNffX8QJ2H6jyy+XPNI9A7j0HvPAG98xT0zjPQO89B77wAvfMS9M4r0DuvQe+8Ab3zFvTOO9A770HvfAC98xH0zifQO59B73wBvfMVdMk3MPsA9M5joc8p30Ff/AB98RP0hcPPvC+C+Zn3RXA/874I4WfeFyH9zPsilJ95X4T2M++LMH7mfRHWz7wvwvmZ90X4oGYtXzpCkLP/+9IRDWb/+NKRTGb1l45sNvvbl45iOPvrS3sYzzqCeYLZh6Avngj1RVQ/877w8jPvC28/877wAX0RDfRFdNAXMUBfxAR9EQv0RWzQF3FAX8QFfeEL+sIP9IUT9IU/6It4oC8CQF8Egr6IDzogAZh9BPriqc2fa+7rn2Me6/uJvp9afq55pp6fq/NCnZc2f65JCHonEeidxKB3koDeSQp6JxnoneSgd1KA3kkJeicV6J3UoHfSgN5JC3onHeid9KB3MoDeyQh6JxPoncygd7KALskKZp+D3nkl9DklG+iL7KAvcoC+yAn6Ihfoi9ygL/KAvsgL+iIf6Iv8oC8KgL4oCPqiEOiLwqAvioC+KAr6ohjoi+KgL0qAvigJOqAUmH0B+uK1UF+UBn1RBvRFWdAX5UBflAd9UQH0RUXQF5VAX1QGfVEF9EVV0BfVQF9UB31RA/RFTdAXtUBf1AZ9UQf0RV3QF/VAB9QHsy9BX7yx+XPNM/1zzCt9v9b3G8vPNW/V8zt13qvzwebPNQ1A7zQEvdMI9E5j0DtNQO80Bb3TDPROc9A7LUDvtAS90wr0TmvQO21A77QFvdMO9E570DsdQO90BL3TCfROZ9AlXcDsO9A7H4U+p3QFfdEN9EV30Bc9QF/0BH3RC/RFb9AXfUBf9AV90Q/0RX/QFwNAXwwEfTEI9MVg0BdDQF8MBX0xDPTFcNAXI0AHjASz70FffBLqi1GgL0aDvhgD+mIs6ItxoC/Gg76YAPpiIuiLSaAvJoO+mAL6Yiroi2mgL6aDvpgB+mIm6ItZoC9mg76YA/piLuiAeWD2A+iLzzZ/rnmrf475qO9P+v5s+bnmi3r+qs43db7b/LlmPuidBaB3FoLeWQR6ZzHonSWgd5aC3lkGemc56J0VoHdWgt5ZBXpnNeidNaB31oLeWQd6Zz3onQ2gdzaC3tkEumQzmP0KeueH0OeULaAvtoK+2Ab6Yjvoix2gL3aCvtgF+mI36Is9oC/2gr7YB/piP+iLA6AvDoK+OAT64jDoiyOgL46CvjgG+uI46IATYPYb6IufQn1xEvTFKdAXp0FfnAF9cRb0xTnQF+dBX1wAfXER9MUl0BeXQV9cAX1xFfTFNdAX10Ff3AB9cRP0xS3QF7dBX9wBHXAXzH4HfeEYae/nmi/655gf+v6p719f98859RxcnRC//mcj/wpLe+ce6J37oHcegN55CHrnEeidx6B3noDeeQp65xnoneegd16A3nkJeucV6J3XoHfegN55C3rnHeid96B3PoDe+Qi65BOYDT7SvHdCgd6x/gqvb+eff6rjP399Bn3xBfTFV9AX30BffAd98QP0xU/QF78G/2n2H34FCwGch3bRuef/sP78cx3/BeX8G/9/TAd3mrsJ4fyHvfzLdEjnP+7wH6dDOc37ObTzX938v+kwzv/w+LfpsE7zzg3nDOL7wzIdPqhZy3SEoGf/nI5oMqunI5nN/jYd2XRWTUcBsyFBTsKMtH5dj//8//7pM9mvz1u/7lD6Dq3vMJbPZGHVczh1wqsT4W+fyWjePJzmefN0muctqtM8b15O87x5O83z5uM0z1s0p3neojvN8xbDaZ63mEHNWqZjBT3753Rsk1k9Hcds9rfpuKazatoXzIYDeYsI8mb9RXPi5zTPidNpnhN/p3lO4jnNcxLgNM9JoNM8J/Gd5jlJ4DTPSUKneU4SBTVrmU4c9Oyf00lMZvV0UrPZ36aTmc6q6eRgNjzISSShnKRwmuckpdM8J6mc5jlJ7TTPSRqneU7SOs1zks5pnpP0TvOcZHCa5yRjULOW6UxBz/45ndlkVk9nMZv9bTqr6ayazgZmI4CcRLb5+S2s/rwWUd+R9B3Z8vktinr2UMdTnag2P79ld5rnLYfTPG85neZ5y+U0z1tup3ne8jjN85bXaZ63fE7zvOV3muetQFCzlumCQc/+OV3IZFZPFzab/W26iOmsmi4KZj1A3ryE3kvFnOY5Ke40z0kJp3lOSjrNc1LKaZ6T0k7znJRxmuekrNM8J+Wc5jkpH9SsZbpC0LN/Tlc0mdXTlcxmf5uubDqrpquAWU+QE2+hnFR1muekmtM8J9Wd5jmp4TTPSU2neU5qOc1zUttpnpM6TvOc1HWa56ReULOW6fpBz/453cBkVk83NJv9bbqR6ayabgxmo4Kc+Nj8/BZFf17z0re3vn0sn9+iqefo6sRQJ6bNz29NnOZ5a+o0z1szp3nemjvN89bCaZ63lk7zvLVymuettdM8b22c5nlrG9SsZbpd0LN/Trc3mdXTHcxmf5vuaDqrpjuB2eggb7GE3kudneY56eI0z0lXp3lOujnNc9LdaZ6THk7znPR0muekl9M8J72d5jnpE9SsZbpv0LN/TvczmdXT/c1mf5seYDqrpgeC2RggJ7GFcjLIaZ6TwU7znAxxmudkqNM8J8Oc5jkZ7jTPyQineU5GOs1zMsppnpPRQc1apscEPfvn9FiTWT09zmz2t+nxprNqegKYjQlyEsfm57do+vNaLH3H1nccy+e3uOrZVx2/X3+Wzc9vE53meZvkNM/bZKd53qY4zfM21Wmet2lO87xNd5rnbYbTPG8zneZ5mxXUrGV6dtCzf07PMZnV03PNZn+bnmc6q6bng1lfkDd/offSAqd5ThY6zXOyyGmek8VO85wscZrnZKnTPCfLnOY5We40z8kKp3lOVgY1a5leFfTsn9OrTWb19Bqz2d+m15rOqul1YNYP5CSeUE7WO81zssFpnpONTvOcbHKa52Sz0zwnW5zmOdnqNM/JNqd5TrY7zXOyI6hZy/TOoGf/nN5lMqund5vN/ja9x3RWTe8Fs06QkwCbn9/i6s9r/vqOp+8Ay+e3QPUcX50E6iS0+fltn9M8b/ud5nk74DTP20Gned4OOc3zdthpnrcjTvO8HXWa5+2Y0zxvx4OatUyfCHr2z+mTJrN6+pTZ7G/Tp01n1fQZMBsf5C2R0HvprNM8J+ec5jk57zTPyQWneU4uOs1zcslpnpPLTvOcXHGa5+Sq0zwn14KatUxfD3r2z+kbJrN6+qbZ7G/Tt0xn1fRtMJsA5CSxUE7uOM1zctdpnpN7TvOc3Hea5+SB0zwnD53mOXnkNM/JY6d5Tp44zXPyNKhZy/SzoGf/nH5uMqunX5jN/jb90nRWTb8CswlBTpLY/PwWqD+vJdJ3Yn0nsXx+S6qek6mTXJ0UNj+/vXaa5+2N0zxvb53meXvnNM/be6d53j44zfP20Wmet09O87x9dprn7UtQs5bpr0HP/jn9zWRWT383m/1t+ofprJr+CWaTgbylFHovOfzNcxLM3zwnwf3NcxLC3zwnIf3NcxLK3zwnof3NcxLG3zwnYf3NcxIuqFnLdPigZ/+cjmAyq6cjms3+Nh3JdFZNRwazyUFOUgnlJArIiQfIiSfISVSQEy+QE2+QEx+Qk2ggJ9FBTmKAnMQEOYkFchIb5CQO+N6PC2ZTgJyktvn5Lan+vJZS36n0ndry+S2Nek6rTjp10tv8/OYL8uYH8uYEefMHeYsH8hYA8hYI8hYf5C0ByFtCkLdEIG+JQd6SmOZCTSc1nf31mQzMpgV5yyD0XkoOcpIC5CQlyEkqkJPUICdpQE7SgpykAzlJD3KSAeQkI8hJJpCTzCAnWcD3flYwmw7kJKNQTrKBnGQHOckBcpIT5CQXyElukJM8ICd5QU7ygZzkBzkpAHJSEOSkEMhJYfC9XwTMpgc5yWTz81sa/Xktg74z6juT5fNbZvWcRZ2s6mSz+fmtKMhbMZC34iBvJUDeSoK8lQJ5Kw3yVgbkrSzIWzmQt/IgbxVA3iqa5kJNVzKdVdOVwWwWkLfsQu+lKiAnVUFOqoGcVAc5qQFyUhPkpBbISW2QkzogJ3VBTuqBnNQHOWkActIQfO83ArNZQU5yCOWkMchJE5CTpiAnzUBOmoOctAA5aQly0grkpDXISRuQk7YgJ+1ATtqDnHQA3/sdwWw2kJOcNj+/Zdaf17LrO4e+c1o+v+VSz7nVyaNOXpuf3zqBvHUGeesC8tYV5K0byFt3kLceIG89Qd56gbz1BnnrA/LWF+Stn2ku1HR/01k1PQDM5gZ5yyf0XhoIcjII5GQwyMkQkJOhICfDQE6Gg5yMADkZCXIyCuRkNMjJGJCTsSAn48D3/ngwmwfkJL9QTiaAnEwEOZkEcjIZ5GQKyMlUkJNpICfTQU5mgJzMBDmZBXIyG+RkDsjJXPC9Pw/M5gU5KWDz81su/Xktn77z67uA5fNbQfVcSJ3C6hSx+fltPsjbApC3hSBvi0DeFoO8LQF5WwrytgzkbTnI2wqQt5Ugb6tA3lab5kJNrzGdVdNrwWwhkLeiQu+ldSAn60FONoCcbAQ52QRyshnkZAvIyVaQk20gJ9tBTnaAnOwEOdkFcrIbfO/vAbOFQU6KCeVkL8jJPpCT/SAnB0BODoKcHAI5OQxycgTk5CjIyTGQk+MgJydATk6CnJwC3/unwWwRkJPiNj+/FdSf14rqu5i+i1s+v5VQzyXVKaVOaZuf386AvJ0FeTsH8nYe5O0CyNtFkLdLIG+XQd6ugLxdBXm7BvJ2HeTthmku1PRN01k1fQvMlgR5KyP0XroNcnIH5OQuyMk9kJP7ICcPQE4egpw8Ajl5DHLyBOTkKcjJM5CT5yAnL8D3/kswWwrkpKxQTl6BnLwGOXkDcvIW5OQdyMl7kJMPICcfQU4+gZx8Bjn5AnLyFeTkG8jJd/C9/wPMlgY5KWfz81sJ/XmtjL7L6ruc5fNbefVcQZ2K6lSy+fntJ8ibI5553oLFM89b8HjmeQsRzzxvIeOZ5y1UPPO8hY5nnrcw8czzFjaoWct0uKBn/5wObzKrpyOYzf42HdF0Vk1HArMVQN4qC72XIsczz0kUkBMPkBNPkJOoICdeICfeICc+ICfRQE6ig5zEADmJCXISC+QkNvjejwNmK4KcVBHKSVyQE1+QEz+QEyfIiT/ISTyQkwCQk0CQk/ggJwlAThKCnCQCOUkMcpIEfO8nBbOVQE6q2vz8Vl5/Xqus7yr6rmr5/FZNPVdXp4Y6NW1+fksG8pYc5C0FyFtKkLdUIG+pQd7SgLylBXlLB/KWHuQtA8hbRpC3TCBvmUGGsoDZ6iBvtYTeS1lBTrKBnGQHOckBcpIT5CQXyElukJM8ICd5QU7ygZzkBzkpAHJSEOSkEPjeLwxma4Cc1BbKSRGQk6IgJ8VAToqDnJQAOSkJclIK5KQ0yEkZkJOyICflQE7Kg5xUADmpSD6TgdmaICd1bH5+q6Y/r9XSd21917F8fqurnuupU1+dBjY/v1UGeasC8lYV5K0ayFt1kLcaIG81Qd5qgbzVBnmrA/JWF+StHshbfZC3BiBDDcFsPZC3hkLvpUYgJ41BTpqAnDQFOWkGctIc5KQFyElLkJNWICetQU7agJy0BTlpB3LSHnzvdwCz9UFOGgnlpCPISSeQk84gJ11ATrqCnHQDOekOctID5KQnyEkvkJPeICd9QE76gpz0A9/7/cFsA5CTxjY/v9XVn9ca6ruRvhtbPr81Uc9N1WmmTnObn98GgLwNBHkbBPI2GORtCMjbUJC3YSBvw0HeRoC8jQR5GwXyNhrkbQzI21iQoXFgtinIWwuh99J4kJMJICcTQU4mgZxMBjmZAnIyFeRkGsjJdJCTGSAnM0FOZoGczAY5mQO+9+eC2WYgJy2FcjIP5GQ+yMkCkJOFICeLQE4Wg5wsATlZCnKyDORkOcjJCpCTlSAnq0BOVoPv/TVgtjnISSubn9+a6M9rLfTdUt+tLJ/fWqvnNuq0Vaedzc9va0He1oG8rQd52wDythHkbRPI22aQty0gb1tB3raBvG0HedsB8rYT5G0XyNBuMNsG5K290HtpD8jJXpCTfSAn+0FODoCcHAQ5OQRychjk5AjIyVGQk2MgJ8dBTk6AnJwE3/unwGxbkJMOQjk5DXJyBuTkLMjJOZCT8yAnF0BOLoKcXAI5uQxycgXk5CrIyTWQk+sgJzfA9/5NMNsO5KSjzc9vrfXntfb67qDvjpbPb53Uc2d1uqjT1ebnt1sgb7dB3u6AvN0FebsH8nYf5O0ByNtDkLdHIG+PQd6egLw9BXl7BvL2HGToBZjtDPLWTei99BLk5BXIyWuQkzcgJ29BTt6BnLwHOfkAcvIR5OQTyMlnkJMvICdfQU6+ge/972C2C8hJd6Gc/AA5+Qly4ggwz0mwAPOcBA8wz0mIAPOchAwwz0moAPOchA4wz0mYoGYt02GDnv1zOpzJrJ4Obzb723QE01k1HRHMdgU56WHz81sn/Xmtm76767uH5fNbT/XcS53e6vSx+fktUoB53iIHmOctCsibB8ibJ8hbVJA3L5A3b5A3H5C3aCBv0UHeYoC8xQR5iwUyFBvM9gJ56yv0XooDchIX5MQX5MQP5MQJcuIPchIP5CQA5CQQ5CQ+yEkCkJOEICeJQE4Sg+/9JGC2N8hJP6GcJAU5SQZykhzkJAXISUqQk1QgJ6lBTtKAnKQFOUkHcpIe5CQDyElGkJNM4Hs/M5jtA3LS3+bnt57681pffffTd3/L57cB6nmgOoPUGWzz81sWkLesIG/ZQN6yg7zlAHnLCfKWC+QtN8hbHpC3vCBv+UDe8oO8FQB5KwgyVAjMDgR5GyL0XioMclIE5KQoyEkxkJPiICclQE5KgpyUAjkpDXJSBuSkLMhJOZCT8iAnFcD3fkUwOwjkZKhQTiqBnFQGOakCclIV5KQayEl1kJMaICc1QU5qgZzUBjmpA3JSF+SkHshJffC93wDMDgY5GWbz89sA/XltiL6H6nuY5fPbcPU8Qp2R6oyy+fmtIchbI5C3xiBvTUDemoK8NQN5aw7y1gLkrSXIWyuQt9Ygb21A3tqCvLUDGWoPZkeAvI0Wei91ADnpCHLSCeSkM8hJF5CTriAn3UBOuoOc9AA56Qly0gvkpDfISR+Qk77ge78fmB0JcjJGKCf9QU4GgJwMBDkZBHIyGORkCMjJUJCTYSAnw0FORoCcjAQ5GQVyMhrkZAz43h8LZkeBnIy1+fltuP68NlrfY/Q91vL5bZx6Hq/OBHUm2vz8Ng7kbTzI2wSQt4kgb5NA3iaDvE0BeZsK8jYN5G06yNsMkLeZIG+zQN5mgwzNAbPjQd4mCb2X5oKczAM5mQ9ysgDkZCHIySKQk8UgJ0tATpaCnCwDOVkOcrIC5GQlyMkq8L2/GsxOADmZLJSTNSAna0FO1oGcrAc52QByshHkZBPIyWaQky0gJ1tBTraBnGwHOdkBcrITfO/vArMTQU6m2Pz8Nk5/Xpuk78n6nmL5/DZVPU9TZ7o6M2x+ftsN8rYH5G0vyNs+kLf9IG8HQN4OgrwdAnk7DPJ2BOTtKMjbMZC34yBvJ0CGToLZaSBvM4XeS6dATk6DnJwBOTkLcnIO5OQ8yMkFkJOLICeXQE4ug5xcATm5CnJyDeTkOvjevwFmp4OczBLKyU2Qk1sgJ7dBTu6AnNwFObkHcnIf5OQByMlDkJNHICePQU6egJw8BTl5Br73n4PZGSAns21+fpuqP6/N1Pcsfc+2fH6bo57nqjNPnfk2P7+9AHl7CfL2CuTtNcjbG5C3tyBv70De3oO8fQB5+wjy9gnk7TPI2xeQt68gQ9/A7FyQtwUuvpdC6dv5l3+if//1HeTkB8jJT7CXeWAvC4Xe145A870ECzTfS/BA8/4IEWjeHyEDzfsjVKB5f4QONO+PMIHm/RE20Lw/wgU1a5kOH/Tsn9MRTGb1dESz2d+mI5nOqunIYHY+yMkim+/rOfr9vEDfC/W9yPK+Xqyel6izVJ1lNt/XUUDePEDePEHeooK8eYG8eYO8+YC8RQN5iw7yFgPkLSbIWyyQt9ggb3FAhuKC2SUgb8uF3ku+ICd+ICdOkBN/kJN4ICcBICeBICfxQU4SgJwkBDlJBHKSGOQkCchJUvC9nwzMLgU5WSGUk+QgJylATlKCnKQCOUkNcpIG5CQtyEk6kJP0ICcZQE4ygpxkAjnJDHKSBXzvZwWzy0BOVtr8/LZYf15bru8V+l5p+fy2Sj2vVmeNOmttfn7LBvKWHeQtB8hbTpC3XCBvuUHe8oC85QV5ywfylh/krQDIW0GQt0Igb4VBhoqA2dUgb+uE3ktFQU6KgZwUBzkpAXJSEuSkFMhJaZCTMiAnZUFOyoGclAc5qQByUhHkpBL43q8MZteAnKwXykkVkJOqICfVQE6qg5zUADmpCXJSC+SkNshJHZCTuiAn9UBO6oOcNAA5aQi+9xuB2bUgJxtsfn5bpT+vrdP3en1vsHx+26ieN6mzWZ0tNj+/NQZ5awLy1hTkrRnIW3OQtxYgby1B3lqBvLUGeWsD8tYW5K0dyFt7kLcOIEMdwewmkLetQu+lTiAnnUFOuoCcdAU56QZy0h3kpAfISU+Qk14gJ71BTvqAnPQFOekHctIffO8PALObQU62CeVkIMjJIJCTwSAnQ0BOhoKcDAM5+T9e/QJqjjM923bbkmUxM7eYmZmZmZmZmZmZmS3JkiwwyBYzMzMzM1rSLuerZL+TP4nrvHvNNXvVX72/9WTGR1991luBcaCT8aCTCaCTiaCTSaCTyaCTKaCTqeC3Pw2c3QQ62Rrg+9tG931ts3vf4t63Bnl/2+Z83u5cO5xrZ4Dvb9NBbzNAbzNBb7NAb7NBb3NAb3NBb/NAb/NBbwtAbwtBb4tAb4tBb0tAQ0vB2e2gt12iv0vLQCc/gk6Wg05WgE5Wgk5+Ap2sAp2sBp2sAZ38DDpZCzpZBzpZDzrZQP5nBeDsDtDJblEnv4JOfgOd/A462Qg6+QN08ifoZBPoZDPoZAvoZCvoZBvoZDvoZAfoZCf47e8CZ3eCTvYE+P62zX1f2+Xed7v3PUHe3/Y6n/c5137nOhDg+9tu0Nse0Nte0Ns+0Nt+0NsB0NtB0Nsh0Nth0NsR0NtR0Nsx0Ntx0NsJ0NBJcHYf6O2g6O/SKdDJadDJGdDJWdDJOdDJedDJBdDJRdDJJdDJZdDJFdDJVdDJNdDJdfDbvwHO7gedHBJ1chN0cgt0cht0cgd0chd0cg90ch908gB08hB08gh08hh08gR08hR08gz89p+DswdAJ4cDfH/b676vHXTvh9z74SDvb0ecz0ed65hzHQ/w/e0F6O0l6O0V6O016O0N6O0t6O0d6O096O0D6O0j6O0T6O0z6O0v0NsX0NBXcPYo6O2E6O/SN9CJL5n3Tr5L5r2TYMm8dxI8mfdOvk/mvZMQybx38kMy752ETOa9k1D/dDbI6dD/fPa/TofxctY9Hdbb2f84Hc7rWed0eHD2GOjkpKiTCMm8dxIRdBIJdBIZdBIFdBIVdBINdBIddBIDdBITdBILdBIbdBIHdBIX/PbjgbPHQSenAnx/O+K+r51w7yfd+6kg72+nnc9nnOusc50L8P0tPugtAegtIejND3pLBHpLDHpLAnpLCnpLBnpLDnpLAXpLCXpLBXpLDRpKA86eAb2dF/1dSgs6SQc6SQ86yQA6yQg6yQQ6yQw6yQI6yQo6yQY6yQ46yQE6yQk6yQV++7nB2bOgkwuiTvKATvKCTvKBTvKDTgqATgqCTgqBTgqDToqAToqCToqBToqDTkqATkqC334pcPYc6ORigO9vp933tfPu/YJ7vxjk/e2S8/myc11xrqsBvr+VBr2VAb2VBb2VA72VB71VAL1VBL1VAr1VBr1VAb1VBb1VA71VB73VAA3VBGcvg96uif4u1QKd1Aad1AGd1AWd1AOd1AedNACdNASdNAKdNAadNAGdNAWdNAOdNAe//Rbg7BXQyXVRJy1BJ61AJ61BJ21AJ21BJ+1AJ+1BJx1AJx1BJ51AJ51BJ11AJ11BJ93Ab787OHsVdHIjwPe3S+772jX3ft293wjy/nbT+XzLuW47150A3996gN56gt56gd56g976gN76gt76gd76g94GgN4Ggt4Ggd4Gg96GgN6GgoaGgbO3QG93RX+XhoNORoBORoJORoFORoNOxoBOxoJOxoFOxoNOJoBOJoJOJoFOJoNOpoDf/lRw9jbo5J6ok2mgk+mgkxmgk5mgk1mgk9mgkzmgk7mgk3mgk/mgkwWgk4Wgk0Wgk8Xgt78EnL0DOrkf4PvbTfd97a57v+fe7wd5f3vgfH7oXI+c63GA729LQW/LQG8/gt6Wg95WgN5Wgt5+Ar2tAr2tBr2tAb39DHpbC3pbB3pbDxraAM4+BL09Ef1d+gV08ivo5DfQye+gk42gkz9AJ3+CTjaBTjaDTraATraCTraBTraDTnaA3/5OcPYR6OSpqJNdoJPdoJM9oJO9oJN9oJP9oJMDoJODoJNDoJPDoJMjoJOjoJNjoJPj4Ld/Apx9DDp5FuD72wP3fe2Je3/q3p8FeX977nx+4VwvnetVgO9vJ0Fvp0Bvp0FvZ0BvZ0Fv50Bv50FvF0BvF0Fvl0Bvl0FvV0BvV0Fv10BD18HZF6C316K/SzdAJzdBJ7dAJ7dBJ3dAJ3dBJ/dAJ/dBJw9AJw9BJ49AJ49BJ09AJ0/Bb/8ZOPsSdPJG1Mlz0MkL0MlL0Mkr0Mlr0Mkb0Mlb0Mk70Ml70MkH0MlH0Mkn0Mln0Mlf4Lf/BZx9BTp5G+D723P3fe21e3/j3t8GeX9753x+71wfnOtjgO9vX0Fv30BvvuTee/suuffegiX33lvw5N57+z65995CJPfe2w/JvfcW8p/OBjkd6p/P/tfp0F7OuqfDeDv7H6fDej3rnA4Hzr4HvX0S/V0Kn9x7JxGSe+8kIugkEugkMugkCugkKugkGugkOugkBugkJugkFugkNugkDvjtxwVnP4BOPos6iQc6iQ86SQA6SQg68YNOEoFOEoNOkoBOkoJOkoFOkoNOUoBOUoJOUoHffmpw9iPo5K8A39/eue9rn9z7Z/f+V5D3ty/O56/O9e3vd7eJ//oPS3tLA3pLC3pLB3pLD3rLAHrLCHrLBHrLDHrLAnrLCnrLBnrLDnrLAXrLCRrKBc5+Bb19N1Hzdyk36CQP6CQv6CQf6CQ/6KQA6KQg6KQQ6KQw6KQI6KQo6KQY6KQ46KQE+O2XBGe/gU6CiTopBTopDTopAzopCzopBzopDzqpADqpCDqpBDqpDDqpAjqpCjqpBjqpDn77NcBZ30TvnQQHnfxP729f3Pe1v/8u/X0P5t7//vf9z3PfO59DONcPzhUywPe3mqC3WqC32qC3OqC3uqC3eqC3+qC3BqC3hqC3RqC3xqC3JqC3pqC3ZqCh5uBsCNBbKNHfpRagk5agk1agk9agkzagk7agk3agk/agkw6gk46gk06gk86gky6gk67gt98NnP0BdBJa1El30EkP0ElP0Ekv0Elv0Ekf0Elf0Ek/0El/0MkA0MlA0Mkg0Mlg0MkQ8NsfCs6GBJ2ECfD97Xv3fS2Uew/t3sMEeX8L63wO51zhnStCgO9vw0Bvw0FvI0BvI0Fvo0Bvo0FvY0BvY0Fv40Bv40FvE0BvE0Fvk0Bvk0FDU8DZcKC3iKK/S1NBJ9NAJ9NBJzNAJzNBJ7NAJ7NBJ3NAJ3NBJ/NAJ/NBJwtAJwtBJ4vAb38xOBsedBJJ1MkS0MlS0Mky0MmPoJPloJMVoJOVoJOfQCerQCerQSdrQCc/g07Wgk7Wgd/+enA2AugkcoDvb2Hd97WI7j2Se48c5P0tivM5qnNFc67oAb6/bQC9/QJ6+xX09hvo7XfQ20bQ2x+gtz9Bb5tAb5tBb1tAb1tBb9tAb9tBQzvA2aigtxiiv0s7QSe7QCe7QSd7QCd7QSf7QCf7QScHQCcHQSeHQCeHQSdHQCdHQSfHwG//ODgbDXQSU9TJCdDJSdDJKdDJadDJGdDJWdDJOdDJedDJBdDJRdDJJdDJZdDJFdDJVfDbvwbORgedxArw/S2K+74Ww73HdO+xgry/xXY+x3GuuM4VL8D3t+ugtxugt5ugt1ugt9ugtzugt7ugt3ugt/ugtwegt4egt0egt8egtyegoafgbBzQW3zR36VnoJPnoJMXoJOXoJNXoJPXoJM3oJO3oJN3oJP3oJMPoJOPoJNPoJPP4Lf/FzgbF3SSQNTJF9DJV9DJN9CJL4X3Tr5L4b2TYCm8dxI8hfdOvk/hvZMQKbx38sM/nQ1yOuQ/n/2v06G8nHVPh/Z29j9Oh/F61jkdFpyNBzpJGOD7W2z3fS2+e0/g3hMGeX/zO58TOVdi50oS4PtbuBTeewufwntvEVJ47y0i6C0S6C0y6C0K6C0q6C0a6C066C0G6C0m6C0W6C02aCgOOJsI9JZU9HcpLugkHugkPugkAegkIejEDzpJBDpJDDpJAjpJCjpJBjpJDjpJATpJCX77qcDZxKCTZKJOUoNO0oBO0oJO0oFO0oNOMoBOMoJOMoFOMoNOsoBOsoJOsoFOsoNOcoDffk5wNgnoJHmA729+930tqXtP5t6TB3l/S+F8TulcqZwrdYDvb7lAb7lBb3lAb3lBb/lAb/lBbwVAbwVBb4VAb4VBb0VAb0VBb8VAb8VBQyXA2ZSgtzSiv0slQSelQCelQSdlQCdlQSflQCflQScVQCcVQSeVQCeVQSdVQCdVQSfVwG+/OnnXA52kFXVSA3RSE3RSC3RSG3RSB3RSF3RSD3RSH3TSAHTSEHTSCHTSGHTSBHTSFPz2m4GzqUEn6QJ8f0vhvq+lce9p3Xu6IO9v6Z3PGZwro3NlCvD9rTnorQXorSXorRXorTXorQ3orS3orR3orT3orQPorSPorRPorTPorQtoqCs4mwH0lln0d6kb6KQ76KQH6KQn6KQX6KQ36KQP6KQv6KQf6KQ/6GQA6GQg6GQQ6GQw+O0PAWczgk6yiDoZCjoZBjoZDjoZAToZCToZBToZDToZAzoZCzoZBzoZDzqZADqZCDqZBH77k8HZTKCTrAG+v6V339cyu/cs7j1rkPe3bM7n7M6Vw7lyBvj+NgX0NhX0Ng30Nh30NgP0NhP0Ngv0Nhv0Ngf0Nhf0Ng/0Nh/0tgD0thA0tAiczQ56yyX6u7QYdLIEdLIUdLIMdPIj6GQ56GQF6GQl6OQn0Mkq0Mlq0Mka0MnPoJO14Le/DpzNATrJLepkPehkA+jkF9DJr6CT30Anv4NONoJO/gCd/Ak62QQ62Qw62QI62Qo62QZ++9vB2ZygkzwBvr9lc9/Xcrn33O49T5D3t7zO53zOld+5CgT4/rYD9LYT9LYL9LYb9LYH9LYX9LYP9LYf9HYA9HYQ9HYI9HYY9HYE9HYUNHQMnM0Heiso+rt0HHRyAnRyEnRyCnRyGnRyBnRyFnRyDnRyHnRyAXRyEXRyCXRyGXRyBfz2r4Kz+UEnhUSdXAOdXAed3ACd3ASd3AKd3Aad3AGd3AWd3AOd3AedPACdPASdPAKdPAa//SfgbAHQSeEA39/yuu9rBd17IfdeOMj7WxHnc1HnKuZcxQN8f3sKensGensOensBensJensFensNensDensLensHensPevsAevsIevsEGvoMzhYFvZUw/l0K4d79/yL63//1F+jkC+jkK/heioHvpaTxewnl3v3/+h/t+9/+9Q2060v5v1v/+3/Bdym9dxMspZfv8P/9FwRP6f37/h6cLQ62KfXftvm//j//09+IIu7fhBLuvaR7LxXkb0Rp53MZ5yrrXOX+298IunGIlN43/gFsHBJsHApsHBrsFgacLQM2Lg82Dvovuk1YsE04sE14sE0EsE1E8H1HAmfLgm0qiLaJDLaJAraJCraJBraJDr7vGOBsObBNxQCfjaXdZ2F5917BvVcM8mys5Hyu7FxVnKtqgM/GmGDjWGDj2GDjOGDjuGC3eOBsZbBxNVF/8cE2CcA2CcE2frBNIvB9JwZnq4Btqou2SQK2SQq2SQa2SQ62SQG+75TgbFWwTY0An42V3GdhNfde3b3XCPJsrOl8ruVctZ2rToDPxlRg49Rg4zRg47Rg43Rgt/TgbC2wcV1RfxnANhnBNpnANpnBNlnA950VnK0Ntqkn2iYb2CY72CYH2CYn2CYX+L5zg7N1wDb1A3w21nSfhXXdez33Xj/Is7GB87mhczVyrsYBPhvzgI3zgo3zgY3zg40LgN0KgrMNwcZNRP0VAtsUBtsUAdsUBdsUI/9zKnC2EdimqWibEmCbkmCbUmCb0mCbMuR/hgHONgbbNAvw2djAfRY2ce9N3XuzIM/G5s7nFs7V0rlaBfhsLAc2Lg82rgA2rgg2rkT++2RwtgXYuLWovypgm6pgm2pgm+pgmxrg+64JzrYE27QRbVMLbFMbbFMHbFMXbFMPfN/1wdlWYJu2AT4bm7vPwtbuvY17bxvk2djO+dzeuTo4V8cAn40NwMYNwcaNwMaNwcZNwG5Nwdn2YONOov6agW2ag21agG1agm1age+7NTjbAWzTWbRNG7BNW7BNO7BNe7BNB/B9dyRnwTZdAnw2tnOfhZ3ce2f33iXIs7Gr87mbc3V3rh4BPhs7gY07g427gI27go27gd26g7PdwMY9Rf31ANv0BNv0Atv0Btv0Ad93X7Ij2KaXaJt+YJv+YJsBYJuBYJtB4PseDM72ANv0DvDZ2NV9FvZ0773ce+8gz8Y+zue+ztXPufoH+GwcAjYeCjYeBjYeDjYeAXYbSVoFGw8Q9TcKbDMabDMGbDMWbDMOfN/jwdl+YJuBom0mgG0mgm0mgW0mg22mgO97KjjbH2wzKMBnYx/3WTjAvQ9074OCPBsHO5+HONdQ5xoW4LNxGth4Oth4Bth4Jth4FthtNjg7BGw8XNTfHLDNXLDNPLDNfLDNAvB9LwRnh4JtRoi2WQS2WQy2WQK2WQq2WQa+7x/B2WFgm5EBPhsHu8/C4e59hHsfGeTZOMr5PNq5xjjX2ACfjcvBxivAxivBxj+BjVeB3VaDs6PBxuNE/a0B2/wMtlkLtlkHtlkPvu8N4OwYsM140Ta/gG1+Bdv8Brb5HWyzEXzff4CzY8E2EwJ8No5yn4Xj3Pt49z4hyLNxovN5knNNdq4pAT4b/wQbbwIbbwYbbwEbbwW7bQNnJ4GNp4r62w622QG22Qm22QW22Q2+7z3g7GSwzTTRNnvBNvvANvvBNgfANgfB930InJ0Ctpke4LNxovssnOrep7n36UGejTOczzOda5ZzzQ7w2XgYbHwEbHwUbHwMbHwc7HYCnJ0JNp4j6u8k2OYU2OY02OYM2OYs+L7PgbOzwDZzRducB9tcANtcBNtcAttcBt/3FfI/twLbzAvw2TjDfRbOce9z3fu8IM/G+c7nBc610LkWBfhsvAo2vgY2vg42vgE2vgl2uwXOLgAbLxb1dxtscwdscxdscw9scx983w/I/2wSbLNEtM1DsM0jsM1jsM0TsM1T8H0/A2cXgW2WBvhsnO8+Cxe79yXufWmQZ+My5/OPzrXcuVYE+Gx8DjZ+ATZ+CTZ+BTZ+DXZ7Q/7nz2DjlaL+3oJt3oFt3oNtPoBtPoLv+xM4uxxs85Nom89gm7/ANl/ANl/BNt/A9+1L5f3sCrDNqgCfjcvcZ+FK9/6Te18V5Nm42vm8xrl+dq61AT4bv0vlfeNgqbxvHDyV942/T+V94xBgtx/A2TVg43Wi/kKCbUKBbUKDbcKAbcKC7zscOPsz2Ga9aJvwYJsIYJuIYJtIYJvI4PuOAs6uBdtsCPDZuNp9Fq5z7+vd+4Ygz8ZfnM+/OtdvzvV7gM/GqGDjaGDj6GDjGGDjmGC3WODsr2DjjaL+YoNt4oBt4oJt4oFt4oPvOwE4+xvY5g/RNgnBNn6wTSKwTWKwTRLwfScFZ38H2/wZ4LPxF/dZuNG9/+He/wzybNzkfN7sXFuca2uAz8ZkYOPkYOMUYOOUYONUYLfU4OxmsPE2UX9pwDZpwTbpwDbpwTYZwPedEZzdArbZLtomE9gmM9gmC9gmK9gmG/i+s4OzW8E2OwJ8Nm5yn4Xb3Pt2974jyLNxp/N5l3Ptdq49AT4bc4CNc4KNc4GNc4ON84Dd8oKzu8DGe0X95QPb5AfbFADbFATbFALfd2FwdjfYZp9omyJgm6Jgm2Jgm+JgmxLg+y4Jzu4B2+wP8Nm4030W7nXv+9z7/iDPxgPO54POdci5Dgf4bCwFNi4NNi4DNi4LNi4HdisPzh4EGx8R9VcBbFMRbFMJbFMZbFMFfN9VwdlDYJujom2qgW2qg21qgG1qgm1qge+7Njh7GGxzLMBn4wH3WXjEvR9178eCPBuPO59PONdJ5zoV4LOxDti4Lti4Hti4Pti4AditITh7Amx8WtRfI7BNY7BNE7BNU7BNM/B9NwdnT4Jtzoi2aQG2aQm2aQW2aQ22aQO+77bg7CmwzdkAn43H3Wfhafd+xr2fDfJsPOd8Pu9cF5zrYoDPxnZg4/Zg4w5g445g405gt87g7Hmw8SVRf13ANl3BNt3ANt3BNj3A990TnL0Atrks2qYX2KY32KYP2KYv2KYf+L77g7MXwTZXAnw2nnOfhZfc+2X3fiXIs/Gq8/mac113rhsBPhsHgI0Hgo0HgY0Hg42HgN2GgrPXwMY3Rf0NA9sMB9uMANuMBNuMAt/3aHD2OtjmlmibMWCbsWCbcWCb8WCbCeD7ngjO3gDb3A7w2XjVfRbedO+33PvtIM/GO87nu851z7nuB/hsnAQ2ngw2ngI2ngo2ngZ2mw7O3gUbPxD1NwNsMxNsMwtsMxtsMwd833PB2Xtgm4eibeaBbeaDbRaAbRaCbRaB73sxOHsfbPMowGfjHfdZ+MC9P3Tvj4I8Gx87n58411Pnehbgs3EJ2Hgp2HgZ2PhHsPFysNsKcPYJ2Pi5qL+VYJufwDarwDarwTZrwPf9Mzj7FGzzQrTNWrDNOrDNerDNBrDNL+D7/hWcfQa2eRngs/Gx+yx87t5fuPeXQZ6Nr5zPr53rjXO9DfDZ+BvY+Hew8Uaw8R9g4z/BbpvA2ddg43ei/jaDbbaAbbaCbbaBbbaD73sHOPsGbPNetM1OsM0usM1usM0esM1e8H3vA2ffgm0+BPhsfOU+C9+59/fu/UOQZ+NH5/Mn5/rsXH8F+GzcDzY+ADY+CDY+BDY+DHY7As5+Aht/EfV3FGxzDGxzHGxzAmxzkvzvN8HZz2Cbr6JtToNtzoBtzoJtzoFtzpP/3Rc4+xfY5luAz8aP7rPwi3v/6t6/BXk2+iY5/2/OFcy5gk/6139YuvFFsPElsPFlsPEVsPFV8r9fAWf//j7/8+w/bfz9JE1/18E2N8A2N8E2t8A2t8H3fQecDQa2CSHa5i7Y5h7Y5j7Y5gHY5iH4vh+Bs8HBNj+Abf6nZ+N/PPd8/6+/v+8h3Pvf/77/eS6k8zmUc4V2rjABPhsfg42fgI2fgo2fgY2fg91egLOhwMZhRf29BNu8Atu8Btu8Adu8Bd/3O3A2NNgmnGib92CbD2Cbj2CbT2Cbz+RdEJwNA7YJH+CzMaT7LAzr3sO59/BBno0RnM8RnSuSc0X+b8/G4O7d/68E3//2ry/ge4gIvocoot/oV/Ab/QZ+o77U3n+j36X2ef6NBkvt/fsODs5GAttEFW3zfWrv24RI7X2bH8A2IcE2ocD3HRqcjQy2iRbg8yOC+7yI4t6juvdoQZ4f0Z3PMZwrpnPFCvDdKgzYOCzYOBzYODzYOALYLSI4GwNsHFvUXySwTWSwTRSwTVSwTTTwfUcHZ2OCbeKItokBtokJtokFtokNtokDvu+44GwssE3cAJ+N0d1nYWz3Hse9xw3ybIznfI7vXAmcK2GAz8Z4YOP4YOMEYOOEYGM/2C0ROBsfbOwX9ZcYbJMEbJMUbJMMbJMcfN8pwNkEYJtEom1Sgm1SgW1Sg23SgG3Sgu87HTibEGyTOMBnYzz3Weh374nce+Igz8YkzuekzpXMuZIH+GxMDzbOADbOCDbOBDbODHbLAs4mBRunEPWXFWyTDWyTHWyTA2yTE3zfucDZZGCblKJtcoNt8oBt8oJt8oFt8oPvuwA4mxxskyrAZ2MS91mYwr2ndO+pgjwbUzuf0zhXWudKF+CzsSDYuBDYuDDYuAjYuCjYrRg4mwZsnF7UX3GwTQmwTUmwTSmwTWnwfZcBZ9OCbTKItikLtikHtikPtqkAtqkIvu9K5B0TbJMxwGdjavdZmN69Z3DvGYM8GzM5nzM7Vxbnyhrgs7Ey2LgK2Lgq2Lga2Lg62K0GOJsZbJxN1F9NsE0tsE1tsE0dsE1d8H3XI+//YJvsom3qg20agG0agm0agW0ag++7CTibFWyTI8BnYyb3WZjNvWd37zmCPBtzOp9zOVdu58oT4LOxKdi4Gdi4Odi4Bdi4JditFfnv8cDGeUX9tQbbtAHbtAXbtAPbtAffdwdwNjfYJp9om45gm05gm85gmy5gm67g++4GzuYB2+QP8NmY030W5nXv+dx7/iDPxgLO54LOVci5Cgf4bOwONu4BNu4JNu4FNu4NdusDzhYEGxcR9dcXbNMPbNMfbDMAbDMQfN+DwNlCYJuiom0Gg22GgG2Ggm2GgW2Gg+97BDhbGGxTLMBnYwH3WVjEvRd178WCPBuLO59LOFdJ5yoV4LNxJNh4FNh4NNh4DNh4LNhtHDhbAmxcWtTfeLDNBLDNRLDNJLDNZPB9TwFnS4Jtyoi2mQq2mQa2mQ62mQG2mQm+71ngbCmwTdkAn43F3Wdhafdexr2XDfJsLOd8Lu9cFZyrYoDPxtlg4zlg47lg43lg4/lgtwXgbHmwcSVRfwvBNovANovBNkvANkvB970MnK0Atqks2uZHsM1ysM0KsM1KsM1P4PteBc5WBNtUCfDZWM59FlZy75Xde5Ugz8aqzudqzlXduWoE+GxcDTZeAzb+GWy8Fmy8Duy2HpytBjauKepvA9jmF7DNr2Cb38A2v4PveyM4Wx1sU0u0zR9gmz/BNpvANpvBNlvA972V/O87wTa1A3w2VnWfhTXdey33XjvIs7GO87muc9VzrvoBPhu3gY23g413gI13go13gd12g7N1wcYNRP3tAdvsBdvsA9vsB9scAN/3QfK/0wbbNBRtcwhscxhscwRscxRscwx838fB2fpgm0YBPhvruM/CBu69oXtvFOTZ2Nj53MS5mjpXswCfjSfAxifBxqfAxqfBxmfAbmfJ/90C2Li5qL9zYJvzYJsLYJuLYJtL4Pu+DM42Bdu0EG1zBWxzFWxzDWxzHWxzA3zfN8HZZmCblgE+Gxu7z8Lm7r2Fe28Z5NnYyvnc2rnaOFfbAJ+Nt8DGt8HGd8DGd8HG98Bu98HZ1mDjdqL+HoBtHoJtHoFtHoNtnoDv+yk42wZs0160zTOwzXOwzQuwzUuwzSvwfb8GZ9uCbToE+Gxs5T4L27n39u69Q5BnY0fncyfn6uxcXQJ8Nr4BG78FG78DG78HG38Au30EZzuBjbuK+vsEtvkMtvkLbPMFbPMVfN/fwNnOYJtuom18abxv810a79sES+N9m+BpvG/zfRrv33cIcLYL2KZ7gM/Gju6zsKt77+beuwd5NvZwPvd0rl7O1TvAZ+MPYOOQYONQYOPQYOMwYLew4GxPsHEfUX/hwDbhwTYRwDYRwTaRwPcdGZztBbbpK9omCtgmKtgmGtgmOtgmBvi+Y4KzvcE2/QJ8NvZwn4V93Htf994vyLOxv/N5gHMNdK5BAT4bY4GNY4ON44CN44KN44Hd4oOzA8DGg0X9JQDbJATb+ME2icA2icH3nQScHQi2GSLaJinYJhnYJjnYJgXYJiX4vlOBs4PANkMDfDb2d5+Fg937EPc+NMizcZjzebhzjXCukQE+G1ODjdOAjdOCjdOBjdOD3TKAs8PBxqNE/WUE22QC22QG22QB22QF33c2cHYE2Ga0aJvsYJscYJucYJtcYJvc4PvOA86OBNuMCfDZOMx9Fo5y76Pd+5ggz8axzudxzjXeuSYE+GzMCzbOBzbODzYuADYuCHYrBM6OAxtPFPVXGGxTBGxTFGxTDGxTHHzfJcDZ8WCbSaJtSoJtSoFtSoNtyoBtyoLvuxw4OwFsMznAZ+NY91k40b1Pcu+TgzwbpzifpzrXNOeaHuCzsTzYuALYuCLYuBLYuDLYrQo4OxVsPEPUX1WwTTWwTXWwTQ2wTU3wfdcCZ6eBbWaKtqkNtqkDtqkLtqkHtqkPvu8G4Ox0sM2sAJ+NU9xn4Qz3PtO9zwrybJztfJ7jXHOda16Az8aGYONGYOPGYOMmYOOmYLdm4OwcsPF8UX/NwTYtwDYtwTatwDatwffdBpydC7ZZINqmLdimHdimPdimA9imI/i+O4Gz88A2CwN8Ns52n4Xz3fsC974wyLNxkfN5sXMtca6lAT4bO4ONu4CNu4KNu4GNu4PdeoCzi8HGy0T99QTb9ALb9Abb9AHb9AXfdz9wdgnY5kfRNv3BNgPANgPBNoPANoPB9z0EnF0Ktlke4LNxkfssXObef3Tvy4M8G1c4n1c610/OtSrAZ+NQsPEwsPFwsPEIsPFIsNsocHYl2Hi1qL/RYJsxYJuxYJtxYJvx5H9OBc7+BLZZI9pmIthmEthmMthmCthmKvmfYYCzq8A2Pwf4bFzhPgtXu/c17v3nIM/Gtc7ndc613rk2BPhsnA42ngE2ngk2ngU2nk3++2Rwdh3Y+BdRf3PBNvPANvPBNgvANgvB970InF0PtvlVtM1isM0SsM1SsM0ysM2P4PteDs5uANv8FuCzca37LPzFvf/q3n8L8mz83fm80bn+cK4/A3w2rgAbrwQb/wQ2XgU2Xg12WwPObgQbbxL19zPYZi3YZh3YZj3YZgP4vn8BZ/8A22wWbfMr2OY3sM3vYJuNYJs/wPf9JzkLttkS4LPxd/dZuMm9b3bvW4I8G7c6n7c513bn2hHgs3ET2Hgz2HgL2Hgr2Hgb2G07OLsNbLxT1N8OsM1OsM0usM1usM0e8H3vJTuCbXaJttkHttkPtjkAtjkItjkEvu/D4OwOsM3uAJ+NW91n4U73vsu97w7ybNzjfN7rXPuca3+Az8YjYOOjYONjYOPjYOMTYLeTpFWw8QFRf6fANqfBNmfANmfBNufA930enN0Htjko2uYC2OYi2OYS2OYy2OYK+L6vgrP7wTaHAnw27nGfhQfc+0H3fijIs/Gw8/mIcx11rmMBPhuvgY2vg41vgI1vgo1vgd1ug7NHwMbHRf3dAdvcBdvcA9vcB9s8AN/3Q3D2KNjmhGibR2Cbx2CbJ2Cbp2CbZ+D7fg7OHgPbnAzw2XjYfRYed+8n3PvJIM/GU87n0851xrnOBvhsfAE2fgk2fgU2fg02fgN2ewvOngYbnxP19w5s8x5s8wFs8xFs8wl835/B2TNgm/PGbYK7d/+//kf7/rd//QX++c+Cf/4LAT4/TrnPi3Pu/bx7vxDk+XHR+XzJuS4715X/9vyI7N79Qf75ff/Hv7789+/h/zj99f/7nf2vp7/9T9/v/3Y6rfdOvkv7v+z2P5wOlvZ/3fj/czp42v/j9/DfTn+f9v/87fzL6RBpvbf6wz+dDXI65D+f/a/TobycdU+H9nb2P06H8XrWOR0WnL0Eerv633r7v/5/Qf9FOwmX1nsn4dN67yRCWu+dRASdRAKdRAadRAGdRAWdRAOdRAedxACdxASdxAKdxAa//Tjg7GXQyTVRJ3FBJ/FAJ/FBJwlAJwlBJ37QSSLQSWLQSRLQSVLQSTLQSXLQSQrQSUrw208Fzl4BnVwHnfxP728X3fe1q+79mnu/HuT97Ybz+aZz3XKu2wG+v6UGvaUBvaUFvaUDvaUHvWUAvWUEvWUCvWUGvWUBvWUFvWUDvWUHveUADeUEZ2+C3u6I/i7lAp3kBp3kAZ3kBZ3kA53kB50UAJ0UBJ0UAp0UBp0UAZ0UBZ0UA50UB7/9EuDsLdDJXVEnJUEnpUAnpUEnZUAnZUEn5UAn5UEnFUAnFUEnlUAnlUEnVUAnVUEn1cBvvzo4ext0ci/A97cb7vvaHfd+173fC/L+dt/5/MC5HjrXowDf32qA3mqC3mqB3mqD3uqA3uqC3uqB3uqD3hqA3hqC3hqB3hqD3pqA3pqChpqBsw9Ab49Ff5eag05agE5agk5agU5ag07agE7agk7agU7ag046gE46gk46gU46g066gN9+V3D2IejkiaiTbqCT7qCTHqCTnqCTXqCT3qCTPqCTvqCTfqCT/qCTAaCTgaCTQaCTweC3PwScfQQ6eRrg+9t9933tsXt/4t6fBnl/e+Z8fu5cL5zrZYDvb0NBb8NAb8NBbyNAbyNBb6NAb6NBb2NAb2NBb+NAb+NBbxNAbxNBb5NAQ5PB2eegt1eiv0tTQCdTQSfTQCfTQSczQCczQSezQCezQSdzQCdzQSfzQCfzQScLQCcLwW9/ETj7AnTyWtTJYtDJEtDJUtDJMtDJj6CT5aCTFaCTlaCTn0Anq0Anq0Ena0AnP4NO1oLf/jpw9iXo5E2A72/P3Pe1V+79tXt/E+T97a3z+Z1zvXeuDwG+v60HvW0Avf0CevsV9PYb6O130NtG0NsfoLc/QW+bQG+bQW9bQG9bQW/bQEPbwdl3oLePor9LO0AnO0Enu0Anu0Ene0Ane0En+0An+0EnB0AnB0Enh0Anh0EnR0AnR8Fv/xg4+x508knUyXHQyQnQyUnQySnQyWnQyRnQyVnQyTnQyXnQyQXQyUXQySXQyWXQyRXw278Kzn4AnXwO8P3trfu+9tG9f3Lvn4O8v/3lfP7iXF+d61uA72/XQG/XQW83QG83QW+3QG+3QW93QG93QW/3QG/3QW8PQG8PQW+PQG+PQUNPwNkvoDffZM3fpaegk2egk+egkxegk5egk1egk9egkzegk7egk3egk/egkw+gk4+gk0/gt/8ZnP0KOvlO1MlfoJMvoJOvoJNvoBNfOu+dfJfOeyfB0nnvJHg67518n857JyH+6WyQ0z/889n/Oh3Sy1n3dChvZ//jdGivZ53TYcDZb6CTYKCT/+n97S/3fe3vv0t/379z73//+/7nueB/f3auEM71w+R//YelvYVN5723cOm89xY+nffeIqTz3ltE0Fsk0Ftk0FsU0FtU0Fs00Ft00FsM0FtM0Fss0FBscPb7yd57Cyn6uxQHdBIXdBIPdBIfdJIAdJIQdOIHnSQCnSQGnSQBnSQFnSQDnSQHnaQAv/2U4GwI0EkoUSepQCepQSdpQCdpQSfpQCfpQScZQCcZQSeZQCeZQSdZQCdZQSfZQCfZwW8/Bzj7A+gkdIDvb8Hd97WQ7j2Uew8d5P0tjPM5rHOFc67wAb6/5QS95QK95Qa95QG95QW95QO95Qe9FQC9FQS9FQK9FQa9FQG9FQW9FQMNFQdnw4LeIoj+LpUAnZQEnZQCnZQGnZQBnZQFnZQDnZQHnVQAnVQEnVQCnVQGnVQBnVQFv/1q4Gw40ElEUSfVQSc1QCc1QSe1QCe1QSd1QCd1QSf1QCf1QScNQCcNQSeNQCeNQSdNwG+/KTgbHnQSKcD3tzDu+1oE9x7RvUcK8v4W2fkcxbmiOle0AN/fmoHemoPeWoDeWoLeWoHeWoPe2oDe2oLe2oHe2oPeOoDeOoLeOoHeOoOGuoCzUUBv0UV/l7qCTrqBTrqDTnqATnqCTnqBTnqDTvqATvqCTvqBTvqDTgaATgaCTgaB3/5gcDYq6CSGqJMhoJOhoJNhoJPhoJMRoJORoJNRoJPRoJMxoJOxoJNxoJPxoJMJoJOJ4Lc/CZyNBjqJGeD7W2T3fS26e4/h3mMGeX+L5XyO7VxxnCtugO9vk0FvU0BvU0Fv00Bv00FvM0BvM0Fvs0Bvs0Fvc0Bvc0Fv80Bv80FvC0BDC8HZ2KC3eKK/S4tAJ4tBJ0tAJ0tBJ8tAJz+CTpaDTlaATlaCTn4CnawCnawGnawBnfwMfvtrwdk4oJP4ok7WgU7Wg042gE5+AZ38Cjr5DXTyO+hkI+jkD9DJn6CTTaCTzaCTLaCTreC3vw2cjQs6SRDg+1ss930tnnuP794TBHl/S/j3f4ZzJXKuxAG+v20Hve0Ave0Eve0Cve0Gve0Bve0Fve0Dve0HvR0AvR0EvR0CvR0GvR0BDR0FZ/2gtySiv0vHQCfHQScnQCcnQSenQCenQSdnQCdnQSfnQCfnQScXQCcXQSeXQCeXwW//CjibCHSSVNTJVdDJNdDJddDJDdDJTdDJLdDJbdDJHdDJXdDJPdDJfdDJA9DJQ9DJI/DbfwzOJgadJAvw/S2h+76WxL0nde/Jgry/JXc+p3CulM6VKsD3tyegt6egt2egt+egtxegt5egt1egt9egtzegt7egt3egt/egtw+gt4+goU/gbArQW2rR36XPoJO/QCdfQCdfQSffQCe+9N47+S69906CpffeSfD03jv5/p/OBjkd4p/P/tfpH7ycdU+H9Hb2P06H8nrWOR0anE0JOkkj6iRMeu+dhE3vvZNw6b13Ej69904ipPfeSUTQSSTQSWTQSRTQSVTQSTTQSXTQSQzQSUzw248FzqYCnaQN8P0tufu+ltq9p3HvaYO8v6VzPqd3rgzOlTHA97fYoLc4oLe4oLd4oLf4oLcEoLeEoDc/6C0R6C0x6C0J6C0p6C0Z6C05aCgFOJse9JZJ9HcpJegkFegkNegkDegkLegkHegkPegkA+gkI+gkE+gkM+gkC+gkK+gkG/jtZwdnM4BOMos6yQE6yQk6yQU6yQ06yQM6yQs6yQc6yQ86KQA6KQg6KQQ6KQw6KQI6KQp++8XA2YygkywBvr+lc9/XMrn3zO49S5D3t6zO52zOld25cgT4/lYc9FYC9FYS9FYK9FYa9FYG9FYW9FYO9FYe9FYB9FYR9FYJ9FYZ9FYFNFQVnM0Gessp+rtUDXRSHXRSA3RSE3RSC3RSG3RSB3RSF3RSD3RSH3TSAHTSEHTSCHTSGPz2m5B3PdBJLlEnTUEnzUAnzUEnLUAnLUEnrUAnrUEnbUAnbUEn7UAn7UEnHUAnHUEnncBvvzM4mwN0kjvA97es7vtaTveey73nDvL+lsf5nNe58jlX/gDf37qA3rqC3rqB3rqD3nqA3nqC3nqB3nqD3vqA3vqC3vqB3vqD3gaA3gaChgaBs3lBbwVEf5cGg06GgE6Ggk6GgU6Gg05GgE5Ggk5GgU5Gg07GgE7Ggk7GgU7Gg04mgN/+RHA2H+ikoKiTSaCTyaCTKaCTqaCTaaCT6aCTGaCTmaCTWaCT2aCTOaCTuaCTeaCT+eC3vwCczQ86KRTg+1se932tgHsv6N4LBXl/K+x8LuJcRZ2rWIDvbwtBb4tAb4tBb0tAb0tBb8tAbz+C3paD3laA3laC3n4Cva0Cva0Gva0BDf0MzhYBvRUX/V1aCzpZBzpZDzrZADr5BXTyK+jkN9DJ76CTjaCTP0Anf4JONoFONoNOtoDf/lZwtijopISok22gk+2gkx2gk52gk12gk92gkz2gk72gk32gk/2gkwOgk4Ogk0Ogk8Pgt38EnC0GOikZ4PtbYfd9rbh7L+HeSwZ5fyvlfC7tXGWcq2yA729HQW/HQG/HQW8nQG8nQW+nQG+nQW9nQG9nQW/nQG/nQW8XQG8XQW+XQEOXwdnSoLdyor9LV0AnV0En10An10EnN0AnN0Ent0Ant0End0And0En90An90EnD0AnD8Fv/xE4WwZ0Ul7UyWPQyRPQyVPQyTPQyXPQyQvQyUvQySvQyWvQyRvQyVvQyTvQyXvQyQfw2/8IzpYFnVQI8P2tlPu+Vs69l3fvFYK8v1V0PldyrsrOVSXA97dPoLfPoLe/QG9fQG9fQW/fQG++DN57+y6D996CZfDeW/B/Ohvk9Pf/fPa/TofwctY9/YO3s/9xOqTXs87pUOBsJdBbVdHfpdAZvHcSJoP3TsJm8N5JuAzeOwmfwXsnETJ47yQi6CQS6CQy6CQK6CQq6CQa6CQ66CQG+O3HBGcrg06qiTqJBTqJDTqJAzqJCzqJBzqJDzpJADpJCDrxg04SgU4Sg06SgE6Sgk6Sgd9+cnC2CuikeoDvbxXd97Wq7r2ae68e5P2thvO5pnPVcq7aAb6/pQC9pQS9pQK9pQa9pQG9pQW9pQO9pQe9ZQC9ZQS9ZQK9ZQa9ZQG9ZQUNZQNna4Le6oj+LmUHneQAneQEneQCneQGneQBneQFneQDneQHnRQAnRQEnRQCnRQGnRQBv/2i4Gwt0EldUSfFQCfFQSclQCclQSelQCelQSdlQCdlQSflQCflQScVQCcVQSeVQCeVyTsZOFsbdFIvwPe3Gu77Wh33Xte91wvy/lbf+dzAuRo6V6MA39+qgt6qgd6qg95qgN5qgt5qgd5qg97qgN7qgt7qgd7qg94agN4agt4agYYag7MNQG+NRX+XmoBOmoJOmoFOmoNOWoBOWoJOWoFOWoNO2oBO2oJO2oFO2oNOOoBOOoLffidwtiHopImok86gky6gk66gk26gk+6gkx6gk56gk16gk96gkz6gk76gk36gk/6gkwHgtz8QnG0EOmka4Ptbffd9rbF7b+LemwZ5f2vmfG7uXC2cq2WA72+DQG+DQW9DQG9DQW/DQG/DQW8jQG8jQW+jQG+jQW9jQG9jQW/jQG/jQUMTwNnmoLdWor9LE0Enk0Ank0EnU0AnU0En00An00EnM0AnM0Ens0Ans0Enc0Anc0En88Bvfz442wJ00lrUyQLQyULQySLQyWLQyRLQyVLQyTLQyY+gk+WgkxWgk5Wgk59AJ6tAJ6vBb38NONsSdNImwPe3Zu77Wiv33tq9twny/tbW+dzOudo7V4cA399+Br2tBb2tA72tB71tAL39Anr7FfT2G+jtd9DbRtDbH6C3P0Fvm0Bvm0FDW8DZdqC3jqK/S1tBJ9tAJ9tBJztAJztBJ7tAJ7tBJ3tAJ3tBJ/tAJ/tBJwdAJwdBJ4fAb/8wONsedNJJ1MkR0MlR0Mkx0Mlx0MkJ0MlJ0Mkp0Mlp0MkZ0MlZ0Mk50Ml50MkF0MlF8Nu/BM52AJ10DvD9ra37vtbRvXdy752DvL91cT53da5uztU9wPe3y6C3K6C3q6C3a6C366C3G6C3m6C3W6C326C3O6C3u6C3e6C3+6C3B6Chh+BsV9BbD9HfpUegk8egkyegk6egk2egk+egkxegk5egk1egk9egkzegk7egk3egk/fgt/8BnO0GOulp7CSEe/f/i+h//9dH0Mkn0Mln8L10B99LrwD/Xndx/z73cO893XuvIH+vezuf+zhXX+fqF+Df67/A9/sFfL9fwXPoG3gO+TJ6fw59l9H7cyhYRu/PoeAZvT+Hvs/o/TkU4p/OBjn9wz+f/a/TIb2cdU+H8nb2P06H9nrWOR0GnO0Deusv+nsdNqP3TsJl9N5J+IzeO4mQ0XsnEUEnkUAnkUEnUUAnUUEn0UAn0UEnMUAnMUEnscBvPzY42xd0MkDUSRzQSVzQSTzQSXzQSQLQSULQiR90kgh0khh0kgR0khR0kgx0khx0kgL89lOCs/1AJwMDfH/r7b6v9XfvA9z7wCDvb4Ocz4Oda4hzDQ3w/S0V6C016C0N6C0t6C0d6C096C0D6C0j6C0T6C0z6C0L6C0r6C0b6C07aCgHODsY9DZM9HcpJ+gkF+gkN+gkD+gkL+gkH+gkP+ikAOikIOikEOikMOikCOikKOikGPjtFwdnh4BOhos6KQE6KQk6KQU6KQ06KQM6KQs6KQc6KQ86qQA6qQg6qQQ6qQw6qQI6qQp++9XA2aGgkxEBvr8Nct/Xhrn34e59RJD3t5HO51HONdq5xgT4/lYd9FYD9FYT9FYL9FYb9FYH9FYX9FYP9FYf9NYA9NYQ9NYI9NYY9NYENNQUnB0Fehsr+rvUDHTSHHTSAnTSEnTSCnTSGnTSBnTSFnTSDnTSHnTSAXTSEXTSCXTSGfz2u4Czo0En40SddAWddAOddAed9ACd9ASd9AKd9Aad9AGd9AWd9AOd9AedDACdDASdDCL/PT44OwZ0Mj7A97eR7vvaWPc+zr2PD/L+NsH5PNG5JjnX5ADf34aA3oaC3oaB3oaD3kaA3kaC3kaB3kaD3saA3saC3saB3saD3iaA3iaChiaBsxNBb1NEf5cmg06mgE6mgk6mgU6mg05mgE5mgk5mgU5mg07mgE7mgk7mgU7mg04WgN/+QtIU6GSqqJNFoJPFoJMloJOloJNloJMfQSfLQScrQCcrQSc/gU5WgU5Wg07WgE5+Br/9teDsZNDJtADf3ya472tT3PtU9z4tyPvbdOfzDOea6VyzAnx/Wwd6Ww962wB6+wX09ivo7TfQ2++gt42gtz9Ab3+C3jaB3jaD3raA3raChraBszNAb7NFf5e2g052gE52gk52gU52g072gE72gk72gU72g04OgE4Ogk4OgU4Og06OgN/+UXB2JuhkjqiTY6CT46CTE6CTk6CTU6CT06CTM6CTs6CTc6CT86CTC6CTi6CTS6CTy+C3fwWcnQU6mRvg+9t0931ttnuf497nBnl/m+d8nu9cC5xrYYDvb1dBb9dAb9dBbzdAbzdBb7dAb7dBb3dAb3dBb/dAb/dBbw9Abw9Bb49AQ4/B2fmgt0Wiv0tPQCdPQSfPQCfPQScvQCcvQSevQCevQSdvQCdvQSfvQCfvQScfQCcfwW//Ezi7AHSyWNTJZ9DJX6CTL6CTr6CTb6ATXybvnXyXyXsnwTJ57yR4Ju+dfP9PZ4OcDvHPZ//r9A9ezrqnQ3o7+x+nQ3k965wODc4uBJ0sCfD9bZ77vrbIvS9270uCvL8tdT4vc64fnWt5gO9vYTJ57y1sJu+9hcvkvbfwmbz3FiGT994igt4igd4ig96igN6igt6igd6ig95igN5igoZigbPLQG8rRH+XYoNO4oBO4oJO4oFO4oNOEoBOEoJO/KCTRKCTxKCTJKCTpKCTZKCT5OC3nwKc/RF0slLUSUrQSSrQSWrQSRrQSVrQSTrQSXrQSQbQSUbQSSbQSWbQSRbQSVbQSTbw288Ozi4HnfwU4PvbUvd9bYV7X+nefwry/rbK+bzaudY4188Bvr/lAL3lBL3lAr3lBr3lAb3lBb3lA73lB70VAL0VBL0VAr0VBr0VAb0VBQ0VA2dXg97Wiv4uFQedlACdlASdlAKdlAadlAGdlAWdlAOdlAedVACdVASdVAKdVAadVAG//arg7BrQyTpRJ9VAJ9VBJzVAJzVBJ7VAJ7VBJ3VAJ3VBJ/VAJ/VBJw1AJw1BJ41AJ43Bb78JOPsz6GR9gO9vq9z3tbXufZ17Xx/k/W2D8/kX5/rVuX4L8P2tKeitGeitOeitBeitJeitFeitNeitDeitLeitHeitPeitA+itI+itE2ioMzj7C+jtd9HfpS6gk66gk26gk+6gkx6gk56gk16gk96gkz6gk76gk36gk/6gkwGgk4Hgtz8InP0VdLJR1Mlg0MkQ0MlQ0Mkw0Mlw0MkI0MlI0Mko0Mlo0MkY0MlY0Mk40Ml40MkE8NufCM7+Bjr5I8D3tw3u+9rv7n2je/8jyPvbn87nTc612bm2BPj+Ngn0Nhn0NgX0NhX0Ng30Nh30NgP0NhP0Ngv0Nhv0Ngf0Nhf0Ng/0Nh80tACc3QR62yr6u7QQdLIIdLIYdLIEdLIUdLIMdPIj6GQ56GQF6GQl6OQn0Mkq0Mlq0Mka8j8rAGc3g062iTpZCzpZBzpZDzrZADr5BXTyK+jkN9DJ76CTjaCTP0Anf4JONoFONoNOtoDf/lZwdgvoZHuA729/uu9rW937Nve+Pcj72w7n807n2uVcuwN8f9sGetsOetsBetsJetsFetsNetsDetsLetsHetsPejsAejsIejsEejsMGjoCzu4Eve0R/V06Cjo5Bjo5Djo5ATo5CTo5BTo5DTo5Azo5Czo5Bzo5Dzq5ADq5CDq5BH77l8HZXaCTvaJOroBOroJOroFOroNOboBOboJOboFOboNO7oBO7oJO7oFO7oNOHoBOHoLf/iNwdjfoZF+A72873Pe1Pe59r3vfF+T9bb/z+YBzHXSuQwG+vz0GvT0BvT0FvT0DvT0Hvb0Avb0Evb0Cvb0Gvb0Bvb0Fvb0Dvb0HvX0ADX0EZw+A3g6L/i59Ap18Bp38BTr5Ajr5Cjr5BjrxZfbeyXeZvXcSLLP3ToL/09kgp7//57P/dTqEl7Pu6R+8nf2P0yG9nnVOhwJnD4JOjog6CZ3ZeydhMnvvJGxm752Ey+y9k/CZvXcSIbP3TiKCTiKBTiKDTqKATqKCTqKBTqKDTmKA335McPYQ6ORogO9v+933tcPu/Yh7Pxrk/e2Y8/m4c51wrpMBvr/FAr3FBr3FAb3FBb3FA73FB70lAL0lBL35QW+JQG+JQW9JQG9JQW/JQEPJwdnjoLdTor9LKUAnKUEnqUAnqUEnaUAnaUEn6UAn6UEnGUAnGUEnmUAnmUEnWUAnWcFvPxs4ewJ0clrUSXbQSQ7QSU7QSS7QSW7QSR7QSV7QST7QSX7QSQHQSUHQSSHQSWHQSRHw2y8Kzp4EnZwJ8P3tmPu+dsq9n3bvZ4K8v511Pp9zrvPOdSHA97dioLfioLcSoLeSoLdSoLfSoLcyoLeyoLdyoLfyoLcKoLeKoLdKoLfKoKEq4Ow50NtF0d+lqqCTaqCT6qCTGqCTmqCTWqCT2qCTOqCTuqCTeqCT+qCTBqCThqCTRuC33xicPQ86uSTqpAnopCnopBnopDnopAXopCXopBXopDXopA3opC3opB3opD3opAPopCP47XcCZy+ATi4H+P521n1fu+jeL7n3y0He3644n6861zXnuh7g+1tn0FsX0FtX0Fs30Ft30FsP0FtP0Fsv0Ftv0Fsf0Ftf0Fs/0Ft/0NsA0NBAcPYq6O2G6O/SINDJYNDJENDJUNDJMNDJcNDJCNDJSNDJKNDJaNDJGNDJWNDJONDJePDbnwDOXgOd3BR1MhF0Mgl0Mhl0MgV0MhV0Mg10Mh10MgN0MhN0Mgt0Mht0Mgd0Mhd0Mg/89ueDs9dBJ7cCfH+74r6v3XDvN937rSDvb7edz3ec665z3Qvw/W0B6G0h6G0R6G0x6G0J6G0p6G0Z6O1H0Nty0NsK0NtK0NtPoLdVoLfVoKE14Owd0Nt90d+ln0Ena0En60An60EnG0Anv4BOfgWd/AY6+R10shF08gfo5E/QySbQyWbw298Czt4FnTwQdbIVdLINdLIddLIDdLITdLILdLIbdLIHdLIXdLIPdLIfdHIAdHIQdHII/PYPg7P3QCcPA3x/u+2+r9137w/c+8Mg72+PnM+PneuJcz0N8P3tCOjtKOjtGOjtOOjtBOjtJOjtFOjtNOjtDOjtLOjtHOjtPOjtAujtImjoEjj7GPT2TPR36TLo5Aro5Cro5Bro5Dro5Abo5Cbo5Bbo5Dbo5A7o5C7o5B7o5D7o5AH47T8EZ5+ATp6LOnkEOnkMOnkCOnkKOnkGOnkOOnkBOnkJOnkFOnkNOnkDOnkLOnkHOnkPfvsfwNmnoJMXAb6/PXLf15659+fu/UWQ97eXzudXzvXaud4E+P72EfT2CfT2GfT2F+jtC+jtK+jtG+jNl8V7b99l8d5bsH86G+R08H8++1+nv/dy1j0dwtvZ/zj9g9ezzumQ4Owr0Ntb0d+lUFm8dxI6i/dOwmTx3knYLN47CZfFeyfhs3jvJEIW751EBJ1EAp1EBp1EAZ1EBZ1EA51EB7/9GODsa9DJO1EnMUEnsUAnsUEncUAncUEn8UAn8UEnCUAnCUEnftBJItBJYtBJEtBJUvDbTwbOvgGdvA/w/e2l+7721r2/c+/vg7y/fXA+f3SuT871OcD3t+SgtxSgt5Sgt1Sgt9SgtzSgt7Sgt3Sgt/Sgtwygt4ygt0ygt8ygtyygoazg7EfQ21+iv0vZQCfZQSc5QCc5QSe5QCe5QSd5QCd5QSf5QCf5QScFQCcFQSeFQCeFwW+/CDj7CXTyRdRJUdBJMdBJcdBJCdBJSdBJKdBJadBJGdBJWdBJOdBJedBJBdBJRdBJJfDbrwzOfgadfA3w/e2D+772l3v/4t6/Bnl/+/b3O9sU5//duYJN+dd/WNpbFdBbVdBbNdBbddBbDdBbTdBbLdBbbdBbHdBbXdBbPdBbfdBbA9BbQ9BQI3D279/2f579p96CT9H8XWoMOmkCOmkKOmkGOmkOOmkBOmkJOmkFOmkNOmkDOmkLOmkHOmkPOukAfvsdwdnvQCffizrpBDrpDDrpAjrpCjrpBjrpDjrpATrpCTrpBTrpDTrpAzrpCzrpBzrpD377A8DZYKCTEKCT/+n97Zv7vvb336W/79+797//ff/z3A/O55DOFcq5Qgf4/jYQ9DYI9DYY9DYE9DYU9DYM9DYc9DYC9DYS9DYK9DYa9DYG9DYW9DYONDQenA0Jegsj+rs0AXQyEXQyCXQyGXQyBXQyFXQyDXQyHXQyA3QyE3QyC3QyG3QyB3QyF/z254GzoUAnYUWdzAedLACdLASdLAKdLAadLAGdLAWdLAOd/Ag6WQ46WQE6WQk6+Ql0sgr89leDs6FBJ+ECfH/7wX1fC+Pew7r3cEHe38I7nyM4V0TnihTg+9sa0NvPoLe1oLd1oLf1oLcNoLdfQG+/gt5+A739DnrbCHr7A/T2J+htE2hoMzgbAfQWWfR3aQvoZCvoZBvoZDvoZAfoZCfoZBfoZDfoZA/oZC/oZB/oZD/o5ADo5CD47R8CZyOCTqKIOjkMOjkCOjkKOjkGOjkOOjkBOjkJOjkFOjkNOjkDOjkLOjkHOjkPOrkAfvsXwdlIoJOoAb6/hXff1yK79yjuPWqQ97dozufozhXDuWIG+P52CfR2GfR2BfR2FfR2DfR2HfR2A/R2E/R2C/R2G/R2B/R2F/R2D/R2HzT0AJyNDnqLJfq79BB08gh08hh08gR08hR08gx08hx08gJ08hJ08gp08hp08gZ08hZ08g789t+DszFAJ7GNnYRw7/5/Ef3v//oAOvkIOvkEvpeY4HuJE+Df62ju3+dY7j22e48T5O91XOdzPOeK71wJ/tvf61Du3f+vBN//9q/P4Bnw1//xnf33/4IvoL+vnrb4f/8F38Buvqzez8YDGyf8bxv/X/+foP+i23yX1fs2wbJ63yZ4Vu/bfJ/V+zYhwPf9AzgbH2zjF20TEmwTCmwTGmwTBmwTFnzf4cDZBGCbRGCb/+nZGNd9FiZ07373nijIszGx8zmJcyV1rmQBPhvDg40jgI0jgo0jgY0jg92igLNJwMbJRf1FBdtEA9tEB9vEANvEBN93LHA2KdgmhWib2GCbOGCbuGCbeGCb+OR5B84mA9ukDPDZmNh9FiZ37ynce8ogz8ZUzufUzpXGudIG+GxMCDb2g40TgY0Tg42TkKbA2dRg43Si/pKBbZKDbVKAbVKCbVKR7xucTQO2SS/aJg3YJi3YJh3YJj3YJgP4vjOCs2nBNhkCfDamcp+F6dx7eveeIcizMaPzOZNzZXauLAE+GzOBjTODjbOAjbOCjbOB3bKDs5nAxllF/eUA2+QE2+QC2+QG2+QB33decDYz2CabaJt8YJv8YJsCYJuCYJtC4PsuDM5mAdtkD/DZmNF9FmZ179nce/Ygz8YczueczpXLuXIH+GwsAjYuCjYuBjYuDjYuAXYrCc7mBBvnEfVXCmxTGmxTBmxTFmxTDnzf5cHZXGCbvKJtKoBtKoJtKoFtKoNtqoDvuyo4mxtsky/AZ2MO91mYx73nde/5gjwb8zufCzhXQecqFOCzsRrYuDrYuAbYuCbYuBbYrTY4WwBsXFjUXx2wTV2wTT2wTX2wTQPwfTcEZwuCbYqItmkEtmkMtmkCtmkKtmkGvu/m4GwhsE3RAJ+N+d1nYWH3XsS9Fw3ybCzmfC7uXCWcq2SAz8YWYOOWYONWYOPWYOM2YLe24GxxsHEpUX/twDbtwTYdwDYdwTadwPfdGZwtAbYpLdqmC9imK9imG9imO9imB/i+e5L/3gxsUybAZ2Mx91lYyr2Xdu9lgjwbyzqfyzlXeeeqEOCzsRfYuDfYuA/YuC/YuB/YrT84Ww5sXFHU3wCwzUCwzSCwzWCwzRDwfQ8l//032KaSaJthYJvhYJsRYJuRYJtR4PseDc5WANtUDvDZWNZ9FlZ075Xce+Ugz8YqzueqzlXNuaoH+GwcAzYeCzYeBzYeDzaeAHabSP5nLGDjGqL+JoFtJoNtpoBtpoJtpoHvezo4Ww1sU1O0zQywzUywzSywzWywzRzwfc8FZ6uDbWoF+Gys4j4La7j3mu69VpBnY23ncx3nqutc9QJ8Ns4DG88HGy8AGy8EGy8Cuy0GZ+uAjeuL+lsCtlkKtlkGtvkRbLMcfN8rwNm6YJsGom1Wgm1+AtusAtusBtusAd/3z+BsPbBNwwCfjbXdZ2F9997AvTcM8mxs5Hxu7FxNnKtpgM/GtWDjdWDj9WDjDWDjX8Buv4KzjcHGzUT9/Qa2+R1ssxFs8wfY5k/wfW8CZ5uAbZqLttkMttkCttkKttkGttkOvu8d4GxTsE2LAJ+NjdxnYTP33ty9twjybGzpfG7lXK2dq02Az8adYONdYOPdYOM9YOO9YLd94GwrsHFbUX/7wTYHwDYHwTaHwDaHwfd9BJxtDbZpJ9rmKNjmGNjmONjmBNjmJPi+T4GzbcA27QN8NrZ0n4Vt3Xs7994+yLOxg/O5o3N1cq7OAT4bT4ONz4CNz4KNz4GNz4PdLoCzHcHGXUT9XQTbXALbXAbbXAHbXAXf9zVwthPYpqtom+tgmxtgm5tgm1tgm9vg+75D/u8NwDbdAnw2dnCfhV3ce1f33i3Is7G787mHc/V0rl4BPhvvgo3vgY3vg40fgI0fgt0egbM9wMa9Rf09Bts8Ads8Bds8A9s8B9/3C/J/UwK26SPa5iXY5hXY5jXY5g3Y5i34vt+Bs73ANn0DfDZ2d5+Fvd17H/feN8izsZ/zub9zDXCugQE+G9+DjT+AjT+CjT+BjT+D3f4i//c+YONBov6+gG2+gm2+gW182bxv81027993MHB2ANhmsGib4Nm8b/N9Nu/bhMjmfZsfwDYhwfcdCpwdCLYZEuCzsZ/7LBzk3ge79yFBno1Dnc/DnGu4c40I8NkYGmwcBmwcFmwcDmwcHuwWAZwdBjYeKeovItgmEtgmMtgmCtgmKvi+o4Gzw8E2o0TbRAfbxADbxATbxALbxAbfdxxwdgTYZnSAz8ah7rNwpHsf5d5HB3k2jnE+j3Wucc41PsBnY1ywcTywcXywcQKwcUKwmx+cHQs2niDqLxHYJjHYJgnYJinYJhn4vpODs+PANhNF26QA26QE26QC26QG26QB33dacHY82GZSgM/GMe6zcIJ7n+jeJwV5Nk52Pk9xrqnONS3AZ2M6sHF6sHEGsHFGsHEmsFtmcHYK2Hi6qL8sYJusYJtsYJvsYJsc4PvOCc5OBdvMEG2TC2yTG2yTB2yTF2yTD3zf+cHZaWCbmQE+Gye7z8Lp7n2Ge58Z5Nk4y/k827nmONfcAJ+NBcDGBcHGhcDGhcHGRcBuRcHZ2WDjeaL+ioFtioNtSoBtSoJtSoHvuzQ4OwdsM1+0TRmwTVmwTTmwTXmwTQXwfVcEZ+eCbRYE+Gyc5T4L57n3+e59QZBn40Ln8yLnWuxcSwJ8NlYCG1cGG1cBG1cFG1cDu1UHZxeBjZeK+qsBtqkJtqkFtqkNtqkDvu+64OxisM0y0Tb1wDb1wTYNwDYNwTaNwPfdGJxdArb5McBn40L3WbjUvS9z7z8GeTYudz6vcK6VzvVTgM/GJmDjpmDjZmDj5mDjFmC3luDsCrDxKlF/rcA2rcE2bcA2bcE27cD33R6cXQm2WS3apgPYpiPYphPYpjPYpgv4vruCsz+BbdYE+Gxc7j4LV7n31e59TZBn48/O57XOtc651gf4bOwGNu4ONu4BNu4JNu4FdusNzq4FG28Q9dcHbNMXbNMPbNMfbDOA/N9+gLPrwDa/iLYZBLYZDLYZArYZCrYZRv7vAsDZ9WCbXwN8Nv7sPgs3uPdf3PuvQZ6Nvzmff3eujc71R4DPxhFg45Fg41Fg49Fg4zHkf/cMzv4ONv5T1N84sM14sM0EsM1EsM0k8H1PBmc3gm02ibaZAraZCraZBraZDraZAb7vmeDsH2CbzQE+G39zn4V/uvdN7n1zkGfjFufzVufa5lzbA3w2zgIbzwYbzwEbzwUbzwO7zQdnt4KNd4j6WwC2WQi2WQS2WQy2WQK+76Xg7DawzU7RNsvANj+CbZaDbVaAbVaS/z4ZnN0OttkV4LNxi/ss3OHed7r3XUGejbudz3uca69z7Qvw2bgKbLwabLwGbPwz2Hgt+e/FwNk9YOP9ov7Wg202gG1+Adv8Crb5jbyng7N7wTYHRNtsBNv8Abb5E2yzCWyzGXzfW8DZfWCbgwE+G3e7z8L97v2Aez8Y5Nl4yPl82LmOONfRAJ+NW8HG28DG28HGO8DGO8Fuu8DZw2DjY6L+doNt9oBt9oJt9oFt9oPv+wA4ewRsc1y0zUGwzSGwzWGwzRGwzVHwfR8DZ4+CbU4E+Gw85D4Lj7n34+79RJBn40nn8ynnOu1cZwJ8Nh4HG58AG58EG58CG58Gu50BZ0+Bjc+K+jsLtjkHtjkPtrkAtrkIvu9L4OxpsM050TaXwTZXwDZXwTbXwDbXwfd9gzQGtjkf4LPxpPssPOvez7n380GejReczxed65JzXQ7w2XgTbHwLbHwbbHwHbHwX7HYPnL0INr4i6u8+2OYB2OYh2OYR2OYx+L6fkOco2OaqaJunYJtnYJvnYJsXYJuX4Pt+Bc5eBttcC/DZeMF9Fl5x71fd+7Ugz8brzucbznXTuW4F+Gx8DTZ+AzZ+CzZ+BzZ+D3b7QP5Wgo1vG/sL7t79//of7fvf/vUR/PPfBP/8d0TPj0/gt/UZ/Lb+Ar+tL+C39RV839/A2Vtgm7sBPj+uu8+L2+79jnu/G+T5cc/5fN+5HjjXwwCfH77s3jf+Lrv3jYNl975x8H86G+S/4HtPZ//ff0EIcPY+2PiRqL8fwDYhwTahwDahwTZhwPcdFpx9ALZ5LNomHNgmPNgmAtgmItgmEvi+I4OzD8E2TwJ8Nt5zn4WP3Ptj9/4kyLPxqfP5mXM9d64XAT4bo4CNo4KNo4GNo4ONY4DdYoKzz8DGL0X9xQLbxAbbxAHbxAXbxAPfd3xw9jnY5pVomwRgm4RgGz/YJhHYJjH4vpOAsy/ANq8DfDY+dZ+FL937K/f+Osiz8Y3z+a1zvXOu9wE+G5OCjZOBjZODjVOAjVOC3VKBs2/Bxh9E/aUG26QB26QF26QD26QH33cGcPYd2OajaJuMYJtMYJvMYJssYJus4PvOBs6+B9t8CvDZ+MZ9Fn5w7x/d+6cgz8bPzue/nOuLc30N8NmYHWycA2ycE2ycC2ycG+yWB5z9C2z8TdRfXrBNPrBNfrBNAbBNQfB9FwJnv4BtfFM12xQG2xQB2xQF2xQD2xQH33cJcPYr2OY7sM3/9Gz87D4Lv7n3v7f+zv33/c9zwZzPwf/+/+9cIab+6z8s3bgk2LgU2Lg02LgM2Lgs2K0cOBt8qveNfxD1Vx5sUwFsUxFsUwlsUxl831XA2e/BNiFF21QF21QD21QH29QA29QE33ct8j/TB9uECvDZGMx9Fv7g3kO691BBno2hnc9hnCusc4UL8NlYG2xcB2xcF2xcD2xcH+zWAJwNAzYOL+qvIdimEdimMdimCdimKfi+m5H/vQ3YJoJom+ZgmxZgm5Zgm1Zgm9bg+24DzoYD20QM8NkY2n0WhnfvEdx7xCDPxkjO58jOFcW5ogb4bGwLNm4HNm4PNu4ANu4IdutE/ndzYONoov46g226gG26gm26gW26g++7BzgbBWwTXbRNT7BNL7BNb7BNH7BNX/B99wNno4JtYgT4bIzkPgujuffo7j1GkGdjTOdzLOeK7VxxAnw29gcbDwAbDwQbDwIbDwa7DQFnY4GN44r6Gwq2GQa2GQ62GQG2GQm+71HgbGywTTzRNqPBNmPANmPBNuPANuPB9z0BnI0Dtokf4LMxpvssjOve47n3+EGejQmczwn//s9xrkQBPhsngo0ngY0ng42ngI2ngt2mgbMJwcaJRf1NB9vMANvMBNvMAtvMBt/3HHDWD7ZJItpmLthmHthmPthmAdhmIfi+F4GzicA2SQN8NiZwn4WJ3XsS9540yLMxmfM5uXOlcK6UAT4bF4ONl4CNl4KNl4GNfwS7LQdnk4ONU4n6WwG2WQm2+Qlsswpssxp832vA2RRgm9SibX4G26wF26wD26wH22wA3/cv4GxKsE2aAJ+NydxnYSr3ntq9pwnybEzrfE7nXOmdK0OAz8Zfwca/gY1/BxtvBBv/AXb7E5xNBzbOKOpvE9hmM9hmC9hmK9hmG/i+t4Oz6cE2mUTb7ADb7ATb7ALb7Abb7AHf915wNgPYJnOAz8a07rMwo3vP5N4zB3k2ZnE+Z3WubM6VPcBn4z6w8X6w8QGw8UGw8SGw22FwNivYOIeovyNgm6Ngm2Ngm+NgmxPg+z4JzmYD2+QUbXMKbHMabHMGbHMWbHMOfN/nwdnsYJtcAT4bs7jPwhzuPad7zxXk2Zjb+ZzHufI6V74An40XwMYXwcaXwMaXwcZXwG5Xwdk8YOP8ov6ugW2ug21ugG1ugm1uge/7NjibF2xTQLTNHbDNXbDNPbDNfbDNA/B9PwRn84FtCgb4bMztPgvzu/cC7r1gkGdjIedzYecq4lxFA3w2PgIbPwYbPwEbPwUbPwO7PQdnC4ONi4n6ewG2eQm2eQW2eQ22eQO+77fgbBGwTXHRNu/ANu/BNh/ANh/BNp/A9/0ZnC0KtikR4LOxkPssLObei7v3EkGejSWdz6Wcq7RzlQnw2fgX2PgL2Pgr2Pgb2NiXw/tu34GzpcDGZUX9BcvhfZvgObxv830O79uEyOF9mx/A9x0SnC0Ntikn2iYU2CY02CYM2CYs2CYc+L7Dg7NlwDblA3w2lnSfhWXdezn3Xj7Is7GC87mic1VyrsoBPhsjgI0jgo0jgY0jg42jgN2igrMVwcZVRP1FA9tEB9vEANvEBNvEAt93bHC2EtimqmibOGCbuGCbeGCb+GCbBOD7TgjOVgbbVAvw2VjBfRZWce9V3Xu1IM/G6s7nGs5V07lqBfhs9IONE4GNE4ONk4CNk4LdkoGzNcDGtUX9JQfbpADbpATbpALbpAbfdxpwtibYpo5om7Rgm3Rgm/Rgmwxgm4zg+84EztYC29QN8NlY3X0W1nbvddx73SDPxnrO5/rO1cC5Ggb4bMwMNs4CNs4KNs4GNs4OdssBztYHGzcS9ZcTbJMLbJMbbJMHbJMXfN/5wNkGYJvGom3yg20KgG0Kgm0KgW0Kg++7CDjbEGzTJMBnYz33WdjIvTd2702CPBubOp+bOVdz52oR4LOxKNi4GNi4ONi4BNi4JPmfIYKzzcDGLUX9lQbblAHblAXblAPblAffdwVwtjnYppVom4pgm0pgm8pgmypgm6rg+64GzrYA27QO8NnY1H0WtnTvrdx76yDPxjbO57bO1c652gf4bKwONq4BNq4JNq4FNq4NdqsDzrYFG3cQ9VcXbFMPbFMfbNMAbNMQfN+NwNl2YJuOom0ag22agG2agm2agW2ak+cdONsebNMpwGdjG/dZ2MG9d3TvnYI8Gzs7n7s4V1fn6hbgs7El2LgV2Lg12LgN2LgtaQqc7QI27i7qrz3YpgPYpiPYphPYpjP5vsHZrmCbHqJtuoJtuoFtuoNteoBteoLvuxc42w1s0zPAZ2Nn91nY3b33cO89gzwbezmfeztXH+fqG+CzsTfYuA/YuC/YuB/YuD/YbQA42xts3E/U30CwzSCwzWCwzRCwzVDwfQ8DZ/uAbfqLthkOthkBthkJthkFthkNvu8x4GxfsM2AAJ+NvdxnYT/33t+9DwjybBzofB7kXIOda0iAz8axYONxYOPxYOMJYOOJYLdJ4OwgsPFQUX+TwTZTwDZTwTbTwDbTwfc9A5wdDLYZJtpmJthmFthmNthmDthmLvi+54GzQ8A2wwN8Ng50n4VD3fsw9z48yLNxhPN5pHONcq7RAT4b54ONF4CNF4KNF4GNF4PdloCzI8HGY0T9LQXbLAPb/Ai2WQ62WQG+75Xg7CiwzVjRNj+BbVaBbVaDbdaAbX4G3/dacHY02GZcgM/GEe6zcIx7H+vexwV5No53Pk9wronONSnAZ+M6sPF6sPEGsPEvYONfwW6/gbMTwMaTRf39DrbZCLb5A2zzJ9hmE/i+N4OzE8E2U0TbbAHbbAXbbAPbbAfb7ADf907y35uBbaYG+Gwc7z4LJ7v3Ke59apBn4zTn83TnmuFcMwN8Nu4CG+8GG+8BG+8FG+8Du+0HZ6eDjWeJ+jsAtjkItjkEtjkMtjkCvu+j5L//BtvMFm1zDGxzHGxzAmxzEmxzCnzfp8HZmWCbOQE+G6e5z8JZ7n22e58T5Nk41/k8z7nmO9eCAJ+NZ8DGZ8HG58DG58HGF8BuF8n/jAVsvFDU3yWwzWWwzRWwzVWwzTXwfV8HZ+eDbRaJtrkBtrkJtrkFtrkNtrkDvu+74OwCsM3iAJ+Nc91n4UL3vsi9Lw7ybFzifF7qXMuc68cAn433wMb3wcYPwMYPwcaPwG6PwdmlYOPlov6egG2egm2egW2eg21egO/7JTi7DGyzQrTNK7DNa7DNG7DNW7DNO/B9vwdnfwTbrAzw2bjEfRYud+8r3PvKIM/Gn5zPq5xrtXOt+W/PxuDu3f+vBN//9q8P4HtYBb6HnwP8Hn5y3T+799XufU2Q72Gt83mdc613rg1T/+d/n7Xu//s6977evW8I8u/zi/P5V+f6zbl+n/r//6/9+19+n7fvZt3U//9/RtD/un/6njZO9fyfYfrn+vvff6Phn+uPf/M/19///n8Y/rn+/Df/c/397/+n4Z9r07/5n+vvf/9Nhn+uzf/mf66///03G/65tvyb/7n+/vffYvjn2vpv/uf6+99/q+Gfa9u/+Z/ru0j/7/kVDP7XBYvk3bD932z4+59/u8EQHBh2CAw7DIbvgWGnwLDTYAgBDLsEhl0Gww/AsFtg2G0whASGPQLDHoMhFDDsFRj2GgyhgWGfwLDPYAgDDPsFhv0GQ1hgOCAwHDAYwgHDQYHhoMEQHhgOCQyHDIYIwHBYYDhsMEQEhiMCwxGDIRIwHBUYjhoMkYHhmMBwzGCIAgzHBYbjBkNUYDghMJwwGKIBw0mB4aTBEB0YTgkMpwyGGMBwWmA4bTDEBIYzAsMZgyEWMJwVGM4aDLGB4ZzAcM5giAMM5wWG8wZDXGC4IDBcMBjiAcNFgeGiwRAfGC4JDJcMhgTAcFlguGwwJASGKwLDFYPBDwxXBYarBkMiYLgmMFwzGBIDw3WB4brBkAQYbggMNwyGpMBwU2C4aTAkA4ZbAsMtgyE5MNwWGG4bDCmA4Y7AcMdgSAkMdwWGuwZDKmC4JzDcMxhSA8N9geG+wZAGGB4IDA8MhrTA8FBgeGgwpAOGRwLDI4MhPTA8FhgeGwwZgOGJwPDEYMgIDE8FhqcGQyZgeCYwPDMYMgPDc4HhucGQBRheCAwvDIaswPBSYHhpMGQDhlcCwyuDITswvBYYXhsMOYDhjcDwxmDICQxvBYa3BkMuYHgnMLwzGHIDw3uB4b3BkAcYPggMHwyGvMDwUWD4aDDkA4ZPAsMngyE/MHwWGD4bDAWA4S+B4S+DoSAwfBEYvhgMhYDhq8Dw1WAoDAzfBIZvBkMRYPBN+/cb/v7PoIaiwPCdwPCdwVAMGIIJDMEMhuLAEFxgCG4wlACG7wWG7w2GksAQQmAIYTCUAoYfBIYfDIbSwBBSYAhpMJQBhlACQyiDoSwwhBYYQhsM5YAhjMAQxmAoDwxhBYawBkMFYAgnMIQzGCoCQ3iBIbzBUAkYIggMEQyGysAQUWCIaDBUAYZIAkMkg6EqMEQWGCIbDNWAIYrAEMVgqA4MUQWGqAZDDWCIJjBEMxhqAkN0gSG6wVALGGIIDDEMhtrAEFNgiGkw1AGGWAJDLIOhLjDEFhhiGwz1gCGOwBDHYKgPDHEFhrgGQwNgiCcwxDMYGgJDfIEhvsHQCBgSCAwJDIbGwJBQYEhoMDQBBr/A4DcYmgJDIoEhkcHQDBgSCwyJDYbmwJBEYEhiMLQAhqQCQ1KDoSUwJBMYkhkMrYAhucCQ3GBoDQwpBIYUBkMbYEgpMKQ0GNoCQyqBIZXB0A4YUgsMqQ2G9sCQRmBIYzB0AIa0AkNag6EjMKQTGNIZDJ2AIb3AkN5g6AwMGQSGDAZDF2DIKDBkNBi6AkMmgSGTwdANGDILDJkNhu7AkEVgyGIw9ACGrAJDVoOhJzBkExiyGQy9gCG7wJDdYOgNDDkEhhwGQx9gyCkw5DQY+gJDLoEhl8HQDxhyCwy5DYb+wJBHYMhjMAwAhrwCQ16DYSAw5BMY8hkMg4Ahv8CQ32AYDAwFBIYCBsMQYCgoMBQ0GIYCQyGBoZDBMAwYCgsMhQ2G4cBQRGAoYjCMAIaiAkNRg2EkMBQTGIoZDKOAobjAUNxgGA0MJQSGEgbDGGAoKTCUNBjGAkMpgaGUwTAOGEoLDKUNhvHAUEZgKGMwTACGsgJDWYNhIjCUExjKGQyTgKG8wFDeYJgMDBUEhgoGwxRgqCgwVDQYpgJDJYGhksEwDRgqCwyVDYbpwFBFYKhiMMwAhqoCQ1WDYSYwVBMYqhkMs4ChusBQ3WCYDQw1BIYaBsMcYKgpMNQ0GOYCQy2BoZbBMA8YagsMtQ2G+cBQR2CoYzAsAIa6AkNdg2EhMNQTGOoZDIuAob7AUN9gWAwMDQSGBgbDEmBoKDA0NBiWAkMjgaGRwbAMGBoLDI0Nhh+BoYnA0MRgWA4MTQWGpgbDCmBoJjA0MxhWAkNzgaG5wfATMLQQGFoYDKuAoaXA0NJgWA0MrQSGVgbDGmBoLTC0Nhh+BoY2AkMbg2EtMLQVGNoaDOuAoZ3A0M5gWA8M7QWG9gbDBmDoIDB0MBh+AYaOAkNHg+FXYOgkMHQyGH4Dhs4CQ2eD4Xdg6CIwdDEYNgJDV4Ghq8HwBzB0Exi6GQx/AkN3gaG7wbAJGHoIDD0Mhs3A0FNg6GkwbAGGXgJDL4NhKzD0Fhh6GwzbgKGPwNDHYNgODH0Fhr4Gww5g6Ccw9DMYdgJDf4Ghv8GwCxgGCAwDDIbdwDBQYBhoMOwBhkECwyCDYS8wDBYYBhsM+4BhiMAwxGDYDwxDBYahBsMBYBgmMAwzGA4Cw3CBYbjBcAgYRggMIwyGw8AwUmAYaTAcAYZRAsMog+EoMIwWGEYbDMeAYYzAMMZgOA4MYwWGsQbDCWAYJzCMMxhOAsN4gWG8wXAKGCYIDBMMhtPAMFFgmGgwnAGGSQLDJIPhLDBMFhgmGwzngGGKwDDFYDgPDFMFhqkGwwVgmCYwTDMYLgLDdIFhusFwCRhmCAwzDIbLwDBTYJhpMFwBhlkCwyyD4SowzBYYZhsM14BhjsAwx2C4DgxzBYa5BsMNYJgnMMwzGG4Cw3yBYb7BcAsYFggMCwyG28CwUGBYaDDcAYZFAsMig+EuMCwWGBYbDPeAYYnAsMRguA8MSwWGpQbDA2BYJjAsMxgeAsOPAsOPBsMjYFguMCw3GB4DwwqBYYXB8AQYVgoMKw2Gp8Dwk8Dwk8HwDBhWCQyrDIbnwLBaYFhtMLwAhjUCwxqD4SUw/Cww/GwwvAKGtQLDWoPhNTCsExjWGQxvgGG9wLDeYHgLDBsEhg0Gwztg+EVg+MVgeA8MvwoMvxoMH4DhN4HhN4PhIzD8LjD8bjB8AoaNAsNGg+EzMPwhMPxhMPwFDH8KDH8aDF+AYZPAsMlg+AoMmwWGzQbDN2DYIjBsMRh8kb0btgoMWw2G74Bhm8CwzWAIBgzbBYbtBkNwYNghMOwwGL4Hhp0Cw06DIQQw7BIYdhkMPwDDboFht8EQEhj2CAx7DIZQwLBXYNhrMIQGhn0Cwz6DIQww7BcY9hsMYYHhgMBwwGAIBwwHBYaDBkN4YDgkMBwyGCIAw2GB4bDBEBEYjggMRwyGSMBwVGA4ajBEBoZjAsMxgyEKMBwXGI4bDFGB4YTAcMJgiAYMJwWGkwZDdGA4JTCcMhhiAMNpgeG0wRATGM4IDGcMhljAcFZgOGswxAaGcwLDOYMhDjCcFxjOGwxxgeGCwHDBYIgHDBcFhosGQ3xguCQwXDIYEgDDZYHhssGQEBiuCAxXDAY/MFwVGK4aDImA4ZrAcM1gSAwM1wWG6wZDEmC4ITDcMBiSAsNNgeGmwZAMGG4JDLcMhuTAcFtguG0wpACGOwLDHYMhJTDcFRjuGgypgOGewHDPYEgNDPcFhvsGQxpgeCAwPDAY0gLDQ4HhocGQDhgeCQyPDIb0wPBYYHhsMGQAhicCwxODISMwPBUYnhoMmYDhmcDwzGDIDAzPBYbnBkMWYHghMLwwGLICw0uB4aXBkA0YXgkMrwyG7MDwWmB4bTDkAIY3AsMbgyEnMLwVGN4aDLmA4Z3A8M5gyA0M7wWG9wZDHmD4IDB8MBjyAsNHgeGjwZAPGD4JDJ8MhvzA8Flg+GwwFACGvwSGvwyGgsDwRWD4YjAUAoavAsNXg6EwMHwTGL4ZDEWAwTf932/4+z+DGooCw3cCw3cGQzFgCCYwBDMYigNDcIEhuMFQAhi+Fxi+NxhKAkMIgSGEwVAKGH4QGH4wGEoDQ0iBIaTBUAYYQgkMoQyGssAQWmAIbTCUA4YwAkMYg6E8MIQVGMIaDBWAIZzAEM5gqAgM4QWG8AZDJWCIIDBEMBgqA0NEgSGiwVAFGCIJDJEMhqrAEFlgiGwwVAOGKAJDFIOhOjBEFRiiGgw1gCGawBDNYKgJDNEFhugGQy1giCEwxDAYagNDTIEhpsFQBxhiCQyxDIa6wBBbYIhtMNQDhjgCQxyDoT4wxBUY4hoMDYAhnsAQz2BoCAzxBYb4BkMjYEggMCQwGBoDQ0KBIaHB0AQY/AKD32BoCgyJBIZEBkMzYEgsMCQ2GJoDQxKBIYnB0AIYkgoMSQ2GlsCQTGBIZjC0AobkAkNyg6E1MKQQGFIYDG2AIaXAkNJgaAsMqQSGVAZDO2BILTCkNhjaA0MagSGNwdABGNIKDGkNho7AkE5gSGcwdAKG9AJDeoOhMzBkEBgyGAxdgCGjwJDRYOgKDJkEhkwGQzdgyCwwZDYYugNDFoEhi8HQAxiyCgxZDYaewJBNYMhmMPQChuwCQ3aDoTcw5BAYchgMfYAhp8CQ02DoCwy5BIZcBkM/YMgtMOQ2GPoDQx6BIY/BMAAY8goMeQ2GgcCQT2DIZzAMAob8AkN+g2EwMBQQGAoYDEOAoaDAUNBgGAoMhQSGQgbDMGAoLDAUNhiGA0MRgaGIwTACGIoKDEUNhpHAUExgKGYwjAKG4gJDcYNhNDCUEBhKGAxjgKGkwFDSYBgLDKUEhlIGwzhgKC0wlDYYxgNDGYGhjMEwARjKCgxlDYaJwFBOYChnMEwChvICQ3mDYTIwVBAYKhgMU4ChosBQ0WCYCgyVBIZKBsM0YKgsMFQ2GKYDQxWBoYrBMAMYqgoMVQ2GmcBQTWCoZjDMAobqAkN1g2E2MNQQGGoYDHOAoabAUNNgmAsMtQSGWgbDPGCoLTDUNhjmA0MdgaGOwbAAGOoKDHUNhoXAUE9gqGcwLAKG+gJDfYNhMTA0EBgaGAxLgKGhwNDQYFgKDI0EhkYGwzJgaCwwNDYYfgSGJgJDE4NhOTA0FRiaGgwrgKGZwNDMYFgJDM0FhuYGw0/A0EJgaGEwrAKGlgJDS4NhNTC0EhhaGQxrgKG1wNDaYPgZGNoIDG0MhrXA0FZgaGswrAOGdgJDO4NhPTC0FxjaGwwbgKGDwNDBYPgFGDoKDB0Nhl+BoZPA0Mlg+A0YOgsMnQ2G34Ghi8DQxWDYCAxdBYauBsMfwNBNYOhmMPwJDN0Fhu4GwyZg6CEw9DAYNgNDT4Ghp8GwBRh6CQy9DIatwNBbYOhtMGwDhj4CQx+DYTsw9BUY+hoMO4Chn8DQz2DYCQz9BYb+BsMuYBggMAwwGHYDw0CBYaDBsAcYBgkMgwyGvcAwWGAYbDDsA4YhAsMQg2E/MAwVGIYaDAeAYZjAMMxgOAgMwwWG4QbDIWAYITCMMBgOA8NIgWGkwXAEGEYJDKMMhqPAMFpgGG0wHAOGMQLDGIPhODCMFRjGGgwngGGcwDDOYDgJDOMFhvEGwylgmCAwTDAYTgPDRIFhosFwBhgmCQyTDIazwDBZYJhsMJwDhikCwxSD4TwwTBUYphoMF4BhmsAwzWC4CAzTBYbpBsMlYJghMMwwGC4Dw0yBYabBcAUYZgkMswyGq8AwW2CYbTBcA4Y5AsMcg+E6MMwVGOYaDDeAYZ7AMM9guAkM8wWG+QbDLWBYIDAsMBhuA8NCgWGhwXAHGBYJDIsMhrvAsFhgWGww3AOGJQLDEoPhPjAsFRiWGgwPgGGZwLDMYHgIDD8KDD8aDI+AYbnAsNxgeAwMKwSGFQbDE2BYKTCsNBieAsNPAsNPBsMzYFglMKwyGJ4Dw2qBYbXB8AIY1ggMawyGl8Dws8Dws8HwChjWCgxrDYbXwLBOYFhnMLwBhvUCw3qD4S0wbBAYNhgM74DhF4HhF4PhPTD8KjD8ajB8AIbfBIbfDIaPwPC7wPC7wfAJGDYKDBsNhs/A8IfA8IfB8Bcw/Ckw/GkwfAGGTQLDJoPhKzBsFhg2GwzfgGHLv9nwXTTnfWkqNwSL5t2wVbDDVsMOwYFhm8CwzWD4Hhi2CwzbDYYQwLBDYNhhMPwADDsFhp0GQ0hg2CUw7DIYQgHDboFht8EQGhj2CAx7DIYwwLBXYNhrMIQFhn0Cwz6DIRww7BcY9hsM4YHhgMBwwGCIAAwHBYaDBkNEYDgkMBwyGCIBw2GB4bDBEBkYjggMRwyGKMBwVGA4ajBEBYZjAsMxgyEaMBwXGI4bDNGB4YTAcMJgiAEMJwWGkwZDTGA4JTCcMhhiAcNpgeG0wRAbGM4IDGcMhjjAcFZgOGswxAWGcwLDOYMhHjCcFxjOGwzxgeGCwHDBYEgADBcFhosGQ0JguCQwXDIY/MBwWWC4bDAkAoYrAsMVgyExMFwVGK4aDEmA4ZrAcM1gSAoM1wWG6wZDMmC4ITDcMBiSA8NNgeGmwZACGG4JDLcMhpTAcFtguG0wpAKGOwLDHYMhNTDcFRjuGgxpgOGewHDPYEgLDPcFhvsGQzpgeCAwPDAY0gPDQ4HhocGQARgeCQyPDIaMwPBYYHhsMGQChicCwxODITMwPBUYnhoMWYDhmcDwzGDICgzPBYbnBkM2YHghMLwwGLIDw0uB4aXBkAMYXgkMrwyGnMDwWmB4bTDkAoY3AsMbgyE3MLwVGN4aDHmA4Z3A8M5gyAsM7wWG9wZDPmD4IDB8MBjyA8NHgeGjwVAAGD4JDJ8MhoLA8Flg+GwwFAKGvwSGvwyGwsDwRWD4YjAUAYavAsNXg6EoMHwTGL4ZDMWAwTfj32/4+z+DGooDw3cCw3cGQwlgCCYwBDMYSgJDcIEhuMFQChi+Fxi+NxhKA0MIgSGEwVAGGH4QGH4wGMoCQ0iBIaTBUA4YQgkMoQyG8sAQWmAIbTBUAIYwAkMYg6EiMIQVGMIaDJWAIZzAEM5gqAwM4QWG8AZDFWCIIDBEMBiqAkNEgSGiwVANGCIJDJEMhurAEFlgiGww1ACGKAJDFIOhJjBEFRiiGgy1gCGawBDNYKgNDNEFhugGQx1giCEwxDAY6gJDTIEhpsFQDxhiCQyxDIb6wBBbYIhtMDQAhjgCQxyDoSEwxBUY4hoMjYAhnsAQz2BoDAzxBYb4BkMTYEggMCQwGJoCQ0KBIaHB0AwY/AKD32BoDgyJBIZEBkMLYEgsMCQ2GFoCQxKBIYnB0AoYkgoMSQ2G1sCQTGBIZjC0AYbkAkNyg6EtMKQQGFIYDO2AIaXAkNJgaA8MqQSGVAZDB2BILTCkNhg6AkMagSGNwdAJGNIKDGkNhs7AkE5gSGcwdAGG9AJDeoOhKzBkEBgyGAzdgCGjwJDRYOgODJkEhkwGQw9gyCwwZDYYegJDFoEhi8HQCxiyCgxZDYbewJBNYMhmMPQBhuwCQ3aDoS8w5BAYchgM/YAhp8CQ02DoDwy5BIZcBsMAYMgtMOQ2GAYCQx6BIY/BMAgY8goMeQ2GwcCQT2DIZzAMAYb8AkN+g2EoMBQQGAoYDMOAoaDAUNBgGA4MhQSGQgbDCGAoLDAUNhhGAkMRgaGIwTAKGIoKDEUNhtHAUExgKGYwjAGG4gJDcYNhLDCUEBhKGAzjgKGkwFDSYBgPDKUEhlIGwwRgKC0wlDYYJgJDGYGhjMEwCRjKCgxlDYbJwFBOYChnMEwBhvICQ3mDYSowVBAYKhgM04ChosBQ0WCYDgyVBIZKBsMMYKgsMFQ2GGYCQxWBoYrBMAsYqgoMVQ2G2cBQTWCoZjDMAYbqAkN1g2EuMNQQGGoYDPOAoabAUNNgmA8MtQSGWgbDAmCoLTDUNhgWAkMdgaGOwbAIGOoKDHUNhsXAUE9gqGcwLAGG+gJDfYNhKTA0EBgaGAzLgKGhwNDQYPgRGBoJDI0MhuXA0FhgaGwwrACGJgJDE4NhJTA0FRiaGgw/AUMzgaGZwbAKGJoLDM0NhtXA0EJgaGEwrAGGlgJDS4PhZ2BoJTC0MhjWAkNrgaG1wbAOGNoIDG0MhvXA0FZgaGswbACGdgJDO4PhF2BoLzC0Nxh+BYYOAkMHg+E3YOgoMHQ0GH4Hhk4CQyeDYSMwdBYYOhsMfwBDF4Ghi8HwJzB0FRi6GgybgKGbwNDNYNgMDN0Fhu4GwxZg6CEw9DAYtgJDT4Ghp8GwDRh6CQy9DIbtwNBbYOhtMOwAhj4CQx+DYScw9BUY+hoMu4Chn8DQz2DYDQz9BYb+BsMeYBggMAwwGPYCw0CBYaDBsA8YBgkMgwyG/cAwWGAYbDAcAIYhAsMQg+EgMAwVGIYaDIeAYZjAMMxgOAwMwwWG4QbDEWAYITCMMBiOAsNIgWGkwXAMGEYJDKMMhuPAMFpgGG0wnACGMQLDGIPhJDCMFRjGGgyngGGcwDDOYDgNDOMFhvEGwxlgmCAwTDAYzgLDRIFhosFwDhgmCQyTDIbzwDBZYJhsMFwAhikCwxSD4SIwTBUYphoMl4BhmsAwzWC4DAzTBYbpBsMVYJghMMwwGK4Cw0yBYabBcA0YZgkMswyG68AwW2CYbTDcAIY5AsMcg+EmMMwVGOYaDLeAYZ7AMM9guA0M8wWG+QbDHWBYIDAsMBjuAsNCgWGhwXAPGBYJDIsMhvvAsFhgWGwwPACGJQLDEoPhITAsFRiWGgyPgGGZwLDMYHgMDD8KDD8aDE+AYbnAsNxgeAoMKwSGFQbDM2BYKTCsNBieA8NPAsNPBsMLYFglMKwyGF4Cw2qBYbXB8AoY1ggMawyG18Dws8Dws8HwBhjWCgxrDYa3wLBOYFhnMLwDhvUCw3qD4T0wbBAYNhgMH4DhF4HhF4PhIzD8KjD8ajB8AobfBIbfDIbPwPC7wPC7wfAXMGwUGDYaDF+A4Q+B4Q+D4Ssw/Ckw/GkwfAOGTQLDJoPBF927YbPAsNlg+A4YtggMWwyGYMCwVWDYajAEB4ZtAsM2g+F7YNguMGw3GEIAww6BYYfB8AMw7BQYdhoMIYFhl8Cwy2AIBQy7BYbdBkNoYNgjMOwxGMIAw16BYa/BEBYY9gkM+wyGcMCwX2DYbzCEB4YDAsMBgyECMBwUGA4aDBGB4ZDAcMhgiAQMhwWGwwZDZGA4IjAcMRiiAMNRgeGowRAVGI4JDMcMhmjAcFxgOG4wRAeGEwLDCYMhBjCcFBhOGgwxgeGUwHDKYIgFDKcFhtMGQ2xgOCMwnDEY4gDDWYHhrMEQFxjOCQznDIZ4wHBeYDhvMMQHhgsCwwWDIQEwXBQYLhoMCYHhksBwyWDwA8NlgeGywZAIGK4IDFcMhsTAcFVguGowJAGGawLDNYMhKTBcFxiuGwzJgOGGwHDDYEgODDcFhpsGQwpguCUw3DIYUgLDbYHhtsGQChjuCAx3DIbUwHBXYLhrMKQBhnsCwz2DIS0w3BcY7hsM6YDhgcDwwGBIDwwPBYaHBkMGYHgkMDwyGDICw2OB4bHBkAkYnggMTwyGzMDwVGB4ajBkAYZnAsMzgyErMDwXGJ4bDNmA4YXA8MJgyA4MLwWGlwZDDmB4JTC8MhhyAsNrgeG1wZALGN4IDG8MhtzA8FZgeGsw5AGGdwLDO4MhLzC8FxjeGwz5gOGDwPDBYMgPDB8Fho8GQwFg+CQwfDIYCgLDZ4Hhs8FQCBj+Ehj+MhgKA8MXgeGLwVAEGL4KDF8NhqLA8E1g+GYwFAMG38x/v+Hv/wxqKA4M3wkM3xkMJYAhmMAQzGAoCQzBBYbgBkMpYPheYPjeYCgNDCEEhhAGQxlg+EFg+MFgKAsMIQWGkAZDOWAIJTCEMhjKA0NogSG0wVABGMIIDGEMhorAEFZgCGswVAKGcAJDOIOhMjCEFxjCGwxVgCGCwBDBYKgKDBEFhogGQzVgiCQwRDIYqgNDZIEhssFQAxiiCAxRDIaawBBVYIhqMNQChmgCQzSDoTYwRBcYohsMdYAhhsAQw2CoCwwxBYaYBkM9YIglMMQyGOoDQ2yBIbbB0AAY4ggMcQyGhsAQV2CIazA0AoZ4AkM8g6ExMMQXGOIbDE2AIYHAkMBgaAoMCQWGhAZDM2DwCwx+g6E5MCQSGBIZDC2AIbHAkNhgaAkMSQSGJAZDK2BIKjAkNRhaA0MygSGZwdAGGJILDMkNhrbAkEJgSGEwtAOGlAJDSoOhPTCkEhhSGQwdgCG1wJDaYOgIDGkEhjQGQydgSCswpDUYOgNDOoEhncHQBRjSCwzpDYauwJBBYMhgMHQDhowCQ0aDoTswZBIYMhkMPYAhs8CQ2WDoCQxZBIYsBkMvYMgqMGQ1GHoDQzaBIZvB0AcYsgsM2Q2GvsCQQ2DIYTD0A4acAkNOg6E/MOQSGHIZDAOAIbfAkNtgGAgMeQSGPAbDIGDIKzDkNRgGA0M+gSGfwTAEGPILDPkNhqHAUEBgKGAwDAOGggJDQYNhODAUEhgKGQwjgKGwwFDYYBgJDEUEhiIGwyhgKCowFDUYRgNDMYGhmMEwBhiKCwzFDYaxwFBCYChhMIwDhpICQ0mDYTwwlBIYShkME4ChtMBQ2mCYCAxlBIYyBsMkYCgrMJQ1GCYDQzmBoZzBMAUYygsM5Q2GqcBQQWCoYDBMA4aKAkNFg2E6MFQSGCoZDDOAobLAUNlgmAkMVQSGKgbDLGCoKjBUNRhmA0M1gaGawTAHGKoLDNUNhrnAUENgqGEwzAOGmgJDTYNhPjDUEhhqGQwLgKG2wFDbYFgIDHUEhjoGwyJgqCsw1DUYFgNDPYGhnsGwBBjqCwz1DYalwNBAYGhgMCwDhoYCQ0OD4UdgaCQwNDIYlgNDY4GhscGwAhiaCAxNDIaVwNBUYGhqMPwEDM0EhmYGwypgaC4wNDcYVgNDC4GhhcGwBhhaCgwtDYafgaGVwNDKYFgLDK0FhtYGwzpgaCMwtDEY1gNDW4GhrcGwARjaCQztDIZfgKG9wNDeYPgVGDoIDB0Mht+AoaPA0NFg+B0YOgkMnQyGjcDQWWDobDD8AQxdBIYuBsOfwNBVYOhqMGwChm4CQzeDYTMwdBcYuhsMW4Chh8DQw2DYCgw9BYaeBsM2YOglMPQyGLYDQ2+BobfBsAMY+ggMfQyGncDQV2DoazDsAoZ+AkM/g2E3MPQXGPobDHuAYYDAMMBg2AsMAwWGgQbDPmAYJDAMMhj2A8NggWGwwXAAGIYIDEMMhoPAMFRgGGowHAKGYQLDMIPhMDAMFxiGGwxHgGGEwDDCYDgKDCMFhpEGwzFgGCUwjDIYjgPDaIFhtMFwAhjGCAxjDIaTwDBWYBhrMJwChnECwziD4TQwjBcYxhsMZ4BhgsAwwWA4CwwTBYaJBsM5YJgkMEwyGM4Dw2SBYbLBcAEYpggMUwyGi8AwVWCYajBcAoZpAsM0g+EyMEwXGKYbDFeAYYbAMMNguAoMMwWGmQbDNWCYJTDMMhiuA8NsgWG2wXADGOYIDHMMhpvAMFdgmGsw3AKGeQLDPIPhNjDMFxjmGwx3gGGBwLDAYLgLDAsFhoUGwz1gWCQwLDIY7gPDYoFhscHwABiWCAxLDIaHwLBUYFhqMDwChmUCwzKD4TEw/Cgw/GgwPAGG5QLDcoPhKTCsEBhWGAzPgGGlwLDSYHgODD8JDD8ZDC+AYZXAsMpgeAkMqwWG1QbDK2BYIzCsMRheA8PPAsPPBsMbYFgrMKw1GN4CwzqBYZ3B8A4Y1gsM6w2G98CwQWDYYDB8AIZfBIZfDIaPwPCrwPCrwfAJGH4TGH4zGD4Dw+8Cw+8Gw1/AsFFg2GgwfAGGPwSGPwyGr8Dwp8Dwp8HwDRg2/ZsN3yVw/k5P5YZgCbwbNgt22GzYITgwbBEYthgM3wPDVoFhq8EQAhi2CQzbDIYfgGG7wLDdYAgJDDsEhh0GQyhg2Ckw7DQYQgPDLoFhl8EQBhh2Cwy7DYawwLBHYNhjMIQDhr0Cw16DITww7BMY9hkMEYBhv8Cw32CICAwHBIYDBkMkYDgoMBw0GCIDwyGB4ZDBEAUYDgsMhw2GqMBwRGA4YjBEA4ajAsNRgyE6MBwTGI4ZDDGA4bjAcNxgiAkMJwSGEwZDLGA4KTCcNBhiA8MpgeGUwRAHGE4LDKcNhrjAcEZgOGMwxAOGswLDWYMhPjCcExjOGQwJgOG8wHDeYEgIDBcEhgsGgx8YLgoMFw2GRMBwSWC4ZDAkBobLAsNlgyEJMFwRGK4YDEmB4arAcNVgSAYM1wSGawZDcmC4LjBcNxhSAMMNgeGGwZASGG4KDDcNhlTAcEtguGUwpAaG2wLDbYMhDTDcERjuGAxpgeGuwHDXYEgHDPcEhnsGQ3pguC8w3DcYMgDDA4HhgcGQERgeCgwPDYZMwPBIYHhkMGQGhscCw2ODIQswPBEYnhgMWYHhqcDw1GDIBgzPBIZnBkN2YHguMDw3GHIAwwuB4YXBkBMYXgoMLw2GXMDwSmB4ZTDkBobXAsNrgyEPMLwRGN4YDHmB4a3A8NZgyAcM7wSGdwZDfmB4LzC8NxgKAMMHgeGDwVAQGD4KDB8NhkLA8Elg+GQwFAaGzwLDZ4OhCDD8JTD8ZTAUBYYvAsMXg6EYMHwVGL4aDMWB4ZvA8M1gKAEMvln/fsPf/xnUUBIYvhMYvjMYSgFDMIEhmMFQGhiCCwzBDYYywPC9wPC9wVAWGEIIDCEMhnLA8IPA8IPBUB4YQgoMIQ2GCsAQSmAIZTBUBIbQAkNog6ESMIQRGMIYDJWBIazAENZgqAIM4QSGcAZDVWAILzCENxiqAUMEgSGCwVAdGCIKDBENhhrAEElgiGQw1ASGyAJDZIOhFjBEERiiGAy1gSGqwBDVYKgDDNEEhmgGQ11giC4wRDcY6gFDDIEhhsFQHxhiCgwxDYYGwBBLYIhlMDQEhtgCQ2yDoREwxBEY4hgMjYEhrsAQ12BoAgzxBIZ4BkNTYIgvMMQ3GJoBQwKBIYHB0BwYEgoMCQ2GFsDgFxj8BkNLYEgkMCQyGFoBQ2KBIbHB0BoYkggMSQyGNsCQVGBIajC0BYZkAkMyg6EdMCQXGJIbDO2BIYXAkMJg6AAMKQWGlAZDR2BIJTCkMhg6AUNqgSG1wdAZGNIIDGkMhi7AkFZgSGswdAWGdAJDOoOhGzCkFxjSGwzdgSGDwJDBYOgBDBkFhowGQ09gyCQwZDIYegFDZoEhs8HQGxiyCAxZDIY+wJBVYMhqMPQFhmwCQzaDoR8wZBcYshsM/YEhh8CQw2AYAAw5BYacBsNAYMglMOQyGAYBQ26BIbfBMBgY8ggMeQyGIcCQV2DIazAMBYZ8AkM+g2EYMOQXGPIbDMOBoYDAUMBgGAEMBQWGggbDSGAoJDAUMhhGAUNhgaGwwTAaGIoIDEUMhjHAUFRgKGowjAWGYgJDMYNhHDAUFxiKGwzjgaGEwFDCYJgADCUFhpIGw0RgKCUwlDIYJgFDaYGhtMEwGRjKCAxlDIYpwFBWYChrMEwFhnICQzmDYRowlBcYyhsM04GhgsBQwWCYAQwVBYaKBsNMYKgkMFQyGGYBQ2WBobLBMBsYqggMVQyGOcBQVWCoajDMBYZqAkM1g2EeMFQXGKobDPOBoYbAUMNgWAAMNQWGmgbDQmCoJTDUMhgWAUNtgaG2wbAYGOoIDHUMhiXAUFdgqGswLAWGegJDPYNhGTDUFxjqGww/AkMDgaGBwbAcGBoKDA0NhhXA0EhgaGQwrASGxgJDY4PhJ2BoIjA0MRhWAUNTgaGpwbAaGJoJDM0MhjXA0FxgaG4w/AwMLQSGFgbDWmBoKTC0NBjWAUMrgaGVwbAeGFoLDK0Nhg3A0EZgaGMw/AIMbQWGtgbDr8DQTmBoZzD8BgztBYb2BsPvwNBBYOhgMGwEho4CQ0eD4Q9g6CQwdDIY/gSGzgJDZ4NhEzB0ERi6GAybgaGrwNDVYNgCDN0Ehm4Gw1Zg6C4wdDcYtgFDD4Ghh8GwHRh6Cgw9DYYdwNBLYOhlMOwEht4CQ2+DYRcw9BEY+hgMu4Ghr8DQ12DYAwz9BIZ+BsNeYOgvMPQ3GPYBwwCBYYDBsB8YBgoMAw2GA8AwSGAYZDAcBIbBAsNgg+EQMAwRGIYYDIeBYajAMNRgOAIMwwSGYQbDUWAYLjAMNxiOAcMIgWGEwXAcGEYKDCMNhhPAMEpgGGUwnASG0QLDaIPhFDCMERjGGAyngWGswDDWYDgDDOMEhnEGw1lgGC8wjDcYzgHDBIFhgsFwHhgmCgwTDYYLwDBJYJhkMFwEhskCw2SD4RIwTBEYphgMl4FhqsAw1WC4AgzTBIZpBsNVYJguMEw3GK4BwwyBYYbBcB0YZgoMMw2GG8AwS2CYZTDcBIbZAsNsg+EWMMwRGOYYDLeBYa7AMNdguAMM8wSGeQbDXWCYLzDMNxjuAcMCgWGBwXAfGBYKDAsNhgfAsEhgWGQwPASGxQLDYoPhETAsERiWGAyPgWGpwLDUYHgCDMsEhmUGw1Ng+FFg+NFgeAYMywWG5QbDc2BYITCsMBheAMNKgWGlwfASGH4SGH4yGF4BwyqBYZXB8BoYVgsMqw2GN8CwRmBYYzC8BYafBYafDYZ3wLBWYFhrMLwHhnUCwzqD4QMwrBcY1hsMH4Fhg8CwwWD4BAy/CAy/GAyfgeFXgeFXg+EvYPhNYPjNYPgCDL8LDL8bDF+BYaPAsNFg+AYMfwgMfxgMvoTeDX8KDH8aDN8BwyaBYZPBEAwYNgsMmw2G4MCwRWDYYjB8DwxbBYatBkMIYNgmMGwzGH4Ahu0Cw3aDISQw7BAYdhgMoYBhp8Cw02AIDQy7BIZdBkMYYNgtMOw2GMICwx6BYY/BEA4Y9goMew2G8MCwT2DYZzBEAIb9AsN+gyEiMBwQGA4YDJGA4aDAcNBgiAwMhwSGQwZDFGA4LDAcNhiiAsMRgeGIwRANGI4KDEcNhujAcExgOGYwxACG4wLDcYMhJjCcEBhOGAyxgOGkwHDSYIgNDKcEhlMGQxxgOC0wnDYY4gLDGYHhjMEQDxjOCgxnDYb4wHBOYDhnMCQAhvMCw3mDISEwXBAYLhgMfmC4KDBcNBgSAcMlgeGSwZAYGC4LDJcNhiTAcEVguGIwJAWGqwLDVYMhGTBcExiuGQzJgeG6wHDdYEgBDDcEhhsGQ0pguCkw3DQYUgHDLYHhlsGQGhhuCwy3DYY0wHBHYLhjMKQFhrsCw12DIR0w3BMY7hkM6YHhvsBw32DIAAwPBIYHBkNGYHgoMDw0GDIBwyOB4ZHBkBkYHgsMjw2GLMDwRGB4YjBkBYanAsNTgyEbMDwTGJ4ZDNmB4bnA8NxgyAEMLwSGFwZDTmB4KTC8NBhyAcMrgeGVwZAbGF4LDK8NhjzA8EZgeGMw5AWGtwLDW4MhHzC8ExjeGQz5geG9wPDeYCgADB8Ehg8GQ0Fg+CgwfDQYCgHDJ4Hhk8FQGBg+CwyfDYYiwPCXwPCXwVAUGL4IDF8MhmLA8FVg+GowFAeGbwLDN4OhBDD4Zv/7DX//Z1BDSWD4TmD4zmAoBQzBBIZgBkNpYAguMAQ3GMoAw/cCw/cGQ1lgCCEwhDAYygHDDwLDDwZDeWAIKTCENBgqAEMogSGUwVARGEILDKENhkrAEEZgCGMwVAaGsAJDWIOhCjCEExjCGQxVgSG8wBDeYKgGDBEEhggGQ3VgiCgwRDQYagBDJIEhksFQExgiCwyRDYZawBBFYIhiMNQGhqgCQ1SDoQ4wRBMYohkMdYEhusAQ3WCoBwwxBIYYBkN9YIgpMMQ0GBoAQyyBIZbB0BAYYgsMsQ2GRsAQR2CIYzA0Boa4AkNcg6EJMMQTGOIZDE2BIb7AEN9gaAYMCQSGBAZDc2BIKDAkNBhaAINfYPAbDC2BIZHAkMhgaAUMiQWGxAZDa2BIIjAkMRjaAENSgSGpwdAWGJIJDMkMhnbAkFxgSG4wtAeGFAJDCoOhAzCkFBhSGgwdgSGVwJDKYOgEDKkFhtQGQ2dgSCMwpDEYugBDWoEhrcHQFRjSCQzpDIZuwJBeYEhvMHQHhgwCQwaDoQcwZBQYMhoMPYEhk8CQyWDoBQyZBYbMBkNvYMgiMGQxGPoAQ1aBIavB0BcYsgkM2QyGfsCQXWDIbjD0B4YcAkMOg2EAMOQUGHIaDAOBIZfAkMtgGAQMuQWG3AbDYGDIIzDkMRiGAENegSGvwTAUGPIJDPkMhmHAkF9gyG8wDAeGAgJDAYNhBDAUFBgKGgwjgaGQwFDIYBgFDIUFhsIGw2hgKCIwFDEYxgBDUYGhqMEwFhiKCQzFDIZxwFBcYChuMIwHhhICQwmDYQIwlBQYShoME4GhlMBQymCYBAylBYbSBsNkYCgjMJQxGKYAQ1mBoazBMBUYygkM5QyGacBQXmAobzBMB4YKAkMFg2EGMFQUGCoaDDOBoZLAUMlgmAUMlQWGygbDbGCoIjBUMRjmAENVgaGqwTAXGKoJDNUMhnnAUF1gqG4wzAeGGgJDDYNhATDUFBhqGgwLgaGWwFDLYFgEDLUFhtoGw2JgqCMw1DEYlgBDXYGhrsGwFBjqCQz1DIZlwFBfYKhvMPwIDA0EhgYGw3JgaCgwNDQYVgBDI4GhkcGwEhgaCwyNDYafgKGJwNDEYFgFDE0FhqYGw2pgaCYwNDMY1gBDc4GhucHwMzC0EBhaGAxrgaGlwNDSYFgHDK0EhlYGw3pgaC0wtDYYNgBDG4GhjcHwCzC0FRjaGgy/AkM7gaGdwfAbMLQXGNobDL8DQweBoYPBsBEYOgoMHQ2GP4Chk8DQyWD4Exg6CwydDYZNwNBFYOhiMGwGhq4CQ1eDYQswdBMYuhkMW4Ghu8DQ3WDYBgw9BIYeBsN2YOgpMPQ0GHYAQy+BoZfBsBMYegsMvQ2GXcDQR2DoYzDsBoa+AkNfg2EPMPQTGPoZDHuBob/A0N9g2AcMAwSGAQbDfmAYKDAMNBgOAMMggWGQwXAQGAYLDIMNhkPAMERgGGIwHAaGoQLDUIPhCDAMExiGGQxHgWG4wDDcYDgGDCMEhhEGw3FgGCkwjDQYTgDDKIFhlMFwEhhGCwyjDYZTwDBGYBhjMJwGhrECw1iD4QwwjBMYxhkMZ4FhvMAw3mA4BwwTBIYJBsN5YJgoMEw0GC4AwySBYZLBcBEYJgsMkw2GS8AwRWCYYjBcBoapAsNUg+EKMEwTGKYZDFeBYbrAMN1guAYMMwSGGQbDdWCYKTDMNBhuAMMsgWGWwXATGGYLDLMNhlvAMEdgmGMw3AaGuQLDXIPhDjDMExjmGQx3gWG+wDDfYLgHDAsEhgUGw31gWCgwLDQYHgDDIoFhkcHwEBgWCwyLDYZHwLBEYFhiMDwGhqUCw1KD4QkwLBMYlhkMT4HhR4HhR4PhGTAsFxiWGwzPgWGFwLDCYHgBDCsFhpUGw0tg+Elg+MlgeAUMqwSGVQbDa2BYLTCsNhjeAMMagWGNwfAWGH4WGH42GN4Bw1qBYa3B8B4Y1gkM6wyGD8CwXmBYbzB8BIYNAsMGg+ETMPwiMPxiMHwGhl8Fhl8Nhr+A4TeB4TeD4Qsw/C4w/G4wfAWGjQLDRoPhGzD88W82/H3+bwc1BPN5N/wp2OFPww7Bfd4NmwSGTQbD9z7vhs0Cw2aDIYTPu2GLwLDFYPjB592wVWDYajCE9Hk3bBMYthkMoXzeDdsFhu0GQ2ifd8MOgWGHwRDG592wU2DYaTCE9Xk37BIYdhkM4XzeDbsFht0GQ3ifd8MegWGPwRDB592wV2DYazBE9Hk37BMY9hkMkXzeDfsFhv0GQ2Sfd8MBgeGAwRDF591wUGA4aDBE9Xk3HBIYDhkM0XzeDYcFhsMGQ3Sfd8MRgeGIwRDD591wVGA4ajDE9Hk3HBMYjhkMsXzeDccFhuMGQ2yfd8MJgeGEwRDH591wUmA4aTDE9Xk3nBIYThkM8XzeDacFhtMGQ3yfd8MZgeGMwZDA591wVmA4azAk9Hk3nBMYzhkMfp93w3mB4bzBkMjn3XBBYLhgMCT2eTdcFBguGgxJfN4NlwSGSwZDUp93w2WB4bLBkMzn3XBFYLhiMCT3eTdcFRiuGgwpfN4N1wSGawZDSp93w3WB4brBkMrn3XBDYLhhMKT2eTfcFBhuGgxpfN4NtwSGWwZDWp93w22B4bbBkM7n3XBHYLhjMKT3eTfcFRjuGgwZfN4N9wSGewZDRp93w32B4b7BkMnn3fBAYHhgMGT2eTc8FBgeGgxZfN4NjwSGRwZDVp93w2OB4bHBkM3n3fBEYHhiMGT3eTc8FRieGgw5fN4NzwSGZwZDTp93w3OB4bnBkMvn3fBCYHhhMOT2eTe8FBheGgx5fN4NrwSGVwZDXp93w2uB4bXBkM/n3fBGYHhjMOT3eTe8FRjeGgwFfN4N7wSGdwZDQZ93w3uB4b3BUMjn3fBBYPhgMBT2eTd8FBg+GgxFfN4NnwSGTwZDUZ93w2eB4bPBUMzn3fCXwPCXwVDc593wRWD4YjCU8Hk3fBUYvhoMJX3eDd8Ehm8GQymfd4Nvzr/f8Pd/BjWU9nk3fCcwfGcwlPF5NwQTGIIZDGV93g3BBYbgBkM5n3fD9wLD9wZDeZ93QwiBIYTBUMHn3fCDwPCDwVDR590QUmAIaTBU8nk3hBIYQhkMlX3eDaEFhtAGQxWfd0MYgSGMwVDV590QVmAIazBU83k3hBMYwhkM1X3eDeEFhvAGQw2fd0MEgSGCwVDT590QUWCIaDDU8nk3RBIYIhkMtX3eDZEFhsgGQx2fd0MUgSGKwVDX590QVWCIajDU83k3RBMYohkM9X3eDdEFhugGQwOfd0MMgSGGwdDQ590QU2CIaTA08nk3xBIYYhkMjX3eDbEFhtgGQxOfd0McgSGOwdDU590QV2CIazA083k3xBMY4hkMzX3eDfEFhvgGQwufd0MCgSGBwdDS592QUGBIaDC08nk3+AUGv8HQ2ufdkEhgSGQwtPF5NyQWGBIbDG193g1JBIYkBkM7n3dDUoEhqcHQ3ufdkExgSGYwdPB5NyQXGJIbDB193g0pBIYUBkMnn3dDSoEhpcHQ2efdkEpgSGUwdPF5N6QWGFIbDF193g1pBIY0BkM3n3dDWoEhrcHQ3efdkE5gSGcw9PB5N6QXGNIbDD193g0ZBIYMBkMvn3dDRoEho8HQ2+fdkElgyGQw9PF5N2QWGDIbDH193g1ZBIYsBkM/n3dDVoEhq8HQ3+fdkE1gyGYwDPB5N2QXGLIbDAN93g05BIYcBsMgn3dDToEhp8Ew2OfdkEtgyGUwDPF5N+QWGHIbDEN93g15BIY8BsMwn3dDXoEhr8Ew3OfdkE9gyGcwjPB5N+QXGPIbDCN93g0FBIYCBsMon3dDQYGhoMEw2ufdUEhgKGQwjPF5NxQWGAobDGN93g1FBIYiBsM4n3dDUYGhqMEw3ufdUExgKGYwTPB5NxQXGIobDBN93g0lBIYSBsMkn3dDSYGhpMEw2efdUEpgKGUwTPF5N5QWGEobDFN93g1lBIYyBsM0n3dDWYGhrMEw3efdUE5gKGcwzPB5N5QXGMobDDN93g0VBIYKBsMsn3dDRYGhosEw2+fdUElgqGQwzPF5N1QWGCobDHN93g1VBIYqBsM8n3dDVYGhqsEw3+fdUE1gqGYwLPB5N1QXGKobDAt93g01BIYaBsMin3dDTYGhpsGw2OfdUEtgqGUwLPF5N9QWGGobDEt93g11BIY6BsMyn3dDXYGhrsHwo8+7oZ7AUM9gWO7zbqgvMNQ3GFb4vBsaCAwNDIaVPu+GhgJDQ4PhJ593QyOBoZHBsMrn3dBYYGhsMKz2eTc0ERiaGAxrfN4NTQWGpgbDzz7vhmYCQzODYa3Pu6G5wNDcYFjn825oITC0MBjW+7wbWgoMLQ2GDT7vhlYCQyuD4Refd0NrgaG1wfCrz7uhjcDQxmD4zefd0FZgaGsw/O7zbmgnMLQzGDb6vBvaCwztDYY/fN4NHQSGDgbDnz7vho4CQ0eDYZPPu6GTwNDJYNjs827oLDB0Nhi2+LwbuggMXQyGrT7vhq4CQ1eDYZvPu6GbwNDNYNju827oLjB0Nxh2+LwbeggMPQyGnT7vhp4CQ0+DYZfPu6GXwNDLYNjt827oLTD0Nhj2+Lwb+ggMfQyGvT7vhr4CQ1+DYZ/Pu6GfwNDPYNjv827oLzD0NxgO+LwbBggMAwyGgz7vhoECw0CD4ZDPu2GQwDDIYDjs824YLDAMNhiO+LwbhggMQwyGoz7vhqECw1CD4ZjPu2GYwDDMYDju824YLjAMNxhO+LwbRggMIwyGkz7vhpECw0iD4ZTPu2GUwDDKYDjt824YLTCMNhjO+LwbxggMYwyGsz7vhrECw1iD4ZzPu2GcwDDOYDjv824YLzCMNxgu+LwbJggMEwyGiz7vhokCw0SD4ZLPu2GSwDDJYLjs826YLDBMNhiu+LwbpggMUwyGqz7vhqkCw1SD4ZrPu2GawDDNYLju826YLjBMNxhu+LwbZggMMwyGmz7vhpkCw0yD4ZbPu2GWwDDLYLjt826YLTDMNhju+Lwb5ggMcwyGuz7vhrkCw1yD4Z7Pu2GewDDPYLjv826YLzDMNxge+LwbFggMCwyGhz7vhoUCw0KD4ZHPu2GRwLDIYHjs825YLDAsNhie+LwblggMSwyGpz7vhqUCw1KD4ZnPu2GZwLDMYHju8274UWD40WB44fNuWC4wLDcYXvq8G1YIDCsMhlc+74aVAsNKg+G1z7vhJ4HhJ4Phjc+7YZXAsMpgeOvzblgtMKw2GN75vBvWCAxrDIb3Pu+GnwWGnw2GDz7vhrUCw1qD4aPPu2GdwLDOYPjk825YLzCsNxg++7wbNggMGwyGv3zeDb8IDL8YDF983g2/Cgy/Ggxffd4NvwkMvxkM33zeDb8LDL8bDH//B/3n2X8ybBQYNhoM3wHDHwLDHwZDMGD4U2D402AIDgybBIZNBsP3wLBZYNhsMIQAhi0CwxaD4Qdg2CowbDUYQgLDNoFhm8EQChi2CwzbDYbQwLBDYNhhMIQBhp0Cw06DISww7BIYdhkM4YBht8Cw22AIDwx7BIY9BkMEYNgrMOw1GCICwz6BYZ/BEAkY9gsM+w2GyMBwQGA4YDBEAYaDAsNBgyEqMBwSGA4ZDNGA4bDAcNhgiA4MRwSGIwZDDGA4KjAcNRhiAsMxgeGYwRALGI4LDMcNhtjAcEJgOGEwxAGGkwLDSYMhLjCcEhhOGQzxgOG0wHDaYIgPDGcEhjMGQwJgOCswnDUYEgLDOYHhnMHgB4bzAsN5gyERMFwQGC4YDImB4aLAcNFgSAIMlwSGSwZDUmC4LDBcNhiSAcMVgeGKwZAcGK4KDFcNhhTAcE1guGYwpASG6wLDdYMhFTDcEBhuGAypgeGmwHDTYEgDDLcEhlsGQ1pguC0w3DYY0gHDHYHhjsGQHhjuCgx3DYYMwHBPYLhnMGQEhvsCw32DIRMwPBAYHhgMmYHhocDw0GDIAgyPBIZHBkNWYHgsMDw2GLIBwxOB4YnBkB0YngoMTw2GHMDwTGB4ZjDkBIbnAsNzgyEXMLwQGF4YDLmB4aXA8NJgyAMMrwSGVwZDXmB4LTC8NhjyAcMbgeGNwZAfGN4KDG8NhgLA8E5geGcwFASG9wLDe4OhEDB8EBg+GAyFgeGjwPDRYCgCDJ8Ehk8GQ1Fg+CwwfDYYigHDXwLDXwZDcWD4IjB8MRhKAMNXgeGrwVASGL4JDN8MhlLA4Jv77zf8/Z9BDaWB4TuB4TuDoQwwBBMYghkMZYEhuMAQ3GAoBwzfCwzfGwzlgSGEwBDCYKgADD8IDD8YDBWBIaTAENJgqAQMoQSGUAZDZWAILTCENhiqAEMYgSGMwVAVGMIKDGENhmrAEE5gCGcwVAeG8AJDeIOhBjBEEBgiGAw1gSGiwBDRYKgFDJEEhkgGQ21giCwwRDYY6gBDFIEhisFQFxiiCgxRDYZ6wBBNYIhmMNQHhugCQ3SDoQEwxBAYYhgMDYEhpsAQ02BoBAyxBIZYBkNjYIgtMMQ2GJoAQxyBIY7B0BQY4goMcQ2GZsAQT2CIZzA0B4b4AkN8g6EFMCQQGBIYDC2BIaHAkNBgaAUMfoHBbzC0BoZEAkMig6ENMCQWGBIbDG2BIYnAkMRgaAcMSQWGpAZDe2BIJjAkMxg6AENygSG5wdARGFIIDCkMhk7AkFJgSGkwdAaGVAJDKoOhCzCkFhhSGwxdgSGNwJDGYOgGDGkFhrQGQ3dgSCcwpDMYegBDeoEhvcHQExgyCAwZDIZewJBRYMhoMPQGhkwCQyaDoQ8wZBYYMhsMfYEhi8CQxWDoBwxZBYasBkN/YMgmMGQzGAYAQ3aBIbvBMBAYcggMOQyGQcCQU2DIaTAMBoZcAkMug2EIMOQWGHIbDEOBIY/AkMdgGAYMeQWGvAbDcGDIJzDkMxhGAEN+gSG/wTASGAoIDAUMhlHAUFBgKGgwjAaGQgJDIYNhDDAUFhgKGwxjgaGIwFDEYBgHDEUFhqIGw3hgKCYwFDMYJgBDcYGhuMEwERhKCAwlDIZJwFBSYChpMEwGhlICQymDYQowlBYYShsMU4GhjMBQxmCYBgxlBYayBsN0YCgnMJQzGGYAQ3mBobzBMBMYKggMFQyGWcBQUWCoaDDMBoZKAkMlg2EOMFQWGCobDHOBoYrAUMVgmAcMVQWGqgbDfGCoJjBUMxgWAEN1gaG6wbAQGGoIDDUMhkXAUFNgqGkwLAaGWgJDLYNhCTDUFhhqGwxLgaGOwFDHYFgGDHUFhroGw4/AUE9gqGcwLAeG+gJDfYNhBTA0EBgaGAwrgaGhwNDQYPgJGBoJDI0MhlXA0FhgaGwwrAaGJgJDE4NhDTA0FRiaGgw/A0MzgaGZwbAWGJoLDM0NhnXA0EJgaGEwrAeGlgJDS4NhAzC0EhhaGQy/AENrgaG1wfArMLQRGNoYDL8BQ1uBoa3B8DswtBMY2hkMG4GhvcDQ3mD4Axg6CAwdDIY/gaGjwNDRYNgEDJ0Ehk4Gw2Zg6CwwdDYYtgBDF4Ghi8GwFRi6CgxdDYZtwNBNYOhmMGwHhu4CQ3eDYQcw9BAYehgMO4Ghp8DQ02DYBQy9BIZeBsNuYOgtMPQ2GPYAQx+BoY/BsBcY+goMfQ2GfcDQT2DoZzDsB4b+AkN/g+EAMAwQGAYYDAeBYaDAMNBgOAQMgwSGQQbDYWAYLDAMNhiOAMMQgWGIwXAUGIYKDEMNhmPAMExgGGYwHAeG4QLDcIPhBDCMEBhGGAwngWGkwDDSYDgFDKMEhlEGw2lgGC0wjDYYzgDDGIFhjMFwFhjGCgxjDYZzwDBOYBhnMJwHhvECw3iD4QIwTBAYJhgMF4FhosAw0WC4BAyTBIZJBsNlYJgsMEw2GK4AwxSBYYrBcBUYpgoMUw2Ga8AwTWCYZjBcB4bpAsN0g+EGMMwQGGYYDDeBYabAMNNguAUMswSGWQbDbWCYLTDMNhjuAMMcgWGOwXAXGOYKDHMNhnvAME9gmGcw3AeG+QLDfIPhATAsEBgWGAwPgWGhwLDQYHgEDIsEhkUGw2NgWCwwLDYYngDDEoFhicHwFBiWCgxLDYZnwLBMYFhmMDwHhh8Fhh8NhhfAsFxgWG4wvASGFQLDCoPhFTCsFBhWGgyvgeEngeEng+ENMKwSGFYZDG+BYbXAsNpgeAcMawSGNQbDe2D4WWD42WD4AAxrBYa1BsNHYFgnMKwzGD4Bw3qBYb3B8BkYNggMGwyGv4DhF4HhF4PhCzD8KjD8ajB8BYbfBIbfDIZvwPD7v9nwnXPwbwc1BPN7N2wU7LDRsENwv3fDHwLDHwbD937vhj8Fhj8NhhB+74ZNAsMmg+EHv3fDZoFhs8EQ0u/dsEVg2GIwhPJ7N2wVGLYaDKH93g3bBIZtBkMYv3fDdoFhu8EQ1u/dsENg2GEwhPN7N+wUGHYaDOH93g27BIZdBkMEv3fDboFht8EQ0e/dsEdg2GMwRPJ7N+wVGPYaDJH93g37BIZ9BkMUv3fDfoFhv8EQ1e/dcEBgOGAwRPN7NxwUGA4aDNH93g2HBIZDBkMMv3fDYYHhsMEQ0+/dcERgOGIwxPJ7NxwVGI4aDLH93g3HBIZjBkMcv3fDcYHhuMEQ1+/dcEJgOGEwxPN7N5wUGE4aDPH93g2nBIZTBkMCv3fDaYHhtMGQ0O/dcEZgOGMw+P3eDWcFhrMGQyK/d8M5geGcwZDY791wXmA4bzAk8Xs3XBAYLhgMSf3eDRcFhosGQzK/d8MlgeGSwZDc791wWWC4bDCk8Hs3XBEYrhgMKf3eDVcFhqsGQyq/d8M1geGawZDa791wXWC4bjCk8Xs33BAYbhgMaf3eDTcFhpsGQzq/d8MtgeGWwZDe791wW2C4bTBk8Hs33BEY7hgMGf3eDXcFhrsGQya/d8M9geGewZDZ791wX2C4bzBk8Xs3PBAYHhgMWf3eDQ8FhocGQza/d8MjgeGRwZDd793wWGB4bDDk8Hs3PBEYnhgMOf3eDU8FhqcGQy6/d8MzgeGZwZDb793wXGB4bjDk8Xs3vBAYXhgMef3eDS8FhpcGQz6/d8MrgeGVwZDf793wWmB4bTAU8Hs3vBEY3hgMBf3eDW8FhrcGQyG/d8M7geGdwVDY793wXmB4bzAU8Xs3fBAYPhgMRf3eDR8Fho8GQzG/d8MngeGTwVDc793wWWD4bDCU8Hs3/CUw/GUwlPR7N3wRGL4YDKX83g1fBYavBkNpv3fDN4Hhm8FQxu/d4Jv37zf8/Z9BDWX93g3fCQzfGQzl/N4NwQSGYAZDeb93Q3CBIbjBUMHv3fC9wPC9wVDR790QQmAIYTBU8ns3/CAw/GAwVPZ7N4QUGEIaDFX83g2hBIZQBkNVv3dDaIEhtMFQze/dEEZgCGMwVPd7N4QVGMIaDDX83g3hBIZwBkNNv3dDeIEhvMFQy+/dEEFgiGAw1PZ7N0QUGCIaDHX83g2RBIZIBkNdv3dDZIEhssFQz+/dEEVgiGIw1Pd7N0QVGKIaDA383g3RBIZoBkNDv3dDdIEhusHQyO/dEENgiGEwNPZ7N8QUGGIaDE383g2xBIZYBkNTv3dDbIEhtsHQzO/dEEdgiGMwNPd7N8QVGOIaDC383g3xBIZ4BkNLv3dDfIEhvsHQyu/dkEBgSGAwtPZ7NyQUGBIaDG383g1+gcFvMLT1ezckEhgSGQzt/N4NiQWGxAZDe793QxKBIYnB0MHv3ZBUYEhqMHT0ezckExiSGQyd/N4NyQWG5AZDZ793QwqBIYXB0MXv3ZBSYEhpMHT1ezekEhhSGQzd/N4NqQWG1AZDd793QxqBIY3B0MPv3ZBWYEhrMPT0ezekExjSGQy9/N4N6QWG9AZDb793QwaBIYPB0Mfv3ZBRYMhoMPT1ezdkEhgyGQz9/N4NmQWGzAZDf793QxaBIYvBMMDv3ZBVYMhqMAz0ezdkExiyGQyD/N4N2QWG7AbDYL93Qw6BIYfBMMTv3ZBTYMhpMAz1ezfkEhhyGQzD/N4NuQWG3AbDcL93Qx6BIY/BMMLv3ZBXYMhrMIz0ezfkExjyGQyj/N4N+QWG/AbDaL93QwGBoYDBMMbv3VBQYChoMIz1ezcUEhgKGQzj/N4NhQWGwgbDeL93QxGBoYjBMMHv3VBUYChqMEz0ezcUExiKGQyT/N4NxQWG4gbDZL93QwmBoYTBMMXv3VBSYChpMEz1ezeUEhhKGQzT/N4NpQWG0gbDdL93QxmBoYzBMMPv3VBWYChrMMz0ezeUExjKGQyz/N4N5QWG8gbDbL93QwWBoYLBMMfv3VBRYKhoMMz1ezdUEhgqGQzz/N4NlQWGygbDfL93QxWBoYrBsMDv3VBVYKhqMCz0ezdUExiqGQyL/N4N1QWG6gbDYr93Qw2BoYbBsMTv3VBTYKhpMCz1ezfUEhhqGQzL/N4NtQWG2gbDj37vhjoCQx2DYbnfu6GuwFDXYFjh926oJzDUMxhW+r0b6gsM9Q2Gn/zeDQ0EhgYGwyq/d0NDgaGhwbDa793QSGBoZDCs8Xs3NBYYGhsMP/u9G5oIDE0MhrV+74amAkNTg2Gd37uhmcDQzGBY7/duaC4wNDcYNvi9G1oIDC0Mhl/83g0tBYaWBsOvfu+GVgJDK4PhN793Q2uBobXB8Lvfu6GNwNDGYNjo925oKzC0NRj+8Hs3tBMY2hkMf/q9G9oLDO0Nhk1+74YOAkMHg2Gz37uho8DQ0WDY4vdu6CQwdDIYtvq9GzoLDJ0Nhm1+74YuAkMXg2G737uhq8DQ1WDY4fdu6CYwdDMYdvq9G7oLDN0Nhl1+74YeAkMPg2G337uhp8DQ02DY4/du6CUw9DIY9vq9G3oLDL0Nhn1+74Y+AkMfg2G/37uhr8DQ12A44Pdu6Ccw9DMYDvq9G/oLDP0NhkN+74YBAsMAg+Gw37thoMAw0GA44vduGCQwDDIYjvq9GwYLDIMNhmN+74YhAsMQg+G437thqMAw1GA44fduGCYwDDMYTvq9G4YLDMMNhlN+74YRAsMIg+G037thpMAw0mA44/duGCUwjDIYzvq9G0YLDKMNhnN+74YxAsMYg+G837thrMAw1mC44PduGCcwjDMYLvq9G8YLDOMNhkt+74YJAsMEg+Gy37thosAw0WC44vdumCQwTDIYrvq9GyYLDJMNhmt+74YpAsMUg+G637thqsAw1WC44fdumCYwTDMYbvq9G6YLDNMNhlt+74YZAsMMg+G237thpsAw02C44/dumCUwzDIY7vq9G2YLDLMNhnt+74Y5AsMcg+G+37thrsAw12B44PdumCcwzDMYHvq9G+YLDPMNhkd+74YFAsMCg+Gx37thocCw0GB44vduWCQwLDIYnvq9GxYLDIsNhmd+74YlAsMSg+G537thqcCw1GB44fduWCYwLDMYXvq9G34UGH40GF75vRuWCwzLDYbXfu+GFQLDCoPhjd+7YaXAsNJgeOv3bvhJYPjJYHjn925YJTCsMhje+70bVgsMqw2GD37vhjUCwxqD4aPfu+FngeFng+GT37thrcCw1mD47PduWCcwrDMY/vJ7N6wXGNYbDF/83g0bBIYNBsNXv3fDLwLDLwbDN793w68Cw68Ggy+Rd8NvAsNvBsN3wPC7wPC7wRAMGDYKDBsNhuDA8IfA8IfB8D0w/Ckw/GkwhACGTQLDJoPhB2DYLDBsNhhCAsMWgWGLwRAKGLYKDFsNhtDAsE1g2GYwhAGG7QLDdoMhLDDsEBh2GAzhgGGnwLDTYAgPDLsEhl0GQwRg2C0w7DYYIgLDHoFhj8EQCRj2Cgx7DYbIwLBPYNhnMEQBhv0Cw36DISowHBAYDhgM0YDhoMBw0GCIDgyHBIZDBkMMYDgsMBw2GGICwxGB4YjBEAsYjgoMRw2G2MBwTGA4ZjDEAYbjAsNxgyEuMJwQGE4YDPGA4aTAcNJgiA8MpwSGUwZDAmA4LTCcNhgSAsMZgeGMweAHhrMCw1mDIREwnBMYzhkMiYHhvMBw3mBIAgwXBIYLBkNSYLgoMFw0GJIBwyWB4ZLBkBwYLgsMlw2GFMBwRWC4YjCkBIarAsNVgyEVMFwTGK4ZDKmB4brAcN1gSAMMNwSGGwZDWmC4KTDcNBjSAcMtgeGWwZAeGG4LDLcNhgzAcEdguGMwZASGuwLDXYMhEzDcExjuGQyZgeG+wHDfYMgCDA8EhgcGQ1ZgeCgwPDQYsgHDI4HhkcGQHRgeCwyPDYYcwPBEYHhiMOQEhqcCw1ODIRcwPBMYnhkMuYHhucDw3GDIAwwvBIYXBkNeYHgpMLw0GPIBwyuB4ZXBkB8YXgsMrw2GAsDwRmB4YzAUBIa3AsNbg6EQMLwTGN4ZDIWB4b3A8N5gKAIMHwSGDwZDUWD4KDB8NBiKAcMngeGTwVAcGD4LDJ8NhhLA8JfA8JfBUBIYvggMXwyGUsDwVWD4ajCUBoZvAsM3g6EMMPjm//sNf/9nUENZYPhOYPjOYCgHDMEEhmAGQ3lgCC4wBDcYKgDD9wLD9wZDRWAIITCEMBgqAcMPAsMPBkNlYAgpMIQ0GKoAQyiBIZTBUBUYQgsMoQ2GasAQRmAIYzBUB4awAkNYg6EGMIQTGMIZDDWBIbzAEN5gqAUMEQSGCAZDbWCIKDBENBjqAEMkgSGSwVAXGCILDJENhnrAEEVgiGIw1AeGqAJDVIOhATBEExiiGQwNgSG6wBDdYGgEDDEEhhgGQ2NgiCkwxDQYmgBDLIEhlsHQFBhiCwyxDYZmwBBHYIhjMDQHhrgCQ1yDoQUwxBMY4hkMLYEhvsAQ32BoBQwJBIYEBkNrYEgoMCQ0GNoAg19g8BsMbYEhkcCQyGBoBwyJBYbEBkN7YEgiMCQxGDoAQ1KBIanB0BEYkgkMyQyGTsCQXGBIbjB0BoYUAkMKg6ELMKQUGFIaDF2BIZXAkMpg6AYMqQWG1AZDd2BIIzCkMRh6AENagSGtwdATGNIJDOkMhl7AkF5gSG8w9AaGDAJDBoOhDzBkFBgyGgx9gSGTwJDJYOgHDJkFhswGQ39gyCIwZDEYBgBDVoEhq8EwEBiyCQzZDIZBwJBdYMhuMAwGhhwCQw6DYQgw5BQYchoMQ4Ehl8CQy2AYBgy5BYbcBsNwYMgjMOQxGEYAQ16BIa/BMBIY8gkM+QyGUcCQX2DIbzCMBoYCAkMBg2EMMBQUGAoaDGOBoZDAUMhgGAcMhQWGwgbDeGAoIjAUMRgmAENRgaGowTARGIoJDMUMhknAUFxgKG4wTAaGEgJDCYNhCjCUFBhKGgxTgaGUwFDKYJgGDKUFhtIGw3RgKCMwlDEYZgBDWYGhrMEwExjKCQzlDIZZwFBeYChvMMwGhgoCQwWDYQ4wVBQYKhoMc4GhksBQyWCYBwyVBYbKBsN8YKgiMFQxGBYAQ1WBoarBsBAYqgkM1QyGRcBQXWCobjAsBoYaAkMNg2EJMNQUGGoaDEuBoZbAUMtgWAYMtQWG2gbDj8BQR2CoYzAsB4a6AkNdg2EFMNQTGOoZDCuBob7AUN9g+AkYGggMDQyGVcDQUGBoaDCsBoZGAkMjg2ENMDQWGBobDD8DQxOBoYnBsBYYmgoMTQ2GdcDQTGBoZjCsB4bmAkNzg2EDMLQQGFoYDL8AQ0uBoaXB8CswtBIYWhkMvwFDa4GhtcHwOzC0ERjaGAwbgaGtwNDWYPgDGNoJDO0Mhj+Bob3A0N5g2AQMHQSGDgbDZmDoKDB0NBi2AEMngaGTwbAVGDoLDJ0Nhm3A0EVg6GIwbAeGrgJDV4NhBzB0Exi6GQw7gaG7wNDdYNgFDD0Ehh4Gw25g6Ckw9DQY9gBDL4Ghl8GwFxh6Cwy9DYZ9wNBHYOhjMOwHhr4CQ1+D4QAw9BMY+hkMB4Ghv8DQ32A4BAwDBIYBBsNhYBgoMAw0GI4AwyCBYZDBcBQYBgsMgw2GY8AwRGAYYjAcB4ahAsNQg+EEMAwTGIYZDCeBYbjAMNxgOAUMIwSGEQbDaWAYKTCMNBjOAMMogWGUwXAWGEYLDKMNhnPAMEZgGGMwnAeGsQLDWIPhAjCMExjGGQwXgWG8wDDeYLgEDBMEhgkGw2VgmCgwTDQYrgDDJIFhksFwFRgmCwyTDYZrwDBFYJhiMFwHhqkCw1SD4QYwTBMYphkMN4FhusAw3WC4BQwzBIYZBsNtYJgpMMw0GO4AwyyBYZbBcBcYZgsMsw2Ge8AwR2CYYzDcB4a5AsNcg+EBMMwTGOYZDA+BYb7AMN9geAQMCwSGBQbDY2BYKDAsNBieAMMigWGRwfAUGP5/vPdTEGtd24ZtPsu2bdu2bVuPbSzbNrNs27Zt27b6S1f1TndV/+95VeVKVfbmzDmOcY/MSqYZDNMEwyNgmG4wTBcMj4FhhsEwQzA8AYaZBsNMwfAUGGYZDLMEwzNgmG0wzBYMz4FhjsEwRzC8AIa5BsNcwfASGOYZDPMEwytgmG8wzBcMr4FhgcGwQDC8AYaFBsNCwfAWGBYZDIsEwztgWGwwLBYM74FhicGwRDB8AIalBsNSwfARGJYZDMsEwydgWG4wLBcMn4FhhcGwQjB8kfZ/N6w0GFYKhjDAsMpgWCUYwgLDaoNhtWAIBwxrDIY1giE8MKw1GNYKhgjAsM5gWCcYIgLDeoNhvWCIBAwbDIYNgiEyMGw0GDYKhijAsMlg2CQYogLDZoNhs2CIBgxbDIYtgiE6MGw1GLYKhhjAsM1g2CYYYgLDdoNhu2CIBQw7DIYdgiE2MOw0GHYKhjjAsMtg2CUY4gLDboNht2CIBwx7DIY9giE+MOw1GPYKhgTAsM9g2CcYEgLDfoNhv2BIBAwHDIYDgiExMBw0GA4KhiTAcMhgOCQYkgLDYYPhsGBIBgxHDIYjgiE5MBw1GI4KhhTAcMxgOCYYUgLDcYPhuGBIBQwnDIYTgiE1MJw0GE4KhjTAcMpgOCUY0gLDaYPhtGBIBwxnDIYzgiE9MJw1GM4KhgzAcM5gOCcYMgLDeYPhvGDIBAwXDIYLgiEzMFw0GC4KhizAcMlguCQYsgLDZYPhsmDIBgxXDIYrgiE7MFw1GK4KhhzAcM1guCYYcgLDdYPhumDIBQw3DIYbgiE3MNw0GG4KhjzAcMtguCUY8gLDbYPhtmDIBwx3DIY7giE/MNw1GO4KhgLAcM9guCcYCgLDfYPhvmAoBAwPDIYHgqEwMDw0GB4KhiLA8MhgeCQYigLDY4PhsWAoBgxPDIYngqE4MDw1GJ4KhhLA8MxgeCYYSgLDc4PhuWAoBQwvDIYXgqE0MLw0GF4KhjLA8MpgeCUYygLDa4PhtWAoBwxvDIY3gqE8MLw1GN4KhgrA8M5geCcYKgLDe4PhvWCoBAwfDIYPgqEyMHw0GD4KhirA8Mlg+CQYqgLDZ4Phs2CoBgxfTAm9IdighurAEMZgCCMYagBDWIMhrGCoCQzhDIZwgqEWMIQ3GMILhtrAEMFgiCAY6gBDRIMhomCoCwyRDIZIgqEeMEQ2GCILhvrAEMVgiCIYGgBDVIMhqmBoCAzRDIZogqERMEQ3GKILhsbAEMNgiCEYmgBDTIMhpmBoCgyxDIZYgqEZMMQ2GGILhubAEMdgiCMYWgBDXIMhrmBoCQzxDIZ4gqEVMMQ3GOILhtbAkMBgSCAY2gBDQoMhoWBoCwyJDIZEgqEdMCQ2GBILhvbAkMRgSCIYOgBDUoMhqWD4EhiSGQzJBMNXwJDcYEguGL4GhhQGQwrB8A0wpDQYUgqGb4EhlcGQSjB8BwypDYbUguF7YEhjMKQRDD8AQ1qDIa1g+BEY0hkM6QTDT8CQ3mBILxh+BoYMBkMGwfALMGQ0GDIKhl+BIZPBkEkw/AYMmQ2GzILhd2DIYjBkEQx/AENWgyGrYPgTGLIZDNkEw1/AkN1gyC4Y/gaGHAZDDsHwDzDkNBhyCoZ/gSGXwZBLMPwHDLkNhtyCoSMw5DEY8giGTsCQ12DIKxg6A0M+gyGfYOgCDPkNhvyCoSswFDAYCgiGbsBQ0GAoKBi6A0Mhg6GQYOgBDIUNhsKCoScwFDEYigiGXsBQ1GAoKhh6A0Mxg6GYYOgDDMUNhuKCoS8wlDAYSgiGfsBQ0mAoKRj6A0Mpg6GUYBgADKUNhtKCYSAwlDEYygiGQcBQ1mAoKxgGA0M5g6GcYBgCDOUNhvKCYSgwVDAYKgiGYcBQ0WCoKBiGA0Mlg6GSYBgBDJUNhsqCYSQwVDEYqgiGUcBQ1WCoKhhGA0M1g6GaYBgDDNUNhuqCYSww1DAYagiGccBQ02CoKRjGA0Mtg6GWYJgADLUNhtqCYSIw1DEY6giGScBQ12CoKxgmA0M9g6GeYJgCDPUNhvqCIQAMDQyGBoJhKjA0NBgaCoZpwNDIYGgkGKYDQ2ODobFgmAEMTQyGJoJhJjA0NRiaCoZZwNDMYGgmGGYDQ3ODoblgmAMMLQyGFoJhLjC0NBhaCoZ5wNDKYGglGOYDQ2uDobVgWAAMbQyGNoJhITC0NRjaCoZFwNDOYGgnGBYDQ3uDob1gWAIMHQyGDoJhKTB8aTB8KRiWAcNXBsNXgmE5MHxtMHwtGFYAwzcGwzeCYSUwfGswfCsYVgHDdwbDd4JhNTB8bzB8LxjWAMMPBsMPgmEtMPxoMPwoGNYBw08Gw0+CYT0w/Gww/CwYNgDDLwbDL4JhIzD8ajD8Khg2AcNvBsNvgmEzMPxuMPwuGLYAwx8Gwx+CYSsw/Gkw/CkYtgHDXwbDX4JhOzD8bTD8LRh2AMM/BsM/gmEnMPxrMPwrGHYBw38Gw3+CYTcwdDQYOgqGPcDQyWDoJBj2AkNng6GzYNgHDF0Mhi6CYT8wdDUYugqGA8DQzWDoJhgOAkN3g6G7YDgEDD0Mhh6C4TAw9DQYegqGI8DQy2DoJRiOAkNvg6G3YDgGDH0Mhj6C4Tgw9DUY+gqGE8DQz2DoJxhOAkN/g6G/YDgFDAMMhgGC4TQwDDQYBgqGM8AwyGAYJBjOAsNgg2GwYDgHDEMMhiGC4TwwDDUYhgqGC8AwzGAYJhguAsNwg2G4YLgEDCMMhhGC4TIwjDQYRgqGK8AwymAYJRiuAsNog2G0YLgGDGMMhjGC4TowjDUYxgqGG8AwzmAYJxhuAsN4g2G8YLgFDBMMhgmC4TYwTDQYJgqGO8AwyWCYJBjuAsNkg2GyYLgHDFMMhimC4T4wBAyGgGB4AAxTDYapguEhMEwzGKYJhkfAMN1gmC4YHgPDDINhhmB4AgwzDYaZguEpMMwyGGYJhmfAMNtgmC0YngPDHINhjmB4AQxzDYa5guElMMwzGOYJhlfAMN9gmC8YXgPDAoNhgWB4AwwLDYaFguEtMCwyGBYJhnfAsNhgWCwY3gPDEoNhiWD4AAxLDYalguEjMCwzGJYJhk/AsNxgWC4YPgPDCoNhhWD4It3/blhpMKwUDGGAYZXBsEowhAWG1QbDasEQDhjWGAxrBEN4YFhrMKwVDBGAYZ3BsE4wRASG9QbDesEQCRg2GAwbBENkYNhoMGwUDFGAYZPBsEkwRAWGzQbDZsEQDRi2GAxbBEN0YNhqMGwVDDGAYZvBsE0wxASG7QbDdsEQCxh2GAw7BENsYNhpMOwUDHGAYZfBsEswxAWG3QbDbsEQDxj2GAx7BEN8YNhrMOwVDAmAYZ/BsE8wJASG/QbDfsGQCBgOGAwHBENiYDhoMBwUDEmA4ZDBcEgwJAWGwwbDYcGQDBiOGAxHBENyYDhqMBwVDCmA4ZjBcEwwpASG4wbDccGQChhOGAwnBENqYDhpMJwUDGmA4ZTBcEowpAWG0wbDacGQDhjOGAxnBEN6YDhrMJwVDBmA4ZzBcE4wZASG8wbDecGQCRguGAwXBENmYLhoMFwUDFmA4ZLBcEkwZAWGywbDZcGQDRiuGAxXBEN2YLhqMFwVDDmA4ZrBcE0w5ASG6wbDdcGQCxhuGAw3BENuYLhpMNwUDHmA4ZbBcEsw5AWG2wbDbcGQDxjuGAx3BEN+YLhrMNwVDAWA4Z7BcE8wFASG+wbDfcFQCBgeGAwPBENhYHhoMDwUDEWA4ZHB8EgwFAWGxwbDY8FQDBieGAxPBENxYHhqMDwVDCWA4ZnB8EwwlASG5wbDc8FQChheGAwvBENpYHhpMLwUDGWA4ZXB8EowlAWG1wbDa8FQDhjeGAxvBEN5YHhrMLwVDBWA4Z3B8E4wVASG9wbDe8FQCRg+GAwfBENlYPhoMHwUDFWA4ZPB8EkwVAWGzwbDZ8FQDRi+CITeEGxQQ3VgCBMIvSHYoIYawBA2EHpDsEENNYEhXCD0hmCDGmoBQ/hA6A3BBjXUBoYIgdAbgg1qqAMMEQOhNwQb1FAXGCIFQm8INqihHjBEDoTeEGxQQ31giBIIvSHYoIYGwBA1EHpDsEENDYEhWiD0hmCDGhoBQ/RA6A3BBjU0BoYYgdAbgg1qaAIMMQOhNwQb1NAUGGIFQm8INqihGTDEDoTeEGxQQ3NgiBMIvSHYoIYWwBA3EHpDsEENLYEhXiD0hmCDGloBQ/xA6A3BBjW0BoYEgdAbgg1qaAMMCQOhNwQb1NAWGBIFQm8INqihHTAkDoTeEGxQQ3tgSBIIvSHYoIYOwJA0EHpDsEENXwJDskDoDcEGNXwFDMkDoTcEG9TwNTCkCITeEGxQwzfAkDIQekOwQQ3fAkOqQOgNwQY1fAcMqQOhNwQb1PA9MKQJhN4QbFDDD8CQNhB6Q7BBDT8CQ7pA6A3BBjX8BAzpA6E3BBvU8DMwZAiE3hBsUMMvwJAxEHpDsEENvwJDpkDoDcEGNfwGDJkDoTcEG9TwOzBkCYTeEGxQwx/AkDUQekOwQQ1/AkO2QOgNwQY1/AUM2QOhNwQb1PA3MOQIhN4QbFDDP8CQMxB6Q7BBDf8CQ65A6A3BBjX8Bwy5A6E3BBvU0BEY8gRCbwg2qKETMOQNhN4QbFBDZ2DIFwi9Idighi7AkD8QekOwQQ1dgaFAIPSGYIMaugFDwUDoDcEGNXQHhkKB0BuCDWroAQyFA6E3BBvU0BMYigRCbwg2qKEXMBQNhN4QbFBDb2AoFgi9Idighj7AUDwQekOwQQ19gaFEIPSGYIMa+gFDyUDoDcEGNfQHhlKB0BuCDWoYAAylA6E3BBvUMBAYygRCbwg2qGEQMJQNhN4QbFDDYGAoFwi9IdighiHAUD4QekOwQQ1DgaFCIPSGYIMahgFDxUDoDcEGNQwHhkqB0BuCDWoYAQyVA6E3BBvUMBIYqgRCbwg2qGEUMFQNhN4QbFDDaGCoFgi9IdighjHAUD0QekOwQQ1jgaFGIPSGYIMaxgFDzUDoDcEGNYwHhlqB0BuCDWqYAAy1A6E3BBvUMBEY6gRCbwg2qGESMNQNhN4QbFDDZGCoFwi9IdighinAUD8QekOwQQ0BYGgQCL0h2KCGqcDQMBB6Q7BBDdOAoVEg9IZggxqmA0PjQOgNwQY1zACGJoHQG4INapgJDE0DoTcEG9QwCxiaBUJvCDaoYTYwNA+E3hBsUMMcYGgRCL0h2KCGucDQMhB6Q7BBDfOAoVUg9IZggxrmA0PrQOgNwQY1LACGNoHQG4INalgIDG0DoTcEG9SwCBjaBUJvCDaoYTEwtA+E3hBsUMMSYOgQCL0h2KCGpcDwZSD0hmCDGpYBw1eB0BuCDWpYDgxfB0JvCDaoYQUwfBMIvSHYoIaVwPBtIPSGYIMaVgHDd4HQG4INalgNDN8HQm8INqhhDTD8EAi9IdighrXA8GMg9IZggxrWAcNPgdAbgg1qWA8MPwdCbwg2qGEDMPwSCL0h2KCGjcDwayD0hmCDGjYBw2+B0BuCDWrYDAy/B0JvCDaoYQsw/BEIvSHYoIatwPBnIPSGYIMatgHDX4HQG4INatgODH8HQm8INqhhBzD8Ewi9Idighp3A8G8g9IZggxp2AcN/gdAbgg1q2A0MHQOhNwQb1LAHGDoFQm8INqhhLzB0DoTeEGxQwz5g6BIIvSHYoIb9wNA1EHpDsEENB4ChWyD0hmCDGg4CQ/dA6A3BBjUcAoYegdAbgg1qOAwMPQOhNwQb1HAEGHoFQm8INqjhKDD0DoTeEGxQwzFg6BMIvSHYoIbjwNA3EHpDsEENJ4ChXyD0hmCDGk4CQ/9A6A3BBjWcAoYBgdAbgg1qOA0MAwOhNwQb1HAGGAYFQm8INqjhLDAMDoTeEGxQwzlgGBIIvSHYoIbzwDA0EHpDsEENF4BhWCD0hmCDGi4Cw/BA6A3BBjVcAoYRgdAbgg1quAwMIwOhNwQb1HAFGEYFQm8INqjhKjCMDoTeEGxQwzVgGBMIvSHYoIbrwDA2EHpDsEENN4BhXCD0hmCDGm4Cw/hA6A3BBjXcAoYJgdAbgg1quA0MEwOhNwQb1HAHGCYFQm8INqjhLjBMDoTeEGxQwz1gmBIIvSHYoIb7wBAIhN4QbFDDA2CYGgi9IdighofAMC0QekOwQQ2PgGF6IPSGYIMaHgPDjEDoDcEGNTwBhpmB0BuCDWp4CgyzAqE3BBvU8AwYZgdCbwg2qOE5MMwJhN4QbFDDC2CYGwi9IdighpfAMC8QekOwQQ2vgGF+IPSGYIMaXgPDgkDoDcEGNbwBhoWB0BuCDWp4CwyLAqE3BBvU8A4YFgdCbwg2qOE9MCwJhN4QbFDDB2BYGgi9Idigho/AsCwQekOwQQ2fgGF5ILSGz5n+7yyN5IYvMv/vhhWB0M8h2KCGMMCwMhB6Q7BBDWGBYVUg9IZggxrCAcPqQOgNwQY1hAeGNYHQG4INaogADGsDoTcEG9QQERjWBUJvCDaoIRIwrA+E3hBsUENkYNgQCL0h2KCGKMCwMRB6Q7BBDVGBYVMg9IZggxqiAcPmQOgNwQY1RAeGLYHQG4INaogBDFsDoTcEG9QQExi2BUJvCDaoIRYwbA+E3hBsUENsYNgRCL0h2KCGOMCwMxB6Q7BBDXGBYVcg9IZggxriAcPuQOgNwQY1xAeGPYHQG4INakgADHsDoTcEG9SQEBj2BUJvCDaoIREw7A+E3hBsUENiYDgQCL0h2KCGJMBwMBB6Q7BBDUmB4VAg9IZggxqSAcPhQOgNwQY1JAeGI4HQG4INakgBDEcDoTcEG9SQEhiOBUJvCDaoIRUwHA+E3hBsUENqYDgRCL0h2KCGNMBwMhB6Q7BBDWmB4VQg9IZggxrSAcPpQOgNwQY1pAeGM4HQG4INasgADGcDoTcEG9SQERjOBUJvCDaoIRMwnA+E3hBsUENmYLgQCL0h2KCGLMBwMRB6Q7BBDVmB4VIg9IZggxqyAcPlQOgNwQY1ZAeGK4HQG4INasgBDFcDoTcEG9SQExiuBUJvCDaoIRcwXA+E3hBsUENuYLgRCL0h2KCGPMBwMxB6Q7BBDXmB4VYg9IZggxryAcPtQOgNwQY15AeGO4HQG4INaigADHcDoTcEG9RQEBjuBUJvCDaooRAw3A+E3hBsUENhYHgQCL0h2KCGIsDwMBB6Q7BBDUWB4VEg9IZggxqKAcPjQOgNwQY1FAeGJ4HQG4INaigBDE8DoTcEG9RQEhieBUJvCDaooRQwPA+E3hBsUENpYHgRCL0h2KCGMsDwMhB6Q7BBDWWB4VUg9IZggxrKAcPrQOgNwQY1lAeGN4HQG4INaqgADG8DoTcEG9RQERjeBUJvCDaooRIwvA+E3hBsUENlYPgQCL0h2KCGKsDwMRB6Q7BBDVWB4VMg9IZggxqqAcPnQOgNwQY1VAeGL6aG3hBsUEMNYAhjMIQRDDWBIazBEFYw1AKGcAZDOMFQGxjCGwzhBUMdYIhgMEQQDHWBIaLBEFEw1AOGSAZDJMFQHxgiGwyRBUMDYIhiMEQRDA2BIarBEFUwNAKGaAZDNMHQGBiiGwzRBUMTYIhhMMQQDE2BIabBEFMwNAOGWAZDLMHQHBhiGwyxBUMLYIhjMMQRDC2BIa7BEFcwtAKGeAZDPMHQGhjiGwzxBUMbYEhgMCQQDG2BIaHBkFAwtAOGRAZDIsHQHhgSGwyJBUMHYEhiMCQRDF8CQ1KDIalg+AoYkhkMyQTD18CQ3GBILhi+AYYUBkMKwfAtMKQ0GFIKhu+AIZXBkEowfA8MqQ2G1ILhB2BIYzCkEQw/AkNagyGtYPgJGNIZDOkEw8/AkN5gSC8YfgGGDAZDBsHwKzBkNBgyCobfgCGTwZBJMPwODJkNhsyC4Q9gyGIwZBEMfwJDVoMhq2D4CxiyGQzZBMPfwJDdYMguGP4BhhwGQw7B8C8w5DQYcgqG/4Ahl8GQSzB0BIbcBkNuwdAJGPIYDHkEQ2dgyGsw5BUMXYAhn8GQTzB0BYb8BkN+wdANGAoYDAUEQ3dgKGgwFBQMPYChkMFQSDD0BIbCBkNhwdALGIoYDEUEQ29gKGowFBUMfYChmMFQTDD0BYbiBkNxwdAPGEoYDCUEQ39gKGkwlBQMA4ChlMFQSjAMBIbSBkNpwTAIGMoYDGUEw2BgKGswlBUMQ4ChnMFQTjAMBYbyBkN5wTAMGCoYDBUEw3BgqGgwVBQMI4ChksFQSTCMBIbKBkNlwTAKGKoYDFUEw2hgqGowVBUMY4ChmsFQTTCMBYbqBkN1wTAOGGoYDDUEw3hgqGkw1BQME4ChlsFQSzBMBIbaBkNtwTAJGOoYDHUEw2RgqGsw1BUMU4ChnsFQTzAEgKG+wVBfMEwFhgYGQwPBMA0YGhoMDQXDdGBoZDA0EgwzgKGxwdBYMMwEhiYGQxPBMAsYmhoMTQXDbGBoZjA0EwxzgKG5wdBcMMwFhhYGQwvBMA8YWhoMLQXDfGBoZTC0EgwLgKG1wdBaMCwEhjYGQxvBsAgY2hoMbQXDYmBoZzC0EwxLgKG9wdBeMCwFhg4GQwfBsAwYvjQYvhQMy4HhK4PhK8GwAhi+Nhi+FgwrgeEbg+EbwbAKGL41GL4VDKuB4TuD4TvBsAYYvjcYvhcMa4HhB4PhB8GwDhh+NBh+FAzrgeEng+EnwbABGH42GH4WDBuB4ReD4RfBsAkYfjUYfhUMm4HhN4PhN8GwBRh+Nxh+FwxbgeEPg+EPwbANGP40GP4UDNuB4S+D4S/BsAMY/jYY/hYMO4HhH4PhH8GwCxj+NRj+FQy7geE/g+E/wbAHGDoaDB0Fw15g6GQwdBIM+4Chs8HQWTDsB4YuBkMXwXAAGLoaDF0Fw0Fg6GYwdBMMh4Chu8HQXTAcBoYeBkMPwXAEGHoaDD0Fw1Fg6GUw9BIMx4Cht8HQWzAcB4Y+BkMfwXACGPoaDH0Fw0lg6Gcw9BMMp4Chv8HQXzCcBoYBBsMAwXAGGAYaDAMFw1lgGGQwDBIM54BhsMEwWDCcB4YhBsMQwXABGIYaDEMFw0VgGGYwDBMMl4BhuMEwXDBcBoYRBsMIwXAFGEYaDCMFw1VgGGUwjBIM14BhtMEwWjBcB4YxBsMYwXADGMYaDGMFw01gGGcwjBMMt4BhvMEwXjDcBoYJBsMEwXAHGCYaDBMFw11gmGQwTBIM94BhssEwWTDcB4YpBsMUwfAAGAIGQ0AwPASGqQbDVMHwCBimGQzTBMNjYJhuMEwXDE+AYYbBMEMwPAWGmQbDTMHwDBhmGQyzBMNzYJhtMMwWDC+AYY7BMEcwvASGuQbDXMHwChjmGQzzBMNrYJhvMMwXDG+AYYHBsEAwvAWGhQbDQsHwDhgWGQyLBMN7YFhsMCwWDB+AYYnBsEQwfASGpQbDUsHwCRiWGQzLBMNnYFhuMCwXDF9k+d8NKwyGFYIhDDCsNBhWCoawwLDKYFglGMIBw2qDYbVgCA8MawyGNYIhAjCsNRjWCoaIwLDOYFgnGCIBw3qDYb1giAwMGwyGDYIhCjBsNBg2CoaowLDJYNgkGKIBw2aDYbNgiA4MWwyGLYIhBjBsNRi2CoaYwLDNYNgmGGIBw3aDYbtgiA0MOwyGHYIhDjDsNBh2Coa4wLDLYNglGOIBw26DYbdgiA8MewyGPYIhATDsNRj2CoaEwLDPYNgnGBIBw36DYb9gSAwMBwyGA4IhCTAcNBgOCoakwHDIYDgkGJIBw2GD4bBgSA4MRwyGI4IhBTAcNRiOCoaUwHDMYDgmGFIBw3GD4bhgSA0MJwyGE4IhDTCcNBhOCoa0wHDKYDglGNIBw2mD4bRgSA8MZwyGM4IhAzCcNRjOCoaMwHDOYDgnGDIBw3mD4bxgyAwMFwyGC4IhCzBcNBguCoaswHDJYLgkGLIBw2WD4bJgyA4MVwyGK4IhBzBcNRiuCoacwHDNYLgmGHIBw3WD4bpgyA0MNwyGG4IhDzDcNBhuCoa8wHDLYLglGPIBw22D4bZgyA8MdwyGO4KhADDcNRjuCoaCwHDPYLgnGAoBw32D4b5gKAwMDwyGB4KhCDA8NBgeCoaiwPDIYHgkGIoBw2OD4bFgKA4MTwyGJ4KhBDA8NRieCoaSwPDMYHgmGEoBw3OD4blgKA0MLwyGF4KhDDC8NBheCoaywPDKYHglGMoBw2uD4bVgKA8MbwyGN4KhAjC8NRjeCoaKwPDOYHgnGCoBw3uD4b1gqAwMHwyGD4KhCjB8NBg+CoaqwPDJYPgkGKoBw2eD4bNgqA4MX0wLvSHYoIYawBDGYAgjGGoCQ1iDIaxgqAUM4QyGcIKhNjCENxjCC4Y6wBDBYIggGOoCQ0SDIaJgqAcMkQyGSIKhPjBENhgiC4YGwBDFYIgiGBoCQ1SDIapgaAQM0QyGaIKhMTBENxiiC4YmwBDDYIghGJoCQ0yDIaZgaAYMsQyGWIKhOTDENhhiC4YWwBDHYIgjGFoCQ1yDIa5gaAUM8QyGeIKhNTDENxjiC4Y2wJDAYEggGNoCQ0KDIaFgaAcMiQyGRIKhPTAkNhgSC4YOwJDEYEgiGL4EhqQGQ1LB8BUwJDMYkgmGr4EhucGQXDB8AwwpDIYUguFbYEhpMKQUDN8BQyqDIZVg+B4YUhsMqQXDD8CQxmBIIxh+BIa0BkNawfATMKQzGNIJhp+BIb3BkF4w/AIMGQyGDILhV2DIaDBkFAy/AUMmgyGTYPgdGDIbDJkFwx/AkMVgyCIY/gSGrAZDVsHwFzBkMxiyCYa/gSG7wZBdMPwDDDkMhhyC4V9gyGkw5BQM/wFDLoMhl2DoCAy5DYbcgqETMOQxGPIIhs7AkNdgyCsYugBDPoMhn2DoCgz5DYb8gqEbMBQwGAoIhu7AUNBgKCgYegBDIYOhkGDoCQyFDYbCgqEXMBQxGIoIht7AUNRgKCoY+gBDMYOhmGDoCwzFDYbigqEfMJQwGEoIhv7AUNJgKCkYBgBDKYOhlGAYCAylDYbSgmEQMJQxGMoIhsHAUNZgKCsYhgBDOYOhnGAYCgzlDYbygmEYMFQwGCoIhuHAUNFgqCgYRgBDJYOhkmAYCQyVDYbKgmEUMFQxGKoIhtHAUNVgqCoYxgBDNYOhmmAYCwzVDYbqgmEcMNQwGGoIhvHAUNNgqCkYJgBDLYOhlmCYCAy1DYbagmESMNQxGOoIhsnAUNdgqCsYpgBDPYOhnmAIAEN9g6G+YJgKDA0MhgaCYRowNDQYGgqG6cDQyGBoJBhmAENjg6GxYJgJDE0MhiaCYRYwNDUYmgqG2cDQzGBoJhjmAENzg6G5YJgLDC0MhhaCYR4wtDQYWgqG+cDQymBoJRgWAENrg6G1YFgIDG0MhjaCYREwtDUY2gqGxcDQzmBoJxiWAEN7g6G9YFgKDB0Mhg6CYRkwfGkwfCkYlgPDVwbDV4JhBTB8bTB8LRhWAsM3BsM3gmEVMHxrMHwrGFYDw3cGw3eCYQ0wfG8wfC8Y1gLDDwbDD4JhHTD8aDD8KBjWA8NPBsNPgmEDMPxsMPwsGDYCwy8Gwy+CYRMw/Gow/CoYNgPDbwbDb4JhCzD8bjD8Lhi2AsMfBsMfgmEbMPxpMPwpGLYDw18Gw1+CYQcw/G0w/C0YdgLDPwbDP4JhFzD8azD8Kxh2A8N/BsN/gmEPMHQ0GDoKhr3A0Mlg6CQY9gFDZ4Ohs2DYDwxdDIYuguEAMHQ1GLoKhoPA0M1g6CYYDgFDd4Ohu2A4DAw9DIYeguEIMPQ0GHoKhqPA0Mtg6CUYjgFDb4Oht2A4Dgx9DIY+guEEMPQ1GPoKhpPA0M9g6CcYTgFDf4Ohv2A4DQwDDIYBguEMMAw0GAYKhrPAMMhgGCQYzgHDYINhsGA4DwxDDIYhguECMAw1GIYKhovAMMxgGCYYLgHDcINhuGC4DAwjDIYRguEKMIw0GEYKhqvAMMpgGCUYrgHDaINhtGC4DgxjDIYxguEGMIw1GMYKhpvAMM5gGCcYbgHDeINhvGC4DQwTDIYJguEOMEw0GCYKhrvAMMlgmCQY7gHDZINhsmC4DwxTDIYpguEBMAQMhoBgeAgMUw2GqYLhETBMMximCYbHwDDdYJguGJ4AwwyDYYZgeAoMMw2GmYLhGTDMMhhmCYbnwDDbYJgtGF4AwxyDYY5geAkMcw2GuYLhFTDMMxjmCYbXwDDfYJgvGN4AwwKDYYFgeAsMCw2GhYLhHTAsMhgWCYb3wLDYYFgsGD4Aw5IQG8Ik/L/GSG4Im/B/Nyw1zGGpMIdwwLDMYFgmGMIDw3KDYblgiAAMKwyGFYIhIjCsNBhWCoZIwLDKYFglGCIDw2qDYbVgiAIMawyGNYIhKjCsNRjWCoZowLDOYFgnGKIDw3qDYb1giAEMGwyGDYIhJjBsNBg2CoZYwLDJYNgkGGIDw2aDYbNgiAMMWwyGLYIhLjBsNRi2CoZ4wLDNYNgmGOIDw3aDYbtgSAAMOwyGHYIhITDsNBh2CoZEwLDLYNglGBIDw26DYbdgSAIMewyGPYIhKTDsNRj2CoZkwLDPYNgnGJIDw36DYb9gSAEMBwyGA4IhJTAcNBgOCoZUwHDIYDgkGFIDw2GD4bBgSAMMRwyGI4IhLTAcNRiOCoZ0wHDMYDgmGNIDw3GD4bhgyAAMJwyGE4IhIzCcNBhOCoZMwHDKYDglGDIDw2mD4bRgyAIMZwyGM4IhKzCcNRjOCoZswHDOYDgnGLIDw3mD4bxgyAEMFwyGC4IhJzBcNBguCoZcwHDJYLgkGHIDw2WD4bJgyAMMVwyGK4IhLzBcNRiuCoZ8wHDNYLgmGPIDw3WD4bpgKAAMNwyGG4KhIDDcNBhuCoZCwHDLYLglGAoDw22D4bZgKAIMdwyGO4KhKDDcNRjuCoZiwHDPYLgnGIoDw32D4b5gKAEMDwyGB4KhJDA8NBgeCoZSwPDIYHgkGEoDw2OD4bFgKAMMTwyGJ4KhLDA8NRieCoZywPDMYHgmGMoDw3OD4blgqAAMLwyGF4KhIjC8NBheCoZKwPDKYHglGCoDw2uD4bVgqAIMbwyGN4KhKjC8NRjeCoZqwPDOYHgnGKoDw3uD4b1gqAEMHwyGD4KhJjB8NBg+CoZawPDJYPgkGGoDw2eD4bNgqAMMX0wPvSHYoIa6wBDGYAgjGOoBQ1iDIaxgqA8M4QyGcIKhATCENxjCC4aGwBDBYIggGBoBQ0SDIaJgaAwMkQyGSIKhCTBENhgiC4amwBDFYIgiGJoBQ1SDIapgaA4M0QyGaIKhBTBENxiiC4aWwBDDYIghGFoBQ0yDIaZgaA0MsQyGWIKhDTDENhhiC4a2wBDHYIgjGNoBQ1yDIa5gaA8M8QyGeIKhAzDENxjiC4YvgSGBwZBAMHwFDAkNhoSC4WtgSGQwJBIM3wBDYoMhsWD4FhiSGAxJBMN3wJDUYEgqGL4HhmQGQzLB8AMwJDcYkguGH4EhhcGQQjD8BAwpDYaUguFnYEhlMKQSDL8AQ2qDIbVg+BUY0hgMaQTDb8CQ1mBIKxh+B4Z0BkM6wfAHMKQ3GNILhj+BIYPBkEEw/AUMGQ2GjILhb2DIZDBkEgz/AENmgyGzYPgXGLIYDFkEw3/AkNVgyCoYOgJDNoMhm2DoBAzZDYbsgqEzMOQwGHIIhi7AkNNgyCkYugJDLoMhl2DoBgy5DYbcgqE7MOQxGPIIhh7AkNdgyCsYegJDPoMhn2DoBQz5DYb8gqE3MBQwGAoIhj7AUNBgKCgY+gJDIYOhkGDoBwyFDYbCgqE/MBQxGIoIhgHAUNRgKCoYBgJDMYOhmGAYBAzFDYbigmEwMJQwGEoIhiHAUNJgKCkYhgJDKYOhlGAYBgylDYbSgmE4MJQxGMoIhhHAUNZgKCsYRgJDOYOhnGAYBQzlDYbygmE0MFQwGCoIhjHAUNFgqCgYxgJDJYOhkmAYBwyVDYbKgmE8MFQxGKoIhgnAUNVgqCoYJgJDNYOhmmCYBAzVDYbqgmEyMNQwGGoIhinAUNNgqCkYAsBQy2CoJRimAkNtg6G2YJgGDHUMhjqCYTow1DUY6gqGGcBQz2CoJxhmAkN9g6G+YJgFDA0MhgaCYTYwNDQYGgqGOcDQyGBoJBjmAkNjg6GxYJgHDE0MhiaCYT4wNDUYmgqGBcDQzGBoJhgWAkNzg6G5YFgEDC0MhhaCYTEwtDQYWgqGJcDQymBoJRiWAkNrg6G1YFgGDG0MhjaCYTkwtDUY2gqGFcDQzmBoJxhWAkN7g6G9YFgFDB0Mhg6CYTUwfGkwfCkY1gDDVwbDV4JhLTB8bTB8LRjWAcM3BsM3gmE9MHxrMHwrGDYAw3cGw3eCYSMwfG8wfC8YNgHDDwbDD4JhMzD8aDD8KBi2AMNPBsNPgmErMPxsMPwsGLYBwy8Gwy+CYTsw/Gow/CoYdgDDbwbDb4JhJzD8bjD8Lhh2AcMfBsMfgmE3MPxpMPwpGPYAw18Gw1+CYS8w/G0w/C0Y9gHDPwbDP4JhPzD8azD8KxgOAMN/BsN/guEgMHQ0GDoKhkPA0Mlg6CQYDgNDZ4Ohs2A4AgxdDIYuguEoMHQ1GLoKhmPA0M1g6CYYjgNDd4Ohu2A4AQw9DIYeguEkMPQ0GHoKhlPA0Mtg6CUYTgNDb4Oht2A4Awx9DIY+guEsMPQ1GPoKhnPA0M9g6CcYzgNDf4Ohv2C4AAwDDIYBguEiMAw0GAYKhkvAMMhgGCQYLgPDYINhsGC4AgxDDIYhguEqMAw1GIYKhmvAMMxgGCYYrgPDcINhuGC4AQwjDIYRguEmMIw0GEYKhlvAMMpgGCUYbgPDaINhtGC4AwxjDIYxguEuMIw1GMYKhnvAMM5gGCcY7gPDeINhvGB4AAwTDIYJguEhMEw0GCYKhkfAMMlgmCQYHgPDZINhsmB4AgxTDIYpguEpMAQMhoBgeAYMUw2GqYLhOTBMMximCYYXwDDdYJguGF4CwwyDYYZgeAUMMw2GmYLhNTDMMhhmCYY3wDDbYJgtGN4CwxyDYY5geAcMcw2GuYLhPTDMMxjmCYYPwDDfYJgvGD4CwwKDYYFg+AQMCw2GhYLhMzAsMhgWCYYvEv3vhsUGw2LBEAYYlhgMSwRDWGBYajAsFQzhgGGZwbBMMIQHhuUGw3LBEAEYVhgMKwRDRGBYaTCsFAyRgGGVwbBKMEQGhtUGw2rBEAUY1hgMawRDVGBYazCsFQzRgGGdwbBOMEQHhvUGw3rBEAMYNhgMGwRDTGDYaDBsFAyxgGGTwbBJMMQGhs0Gw2bBEAcYthgMWwRDXGDYajBsFQzxgGGbwbBNMMQHhu0Gw3bBkAAYdhgMOwRDQmDYaTDsFAyJgGGXwbBLMCQGht0Gw27BkAQY9hgMewRDUmDYazDsFQzJgGGfwbBPMCQHhv0Gw37BkAIYDhgMBwRDSmA4aDAcFAypgOGQwXBIMKQGhsMGw2HBkAYYjhgMRwRDWmA4ajAcFQzpgOGYwXBMMKQHhuMGw3HBkAEYThgMJwRDRmA4aTCcFAyZgOGUwXBKMGQGhtMGw2nBkAUYzhgMZwRDVmA4azCcFQzZgOGcwXBOMGQHhvMGw3nBkAMYLhgMFwRDTmC4aDBcFAy5gOGSwXBJMOQGhssGw2XBkAcYrhgMVwRDXmC4ajBcFQz5gOGawXBNMOQHhusGw3XBUAAYbhgMNwRDQWC4aTDcFAyFgOGWwXBLMBQGhtsGw23BUAQY7hgMdwRDUWC4azDcFQzFgOGewXBPMBQHhvsGw33BUAIYHhgMDwRDSWB4aDA8FAylgOGRwfBIMJQGhscGw2PBUAYYnhgMTwRDWWB4ajA8FQzlgOGZwfBMMJQHhucGw3PBUAEYXhgMLwRDRWB4aTC8FAyVgOGVwfBKMFQGhtcGw2vBUAUY3hgMbwRDVWB4azC8FQzVgOGdwfBOMFQHhvcGw3vBUAMYPhgMHwRDTWD4aDB8FAy1gOGTwfBJMNQGhs8Gw2fBUAcYvpgRekOwQQ11gSGMwRBGMNQDhrAGQ1jBUB8YwhkM4QRDA2AIbzCEFwwNgSGCwRBBMDQChogGQ0TB0BgYIhkMkQRDE2CIbDBEFgxNgSGKwRBFMDQDhqgGQ1TB0BwYohkM0QRDC2CIbjBEFwwtgSGGwRBDMLQChpgGQ0zB0BoYYhkMsQRDG2CIbTDEFgxtgSGOwRBHMLQDhrgGQ1zB0B4Y4hkM8QRDB2CIbzDEFwxfAkMCgyGBYPgKGBIaDAkFw9fAkMhgSCQYvgGGxAZDYsHwLTAkMRiSCIbvgCGpwZBUMHwPDMkMhmSC4QdgSG4wJBcMPwJDCoMhhWD4CRhSGgwpBcPPwJDKYEglGH4BhtQGQ2rB8CswpDEY0giG34AhrcGQVjD8DgzpDIZ0guEPYEhvMKQXDH8CQwaDIYNg+AsYMhoMGQXD38CQyWDIJBj+AYbMBkNmwfAvMGQxGLIIhv+AIavBkFUwdASGbAZDNsHQCRiyGwzZBUNnYMhhMOQQDF2AIafBkFMwdAWGXAZDLsHQDRhyGwy5BUN3YMhjMOQRDD2AIa/BkFcw9ASGfAZDPsHQCxjyGwz5BUNvYChgMBQQDH2AoaDBUFAw9AWGQgZDIcHQDxgKGwyFBUN/YChiMBQRDAOAoajBUFQwDASGYgZDMcEwCBiKGwzFBcNgYChhMJQQDEOAoaTBUFIwDAWGUgZDKcEwDBhKGwylBcNwYChjMJQRDCOAoazBUFYwjASGcgZDOcEwChjKGwzlBcNoYKhgMFQQDGOAoaLBUFEwjAWGSgZDJcEwDhgqGwyVBcN4YKhiMFQRDBOAoarBUFUwTASGagZDNcEwCRiqGwzVBcNkYKhhMNQQDFOAoabBUFMwBIChlsFQSzBMBYbaBkNtwTANGOoYDHUEw3RgqGsw1BUMM4ChnsFQTzDMBIb6BkN9wTALGBoYDA0Ew2xgaGgwNBQMc4ChkcHQSDDMBYbGBkNjwTAPGJoYDE0Ew3xgaGowNBUMC4ChmcHQTDAsBIbmBkNzwbAIGFoYDC0Ew2JgaGkwtBQMS4ChlcHQSjAsBYbWBkNrwbAMGNoYDG0Ew3JgaGswtBUMK4ChncHQTjCsBIb2BkN7wbAKGDoYDB0Ew2pg+NJg+FIwrAGGrwyGrwTDWmD42mD4WjCsA4ZvDIZvBMN6YPjWYPhWMGwAhu8Mhu8Ew0Zg+N5g+F4wbAKGHwyGHwTDZmD40WD4UTBsAYafDIafBMNWYPjZYPhZMGwDhl8Mhl8Ew3Zg+NVg+FUw7ACG3wyG3wTDTmD43WD4XTDsAoY/DIY/BMNuYPjTYPhTMOwBhr8Mhr8Ew15g+Ntg+Fsw7AOGfwyGfwTDfmD412D4VzAcAIb/DIb/BMNBYOhoMHQUDIeAoZPB0EkwHAaGzgZDZ8FwBBi6GAxdBMNRYOhqMHQVDMeAoZvB0E0wHAeG7gZDd8FwAhh6GAw9BMNJYOhpMPQUDKeAoZfB0EswnAaG3gZDb8FwBhj6GAx9BMNZYOhrMPQVDOeAoZ/B0E8wnAeG/gZDf8FwARgGGAwDBMNFYBhoMAwUDJeAYZDBMEgwXAaGwQbDYMFwBRiGGAxDBMNVYBhqMAwVDNeAYZjBMEwwXAeG4QbDcMFwAxhGGAwjBMNNYBhpMIwUDLeAYZTBMEow3AaG0QbDaMFwBxjGGAxjBMNdYBhrMIwVDPeAYZzBME4w3AeG8QbDeMHwABgmGAwTBMNDYJhoMEwUDI+AYZLBMEkwPAaGyQbDZMHwBBimGAxTBMNTYAgYDAHB8AwYphoMUwXDc2CYZjBMEwwvgGG6wTBdMLwEhhkGwwzB8AoYZhoMMwXDa2CYZTDMEgxvgGG2wTBbMLwFhjkGwxzB8A4Y5hoMcwXDe2CYZzDMEwwfgGG+wTBfMHwEhgUGwwLB8AkYFhoMCwXDZ2BYZDCsmsgNwRv+P9f+PxkWGwwbRguGuP+7YYnBsGSa8J3O8r8blobYsOn/DMH3//d9/0/rWjYDzOwLvq4wkf9vb0fyvQ0b+X83LDecj+XCsyYcMKwwGFYIhvDAsNJgWCkYIgDDKsczXzBEBIbVBsNqwRAJGNYYDGsEQ2RgWGswrBUMUYBhncGwTjBEBYb1BsN6wRANGDY4fscJhujAsNFg2CgYYgDDJoNhk2CICQybDYbNgiEWMGwxGLYIhtjAsNVg2CoY4gDDNoNhm2CICwzbDYbtgiEeMOwwGHYIhvjAsNNg2CkYEgDDLoNhl2BICAy7DYbdgiERMOwxGPYIhsTAsNdg2CsYkgDDPoNhn2BICgz7DYb9giEZMBwwGA4IhuTAcNBgOCgYUgDDIYPhkGBICQyHDYbDgiEVMBwxGI4IhtTAcNRgOCoY0gDDMYPhmGBICwzHDYbjgiEdMJwwGE4IhvTAcNJgOCkYMgDDKYPhlGDICAynDYbTgiETMJwxGM4IhszAcNZgOCsYsgDDOYPhnGDICgznDYbzgiEbMFwwGC4IhuzAcNFguCgYcgDDJYPhkmDICQyXDYbLgiEXMFwxGK4IhtzAcNVguCoY8gDDNYPhmmDICwzXDYbrgiEfMNwwGG4IhvzAcNNguCkYCgDDLYPhlmAoCAy3DYbbgqEQMNwxGO4IhsLAcNdguCsYigDDPYPhnmAoCgz3DYb7gqEYMDwwGB4IhuLA8NBgeCgYSgDDI4PhkWAoCQyPDYbHgqEUMDwxGJ4IhtLA8NRgeCoYygDDM4PhmWAoCwzPDYbngqEcMLwwGF4IhvLA8NJgeCkYKgDDK4PhlWCoCAyvDYbXgqESMLwxGN4IhsrA8NZgeCsYqgDDO4PhnWCoCgzvDYb3gqEaMHwwGD4IhurA8NFg+CgYagDDJ4Phk2CoCQyfDYbPgqEWMHwxM/SGYIMaagNDGIMhjGCoAwxhDYawgqEuMIQzGMIJhnrAEN5gCC8Y6gNDBIMhgmBoAAwRDYaIgqEhMEQyGCIJhkbAENlgiCwYGgNDFIMhimBoAgxRDYaogqEpMEQzGKIJhmbAEN1giC4YmgNDDIMhhmBoAQwxDYaYgqElMMQyGGIJhlbAENtgiC0YWgNDHIMhjmBoAwxxDYa4gqEtMMQzGOIJhnbAEN9giC8Y2gNDAoMhgWDoAAwJDYaEguFLYEhkMCQSDF8BQ2KDIbFg+BoYkhgMSQTDN8CQ1GBIKhi+BYZkBkMywfAdMCQ3GJILhu+BIYXBkEIw/AAMKQ2GlILhR2BIZTCkEgw/AUNqgyG1YPgZGNIYDGkEwy/AkNZgSCsYfgWGdAZDOsHwGzCkNxjSC4bfgSGDwZBBMPwBDBkNhoyC4U9gyGQwZBIMfwFDZoMhs2D4GxiyGAxZBMM/wJDVYMgqGP4FhmwGQzbB8B8wZDcYsguGjsCQw2DIIRg6AUNOgyGnYOgMDLkMhlyCoQsw5DYYcguGrsCQx2DIIxi6AUNegyGvYOgODPkMhnyCoQcw5DcY8guGnsBQwGAoIBh6AUNBg6GgYOgNDIUMhkKCoQ8wFDYYCguGvsBQxGAoIhj6AUNRg6GoYOgPDMUMhmKCYQAwFDcYiguGgcBQwmAoIRgGAUNJg6GkYBgMDKUMhlKCYQgwlDYYSguGocBQxmAoIxiGAUNZg6GsYBgODOUMhnKCYQQwlDcYyguGkcBQwWCoIBhGAUNFg6GiYBgNDJUMhkqCYQwwVDYYKguGscBQxWCoIhjGAUNVg6GqYBgPDNUMhmqCYQIwVDcYqguGicBQw2CoIRgmAUNNg6GmYJgMDLUMhlqCYQow1DYYaguGADDUMRjqCIapwFDXYKgrGKYBQz2DoZ5gmA4M9Q2G+oJhBjA0MBgaCIaZwNDQYGgoGGYBQyODoZFgmA0MjQ2GxoJhDjA0MRiaCIa5wNDUYGgqGOYBQzODoZlgmA8MzQ2G5oJhATC0MBhaCIaFwNDSYGgpGBYBQyuDoZVgWAwMrQ2G1oJhCTC0MRjaCIalwNDWYGgrGJYBQzuDoZ1gWA4M7Q2G9oJhBTB0MBg6CIaVwPClwfClYFgFDF8ZDF8JhtXA8LXB8LVgWAMM3xgM3wiGtcDwrcHwrWBYBwzfGQzfCYb1wPC9wfC9YNgADD8YDD8Iho3A8KPB8KNg2AQMPxkMPwmGzcDws8Hws2DYAgy/GAy/CIatwPCrwfCrYNgGDL8ZDL8Jhu3A8LvB8Ltg2AEMfxgMfwiGncDwp8Hwp2DYBQx/GQx/CYbdwPC3wfC3YNgDDP8YDP8Ihr3A8K/B8K9g2AcM/xkM/wmG/cDQ0WDoKBgOAEMng6GTYDgIDJ0Nhs6C4RAwdDEYugiGw8DQ1WDoKhiOAEM3g6GbYDgKDN0Nhu6C4Rgw9DAYegiG48DQ02DoKRhOAEMvg6GXYDgJDL0Nht6C4RQw9DEY+giG08DQ12DoKxjOAEM/g6GfYDgLDP0Nhv6C4RwwDDAYBgiG88Aw0GAYKBguAMMgg2GQYLgIDIMNhsGC4RIwDDEYhgiGy8Aw1GAYKhiuAMMwg2GYYLgKDMMNhuGC4RowjDAYRgiG68Aw0mAYKRhuAMMog2GUYLgJDKMNhtGC4RYwjDEYxgiG28Aw1mAYKxjuAMM4g2GcYLgLDOMNhvGC4R4wTDAYJgiG+8Aw0WCYKBgeAMMkg2GSYHgIDJMNhsmC4REwTDEYpgiGx8AQMBgCguEJMEw1GKYKhqfAMM1gmCYYngHDdINhumB4DgwzDIYZguEFMMw0GGYKhpfAMMtgmCUYXgHDbINhtmB4DQxzDIY5guENMMw1GOYKhrfAMM9gmCcY3gHDfINhvmB4DwwLDIYFguEDMCw0GBYKho/AsMhgWCQYPgHDYoNhsWD4DAxLDIYlguGLKP+7YanBsFQwhAGGZQbDMsEQFhiWGwzLBUM4YFhhMKwQDOGBYaXBsFIwRACGVQbDKsEQERhWGwyrBUMkYFhjMKwRDJGBYa3BsFYwRAGGdQbDOsEQFRjWGwzrBUM0YNhgMGwQDNGBYaPBsFEwxACGTQbDJsEQExg2GwybBUMsYNhiMGwRDLGBYavBsFUwxAGGbQbDNsEQFxi2GwzbBUM8YNhhMOwQDPGBYafBsFMwJACGXQbDLsGQEBh2Gwy7BUMiYNhjMOwRDImBYa/BsFcwJAGGfQbDPsGQFBj2Gwz7BUMyYDhgMBwQDMmB4aDBcFAwpACGQwbDIcGQEhgOGwyHBUMqYDhiMBwRDKmB4ajBcFQwpAGGYwbDMcGQFhiOGwzHBUM6YDhhMJwQDOmB4aTBcFIwZACGUwbDKcGQERhOGwynBUMmYDhjMJwRDJmB4azBcFYwZAGGcwbDOcGQFRjOGwznBUM2YLhgMFwQDNmB4aLBcFEw5ACGSwbDJcGQExguGwyXBUMuYLhiMFwRDLmB4arBcFUw5AGGawbDNcGQFxiuGwzXBUM+YLhhMNwQDPmB4abBcFMwFACGWwbDLcFQEBhuGwy3BUMhYLhjMNwRDIWB4a7BcFcwFAGGewbDPcFQFBjuGwz3BUMxYHhgMDwQDMWB4aHB8FAwlACGRwbDI8FQEhgeGwyPBUMpYHhiMDwRDKWB4anB8FQwlAGGZwbDM8FQFhieGwzPBUM5YHhhMLwQDOWB4aXB8FIwVACGVwbDK8FQERheGwyvBUMlYHhjMLwRDJWB4a3B8FYwVAGGdwbDO8FQFRjeGwzvBUM1YPhgMHwQDNWB4aPB8FEw1ACGTwbDJ8FQExg+GwyfBUMtYPhiVugNwQY11AaGMAZDGMFQBxjCGgxhBUNdYAhnMIQTDPWAIbzBEF4w1AeGCAZDBMHQABgiGgwRBUNDYIhkMEQSDI2AIbLBEFkwNAaGKAZDFMHQBBiiGgxRBUNTYIhmMEQTDM2AIbrBEF0wNAeGGAZDDMHQAhhiGgwxBUNLYIhlMMQSDK2AIbbBEFswtAaGOAZDHMHQBhjiGgxxBUNbYIhnMMQTDO2AIb7BEF8wtAeGBAZDAsHQARgSGgwJBcOXwJDIYEgkGL4ChsQGQ2LB8DUwJDEYkgiGb4AhqcGQVDB8CwzJDIZkguE7YEhuMCQXDN8DQwqDIYVg+AEYUhoMKQXDj8CQymBIJRh+AobUBkNqwfAzMKQxGNIIhl+AIa3BkFYw/AoM6QyGdILhN2BIbzCkFwy/A0MGgyGDYPgDGDIaDBkFw5/AkMlgyCQY/gKGzAZDZsHwNzBkMRiyCIZ/gCGrwZBVMPwLDNkMhmyC4T9gyG4wZBcMHYEhh8GQQzB0AoacBkNOwdAZGHIZDLkEQxdgyG0w5BYMXYEhj8GQRzB0A4a8BkNewdAdGPIZDPkEQw9gyG8w5BcMPYGhgMFQQDD0AoaCBkNBwdAbGAoZDIUEQx9gKGwwFBYMfYGhiMFQRDD0A4aiBkNRwdAfGIoZDMUEwwBgKG4wFBcMA4GhhMFQQjAMAoaSBkNJwTAYGEoZDKUEwxBgKG0wlBYMQ4GhjMFQRjAMA4ayBkNZwTAcGMoZDOUEwwhgKG8wlBcMI4GhgsFQQTCMAoaKBkNFwTAaGCoZDJUEwxhgqGwwVBYMY4GhisFQRTCMA4aqBkNVwTAeGKoZDNUEwwRgqG4wVBcME4GhhsFQQzBMAoaaBkNNwTAZGGoZDLUEwxRgqG0w1BYMAWCoYzDUEQxTgaGuwVBXMEwDhnoGQz3BMB0Y6hsM9QXDDGBoYDA0EAwzgaGhwdBQMMwChkYGQyPBMBsYGhsMjQXDHGBoYjA0EQxzgaGpwdBUMMwDhmYGQzPBMB8YmhsMzQXDAmBoYTC0EAwLgaGlwdBSMCwChlYGQyvBsBgYWhsMrQXDEmBoYzC0EQxLgaGtwdBWMCwDhnYGQzvBsBwY2hsM7QXDCmDoYDB0EAwrgeFLg+FLwbAKGL4yGL4SDKuB4WuD4WvBsAYYvjEYvhEMa4HhW4PhW8GwDhi+Mxi+EwzrgeF7g+F7wbABGH4wGH4QDBuB4UeD4UfBsAkYfjIYfhIMm4HhZ4PhZ8GwBRh+MRh+EQxbgeFXg+FXwbANGH4zGH4TDNuB4XeD4XfBsAMY/jAY/hAMO4HhT4PhT8GwCxj+Mhj+Egy7geFvg+FvwbAHGP4xGP4RDHuB4V+D4V/BsA8Y/jMY/hMM+4Gho8HQUTAcAIZOBkMnwXAQGDobDJ0FwyFg6GIwdBEMh4Ghq8HQVTAcAYZuBkM3wXAUGLobDN0FwzFg6GEw9BAMx4Ghp8HQUzCcAIZeBkMvwXASGHobDL0Fwylg6GMw9BEMp4Ghr8HQVzCcAYZ+BkM/wXAWGPobDP0FwzlgGGAwDBAM54FhoMEwUDBcAIZBBsMgwXARGAYbDIMFwyVgGGIwDBEMl4FhqMEwVDBcAYZhBsMwwXAVGIYbDMMFwzVgGGEwjBAM14FhpMEwUjDcAIZRBsMowXATGEYbDKMFwy1gGGMwjBEMt4FhrMEwVjDcAYZxBsM4wXAXGMYbDOMFwz1gmGAwTBAM94FhosEwUTA8AIZJBsMkwfAQGCYbDJMFwyNgmGIwTBEMj4EhYDAEBMMTYJhqMEwVDE+BYZrBME0wPAOG6QbDdMHwHBhmGAwzBMMLYJhpMMwUDC+BYZbBMEswvAKG2QbDbMHwGhjmGAxzBMMbYJhrMMwVDG+BYZ7BME8wvAOG+QbDfMHwHhgWGAwLBMMHYFhoMCwUDB+BYZHBsEgwfAKGxQbDYsHwGRiWhNgQJvz/NUZyQ9jw/7thqWEOS4U5hAOGZQbDMsEQHhiWGwzLBUMEYFhhMKwQDBGBYaXBsFIwRAKGVQbDKsEQGRhWGwyrBUMUYFhjMKwRDFGBYa3BsFYwRAOGdQbDOsEQHRjWGwzrBUMMYNhgMGwQDDGBYaPBsFEwxAKGTQbDJsEQGxg2GwybBUMcYNhiMGwRDHGBYavBsFUwxAOGbQbDNsEQHxi2GwzbBUMCYNhhMOwQDAmBYafBsFMwJAKGXQbDLsGQGBh2Gwy7BUMSYNhjMOwRDEmBYa/BsFcwJAOGfQbDPsGQHBj2Gwz7BUMKYDhgMBwQDCmB4aDBcFAwpAKGQwbDIcGQGhgOGwyHBUMaYDhiMBwRDGmB4ajBcFQwpAOGYwbDMcGQHhiOGwzHBUMGYDhhMJwQDBmB4aTBcFIwZAKGUwbDKcGQGRhOGwynBUMWYDhjMJwRDFmB4azBcFYwZAOGcwbDOcGQHRjOGwznBUMOYLhgMFwQDDmB4aLBcFEw5AKGSwbDJcGQGxguGwyXBUMeYLhiMFwRDHmB4arBcFUw5AOGawbDNcGQHxiuGwzXBUMBYLhhMNwQDAWB4abBcFMwFAKGWwbDLcFQGBhuGwy3BUMRYLhjMNwRDEWB4a7BcFcwFAOGewbDPcFQHBjuGwz3BUMJYHhgMDwQDCWB4aHB8FAwlAKGRwbDI8FQGhgeGwyPBUMZYHhiMDwRDGWB4anB8FQwlAOGZwbDM8FQHhieGwzPBUMFYHhhMLwQDBWB4aXB8FIwVAKGVwbDK8FQGRheGwyvBUMVYHhjMLwRDFWB4a3B8FYwVAOGdwbDO8FQHRjeGwzvBUMNYPhgMHwQDDWB4aPB8FEw1AKGTwbDJ8FQGxg+GwyfBUMdYPhidugNwQY11AWGMAZDGMFQDxjCGgxhBUN9YAhnMIQTDA2AIbzBEF4wNASGCAZDBMHQCBgiGgwRBUNjYIhkMEQSDE2AIbLBEFkwNAWGKAZDFMHQDBiiGgxRBUNzYIhmMEQTDC2AIbrBEF0wtASGGAZDDMHQChhiGgwxBUNrYIhlMMQSDG2AIbbBEFswtAWGOAZDHMHQDhjiGgxxBUN7YIhnMMQTDB2AIb7BEF8wfAkMCQyGBILhK2BIaDAkFAxfA0MigyGRYPgGGBIbDIkFw7fAkMRgSCIYvgOGpAZDUsHwPTAkMxiSCYYfgCG5wZBcMPwIDCkMhhSC4SdgSGkwpBQMPwNDKoMhlWD4BRhSGwypBcOvwJDGYEgjGH4DhrQGQ1rB8DswpDMY0gmGP4AhvcGQXjD8CQwZDIYMguEvYMhoMGQUDH8DQyaDIZNg+AcYMhsMmQXDv8CQxWDIIhj+A4asBkNWwdARGLIZDNkEQydgyG4wZBcMnYEhh8GQQzB0AYacBkNOwdAVGHIZDLkEQzdgyG0w5BYM3YEhj8GQRzD0AIa8BkNewdATGPIZDPkEQy9gyG8w5BcMvYGhgMFQQDD0AYaCBkNBwdAXGAoZDIUEQz9gKGwwFBYM/YGhiMFQRDAMAIaiBkNRwTAQGIoZDMUEwyBgKG4wFBcMg4GhhMFQQjAMAYaSBkNJwTAUGEoZDKUEwzBgKG0wlBYMw4GhjMFQRjCMAIayBkNZwTASGMoZDOUEwyhgKG8wlBcMo4GhgsFQQTCMAYaKBkNFwTAWGCoZDJUEwzhgqGwwVBYM44GhisFQRTBMAIaqBkNVwTARGKoZDNUEwyRgqG4wVBcMk4GhhsFQQzBMAYaaBkNNwRAAhloGQy3BMBUYahsMtQXDNGCoYzDUEQzTgaGuwVBXMMwAhnoGQz3BMBMY6hsM9QXDLGBoYDA0EAyzgaGhwdBQMMwBhkYGQyPBMBcYGhsMjQXDPGBoYjA0EQzzgaGpwdBUMCwAhmYGQzPBsBAYmhsMzQXDImBoYTC0EAyLgaGlwdBSMCwBhlYGQyvBsBQYWhsMrQXDMmBoYzC0EQzLgaGtwdBWMKwAhnYGQzvBsBIY2hsM7QXDKmDoYDB0EAyrgeFLg+FLwbAGGL4yGL4SDGuB4WuD4WvBsA4YvjEYvhEM64HhW4PhW8GwARi+Mxi+EwwbgeF7g+F7wbAJGH4wGH4QDJuB4UeD4UfBsAUYfjIYfhIMW4HhZ4PhZ8GwDRh+MRh+EQzbgeFXg+FXwbADGH4zGH4TDDuB4XeD4XfBsAsY/jAY/hAMu4HhT4PhT8GwBxj+Mhj+Egx7geFvg+FvwbAPGP4xGP4RDPuB4V+D4V/BcAAY/jMY/hMMB4Gho8HQUTAcAoZOBkMnwXAYGDobDJ0FwxFg6GIwdBEMR4Ghq8HQVTAcA4ZuBkM3wXAcGLobDN0Fwwlg6GEw9BAMJ4Ghp8HQUzCcAoZeBkMvwXAaGHobDL0Fwxlg6GMw9BEMZ4Ghr8HQVzCcA4Z+BkM/wXAeGPobDP0FwwVgGGAwDBAMF4FhoMEwUDBcAoZBBsMgwXAZGAYbDIMFwxVgGGIwDBEMV4FhqMEwVDBcA4ZhBsMwwXAdGIYbDMMFww1gGGEwjBAMN4FhpMEwUjDcAoZRBsMowXAbGEYbDKMFwx1gGGMwjBEMd4FhrMEwVjDcA4ZxBsM4wXAfGMYbDOMFwwNgmGAwTBAMD4FhosEwUTA8AoZJBsMkwfAYGCYbDJMFwxNgmGIwTBEMT4EhYDAEBMMzYJhqMEwVDM+BYZrBME0wvACG6QbDdMHwEhhmGAwzBMMrYJhpMMwUDK+BYZbBMEswvAGG2QbDbMHwFhjmGAxzBMM7YJhrMMwVDO+BYZ7BME8wfACG+QbDfMHwERgWGAwLBMMnYFhoMCwUDJ+BYZHBsEgwfBHhfzcsNhgWC4YwwLDEYFgiGMICw1KDYalgCAcMywyGZYIhPDAsNxiWC4YIwLDCYFghGCICw0qDYaVgiAQMqwyGVYIhMjCsNhhWC4YowLDGYFgjGKICw1qDYa1giAYM6wyGdYIhOjCsNxjWC4YYwLDBYNggGGICw0aDYaNgiAUMmwyGTYIhNjBsNhg2C4Y4wLDFYNgiGOICw1aDYatgiAcM2wyGbYIhPjBsNxi2C4YEwLDDYNghGBICw06DYadgSAQMuwyGXYIhMTDsNhh2C4YkwLDHYNgjGJICw16DYa9gSAYM+wyGfYIhOTDsNxj2C4YUwHDAYDggGFICw0GD4aBgSAUMhwyGQ4IhNTAcNhgOC4Y0wHDEYDgiGNICw1GD4ahgSAcMxwyGY4IhPTAcNxiOC4YMwHDCYDghGDICw0mD4aRgyAQMpwyGU4IhMzCcNhhOC4YswHDGYDgjGLICw1mD4axgyAYM5wyGc4IhOzCcNxjOC4YcwHDBYLggGHICw0WD4aJgyAUMlwyGS4IhNzBcNhguC4Y8wHDFYLgiGPICw1WD4apgyAcM1wyGa4IhPzBcNxiuC4YCwHDDYLghGAoCw02D4aZgKAQMtwyGW4KhMDDcNhhuC4YiwHDHYLgjGIoCw12D4a5gKAYM9wyGe4KhODDcNxjuC4YSwPDAYHggGEoCw0OD4aFgKAUMjwyGR4KhNDA8NhgeC4YywPDEYHgiGMoCw1OD4algKAcMzwyGZ4KhPDA8NxieC4YKwPDCYHghGCoCw0uD4aVgqAQMrwyGV4KhMjC8NhheC4YqwPDGYHgjGKoCw1uD4a1gqAYM7wyGd4KhOjC8NxjeC4YawPDBYPggGGoCw0eD4aNgqAUMnwyGT4KhNjB8Nhg+C4Y6wPDFnNAbgg1qqAsMYQyGMIKhHjCENRjCCob6wBDOYAgnGBoAQ3iDIbxgaAgMEQyGCIKhETBENBgiCobGwBDJYIgkGJoAQ2SDIbJgaAoMUQyGKIKhGTBENRiiCobmwBDNYIgmGFoAQ3SDIbpgaAkMMQyGGIKhFTDENBhiCobWwBDLYIglGNoAQ2yDIbZgaAsMcQyGOIKhHTDENRjiCob2wBDPYIgnGDoAQ3yDIb5g+BIYEhgMCQTDV8CQ0GBIKBi+BoZEBkMiwfANMCQ2GBILhm+BIYnBkEQwfAcMSQ2GpILhe2BIZjAkEww/AENygyG5YPgRGFIYDCkEw0/AkNJgSCkYfgaGVAZDKsHwCzCkNhhSC4ZfgSGNwZBGMPwGDGkNhrSC4XdgSGcwpBMMfwBDeoMhvWD4ExgyGAwZBMNfwJDRYMgoGP4GhkwGQybB8A8wZDYYMguGf4Ehi8GQRTD8BwxZDYasgqEjMGQzGLIJhk7AkN1gyC4YOgNDDoMhh2DoAgw5DYacgqErMOQyGHIJhm7AkNtgyC0YugNDHoMhj2DoAQx5DYa8gqEnMOQzGPIJhl7AkN9gyC8YegNDAYOhgGDoAwwFDYaCgqEvMBQyGAoJhn7AUNhgKCwY+gNDEYOhiGAYAAxFDYaigmEgMBQzGIoJhkHAUNxgKC4YBgNDCYOhhGAYAgwlDYaSgmEoMJQyGEoJhmHAUNpgKC0YhgNDGYOhjGAYAQxlDYaygmEkMJQzGMoJhlHAUN5gKC8YRgNDBYOhgmAYAwwVDYaKgmEsMFQyGCoJhnHAUNlgqCwYxgNDFYOhimCYAAxVDYaqgmEiMFQzGKoJhknAUN1gqC4YJgNDDYOhhmCYAgw1DYaagiEADLUMhlqCYSow1DYYaguGacBQx2CoIximA0Ndg6GuYJgBDPUMhnqCYSYw1DcY6guGWcDQwGBoIBhmA0NDg6GhYJgDDI0MhkaCYS4wNDYYGguGecDQxGBoIhjmA0NTg6GpYFgADM0MhmaCYSEwNDcYmguGRcDQwmBoIRgWA0NLg6GlYFgCDK0MhlaCYSkwtDYYWguGZcDQxmBoIxiWA0Nbg6GtYFgBDO0MhnaCYSUwtDcY2guGVcDQwWDoIBhWA8OXBsOXgmENMHxlMHwlGNYCw9cGw9eCYR0wfGMwfCMY1gPDtwbDt4JhAzB8ZzB8Jxg2AsP3BsP3gmETMPxgMPwgGDYDw48Gw4+CYQsw/GQw/CQYtgLDzwbDz4JhGzD8YjD8Ihi2A8OvBsOvgmEHMPxmMPwmGHYCw+8Gw++CYRcw/GEw/CEYdgPDnwbDn4JhDzD8ZTD8JRj2AsPfBsPfgmEfMPxjMPwjGPYDw78Gw7+C4QAw/Gcw/CcYDgJDR4Oho2A4BAydDIZOguEwMHQ2GDoLhiPA0MVg6CIYjgJDV4Ohq2A4BgzdDIZuguE4MHQ3GLoLhhPA0MNg6CEYTgJDT4Ohp2A4BQy9DIZeguE0MPQ2GHoLhjPA0Mdg6CMYzgJDX4Ohr2A4Bwz9DIZ+guE8MPQ3GPoLhgvAMMBgGCAYLgLDQINhoGC4BAyDDIZBguEyMAw2GAYLhivAMMRgGCIYrgLDUINhqGC4BgzDDIZhguE6MAw3GIYLhhvAMMJgGCEYbgLDSINhpGC4BQyjDIZRguE2MIw2GEYLhjvAMMZgGCMY7gLDWINhrGC4BwzjDIZxguE+MIw3GMYLhgfAMMFgmCAYHgLDRINhomB4BAyTDIZJguExMEw2GCYLhifAMMVgmCIYngJDwGAICIZnwDDVYJgqGJ4DwzSDYZpgeAEM0w2G6YLhJTDMMBhmCIZXwDDTYJgpGF4DwyyDYZZgeAMMsw2G2YLhLTDMMRjmCIZ3wDDXYJgrGN4DwzyDYZ5g+AAM8w2G+YLhIzAsMBgWCIZPwLDQYFgoGD4Dw6IQGz5m++KLoAPPIdv/blhsmMNiZQ7AsMRgWCIYvsj+vxuWGgxLBUMYYFhmMCwTDGGBYbnBsFwwhAOGFQbDCsEQHhhWGgwrBUMEYFhlMKwSDBGBYbXBsFowRAKGNQbDGsEQGRjWGgxrBUMUYFhnMKwTDFGBYb3BsF4wRAOGDQbDBsEQHRg2GgwbBUMMYNhkMGwSDDGBYbPBsFkwxAKGLQbDFsEQGxi2GgxbBUMcYNhmMGwTDHGBYbvBsF0wxAOGHQbDDsEQHxh2Ggw7BUMCYNhlMOwSDAmBYbfBsFswJAKGPQbDHsGQGBj2Ggx7BUMSYNhnMOwTDEmBYb/BsF8wJAOGAwbDAcGQHBgOGgwHBUMKYDhkMBwSDCmB4bDBcFgwpAKGIwbDEcGQGhiOGgxHBUMaYDhmMBwTDGmB4bjBcFwwpAOGEwbDCcGQHhhOGgwnBUMGYDhlMJwSDBmB4bTBcFowZAKGMwbDGcGQGRjOGgxnBUMWYDhnMJwTDFmB4bzBcF4wZAOGCwbDBcGQHRguGgwXBUMOYLhkMFwSDDmB4bLBcFkw5AKGKwbDFcGQGxiuGgxXBUMeYLhmMFwTDHmB4brBcF0w5AOGGwbDDcGQHxhuGgw3BUMBYLhlMNwSDAWB4bbBcFswFAKGOwbDHcFQGBjuGgx3BUMRYLhnMNwTDEWB4b7BcF8wFAOGBwbDA8FQHBgeGgwPBUMJYHhkMDwSDCWB4bHB8FgwlAKGJwbDE8FQGhieGgxPBUMZYHhmMDwTDGWB4bnB8FwwlAOGFwbDC8FQHhheGgwvBUMFYHhlMLwSDBWB4bXB8FowVAKGNwbDG8FQGRjeGgxvBUMVYHhnMLwTDFWB4b3B8F4wVAOGDwbDB8FQHRg+GgwfBUMNYPhkMHwSDDWB4bPB8Fkw1AKGL+aG3hBsUENtYAhjMIQRDHWAIazBEFYw1AWGcAZDOMFQDxjCGwzhBUN9YIhgMEQQDA2AIaLBEFEwNASGSAZDJMHQCBgiGwyRBUNjYIhiMEQRDE2AIarBEFUwNAWGaAZDNMHQDBiiGwzRBUNzYIhhMMQQDC2AIabBEFMwtASGWAZDLMHQChhiGwyxBUNrYIhjMMQRDG2AIa7BEFcwtAWGeAZDPMHQDhjiGwzxBUN7YEhgMCQQDB2AIaHBkFAwfAkMiQyGRILhK2BIbDAkFgxfA0MSgyGJYPgGGJIaDEkFw7fAkMxgSCYYvgOG5AZDcsHwPTCkMBhSCIYfgCGlwZBSMPwIDKkMhlSC4SdgSG0wpBYMPwNDGoMhjWD4BRjSGgxpBcOvwJDOYEgnGH4DhvQGQ3rB8DswZDAYMgiGP4Aho8GQUTD8CQyZDIZMguEvYMhsMGQWDH8DQxaDIYtg+AcYshoMWQXDv8CQzWDIJhj+A4bsBkN2wdARGHIYDDkEQydgyGkw5BQMnYEhl8GQSzB0AYbcBkNuwdAVGPIYDHkEQzdgyGsw5BUM3YEhn8GQTzD0AIb8BkN+wdATGAoYDAUEQy9gKGgwFBQMvYGhkMFQSDD0AYbCBkNhwdAXGIoYDEUEQz9gKGowFBUM/YGhmMFQTDAMAIbiBkNxwTAQGEoYDCUEwyBgKGkwlBQMg4GhlMFQSjAMAYbSBkNpwTAUGMoYDGUEwzBgKGswlBUMw4GhnMFQTjCMAIbyBkN5wTASGCoYDBUEwyhgqGgwVBQMo4GhksFQSTCMAYbKBkNlwTAWGKoYDFUEwzhgqGowVBUM44GhmsFQTTBMAIbqBkN1wTARGGoYDDUEwyRgqGkw1BQMk4GhlsFQSzBMAYbaBkNtwRAAhjoGQx3BMBUY6hoMdQXDNGCoZzDUEwzTgaG+wVBfMMwAhgYGQwPBMBMYGhoMDQXDLGBoZDA0EgyzgaGxwdBYMMwBhiYGQxPBMBcYmhoMTQXDPGBoZjA0EwzzgaG5wdBcMCwAhhYGQwvBsBAYWhoMLQXDImBoZTC0EgyLgaG1wdBaMCwBhjYGQxvBsBQY2hoMbQXDMmBoZzC0EwzLgaG9wdBeMKwAhg4GQwfBsBIYvjQYvhQMq4DhK4PhK8GwGhi+Nhi+FgxrgOEbg+EbwbAWGL41GL4VDOuA4TuD4TvBsB4YvjcYvhcMG4DhB4PhB8GwERh+NBh+FAybgOEng+EnwbAZGH42GH4WDFuA4ReD4RfBsBUYfjUYfhUM24DhN4PhN8GwHRh+Nxh+Fww7gOEPg+EPwbATGP40GP4UDLuA4S+D4S/BsBsY/jYY/hYMe4DhH4PhH8GwFxj+NRj+FQz7gOE/g+E/wbAfGDoaDB0FwwFg6GQwdBIMB4Ghs8HQWTAcAoYuBkMXwXAYGLoaDF0FwxFg6GYwdBMMR4Ghu8HQXTAcA4YeBkMPwXAcGHoaDD0Fwwlg6GUw9BIMJ4Ght8HQWzCcAoY+BkMfwXAaGPoaDH0Fwxlg6Gcw9BMMZ4Ghv8HQXzCcA4YBBsMAwXAeGAYaDAMFwwVgGGQwDBIMF4FhsMEwWDBcAoYhBsMQwXAZGIYaDEMFwxVgGGYwDBMMV4FhuMEwXDBcA4YRBsMIwXAdGEYaDCMFww1gGGUwjBIMN4FhtMEwWjDcAoYxBsMYwXAbGMYaDGMFwx1gGGcwjBMMd4FhvMEwXjDcA4YJBsMEwXAfGCYaDBMFwwNgmGQwTBIMD4FhssEwWTA8AoYpBsMUwfAYGAIGQ0AwPAGGqQbDVMHwFBimGQzTBMMzYJhuMEwXDM+BYYbBMEMwvACGmQbDTMHwEhhmGQyzBMMrYJhtMMwWDK+BYY7BMEcwvAGGuQbDXMHwFhjmGQzzBMM7YJhvMMwXDO+BYYHBsEAwfACGhQbDQsHwERgWGQyLBMMnYFhsMCwWDJ+BYYnBsEQwfJHjfzcsNRiWCoYwwLDMYFgmGMICw3KDYblgCAcMKwyGFYIhPDCsNBhWCoYIwLDKYFglGCICw2qDYbVgiAQMawyGNYIhMjCsNRjWCoYowLDOYFgnGKICw3qDYb1giAYMGwyGDYIhOjBsNBg2CoYYwLDJYNgkGGICw2aDYbNgiAUMWwyGLYIhNjBsNRi2CoY4wLDNYNgmGOICw3aDYbtgiAcMOwyGHYIhPjDsNBh2CoYEwLDLYNglGBICw26DYbdgSAQMewyGPYIhMTDsNRj2CoYkwLDPYNgnGJICw36DYb9gSAYMBwyGA4IhOTAcNBgOCoYUwHDIYDgkGFICw2GD4bBgSAUMRwyGI4IhNTAcNRiOCoY0wHDMYDgmGNICw3GD4bhgSAcMJwyGE4IhPTCcNBhOCoYMwHDKYDglGDICw2mD4bRgyAQMZwyGM4IhMzCcNRjOCoYswHDOYDgnGLICw3mD4bxgyAYMFwyGC4IhOzBcNBguCoYcwHDJYLgkGHICw2WD4bJgyAUMVwyGK4IhNzBcNRiuCoY8wHDNYLgmGPICw3WD4bpgyAcMNwyGG4IhPzDcNBhuCoYCwHDLYLglGAoCw22D4bZgKAQMdwyGO4KhMDDcNRjuCoYiwHDPYLgnGIoCw32D4b5gKAYMDwyGB4KhODA8NBgeCoYSwPDIYHgkGEoCw2OD4bFgKAUMTwyGJ4KhNDA8NRieCoYywPDMYHgmGMoCw3OD4blgKAcMLwyGF4KhPDC8NBheCoYKwPDKYHglGCoCw2uD4bVgqAQMbwyGN4KhMjC8NRjeCoYqwPDOYHgnGKoCw3uD4b1gqAYMHwyGD4KhOjB8NBg+CoYawPDJYPgkGGoCw2eD4bNgqAUMX8wLvSHYoIbawBDGYAgjGOoAQ1iDIaxgqAsM4QyGcIKhHjCENxjCC4b6wBDBYIggGBoAQ0SDIaJgaAgMkQyGSIKhETBENhgiC4bGwBDFYIgiGJoAQ1SDIapgaAoM0QyGaIKhGTBENxiiC4bmwBDDYIghGFoAQ0yDIaZgaAkMsQyGWIKhFTDENhhiC4bWwBDHYIgjGNoAQ1yDIa5gaAsM8QyGeIKhHTDENxjiC4b2wJDAYEggGDoAQ0KDIaFg+BIYEhkMiQTDV8CQ2GBILBi+BoYkBkMSwfANMCQ1GJIKhm+BIZnBkEwwfAcMyQ2G5ILhe2BIYTCkEAw/AENKgyGlYPgRGFIZDKkEw0/AkNpgSC0YfgaGNAZDGsHwCzCkNRjSCoZfgSGdwZBOMPwGDOkNhvSC4XdgyGAwZBAMfwBDRoMho2D4ExgyGQyZBMNfwJDZYMgsGP4GhiwGQxbB8A8wZDUYsgqGf4Ehm8GQTTD8BwzZDYbsgqEjMOQwGHIIhk7AkNNgyCkYOgNDLoMhl2DoAgy5DYbcgqErMOQxGPIIhm7AkNdgyCsYugNDPoMhn2DoAQz5DYb8gqEnMBQwGAoIhl7AUNBgKCgYegNDIYOhkGDoAwyFDYbCgqEvMBQxGIoIhn7AUNRgKCoY+gNDMYOhmGAYAAzFDYbigmEgMJQwGEoIhkHAUNJgKCkYBgNDKYOhlGAYAgylDYbSgmEoMJQxGMoIhmHAUNZgKCsYhgNDOYOhnGAYAQzlDYbygmEkMFQwGCoIhlHAUNFgqCgYRgNDJYOhkmAYAwyVDYbKgmEsMFQxGKoIhnHAUNVgqCoYxgNDNYOhmmCYAAzVDYbqgmEiMNQwGGoIhknAUNNgqCkYJgNDLYOhlmCYAgy1DYbagiEADHUMhjqCYSow1DUY6gqGacBQz2CoJximA0N9g6G+YJgBDA0MhgaCYSYwNDQYGgqGWcDQyGBoJBhmA0Njg6GxYJgDDE0MhiaCYS4wNDUYmgqGecDQzGBoJhjmA0Nzg6G5YFgADC0MhhaCYSEwtDQYWgqGRcDQymBoJRgWA0Nrg6G1YFgCDG0MhjaCYSkwtDUY2gqGZcDQzmBoJxiWA0N7g6G9YFgBDB0Mhg6CYSUwfGkwfCkYVgHDVwbDV4JhNTB8bTB8LRjWAMM3BsM3gmEtMHxrMHwrGNYBw3cGw3eCYT0wfG8wfC8YNgDDDwbDD4JhIzD8aDD8KBg2AcNPBsNPgmEzMPxsMPwsGLYAwy8Gwy+CYSsw/Gow/CoYtgHDbwbDb4JhOzD8bjD8Lhh2AMMfBsMfgmEnMPxpMPwpGHYBw18Gw1+CYTcw/G0w/C0Y9gDDPwbDP4JhLzD8azD8Kxj2AcN/BsN/gmE/MHQ0GDoKhgPA0Mlg6CQYDgJDZ4Ohs2A4BAxdDIYuguEwMHQ1GLoKhiPA0M1g6CYYjgJDd4Ohu2A4Bgw9DIYeguE4MPQ0GHoKhhPA0Mtg6CUYTgJDb4Oht2A4BQx9DIY+guE0MPQ1GPoKhjPA0M9g6CcYzgJDf4Ohv2A4BwwDDIYBguE8MAw0GAYKhgvAMMhgGCQYLgLDYINhsGC4BAxDDIYhguEyMAw1GIYKhivAMMxgGCYYrgLDcINhuGC4BgwjDIYRguE6MIw0GEYKhhvAMMpgGCUYbgLDaINhtGC4BQxjDIYxguE2MIw1GMYKhjvAMM5gGCcY7gLDeINhvGC4BwwTDIYJguE+MEw0GCYKhgfAMMlgmCQYHgLDZINhsmB4BAxTDIYpguExMAQMhoBgeAIMUw2GqYLhKTBMMximCYZnwDDdYJguGJ4DwwyDYYZgeAEMMw2GmYLhJTDMMhhmCYZXwDDbYJgtGF4DwxyDYY5geAMMcw2GuYLhLTDMMxjmCYZ3wDDfYJgvGN4DwwKDYYFg+AAMCw2GhYLhIzAsMhgWCYZPwLDYYFgsGD4DwxKDYYlg+CLn/25YajAsFQxhgGGZwbBMMIQFhuUGw3LBEA4YVhgMKwRDeGBYaTCsFAwRgGGVwbBKMEQEhtUGw2rBEAkY1hgMawRDZGBYazCsFQxRgGGdwbBOMEQFhvUGw3rBEA0YNhgMGwRDdGDYaDBsFAwxgGGTwbBJMMQEhs0Gw2bBEAsYthgMWwRDbGDYajBsFQxxgGGbwbBNMMQFhu0Gw3bBEA8YdhgMOwRDfGDYaTDsFAwJgGGXwbBLMCQEht0Gw27BkAgY9hgMewRDYmDYazDsFQxJgGGfwbBPMCQFhv0Gw37BkAwYDhgMBwRDcmA4aDAcFAwpgOGQwXBIMKQEhsMGw2HBkAoYjhgMRwRDamA4ajAcFQxpgOGYwXBMMKQFhuMGw3HBkA4YThgMJwRDemA4aTCcFAwZgOGUwXBKMGQEhtMGw2nBkAkYzhgMZwRDZmA4azCcFQxZgOGcwXBOMGQFhvMGw3nBkA0YLhgMFwRDdmC4aDBcFAw5gOGSwXBJMOQEhssGw2XBkAsYrhgMVwRDbmC4ajBcFQx5gOGawXBNMOQFhusGw3XBkA8YbhgMNwRDfmC4aTDcFAwFgOGWwXBLMBQEhtsGw23BUAgY7hgMdwRDYWC4azDcFQxFgOGewXBPMBQFhvsGw33BUAwYHhgMDwRDcWB4aDA8FAwlgOGRwfBIMJQEhscGw2PBUAoYnhgMTwRDaWB4ajA8FQxlgOGZwfBMMJQFhucGw3PBUA4YXhgMLwRDeWB4aTC8FAwVgOGVwfBKMFQEhtcGw2vBUAkY3hgMbwRDZWB4azC8FQxVgOGdwfBOMFQFhvcGw3vBUA0YPhgMHwRDdWD4aDB8FAw1gOGTwfBJMNQEhs8Gw2fBUAsYvpgfekOwQQ21gSGMwRBGMNQBhrAGQ1jBUBcYwhkM4QRDPWAIbzCEFwz1gSGCwRBBMDQAhogGQ0TB0BAYIhkMkQRDI2CIbDBEFgyNgSGKwRBFMDQBhqgGQ1TB0BQYohkM0QRDM2CIbjBEFwzNgSGGwRBDMLQAhpgGQ0zB0BIYYhkMsQRDK2CIbTDEFgytgSGOwRBHMLQBhrgGQ1zB0BYY4hkM8QRDO2CIbzDEFwztgSGBwZBAMHQAhoQGQ0LB8CUwJDIYEgmGr4AhscGQWDB8DQxJDIYkguEbYEhqMCQVDN8CQzKDIZlg+A4YkhsMyQXD98CQwmBIIRh+AIaUBkNKwfAjMKQyGFIJhp+AIbXBkFow/AwMaQyGNILhF2BIazCkFQy/AkM6gyGdYPgNGNIbDOkFw+/AkMFgyCAY/gCGjAZDRsHwJzBkMhgyCYa/gCGzwZBZMPwNDFkMhiyC4R9gyGowZBUM/wJDNoMhm2D4DxiyGwzZBUNHYMhhMOQQDJ2AIafBkFMwdAaGXAZDLsHQBRhyGwy5BUNXYMhjMOQRDN2AIa/BkFcwdAeGfAZDPsHQAxjyGwz5BUNPYChgMBQQDL2AoaDBUFAw9AaGQgZDIcHQBxgKGwyFBUNfYChiMBQRDP2AoajBUFQw9AeGYgZDMcEwABiKGwzFBcNAYChhMJQQDIOAoaTBUFIwDAaGUgZDKcEwBBhKGwylBcNQYChjMJQRDMOAoazBUFYwDAeGcgZDOcEwAhjKGwzlBcNIYKhgMFQQDKOAoaLBUFEwjAaGSgZDJcEwBhgqGwyVBcNYYKhiMFQRDOOAoarBUFUwjAeGagZDNcEwARiqGwzVBcNEYKhhMNQQDJOAoabBUFMwTAaGWgZDLcEwBRhqGwy1BUMAGOoYDHUEw1RgqGsw1BUM04ChnsFQTzBMB4b6BkN9wTADGBoYDA0Ew0xgaGgwNBQMs4ChkcHQSDDMBobGBkNjwTAHGJoYDE0Ew1xgaGowNBUM84ChmcHQTDDMB4bmBkNzwbAAGFoYDC0Ew0JgaGkwtBQMi4ChlcHQSjAsBobWBkNrwbAEGNoYDG0Ew1JgaGswtBUMy4ChncHQTjAsB4b2BkN7wbACGDoYDB0Ew0pg+NJg+FIwrAKGrwyGrwTDamD42mD4WjCsAYZvDIZvBMNaYPjWYPhWMKwDhu8Mhu8Ew3pg+N5g+F4wbACGHwyGHwTDRmD40WD4UTBsAoafDIafBMNmYPjZYPhZMGwBhl8Mhl8Ew1Zg+NVg+FUwbAOG3wyG3wTDdmD43WD4XTDsAIY/DIY/BMNOYPjTYPhTMOwChr8Mhr8Ew25g+Ntg+Fsw7AGGfwyGfwTDXmD412D4VzDsA4b/DIb/BMN+YOhoMHQUDAeAoZPB0EkwHASGzgZDZ8FwCBi6GAxdBMNhYOhqMHQVDEeAoZvB0E0wHAWG7gZDd8FwDBh6GAw9BMNxYOhpMPQUDCeAoZfB0EswnASG3gZDb8FwChj6GAx9BMNpYOhrMPQVDGeAoZ/B0E8wnAWG/gZDf8FwDhgGGAwDBMN5YBhoMAwUDBeAYZDBMEgwXASGwQbDYMFwCRiGGAxDBMNlYBhqMAwVDFeAYZjBMEwwXAWG4QbDcMFwDRhGGAwjBMN1YBhpMIwUDDeAYZTBMEow3ASG0QbDaMFwCxjGGAxjBMNtYBhrMIwVDHeAYZzBME4w3AWG8QbDeMFwDxgmGAwTBMN9YJhoMEwUDA+AYZLBMEkwPASGyQbDZMHwCBimGAxTBMNjYAgYDAHB8AQYphoMUwXDU2CYZjBMEwzPgGG6wTBdMDwHhhkGwwzB8AIYZhoMMwXDS2CYZTDMEgyvgGG2wTBbMLwGhjkGwxzB8AYY5hoMcwXDW2CYZzDMEwzvgGG+wTBfMLwHhgUGwwLB8AEYFhoMCwXDR2BYZDAsEgyfgGGxwbBYMHwGhiUGwxLB8EWu/92w1GBYKhjCAMMyg2GZYAgLDMsNhuWCIRwwrDAYVgiG8MCw0mBYKRgiAMMqg2GVYIgIDKsNhtWCIRIwrDEY1giGyMCw1mBYKxiiAMM6g2GdYIgKDOsNhvWCIRowbDAYNgiG6MCw0WDYKBhiAMMmg2GTYIgJDJsNhs2CIRYwbDEYtgiG2MCw1WDYKhjiAMM2g2GbYIgLDNsNhu2CIR4w7DAYdgiG+MCw02DYKRgSAMMug2GXYEgIDLsNht2CIREw7DEY9giGxMCw12DYKxiSAMM+g2GfYEgKDPsNhv2CIRkwHDAYDgiG5MBw0GA4KBhSAMMhg+GQYEgJDIcNhsOCIRUwHDEYjgiG1MBw1GA4KhjSAMMxg+GYYEgLDMcNhuOCIR0wnDAYTgiG9MBw0mA4KRgyAMMpg+GUYMgIDKcNhtOCIRMwnDEYzgiGzMBw1mA4KxiyAMM5g+GcYMgKDOcNhvOCIRswXDAYLgiG7MBw0WC4KBhyAMMlg+GSYMgJDJcNhsuCIRcwXDEYrgiG3MBw1WC4KhjyAMM1g+GaYMgLDNcNhuuCIR8w3DAYbgiG/MBw02C4KRgKAMMtg+GWYCgIDLcNhtuCoRAw3DEY7giGwsBw12C4KxiKAMM9g+GeYCgKDPcNhvuCoRgwPDAYHgiG4sDw0GB4KBhKAMMjg+GRYCgJDI8NhseCoRQwPDEYngiG0sDw1GB4KhjKAMMzg+GZYCgLDM8NhueCoRwwvDAYXgiG8sDw0mB4KRgqAMMrg+GVYKgIDK8NhteCoRIwvDEY3giGysDw1mB4KxiqAMM7g+GdYKgKDO8NhveCoRowfDAYPgiG6sDw0WD4KBhqAMMng+GTYKgJDJ8Nhs+CoRYwfLEg9IZggxpqA0MYgyGMYKgDDGENhrCCoS4whDMYwgmGesAQ3mAILxjqA0MEgyGCYGgADBENhoiCoSEwRDIYIgmGRsAQ2WCILBgaA0MUgyGKYGgCDFENhqiCoSkwRDMYogmGZsAQ3WCILhiaA0MMgyGGYGgBDDENhpiCoSUwxDIYYgmGVsAQ22CILRhaA0McgyGOYGgDDHENhriCoS0wxDMY4gmGdsAQ32CILxjaA0MCgyGBYOgADAkNhoSC4UtgSGQwJBIMXwFDYoMhsWD4GhiSGAxJBMM3wJDUYEgqGL4FhmQGQzLB8B0wJDcYkguG74EhhcGQQjD8AAwpDYaUguFHYEhlMKQSDD8BQ2qDIbVg+BkY0hgMaQTDL8CQ1mBIKxh+BYZ0BkM6wfAbMKQ3GNILht+BIYPBkEEw/AEMGQ2GjILhT2DIZDBkEgx/AUNmgyGzYPgbGLIYDFkEwz/AkNVgyCoY/gWGbAZDNsHwHzBkNxiyC4aOwJDDYMghGDoBQ06DIadg6AwMuQyGXIKhCzDkNhhyC4auwJDHYMgjGLoBQ16DIa9g6A4M+QyGfIKhBzDkNxjyC4aewFDAYCggGHoBQ0GDoaBg6A0MhQyGQoKhDzAUNhgKC4a+wFDEYCgiGPoBQ1GDoahg6A8MxQyGYoJhADAUNxiKC4aBwFDCYCghGAYBQ0mDoaRgGAwMpQyGUoJhCDCUNhhKC4ahwFDGYCgjGIYBQ1mDoaxgGA4M5QyGcoJhBDCUNxjKC4aRwFDBYKggGEYBQ0WDoaJgGA0MlQyGSoJhDDBUNhgqC4axwFDFYKgiGMYBQ1WDoapgGA8M1QyGaoJhAjBUNxiqC4aJwFDDYKghGCYBQ02DoaZgmAwMtQyGWoJhCjDUNhhqC4YAMNQxGOoIhqnAUNdgqCsYpgFDPYOhnmCYDgz1DYb6gmEGMDQwGBoIhpnA0NBgaCgYZgFDI4OhkWCYDQyNDYbGgmEOMDQxGJoIhrnA0NRgaCoY5gFDM4OhmWCYDwzNDYbmgmEBMLQwGFoIhoXA0NJgaCkYFgFDK4OhlWBYDAytDYbWgmEJMLQxGNoIhqXA0NZgaCsYlgFDO4OhnWBYDgztDYb2gmEFMHQwGDoIhpXA8KXB8KVgWAUMXxkMXwmG1cDwtcHwtWBYAwzfGAzfCIa1wPCtwfCtYFgHDN8ZDN8JhvXA8L3B8L1g2AAMPxgMPwiGjcDwo8Hwo2DYBAw/GQw/CYbNwPCzwfCzYNgCDL8YDL8Ihq3A8KvB8Ktg2AYMvxkMvwmG7cDwu8Hwu2DYAQx/GAx/CIadwPCnwfCnYNgFDH8ZDH8Jht3A8LfB8Ldg2AMM/xgM/wiGvcDwr8Hwr2DYBwz/GQz/CYb9wNDRYOgoGA4AQyeDoZNgOAgMnQ2GzoLhEDB0MRi6CIbDwNDVYOgqGI4AQzeDoZtgOAoM3Q2G7oLhGDD0MBh6CIbjwNDTYOgpGE4AQy+DoZdgOAkMvQ2G3oLhFDD0MRj6CIbTwNDXYOgrGM4AQz+DoZ9gOAsM/Q2G/oLhHDAMMBgGCIbzwDDQYBgoGC4AwyCDYZBguAgMgw2GwYLhEjAMMRiGCIbLwDDUYBgqGK4AwzCDYZhguAoMww2G4YLhGjCMMBhGCIbrwDDSYBgpGG4AwyiDYZRguAkMow2G0YLhFjCMMRjGCIbbwDDWYBgrGO4AwziDYZxguAsM4w2G8YLhHjBMMBgmCIb7wDDRYJgoGB4AwySDYZJgeAgMkw2GyYLhETBMMRimCIbHwBAwGAKC4QkwTDUYpgqGp8AwzWCYJhieAcN0g2G6YHgODDMMhhmC4QUwzDQYZgqGl8Awy2CYJRheAcNsg2G2YHgNDHMMhjmC4Q0wzDUY5gqGt8Awz2CYJxjeAcP8EBve5/vii6CDGj7k+98NCwxzWCDM4SMwLDQYFgqGT8CwyGBYJBg+A8Nig2GxYPgi//9uWGIwLBEMYYBhqcGwVDCEBYZlBsMywRAOGJYbDMsFQ3hgWGEwrBAMEYBhpcGwUjBEBIZVBsMqwRAJGFYbDKsFQ2RgWGMwrBEMUYBhrcGwVjBEBYZ1BsM6wRANGNYbDOsFQ3Rg2GAwbBAMMYBho8GwUTDEBIZNBsMmwRALGDYbDJsFQ2xg2GIwbBEMcYBhq8GwVTDEBYZtBsM2wRAPGLYbDNsFQ3xg2GEw7BAMCYBhp8GwUzAkBIZdBsMuwZAIGHYbDLsFQ2Jg2GMw7BEMSYBhr8GwVzAkBYZ9BsM+wZAMGPYbDPsFQ3JgOGAwHBAMKYDhoMFwUDCkBIZDBsMhwZAKGA4bDIcFQ2pgOGIwHBEMaYDhqMFwVDCkBYZjBsMxwZAOGI4bDMcFQ3pgOGEwnBAMGYDhpMFwUjBkBIZTBsMpwZAJGE4bDKcFQ2ZgOGMwnBEMWYDhrMFwVjBkBYZzBsM5wZANGM4bDOcFQ3ZguGAwXBAMOYDhosFwUTDkBIZLBsMlwZALGC4bDJcFQ25guGIwXBEMeYDhqsFwVTDkBYZrBsM1wZAPGK4bDNcFQ35guGEw3BAMBYDhpsFwUzAUBIZbBsMtwVAIGG4bDLcFQ2FguGMw3BEMRYDhrsFwVzAUBYZ7BsM9wVAMGO4bDPcFQ3FgeGAwPBAMJYDhocHwUDCUBIZHBsMjwVAKGB4bDI8FQ2lgeGIwPBEMZYDhqcHwVDCUBYZnBsMzwVAOGJ4bDM8FQ3lgeGEwvBAMFYDhpcHwUjBUBIZXBsMrwVAJGF4bDK8FQ2VgeGMwvBEMVYDhrcHwVjBUBYZ3BsM7wVANGN4bDO8FQ3Vg+GAwfBAMNYDho8HwUTDUBIZPBsMnwVALGD4bDJ8FQ21g+GJh6A3BBjXUAYYwBkMYwVAXGMIaDGEFQz1gCGcwhBMM9YEhvMEQXjA0AIYIBkMEwdAQGCIaDBEFQyNgiGQwRBIMjYEhssEQWTA0AYYoBkMUwdAUGKIaDFEFQzNgiGYwRBMMzYEhusEQXTC0AIYYBkMMwdASGGIaDDEFQytgiGUwxBIMrYEhtsEQWzC0AYY4BkMcwdAWGOIaDHEFQztgiGcwxBMM7YEhvsEQXzB0AIYEBkMCwfAlMCQ0GBIKhq+AIZHBkEgwfA0MiQ2GxILhG2BIYjAkEQzfAkNSgyGpYPgOGJIZDMkEw/fAkNxgSC4YfgCGFAZDCsHwIzCkNBhSCoafgCGVwZBKMPwMDKkNhtSC4RdgSGMwpBEMvwJDWoMhrWD4DRjSGQzpBMPvwJDeYEgvGP4AhgwGQwbB8CcwZDQYMgqGv4Ahk8GQSTD8DQyZDYbMguEfYMhiMGQRDP8CQ1aDIatg+A8YshkM2QRDR2DIbjBkFwydgCGHwZBDMHQGhpwGQ07B0AUYchkMuQRDV2DIbTDkFgzdgCGPwZBHMHQHhrwGQ17B0AMY8hkM+QRDT2DIbzDkFwy9gKGAwVBAMPQGhoIGQ0HB0AcYChkMhQRDX2AobDAUFgz9gKGIwVBEMPQHhqIGQ1HBMAAYihkMxQTDQGAobjAUFwyDgKGEwVBCMAwGhpIGQ0nBMAQYShkMpQTDUGAobTCUFgzDgKGMwVBGMAwHhrIGQ1nBMAIYyhkM5QTDSGAobzCUFwyjgKGCwVBBMIwGhooGQ0XBMAYYKhkMlQTDWGCobDBUFgzjgKGKwVBFMIwHhqoGQ1XBMAEYqhkM1QTDRGCobjBUFwyTgKGGwVBDMEwGhpoGQ03BMAUYahkMtQRDABhqGwy1BcNUYKhjMNQRDNOAoa7BUFcwTAeGegZDPcEwAxjqGwz1BcNMYGhgMDQQDLOAoaHB0FAwzAaGRgZDI8EwBxgaGwyNBcNcYGhiMDQRDPOAoanB0FQwzAeGZgZDM8GwABiaGwzNBcNCYGhhMLQQDIuAoaXB0FIwLAaGVgZDK8GwBBhaGwytBcNSYGhjMLQRDMuAoa3B0FYwLAeGdgZDO8GwAhjaGwztBcNKYOhgMHQQDKuA4UuD4UvBsBoYvjIYvhIMa4Dha4Pha8GwFhi+MRi+EQzrgOFbg+FbwbAeGL4zGL4TDBuA4XuD4XvBsBEYfjAYfhAMm4DhR4PhR8GwGRh+Mhh+EgxbgOFng+FnwbAVGH4xGH4RDNuA4VeD4VfBsB0YfjMYfhMMO4Dhd4Phd8GwExj+MBj+EAy7gOFPg+FPwbAbGP4yGP4SDHuA4W+D4W/BsBcY/jEY/hEM+4DhX4PhX8GwHxj+Mxj+EwwHgKGjwdBRMBwEhk4GQyfBcAgYOhsMnQXDYWDoYjB0EQxHgKGrwdBVMBwFhm4GQzfBcAwYuhsM3QXDcWDoYTD0EAwngKGnwdBTMJwEhl4GQy/BcAoYehsMvQXDaWDoYzD0EQxngKGvwdBXMJwFhn4GQz/BcA4Y+hsM/QXDeWAYYDAMEAwXgGGgwTBQMFwEhkEGwyDBcAkYBhsMgwXDZWAYYjAMEQxXgGGowTBUMFwFhmEGwzDBcA0YhhsMwwXDdWAYYTCMEAw3gGGkwTBSMNwEhlEGwyjBcAsYRhsMowXDbWAYYzCMEQx3gGGswTBWMNwFhnEGwzjBcA8YxhsM4wXDfWCYYDBMEAwPgGGiwTBRMDwEhkkGwyTB8AgYJhsMkwXDY2CYYjBMEQxPgCFgMAQEw1NgmGowTBUMz4BhmsEwTTA8B4bpBsN0wfACGGYYDDMEw0tgmGkwzBQMr4BhlsEwSzC8BobZBsNswfAGGOYYDHMEw1tgmGswzBUM74BhnsEwTzC8B4b5BsN8wfABGBYYDAsEw0dgWGgwLBQMn4BhkcGwSDB8BobFBsNiwfBFgf/dsMRgWCIYwgDDUoNhqWAICwzLDIZlgiEcMCw3GJYLhvDAsMJgWCEYIgDDSoNhpWCICAyrDIZVgiESMKw2GFYLhsjAsMZgWCMYogDDWoNhrWCICgzrDIZ1giEaMKw3GNYLhujAsMFg2CAYYgDDRoNho2CICQybDIZNgiEWMGw2GDYLhtjAsMVg2CIY4gDDVoNhq2CICwzbDIZtgiEeMGw3GLYLhvjAsMNg2CEYEgDDToNhp2BICAy7DIZdgiERMOw2GHYLhsTAsMdg2CMYkgDDXoNhr2BICgz7DIZ9giEZMOw3GPYLhuTAcMBgOCAYUgDDQYPhoGBICQyHDIZDgiEVMBw2GA4LhtTAcMRgOCIY0gDDUYPhqGBICwzHDIZjgiEdMBw3GI4LhvTAcMJgOCEYMgDDSYPhpGDICAynDIZTgiETMJw2GE4LhszAcMZgOCMYsgDDWYPhrGDICgznDIZzgiEbMJw3GM4LhuzAcMFguCAYcgDDRYPhomDICQyXDIZLgiEXMFw2GC4LhtzAcMVguCIY8gDDVYPhqmDICwzXDIZrgiEfMFw3GK4LhvzAcMNguCEYCgDDTYPhpmAoCAy3DIZbgqEQMNw2GG4LhsLAcMdguCMYigDDXYPhrmAoCgz3DIZ7gqEYMNw3GO4LhuLA8MBgeCAYSgDDQ4PhoWAoCQyPDIZHgqEUMDw2GB4LhtLA8MRgeCIYygDDU4PhqWAoCwzPDIZngqEcMDw3GJ4LhvLA8MJgeCEYKgDDS4PhpWCoCAyvDIZXgqESMLw2GF4LhsrA8MZgeCMYqgDDW4PhrWCoCgzvDIZ3gqEaMLw3GN4LhurA8MFg+CAYagDDR4Pho2CoCQyfDIZPgqEWMHw2GD4LhtrA8MWi0BuCDWqoAwxhDIYwgqEuMIQ1GMIKhnrAEM5gCCcY6gNDeIMhvGBoAAwRDIYIgqEhMEQ0GCIKhkbAEMlgiCQYGgNDZIMhsmBoAgxRDIYogqEpMEQ1GKIKhmbAEM1giCYYmgNDdIMhumBoAQwxDIYYgqElMMQ0GGIKhlbAEMtgiCUYWgNDbIMhtmBoAwxxDIY4gqEtMMQ1GOIKhnbAEM9giCcY2gNDfIMhvmDoAAwJDIYEguFLYEhoMCQUDF8BQyKDIZFg+BoYEhsMiQXDN8CQxGBIIhi+BYakBkNSwfAdMCQzGJIJhu+BIbnBkFww/AAMKQyGFILhR2BIaTCkFAw/AUMqgyGVYPgZGFIbDKkFwy/AkMZgSCMYfgWGtAZDWsHwGzCkMxjSCYbfgSG9wZBeMPwBDBkMhgyC4U9gyGgwZBQMfwFDJoMhk2D4GxgyGwyZBcM/wJDFYMgiGP4FhqwGQ1bB8B8wZDMYsgmGjsCQ3WDILhg6AUMOgyGHYOgMDDkNhpyCoQsw5DIYcgmGrsCQ22DILRi6AUMegyGPYOgODHkNhryCoQcw5DMY8gmGnsCQ32DILxh6AUMBg6GAYOgNDAUNhoKCoQ8wFDIYCgmGvsBQ2GAoLBj6AUMRg6GIYOgPDEUNhqKCYQAwFDMYigmGgcBQ3GAoLhgGAUMJg6GEYBgMDCUNhpKCYQgwlDIYSgmGocBQ2mAoLRiGAUMZg6GMYBgODGUNhrKCYQQwlDMYygmGkcBQ3mAoLxhGAUMFg6GCYBgNDBUNhoqCYQwwVDIYKgmGscBQ2WCoLBjGAUMVg6GKYBgPDFUNhqqCYQIwVDMYqgmGicBQ3WCoLhgmAUMNg6GGYJgMDDUNhpqCYQow1DIYagmGADDUNhhqC4apwFDHYKgjGKYBQ12Doa5gmA4M9QyGeoJhBjDUNxjqC4aZwNDAYGggGGYBQ0ODoaFgmA0MjQyGRoJhDjA0NhgaC4a5wNDEYGgiGOYBQ1ODoalgmA8MzQyGZoJhATA0NxiaC4aFwNDCYGghGBYBQ0uDoaVgWAwMrQyGVoJhCTC0NhhaC4alwNDGYGgjGJYBQ1uDoa1gWA4M7QyGdoJhBTC0NxjaC4aVwNDBYOggGFYBw5cGw5eCYTUwfGUwfCUY1gDD1wbD14JhLTB8YzB8IxjWAcO3BsO3gmE9MHxnMHwnGDYAw/cGw/eCYSMw/GAw/CAYNgHDjwbDj4JhMzD8ZDD8JBi2AMPPBsPPgmErMPxiMPwiGLYBw68Gw6+CYTsw/GYw/CYYdgDD7wbD74JhJzD8YTD8IRh2AcOfBsOfgmE3MPxlMPwlGPYAw98Gw9+CYS8w/GMw/CMY9gHDvwbDv4JhPzD8ZzD8JxgOAENHg6GjYDgIDJ0Mhk6C4RAwdDYYOguGw8DQxWDoIhiOAENXg6GrYDgKDN0Mhm6C4RgwdDcYuguG48DQw2DoIRhOAENPg6GnYDgJDL0Mhl6C4RQw9DYYeguG08DQx2DoIxjOAENfg6GvYDgLDP0Mhn6C4Rww9DcY+guG88AwwGAYIBguAMNAg2GgYLgIDIMMhkGC4RIwDDYYBguGy8AwxGAYIhiuAMNQg2GoYLgKDMMMhmGC4RowDDcYhguG68AwwmAYIRhuAMNIg2GkYLgJDKMMhlGC4RYwjDYYRguG28AwxmAYIxjuAMNYg2GsYLgLDOMMhnGC4R4wjDcYxguG+8AwwWCYIBgeAMNEg2GiYHgIDJMMhkmC4REwTDYYJguGx8AwxWCYIhieAEPAYAgIhqfAMNVgmCoYngHDNINhmmB4DgzTDYbpguEFMMwwGGYIhpfAMNNgmCkYXgHDLINhlmB4DQyzDYbZguENMMwxGBbN4YYvIv7vhrkGwxxhDm/BHOaF2BAm+hdfBB3UEDb6/26Yb5jDfGEO4YBhgcGwQDCEB4aFBsNCwRABGBY5nkuCISIwLDYYFguGSMCwxGBYIhgiA8NSg2GpYIgCDMsMhmWCISowLDcYlguGaMCwwmBYIRiiA8NKg2GlYIgBDKsMhlWCISYwrDYYVguGWMCwxmBYIxhiA8Nag2GtYIgDDOsMhnWCIS4wrDcY1guGeMCwwWDYIBjiA8NGg2GjYEgADJsMhk2CISEwbDYYNguGRMCwxWDYIhgSA8NWg2GrYEgCDNsMhm2CISkwbDcYtguGZMCww2DYIRiSA8NOg2GnYEgBDLsMhl2CISUw7DYYdguGVMCwx2DYIxhSA8Neg2GvYEgDDPsMhn2CIS0w7DcY9guGdMBwwGA4IBjSA8NBg+GgYMgADIcMhkOCISMwHDYYDguGTMBwxGA4IhgyA8NRg+GoYMgCDMcMhmOCISswHDcYjguGbMBwwmA4IRiyA8NJg+GkYMgBDKcMhlOCIScwnDYYTguGXMBwxmA4IxhyA8NZg+GsYMgDDOcMhnOCIS8wnDcYzguGfMBwwWC4IBjyA8NFg+GiYCgADJcMhkuCoSAwXDYYLguGQsBwxWC4IhgKA8NVg+GqYCgCDNcMhmuCoSgwXDcYrguGYsBww2C4IRiKA8NNg+GmYCgBDLcMhluCoSQw3DYYbguGUsBwx2C4IxhKA8Ndg+GuYCgDDPcMhnuCoSww3DcY7guGcsDwwGB4IBjKA8NDg+GhYKgADI8MhkeCoSIwPDYYHguGSsDwxGB4IhgqA8NTg+GpYKgCDM8MhmeCoSowPDcYnguGasDwwmB4IRiqA8NLg+GlYKgBDK8MhleCoSYwvDYYXguGWsDwxmB4IxhqA8Nbg+GtYKgDDO8MhneCoS4wvDcY3guGesDwwWD4IBjqA8NHg+GjYGgADJ8Mhk+CoSEwfDYYPguGRsDwxeLQG4INamgMDGEMhjCCoQkwhDUYwgqGpsAQzmAIJxiaAUN4gyG8YGgODBEMhgiCoQUwRDQYIgqGlsAQyWCIJBhaAUNkgyGyYGgNDFEMhiiCoQ0wRDUYogqGtsAQzWCIJhjaAUN0gyG6YGgPDDEMhhiCoQMwxDQYYgqGL4EhlsEQSzB8BQyxDYbYguFrYIhjMMQRDN8AQ1yDIa5g+BYY4hkM8QTDd8AQ32CILxi+B4YEBkMCwfADMCQ0GBIKhh+BIZHBkEgw/AQMiQ2GxILhZ2BIYjAkEQy/AENSgyGpYPgVGJIZDMkEw2/AkNxgSC4YfgeGFAZDCsHwBzCkNBhSCoY/gSGVwZBKMPwFDKkNhtSC4W9gSGMwpBEM/wBDWoMhrWD4FxjSGQzpBMN/wJDeYEgvGDoCQwaDIYNg6AQMGQ2GjIKhMzBkMhgyCYYuwJDZYMgsGLoCQxaDIYtg6AYMWQ2GrIKhOzBkMxiyCYYewJDdYMguGHoCQw6DIYdg6AUMOQ2GnIKhNzDkMhhyCYY+wJDbYMgtGPoCQx6DIY9g6AcMeQ2GvIKhPzDkMxjyCYYBwJDfYMgvGAYCQwGDoYBgGAQMBQ2GgoJhMDAUMhgKCYYhwFDYYCgsGIYCQxGDoYhgGAYMRQ2GooJhODAUMxiKCYYRwFDcYCguGEYCQwmDoYRgGAUMJQ2GkoJhNDCUMhhKCYYxwFDaYCgtGMYCQxmDoYxgGAcMZQ2GsoJhPDCUMxjKCYYJwFDeYCgvGCYCQwWDoYJgmAQMFQ2GioJhMjBUMhgqCYYpwFDZYKgsGALAUMVgqCIYpgJDVYOhqmCYBgzVDIZqgmE6MFQ3GKoLhhnAUMNgqCEYZgJDTYOhpmCYBQy1DIZagmE2MNQ2GGoLhjnAUMdgqCMY5gJDXYOhrmCYBwz1DIZ6gmE+MNQ3GOoLhgXA0MBgaCAYFgJDQ4OhoWBYBAyNDIZGgmExMDQ2GBoLhiXA0MRgaCIYlgJDU4OhqWBYBgzNDIZmgmE5MDQ3GJoLhhXA0MJgaCEYVgJDS4OhpWBYBQytDIZWgmE1MLQ2GFoLhjXA0MZgaCMY1gJDW4OhrWBYBwztDIZ2gmE9MLQ3GNoLhg3A0MFg6CAYNgLDlwbDl4JhEzB8ZTB8JRg2A8PXBsPXgmELMHxjMHwjGLYCw7cGw7eCYRswfGcwfCcYtgPD9wbD94JhBzD8YDD8IBh2AsOPBsOPgmEXMPxkMPwkGHYDw88Gw8+CYQ8w/GIw/CIY9gLDrwbDr4JhHzD8ZjD8Jhj2A8PvBsPvguEAMPxhMPwhGA4Cw58Gw5+C4RAw/GUw/CUYDgPD3wbD34LhCDD8YzD8IxiOAsO/BsO/guEYMPxnMPwnGI4DQ0eDoaNgOAEMnQyGToLhJDB0Nhg6C4ZTwNDFYOgiGE4DQ1eDoatgOAMM3QyGboLhLDB0Nxi6C4ZzwNDDYOghGM4DQ0+DoadguAAMvQyGXoLhIjD0Nhh6C4ZLwNDHYOgjGC4DQ1+Doa9guAIM/QyGfoLhKjD0Nxj6C4ZrwDDAYBggGK4Dw0CDYaBguAEMgwyGQYLhJjAMNhgGC4ZbwDDEYBgiGG4Dw1CDYahguAMMwwyGYYLhLjAMNxiGC4Z7wDDCYBghGO4Dw0iDYaRgeAAMowyGUYLhITCMNhhGC4ZHwDDGYBgjGB4Dw1iDYaxgeAIM4wyGcYLhKTCMNxjGC4ZnwDDBYJggGJ4Dw0SDYaJgeAEMkwyGSYLhJTBMNhgmC4ZXwDDFYJgiGF4DQ8BgCAiGN8Aw1WCYKhjeAsM0g2GaYHgHDNMNhumC4T0wzDAYZgiGD8Aw02CYKRg+AsMsg2GWYPgEDLMNhtmC4TMwzDEY5giGL2L874a5BsNcwRAGGOYZDPMEQ1hgmG8wzBcM4YBhgcGwQDCEB4aFBsNCwRABGBYZDIsEQ0RgWGwwLBYMkYBhicGwRDBEBoalBsNSwRAFGJYZDMsEQ1RgWG4wLBcM0YBhhcGwQjBEB4aVBsNKwRADGFYZDKsEQ0xgWG0wrBYMsYBhjcGwRjDEBoa1BsNawRAHGNYZDOsEQ1xgWG8wrBcM8YBhg8GwQTDEB4aNBsNGwZAAGDYZDJsEQ0Jg2GwwbBYMiYBhi8GwRTAkBoatBsNWwZAEGLYZDNsEQ1Jg2G4wbBcMyYBhh8GwQzAkB4adBsNOwZACGHYZDLsEQ0pg2G0w7BYMqYBhj8GwRzCkBoa9BsNewZAGGPYZDPsEQ1pg2G8w7BcM6YDhgMFwQDCkB4aDBsNBwZABGA4ZDIcEQ0ZgOGwwHBYMmYDhiMFwRDBkBoajBsNRwZAFGI4ZDMcEQ1ZgOG4wHBcM2YDhhMFwQjBkB4aTBsNJwZADGE4ZDKcEQ05gOG0wnBYMuYDhjMFwRjDkBoazBsNZwZAHGM4ZDOcEQ15gOG8wnBcM+YDhgsFwQTDkB4aLBsNFwVAAGC4ZDJcEQ0FguGwwXBYMhYDhisFwRTAUBoarBsNVwVAEGK4ZDNcEQ1FguG4wXBcMxYDhhsFwQzAUB4abBsNNwVACGG4ZDLcEQ0lguG0w3BYMpYDhjsFwRzCUBoa7BsNdwVAGGO4ZDPcEQ1lguG8w3BcM5YDhgcHwQDCUB4aHBsNDwVABGB4ZDI8EQ0VgeGwwPBYMlYDhicHwRDBUBoanBsNTwVAFGJ4ZDM8EQ1VgeG4wPBcM1YDhhcHwQjBUB4aXBsNLwVADGF4ZDK8EQ01geG0wvBYMtYDhjcHwRjDUBoa3BsNbwVAHGN4ZDO8EQ11geG8wvBcM9YDhg8HwQTDUB4aPBsNHwdAAGD4ZDJ8EQ0Ng+GwwfBYMjYDhiyWhNwQb1NAYGMIYDGEEQxNgCGswhBUMTYEhnMEQTjA0A4bwBkN4wdAcGCIYDBEEQwtgiGgwRBQMLYEhksEQSTC0AobIBkNkwdAaGKIYDFEEQxtgiGowRBUMbYEhmsEQTTC0A4boBkN0wdAeGGIYDDEEQwdgiGkwxBQMXwJDLIMhlmD4ChhiGwyxBcPXwBDHYIgjGL4BhrgGQ1zB8C0wxDMY4gmG74AhvsEQXzB8DwwJDIYEguEHYEhoMCQUDD8CQyKDIZFg+AkYEhsMiQXDz8CQxGBIIhh+AYakBkNSwfArMCQzGJIJht+AIbnBkFww/A4MKQyGFILhD2BIaTCkFAx/AkMqgyGVYPgLGFIbDKkFw9/AkMZgSCMY/gGGtAZDWsHwLzCkMxjSCYb/gCG9wZBeMHQEhgwGQwbB0AkYMhoMGQVDZ2DIZDBkEgxdgCGzwZBZMHQFhiwGQxbB0A0YshoMWQVDd2DIZjBkEww9gCG7wZBdMPQEhhwGQw7B0AsYchoMOQVDb2DIZTDkEgx9gCG3wZBbMPQFhjwGQx7B0A8Y8hoMeQVDf2DIZzDkEwwDgCG/wZBfMAwEhgIGQwHBMAgYChoMBQXDYGAoZDAUEgxDgKGwwVBYMAwFhiIGQxHBMAwYihoMRQXDcGAoZjAUEwwjgKG4wVBcMIwEhhIGQwnBMAoYShoMJQXDaGAoZTCUEgxjgKG0wVBaMIwFhjIGQxnBMA4YyhoMZQXDeGAoZzCUEwwTgKG8wVBeMEwEhgoGQwXBMAkYKhoMFQXDZGCoZDBUEgxTgKGywVBZMASAoYrBUEUwTAWGqgZDVcEwDRiqGQzVBMN0YKhuMFQXDDOAoYbBUEMwzASGmgZDTcEwCxhqGQy1BMNsYKhtMNQWDHOAoY7BUEcwzAWGugZDXcEwDxjqGQz1BMN8YKhvMNQXDAuAoYHB0EAwLASGhgZDQ8GwCBgaGQyNBMNiYGhsMDQWDEuAoYnB0EQwLAWGpgZDU8GwDBiaGQzNBMNyYGhuMDQXDCuAoYXB0EIwrASGlgZDS8GwChhaGQytBMNqYGhtMLQWDGuAoY3B0EYwrAWGtgZDW8GwDhjaGQztBMN6YGhvMLQXDBuAoYPB0EEwbASGLw2GLwXDJmD4ymD4SjBsBoavDYavBcMWYPjGYPhGMGwFhm8Nhm8FwzZg+M5g+E4wbAeG7w2G7wXDDmD4wWD4QTDsBIYfDYYfBcMuYPjJYPhJMOwGhp8Nhp8Fwx5g+MVg+EUw7AWGXw2GXwXDPmD4zWD4TTDsB4bfDYbfBcMBYPjDYPhDMBwEhj8Nhj8FwyFg+Mtg+EswHAaGvw2GvwXDEWD4x2D4RzAcBYZ/DYZ/BcMxYPjPYPhPMBwHho4GQ0fBcAIYOhkMnQTDSWDobDB0FgyngKGLwdBFMJwGhq4GQ1fBcAYYuhkM3QTDWWDobjB0FwzngKGHwdBDMJwHhp4GQ0/BcAEYehkMvQTDRWDobTD0FgyXgKGPwdBHMFwGhr4GQ1/BcAUY+hkM/QTDVWDobzD0FwzXgGGAwTBAMFwHhoEGw0DBcAMYBhkMgwTDTWAYbDAMFgy3gGGIwTBEMNwGhqEGw1DBcAcYhhkMwwTDXWAYbjAMFwz3gGGEwTBCMNwHhpEGw0jB8AAYRhkMowTDQ2AYbTCMFgyPgGGMwTBGMDwGhrEGw1jB8AQYxhkM4wTDU2AYbzCMFwzPgGGCwTBBMDwHhokGw0TB8AIYJhkMkwTDS2CYbDBMFgyvgGGKwTBFMLwGhoDBEBAMb4BhqsEwVTC8BYZpBsM0wfAOGKYbDNMFw3tgmGEwzBAMH4BhpsEwUzB8BIZZBsMswfAJGGYbDLMFw2dgmGMwzBEMX8T83w1zDYZ1Y/9/7/t/WtfZs2xd4f6/Pv//zyvW509X/t/rmr8AOGb8314t+t+vX/Z/18/7v+vD/+/r+n/f90XC/93wPtf/vp/z/vc5h6F7T89EmP870MH9p+c6bNj/3TvfcK7nC9/NcMCwwGBYIBjCA8NCg2GhYIgADIsMhkWCISIwLDYYFguGSMCwxGBYIhgiA8NSg2GpYIgCDMsMhmWCISowLDcYlguGaMCwwmBYIRiiA8NKg2GlYIgBDKsMhlWCISYwrDYYVguGWMCwxmBYIxhiA8Nag2GtYIgDDOsc/ykFQ1xgWG8wrBcM8YBhg8GwQTDEB4aNBsNGwZAAGDYZDJsEQ0Jg2GwwbBYMiYBhi8GwRTAkBoatBsNWwZAEGLYZDNsEQ1Jg2G4wbBcMyYBhh8GwQzAkB4adBsNOwZACGHYZDLsEQ0pg2G0w7BYMqYBhj8GwRzCkBoa9BsNewZAGGPYZDPsEQ1pg2G8w7BcM6YDhgMFwQDCkB4aDBsNBwZABGA4ZDIcEQ0ZgOGwwHBYMmYDhiMFwRDBkBoajBsNRwZAFGI4ZDMcEQ1ZgOG4wHBcM2YDhhMFwQjBkB4aTBsNJwZADGE4ZDKcEQ05gOG0wnBYMuYDhjMFwRjDkBoazBsNZwZAHGM4ZDOcEQ15gOG8wnBcM+YDhgsFwQTDkB4aLBsNFwVAAGC4ZDJcEQ0FguGwwXBYMhYDhisFwRTAUBoarBsNVwVAEGK4ZDNcEQ1FguG4wXBcMxYDhhsFwQzAUB4abBsNNwVACGG4ZDLcEQ0lguG0w3BYMpYDhjsFwRzCUBoa7BsNdwVAGGO4ZDPcEQ1lguG8w3BcM5YDhgcHwQDCUB4aHBsNDwVABGB4ZDI8EQ0VgeGwwPBYMlYDhicHwRDBUBoanBsNTwVAFGJ4ZDM8EQ9Ww/7vhucHwXDBUA4YXBsMLwVAdGF4aDC8FQw1geGUwvBIMNYHhtcHwWjDUAoY3BsMbwVAbGN4aDG8FQx1geGcwvBMMdYHhvcHwXjDUA4YPBsMHwVAfGD4aDB8FQwNg+GQwfBIMDYHhs8HwWTA0AoYvlobeEGxQQ2NgCGMwhBEMTYAhrMEQVjA0BYZwBkM4wdAMGMIbDOEFQ3NgiGAwRBAMLYAhosEQUTC0BIZIBkMkwdAKGCIbDJEFQ2tgiGIwRBEMbYAhqsEQVTC0BYZoBkM0wdAOGKIbDNEFQ3tgiGEwxBAMHYAhpsEQUzB8CQyxDIZYguErYIhtMMQWDF8DQxyDIY5g+AYY4hoMcQXDt8AQz2CIJxi+A4b4BkN8wfA9MCQwGBIIhh+AIaHBkFAw/AgMiQyGRILhJ2BIbDAkFgw/A0MSgyGJYPgFGJIaDEkFw6/AkMxgSCYYfgOG5AZDcsHwOzCkMBhSCIY/gCGlwZBSMPwJDKkMhlSC4S9gSG0wpBYMfwNDGoMhjWD4BxjSGgxpBcO/wJDOYEgnGP4DhvQGQ3rB0BEYMhgMGQRDJ2DIaDBkFAydgSGTwZBJMHQBhswGQ2bB0BUYshgMWQRDN2DIajBkFQzdgSGbwZBNMPQAhuwGQ3bB0BMYchgMOQRDL2DIaTDkFAy9gSGXwZBLMPQBhtwGQ27B0BcY8hgMeQRDP2DIazDkFQz9gSGfwZBPMAwAhvwGQ37BMBAYChgMBQTDIGAoaDAUFAyDgaGQwVBIMAwBhsIGQ2HBMBQYihgMRQTDMGAoajAUFQzDgaGYwVBMMIwAhuIGQ3HBMBIYShgMJQTDKGAoaTCUFAyjgaGUwVBKMIwBhtIGQ2nBMBYYyhgMZQTDOGAoazCUFQzjgaGcwVBOMEwAhvIGQ3nBMBEYKhgMFQTDJGCoaDBUFAyTgaGSwVBJMEwBhsoGQ2XBEACGKgZDFcEwFRiqGgxVBcM0YKhmMFQTDNOBobrBUF0wzACGGgZDDcEwExhqGgw1BcMsYKhlMNQSDLOBobbBUFswzAGGOgZDHcEwFxjqGgx1BcM8YKhnMNQTDPOBob7BUF8wLACGBgZDA8GwEBgaGgwNBcMiYGhkMDQSDIuBobHB0FgwLAGGJgZDE8GwFBiaGgxNBcMyYGhmMDQTDMuBobnB0FwwrACGFgZDC8GwEhhaGgwtBcMqYGhlMLQSDKuBobXB0FowrAGGNgZDG8GwFhjaGgxtBcM6YGhnMLQTDOuBob3B0F4wbACGDgZDB8GwERi+NBi+FAybgOErg+ErwbAZGL42GL4WDFuA4RuD4RvBsBUYvjUYvhUM24DhO4PhO8GwHRi+Nxi+Fww7gOEHg+EHwbATGH40GH4UDLuA4SeD4SfBsBsYfjYYfhYMe4DhF4PhF8GwFxh+NRh+FQz7gOE3g+E3wbAfGH43GH4XDAeA4Q+D4Q/BcBAY/jQY/hQMh4DhL4PhL8FwGBj+Nhj+FgxHgOEfg+EfwXAUGP41GP4VDMeA4T+D4T/BcBwYOhoMHQXDCWDoZDB0EgwngaGzwdBZMJwChi4GQxfBcBoYuhoMXQXDGWDoZjB0EwxngaG7wdBdMJwDhh4GQw/BcB4YehoMPQXDBWDoZTD0EgwXgaG3wdBbMFwChj4GQx/BcBkY+hoMfQXDFWDoZzD0EwxXgaG/wdBfMFwDhgEGwwDBcB0YBhoMAwXDDWAYZDAMEgw3gWGwwTBYMNwChiEGwxDBcBsYhhoMQwXDHWAYZjAMEwx3gWG4wTBcMNwDhhEGwwjBcB8YRhoMIwXDA2AYZTCMEgwPgWG0wTBaMDwChjEGwxjB8BgYxhoMYwXDE2AYZzCMEwxPgWG8wTBeMDwDhgkGwwTB8BwYJhoMEwXDC2CYZDBMEgwvgWGywTBZMLwChikGwxTB8BoYAgZDQDC8AYapBsNUwfAWGKYZDNMEwztgmG4wTBcM74FhhsEwQzB8AIaZBsNMwfARGGYZDLMEwydgmG0wzBYMn4FhjsEwRzB8Ee5/N8w1GOYKhjDAMM9gmCcYwgLDfINhvmAIBwwLDIYFgiE8MCw0GBYKhgjAsMhgWCQYIgLDYoNhsWCIBAxLDIYlgiEyMCw1GJYKhijAsMxgWCYYogLDcoNhuWCIBgwrDIYVgiE6MKw0GFYKhhjAsMpgWCUYYgLDaoNhtWCIBQxrDIY1giE2MKw1GNYKhjjAsM5gWCcY4gLDeoNhvWCIBwwbDIYNgiE+MGw0GDYKhgTAsMlg2CQYEgLDZoNhs2BIBAxbDIYtgiExMGw1GLYKhiTAsM1g2CYYkgLDdoNhu2BIBgw7DIYdgiE5MOw0GHYKhhTAsMtg2CUYUgLDboNht2BIBQx7DIY9giE1MOw1GPYKhjTAsM9g2CcY0gLDfoNhv2BIBwwHDIYDgiE9MBw0GA4KhgzAcMhgOCQYMgLDYYPhsGDIBAxHDIYjgiEzMBw1GI4KhizAcMxgOCYYsgLDcYPhuGDIBgwnDIYTgiE7MJw0GE4KhhzAcMpgOCUYcgLDaYPhtGDIBQxnDIYzgiE3MJw1GM4KhjzAcM5gOCcY8gLDeYPhvGDIBwwXDIYLgiE/MFw0GC4KhgLAcMlguCQYCgLDZYPhsmAoBAxXDIYrgqEwMFw1GK4KhiLAcM1guCYYigLDdYPhumAoBgw3DIYbgqE4MNw0GG4KhhLAcMtguCUYSgLDbYPhtmAoBQx3DIY7gqE0MNw1GO4KhjLAcM9guCcYygLDfYPhvmAoBwwPDIYHgqE8MDw0GB4KhgrA8MhgeCQYKgLDY4PhsWCoBAxPDIYngqEyMDw1GJ4KhirA8MxgeCYYqgLDc4PhuWCoBgwvDIYXgqE6MLw0GF4KhhrA8MpgeCUYagLDa4PhtWCoBQxvDIY3gqE2MLw1GN4KhjrA8M5geCcY6gLDe4PhvWCoBwwfDIYPgqE+MHw0GD4KhgbA8Mlg+CQYGgLDZ4Phs2BoBAxfLAu9IdighsbAEMZgCCMYmgBDWIMhrGBoCgzhDIZwgqEZMIQ3GMILhubAEMFgiCAYWgBDRIMhomBoCQyRDIZIgqEVMEQ2GCILhtbAEMVgiCIY2gBDVIMhqmBoCwzRDIZogqEdMEQ3GKILhvbAEMNgiCEYOgBDTIMhpmD4EhhiGQyxBMNXwBDbYIgtGL4GhjgGQxzB8A0wxDUY4gqGb4EhnsEQTzB8BwzxDYb4guF7YEhgMCQQDD8AQ0KDIaFg+BEYEhkMiQTDT8CQ2GBILBh+BoYkBkMSwfALMCQ1GJIKhl+BIZnBkEww/AYMyQ2G5ILhd2BIYTCkEAx/AENKgyGlYPgTGFIZDKkEw1/AkNpgSC0Y/gaGNAZDGsHwDzCkNRjSCoZ/gSGdwZBOMPwHDOkNhvSCoSMwZDAYMgiGTsCQ0WDIKBg6A0MmgyGTYOgCDJkNhsyCoSswZDEYsgiGbsCQ1WDIKhi6A0M2gyGbYOgBDNkNhuyCoScw5DAYcgiGXsCQ02DIKRh6A0MugyGXYOgDDLkNhtyCoS8w5DEY8giGfsCQ12DIKxj6A0M+gyGfYBgADPkNhvyCYSAwFDAYCgiGQcBQ0GAoKBgGA0Mhg6GQYBgCDIUNhsKCYSgwFDEYigiGYcBQ1GAoKhiGA0Mxg6GYYBgBDMUNhuKCYSQwlDAYSgiGUcBQ0mAoKRhGA0Mpg6GUYBgDDKUNhtKCYSwwlDEYygiGccBQ1mAoKxjGA0M5g6GcYJgADOUNhvKCYSIwVDAYKgiGScBQ0WCoKBgmA0Mlg6GSYJgCDJUNhsqCIQAMVQyGKoJhKjBUNRiqCoZpwFDNYKgmGKYDQ3WDobpgmAEMNQyGGoJhJjDUNBhqCoZZwFDLYKglGGYDQ22DobZgmAMMdQyGOoJhLjDUNRjqCoZ5wFDPYKgnGOYDQ32Dob5gWAAMDQyGBoJhITA0NBgaCoZFwNDIYGgkGBYDQ2ODobFgWAIMTQyGJoJhKTA0NRiaCoZlwNDMYGgmGJYDQ3ODoblgWAEMLQyGFoJhJTC0NBhaCoZVwNDKYGglGFYDQ2uDobVgWAMMbQyGNoJhLTC0NRjaCoZ1wNDOYGgnGNYDQ3uDob1g2AAMHQyGDoJhIzD8v3irByW6sjWKwh3btu2kk7Ttjm3btm2bHdv2iW3btp3cOm9wx6w68wlGfTX/tXcdg6GOYNgMDHUNhrqCYQsw1DMY6gmGADDUNxjqC4atwNDAYGggGLYBQ0ODoaFg2A4MjQyGRoJhBzA0NhgaC4adwNDEYGgiGHYBQ1ODoalg2A0MzQyGZoJhDzA0NxiaC4a9wNDCYGghGPYBQ0uDoaVg2A8MrQyGVoLhADC0NhhaC4aDwNDGYGgjGA4BQ1uDoa1gOAwM7QyGdoLhCDC0NxjaC4ajwNDBYOggGI4BQ0eDoaNgOA4MnQyGToLhBDB0Nhg6C4aTwNDFYOgiGE4BQ1eDoatgOA0M3QyGboLhDDB0Nxi6C4azwNDDYOghGM4BQ0+DoadgOA8MvQyGXoLhAjD0Nhh6C4aLwNDHYOgjGC4BQ1+Doa9guAwM/QyGfoLhCjD0Nxj6C4arwDDAYBggGK4Bw0CDYaBguA4MgwyGQYLhBjAMNhgGC4abwDDEYBgiGG4Bw1CDYahguA0MwwyGYYLhDjAMNxiGC4a7wDDCYBghGO4Bw0iDYaRguA8MowyGUYLhATCMNhhGC4aHwDDGYBgjGB4Bw1iDYaxgeAwM4wyGcYLhCTCMNxjGC4anwDDBYJggGJ4Bw0SDYaJgeA4MkwyGSYLhBTBMNhgmC4aXwDDFYJgiGF4Bw1SDYapgeA0M/xkM/wmGN8AwzWCYJhjeAsN0g2G6YHgHDDMMhhmC4T0wzDQYZgqGD8Awy2CYJRg+AsNsg2G2YPgEDHMMhjmC4TMwzA2x4Yv0X3wRdFBDmPT/v2GeYYd5wg5hgWG+wTBfMIQDhgUGwwLBEB4YFhoMCwVDBGBYZDAsEgwRgWGxwbBYMEQChiUGwxLBEBkYlhoMSwVDFGBYZjAsEwxRgWG5wbBcMEQDhhUGwwrBEB0YVhoMKwVDDGBYZTCsEgwxgWG1wbBaMMQChjUGwxrBEBsY1hoMawVDHGBYZzCsEwxxgWG9wbBeMMQDhg0GwwbBEB8YNhoMGwVDAmDYZDBsEgwJgWGzwbBZMCQChi0GwxbBkBgYAgZDQDAkAYatBsNWwZAUGLYZDNsEQzJg2G4wbBcMyYFhh8GwQzCkAIadBsNOwZASGHYZDLsEQypg2G0w7BYMqYFhj8GwRzCkAYa9BsNewZAWGPYZDPsEQzpg2G8w7BcM6YHhgMFwQDBkAIaDBsNBwZARGA4ZDIcEQyZgOGwwHBYMmYHhiMFwRDBkAYajBsNRwZAVGI4ZDMcEQzZgOG4wHBcM2YHhhMFwQjDkAIaTBsNJwZATGE4ZDKcEQy5gOG0wnBYMuYHhjMFwRjDkAYazBsNZwZAXGM4ZDOcEQz5gOG8wnBcMXwLDBYPhgmDIDwwXDYaLgqEAMFwyGC4JhoLAcNlguCwYvgKGKwbDFcHwNTBcNRiuCoZvgOGawXBNMHwLDNcNhuuC4TtguGEw3BAM3wPDTYPhpmD4ARhuGQy3BMOPwHDbYLgtGH4ChjsGwx3B8DMw3DUY7gqGX4DhnsFwTzD8Cgz3DYb7guE3YHhgMDwQDL8Dw0OD4aFg+AMYHhkMjwTDn8Dw2GB4LBj+AoYnBsMTwfA3MDw1GJ4Khn+A4ZnB8Eww/AsMzw2G54KhEDC8MBheCIbCwPDSYHgpGIoAwyuD4ZVgKAoMrw2G14KhGDC8MRjeCIbiwPDWYHgrGEoAwzuD4Z1gKAkM7w2G94KhFDB8MBg+CIbSwPDRYPgoGMoAwyeD4ZNgKAsMnw2Gz4KhHDB8sSL0hmCDGsoDQxiDIYxgqAAMYQ2GsIKhIjCEMxjCCYZKwBDeYAgvGCoDQwSDIYJgqAIMEQ2GiIKhKjBEMhgiCYZqwBDZYIgsGKoDQxSDIYpgqAEMUQ2GqIKhJjBEMxiiCYZawBDdYIguGGoDQwyDIYZgqAMMMQ2GmIKhLjDEMhhiCYZ6wBDbYIgtGOoDQxyDIY5gaAAMcQ2GuIKhITDEMxjiCYZGwBDfYIgvGBoDQwKDIYFgaAIMCQ2GhIKhKTAkMhgSCYZmwJDYYEgsGJoDQxKDIYlgaAEMSQ2GpIKhJTAkMxiSCYZWwJDcYEguGFoDQwqDIYVgaAMMKQ2GlIKhLTCkMhhSCYZ2wJDaYEgtGNoDQxqDIY1g6AAMaQ2GtIKhIzCkMxjSCYZOwJDeYEgvGDoDQwaDIYNg6AIMGQ2GjIKhKzBkMhgyCYZuwJDZYMgsGLoDQxaDIYtg6AEMWQ2GrIKhJzBkMxiyCYZewJDdYMguGHoDQw6DIYdg6AMMOQ2GnIKhLzDkMhhyCYZ+wJDbYMgtGPoDQx6DIY9gGAAMeQ2GvIJhIDDkMxjyCYZBwPClwfClYBgMDPkNhvyCYQgwFDAYCgiGocBQ0GAoKBiGAcNXBsNXgmE4MHxtMHwtGEYAwzcGwzeCYSQwfGswfCsYRgHDdwbDd4JhNDB8bzB8LxjGAMMPBsMPgmEsMPxoMPwoGMYBw08Gw0+CYTww/Gww/CwYJgDDLwbDL4JhIjD8ajD8KhgmAcNvBsNvgmEyMPxuMPwuGKYAwx8Gwx+CYSow/Gkw/CkY/gOGvwyGvwTDNGD422D4WzBMB4Z/DIZ/BMMMYPjXYPhXMMwEhkIGQyHBMAsYChsMhQXDbGAoYjAUEQxzgKGowVBUMMwFhmIGQzHBMA8YihsMxQXDfGAoYTCUEAwLgKGkwVBSMCwEhlIGQynBsAgYShsMpQXDYmAoYzCUEQxLgKGswVBWMCwFhnIGQznBsAwYyhsM5QXDcmCoYDBUEAwrgKGiwVBRMKwEhkoGQyXBsAoYKhsMlQXDamCoYjBUEQxrgKGqwVBVMKwFhmoGQzXBsA4YqhsM1QXDemCoYTDUEAwbgKGmwVBTMGwEhloGQy3BsAkYahsMtQXDZmCoYzDUEQxbgKGuwVBXMASAoZ7BUE8wbAWG+gZDfcGwDRgaGAwNBMN2YGhoMDQUDDuAoZHB0Egw7ASGxgZDY8GwCxiaGAxNBMNuYGhqMDQVDHuAoZnB0Eww7AWG5gZDc8GwDxhaGAwtBMN+YGhpMLQUDAeAoZXB0EowHASG1gZDa8FwCBjaGAxtBMNhYGhrMLQVDEeAoZ3B0E4wHAWG9gZDe8FwDBg6GAwdBMNxYOhoMHQUDCeAoZPB0EkwnASGzgZDZ8FwChi6GAxdBMNpYOhqMHQVDGeAoZvB0E0wnAWG7gZDd8FwDhh6GAw9BMN5YOhpMPQUDBeAoZfB0EswXASG3gZDb8FwCRj6GAx9BMNlYOhrMPQVDFeAoZ/B0E8wXAWG/gZDf8FwDRgGGAwDBMN1YBhoMAwUDDeAYZDBMEgw3ASGwQbDYMFwCxiGGAxDBMNtYBhqMAwVDHeAYZjBMEww3AWG4QbDcMFwDxhGGAwjBMN9YBhpMIwUDA+AYZTBMEowPASG0QbDaMHwCBjGGAxjBMNjYBhrMIwVDE+AYZzBME4wPAWG8QbDeMHwDBgmGAwTBMNzYJhoMEwUDC+AYZLBMEkwvASGyQbDZMHwChimGAxTBMNrYJhqMEwVDG+A4T+D4T/B8BYYphkM0wTDO2CYbjBMFwzvgWGGwTBDMHwAhpkGw0zB8BEYZhkMswTDJ2CYbTDMFgyfgWGOwTBHMHyR4f83zDUY5gqGMMAwz2CYJxjCAsN8g2G+YAgHDAsMhgWCITwwLDQYFgqGCMCwyGBYJBgiAsNig2GxYIgEDEsMhiWCITIwLDUYlgqGKMCwzGBYJhiiAsNyg2G5YIgGDCsMhhWCITowrDQYVgqGGMCwymBYJRhiAsNqg2G1YIgFDGsMhjWCITYwrDUY1gqGOMCwzmBYJxjiAsN6g2G9YIgHDBsMhg2CIT4wbDQYNgqGBMCwyWDYJBgSAsNmg2GzYEgEDFsMhi2CITEwBAyGgGBIAgxbDYatgiEpMGwzGLYJhmTAsN1g2C4YkgPDDoNhh2BIAQw7DYadgiElMOwyGHYJhlTAsNtg2C0YUgPDHoNhj2BIAwx7DYa9giEtMOwzGPYJhnTAsN9g2C8Y0gPDAYPhgGDIAAwHDYaDgiEjMBwyGA4JhkzAcNhgOCwYMgPDEYPhiGDIAgxHDYajgiErMBwzGI4JhmzAcNxgOC4YsgPDCYPhhGDIAQwnDYaTgiEnMJwyGE4JhlzAcNpgOC0YcgPDGYPhjGDIAwxnDYazgiEvMJwzGM4JhnzAcN5gOC8YvgSGCwbDBcGQHxguGgwXBUMBYLhkMFwSDAWB4bLBcFkwfAUMVwyGK4Lha2C4ajBcFQzfAMM1g+GaYPgWGK4bDNcFw3fAcMNguCEYvgeGmwbDTcHwAzDcMhhuCYYfgeG2wXBbMPwEDHcMhjuC4WdguGsw3BUMvwDDPYPhnmD4FRjuGwz3BcNvwPDAYHggGH4HhocGw0PB8AcwPDIYHgmGP4HhscHwWDD8BQxPDIYnguFvYHhqMDwVDP8AwzOD4Zlg+BcYnhsMzwVDIWB4YTC8EAyFgeGlwfBSMBQBhlcGwyvBUBQYXhsMrwVDMWB4YzC8EQzFgeGtwfBWMJQAhncGwzvBUBIY3hsM7wVDKWD4YDB8EAylgeGjwfBRMJQBhk8GwyfBUBYYPhsMnwVDOWD4YmXoDcEGNZQHhjAGQxjBUAEYwhoMYQVDRWAIZzCEEwyVgCG8wRBeMFQGhggGQwTBUAUYIhoMEQVDVWCIZDBEEgzVgCGywRBZMFQHhigGQxTBUAMYohoMUQVDTWCIZjBEEwy1gCG6wRBdMNQGhhgGQwzBUAcYYhoMMQVDXWCIZTDEEgz1gCG2wRBbMNQHhjgGQxzB0AAY4hoMcQVDQ2CIZzDEEwyNgCG+wRBfMDQGhgQGQwLB0AQYEhoMCQVDU2BIZDAkEgzNgCGxwZBYMDQHhiQGQxLB0AIYkhoMSQVDS2BIZjAkEwytgCG5wZBcMLQGhhQGQwrB0AYYUhoMKQVDW2BIZTCkEgztgCG1wZBaMLQHhjQGQxrB0AEY0hoMaQVDR2BIZzCkEwydgCG9wZBeMHQGhgwGQwbB0AUYMhoMGQVDV2DIZDBkEgzdgCGzwZBZMHQHhiwGQxbB0AMYshoMWQVDT2DIZjBkEwy9gCG7wZBdMPQGhhwGQw7B0AcYchoMOQVDX2DIZTDkEgz9gCG3wZBbMPQHhjwGQx7BMAAY8hoMeQXDQGDIZzDkEwyDgOFLg+FLwTAYGPIbDPkFwxBgKGAwFBAMQ4GhoMFQUDAMA4avDIavBMNwYPjaYPhaMIwAhm8Mhm8Ew0hg+NZg+FYwjAKG7wyG7wTDaGD43mD4XjCMAYYfDIYfBMNYYPjRYPhRMIwDhp8Mhp8Ew3hg+Nlg+FkwTACGXwyGXwTDRGD41WD4VTBMAobfDIbfBMNkYPjdYPhdMEwBhj8Mhj8Ew1Rg+NNg+FMw/AcMfxkMfwmGacDwt8Hwt2CYDgz/GAz/CIYZwPCvwfCvYJgJDIUMhkKCYRYwFDYYCguG2cBQxGAoIhjmAENRg6GoYJgLDMUMhmKCYR4wFDcYiguG+cBQwmAoIRgWAENJg6GkYFgIDKUMhlKCYREwlDYYSguGxcBQxmAoIxiWAENZg6GsYFgKDOUMhnKCYRkwlDcYyguG5cBQwWCoIBhWAENFg6GiYFgJDJUMhkqCYRUwVDYYKguG1cBQxWCoIhjWAENVg6GqYFgLDNUMhmqCYR0wVDcYqguG9cBQw2CoIRg2AENNg6GmYNgIDLUMhlqCYRMw1DYYaguGzcBQx2CoIxi2AENdg6GuYAgAQz2DoZ5g2AoM9Q2G+oJhGzA0MBgaCIbtwNDQYGgoGHYAQyODoZFg2AkMjQ2GxoJhFzA0MRiaCIbdwNDUYGgqGPYAQzODoZlg2AsMzQ2G5oJhHzC0MBhaCIb9wNDSYGgpGA4AQyuDoZVgOAgMrQ2G1oLhEDC0MRjaCIbDwNDWYGgrGI4AQzuDoZ1gOAoM7Q2G9oLhGDB0MBg6CIbjwNDRYOgoGE4AQyeDoZNgOAkMnQ2GzoLhFDB0MRi6CIbTwNDVYOgqGM4AQzeDoZtgOAsM3Q2G7oLhHDD0MBh6CIbzwNDTYOgpGC4AQy+DoZdguAgMvQ2G3oLhEjD0MRj6CIbLwNDXYOgrGK4AQz+DoZ9guAoM/Q2G/oLhGjAMMBgGCIbrwDDQYBgoGG4AwyCDYZBguAkMgw2GwYLhFjAMMRiGCIbbwDDUYBgqGO4AwzCDYZhguAsMww2G4YLhHjCMMBhGCIb7wDDSYBgpGB4AwyiDYZRgeAgMow2G0YLhETCMMRjGCIbHwDDWYBgrGJ4AwziDYZxgeAoM4w2G8YLhGTBMMBgmCIbnwDDRYJgoGF4AwySDYZJgeAkMkw2GyYLhFTBMMRimCIbXwDDVYJgqGN4Aw38Gw3+C4S0wTDMYpgmGd8Aw3WCYLhjeA8MMg2GGYPgADDMNhpmC4SMwzDIYZgmGT8Aw22CYLRg+A8Mcg2GOYPgi4/9vmGswzBUMYYBhnsEwTzCEBYb5BsN8wRAOGBYYDAsEQ3hgWGgwLBQMEYBhkcGwSDBEBIbFBsNiwRAJGJYYDEsEQ2RgWGowLBUMUYBhmcGwTDBEBYblBsNywRANGFYYDCsEQ3RgWGkwrBQMMYBhlcGwSjDEBIbVBsNqwRALGNYYDGsEQ2xgWGswrBUMcYBhncGwTjDEBYb1BsN6wRAPGDYYDBsEQ3xg2GgwbBQMCYBhk8GwSTAkBIbNBsNmwZAIGLYYDFsEQ2JgCBgMAcGQBBi2GgxbBUNSYNhmMGwTDMmAYbvBsF0wJAeGHQbDDsGQAhh2Ggw7BUNKYNhlMOwSDKmAYbfBsFswpAaGPQbDHsGQBhj2Ggx7BUNaYNhnMOwTDOmAYb/BsF8wpAeGAwbDAcGQARgOGgwHBUNGYDhkMBwSDJmA4bDBcFgwZAaGIwbDEcGQBRiOGgxHBUNWYDhmMBwTDNmA4bjBcFwwZAeGEwbDCcGQAxhOGgwnBUNOYDhlMJwSDLmA4bTBcFow5AaGMwbDGcGQBxjOGgxnBUNeYDhnMJwTDPmA4bzBcF4wfAkMFwyGC4IhPzBcNBguCoYCwHDJYLgkGAoCw2WD4bJg+AoYrhgMVwTD18Bw1WC4Khi+AYZrBsM1wfAtMFw3GK4Lhu+A4YbBcEMwfA8MNw2Gm4LhB2C4ZTDcEgw/AsNtg+G2YPgJGO4YDHcEw8/AcNdguCsYfgGGewbDPcHwKzDcNxjuC4bfgOGBwfBAMPwODA8NhoeC4Q9geGQwPBIMfwLDY4PhsWD4CxieGAxPBMPfwPDUYHgqGP4BhmcGwzPB8C8wPDcYnguGQsDwwmB4IRgKA8NLg+GlYCgCDK8MhleCoSgwvDYYXguGYsDwxmB4IxiKA8Nbg+GtYCgBDO8MhneCoSQwvDcY3guGUsDwwWD4IBhKA8NHg+GjYCgDDJ8Mhk+CoSwwfDYYPguGcsDwxarQG4INaigPDGEMhjCCoQIwhDUYwgqGisAQzmAIJxgqAUN4gyG8YKgMDBEMhgiCoQowRDQYIgqGqsAQyWCIJBiqAUNkgyGyYKgODFEMhiiCoQYwRDUYogqGmsAQzWCIJhhqAUN0gyG6YKgNDDEMhhiCoQ4wxDQYYgqGusAQy2CIJRjqAUNsgyG2YKgPDHEMhjiCoQEwxDUY4gqGhsAQz2CIJxgaAUN8gyG+YGgMDAkMhgSCoQkwJDQYEgqGpsCQyGBIJBiaAUNigyGxYGgODEkMhiSCoQUwJDUYkgqGlsCQzGBIJhhaAUNygyG5YGgNDCkMhhSCoQ0wpDQYUgqGtsCQymBIJRjaAUNqgyG1YGgPDGkMhjSCoQMwpDUY0gqGjsCQzmBIJxg6AUN6gyG9YOgMDBkMhgyCoQswZDQYMgqGrsCQyWDIJBi6AUNmgyGzYOgODFkMhiyCoQcwZDUYsgqGnsCQzWDIJhh6AUN2gyG7YOgNDDkMhhyCoQ8w5DQYcgqGvsCQy2DIJRj6AUNugyG3YOgPDHkMhjyCYQAw5DUY8gqGgcCQz2DIJxgGAcOXBsOXgmEwMOQ3GPILhiHAUMBgKCAYhgJDQYOhoGAYBgxfGQxfCYbhwPC1wfC1YBgBDN8YDN8IhpHA8K3B8K1gGAUM3xkM3wmG0cDwvcHwvWAYAww/GAw/CIaxwPCjwfCjYBgHDD8ZDD8JhvHA8LPB8LNgmAAMvxgMvwiGicDwq8Hwq2CYBAy/GQy/CYbJwPC7wfC7YJgCDH8YDH8IhqnA8KfB8Kdg+A8Y/jIY/hIM04Dhb4Phb8EwHRj+MRj+EQwzgOFfg+FfwTATGAoZDIUEwyxgKGwwFBYMs4GhiMFQRDDMAYaiBkNRwTAXGIoZDMUEwzxgKG4wFBcM84GhhMFQQjAsAIaSBkNJwbAQGEoZDKUEwyJgKG0wlBYMi4GhjMFQRjAsAYayBkNZwbAUGMoZDOUEwzJgKG8wlBcMy4GhgsFQQTCsAIaKBkNFwbASGCoZDJUEwypgqGwwVBYMq4GhisFQRTCsAYaqBkNVwbAWGKoZDNUEwzpgqG4wVBcM64GhhsFQQzBsAIaaBkNNwbARGGoZDLUEwyZgqG0w1BYMm4GhjsFQRzBsAYa6BkNdwRAAhnoGQz3BsBUY6hsM9QXDNmBoYDA0EAzbgaGhwdBQMOwAhkYGQyPBsBMYGhsMjQXDLmBoYjA0EQy7gaGpwdBUMOwBhmYGQzPBsBcYmhsMzQXDPmBoYTC0EAz7gaGlwdBSMBwAhlYGQyvBcBAYWhsMrQXDIWBoYzC0EQyHgaGtwdBWMBwBhnYGQzvBcBQY2hsM7QXDMWDoYDB0EAzHgaGjwdBRMJwAhk4GQyfBcBIYOhsMnQXDKWDoYjB0EQyngaGrwdBVMJwBhm4GQzfBcBYYuhsM3QXDOWDoYTD0EAzngaGnwdBTMFwAhl4GQy/BcBEYehsMvQXDJWDoYzD0EQyXgaGvwdBXMFwBhn4GQz/BcBUY+hsM/QXDNWAYYDAMEAzXgWGgwTBQMNwAhkEGwyDBcBMYBhsMgwXDLWAYYjAMEQy3gWGowTBUMNwBhmEGwzDBcBcYhhsMwwXDPWAYYTCMEAz3gWGkwTBSMDwAhlEGwyjB8BAYRhsMowXDI2AYYzCMEQyPgWGswTBWMDwBhnEGwzjB8BQYxhsM4wXDM2CYYDBMEAzPgWGiwTBRMLwAhkkGwyTB8BIYJhsMkwXDK2CYYjBMEQyvgWGqwTBVMLwBhv8Mhv8Ew1tgmGYwTBMM74BhusEwXTC8B4YZBsMMwfABGGYaDDMFw0dgmGUwzBIMn4BhtsEwWzB8BoY5BsMcwfBFpv/fMNdgmCsYwgDDPINhnmAICwzzDYb5giEcMCwwGBYIhvDAsNBgWCgYIgDDIoNhkWCICAyLDYbFgiESMCwxGJYIhsjAsNRgWCoYogDDMoNhmWCICgzLDYblgiEaMKwwGFYIhujAsNJgWCkYYgDDKoNhlWCICQyrDYbVgiEWMKwxGNYIhtjAsNZgWCsY4gDDOoNhnWCICwzrDYb1giEeMGwwGDYIhvjAsNFg2CgYEgDDJoNhk2BICAybDYbNgiERMGwxGLYIhsTAEDAYAoIhCTBsNRi2CoakwLDNYNgmGJIBw3aDYbtgSA4MOwyGHYIhBTDsNBh2CoaUwLDLYNglGFIBw26DYbdgSA0MewyGPYIhDTDsNRj2Coa0wLDPYNgnGNIBw36DYb9gSA8MBwyGA4IhAzAcNBgOCoaMwHDIYDgkGDIBw2GD4bBgyAwMRwyGI4IhCzAcNRiOCoaswHDMYDgmGLIBw3GD4bhgyA4MJwyGE4IhBzCcNBhOCoacwHDKYDglGHIBw2mD4bRgyA0MZwyGM4IhDzCcNRjOCoa8wHDOYDgnGPIBw3mD4bxg+BIYLhgMFwRDfmC4aDBcFAwFgOGSwXBJMBQEhssGw2XB8BUwXDEYrgiGr4HhqsFwVTB8AwzXDIZrguFbYLhuMFwXDN8Bww2D4YZg+B4YbhoMNwXDD8Bwy2C4JRh+BIbbBsNtwfATMNwxGO4Ihp+B4a7BcFcw/AIM9wyGe4LhV2C4bzDcFwy/AcMDg+GBYPgdGB4aDA8Fwx/A8MhgeCQY/gSGxwbDY8HwFzA8MRieCIa/geGpwfBUMPwDDM8MhmeC4V9geG4wPBcMhYDhhcHwQjAUBoaXBsNLwVAEGF4ZDK8EQ1FgeG0wvBYMxYDhjcHwRjAUB4a3BsNbwVACGN4ZDO8EQ0lgeG8wvBcMpYDhg8HwQTCUBoaPBsNHwVAGGD4ZDJ8EQ1lg+GwwfBYM5YDhi9WhNwQb1FAeGMIYDGEEQwVgCGswhBUMFYEhnMEQTjBUAobwBkN4wVAZGCIYDBEEQxVgiGgwRBQMVYEhksEQSTBUA4bIBkNkwVAdGKIYDFEEQw1giGowRBUMNYEhmsEQTTDUAoboBkN0wVAbGGIYDDEEQx1giGkwxBQMdYEhlsEQSzDUA4bYBkNswVAfGOIYDHEEQwNgiGswxBUMDYEhnsEQTzA0Aob4BkN8wdAYGBIYDAkEQxNgSGgwJBQMTYEhkcGQSDA0A4bEBkNiwdAcGJIYDEkEQwtgSGowJBUMLYEhmcGQTDC0AobkBkNywdAaGFIYDCkEQxtgSGkwpBQMbYEhlcGQSjC0A4bUBkNqwdAeGNIYDGkEQwdgSGswpBUMHYEhncGQTjB0Aob0BkN6wdAZGDIYDBkEQxdgyGgwZBQMXYEhk8GQSTB0A4bMBkNmwdAdGLIYDFkEQw9gyGowZBUMPYEhm8GQTTD0AobsBkN2wdAbGHIYDDkEQx9gyGkw5BQMfYEhl8GQSzD0A4bcBkNuwdAfGPIYDHkEwwBgyGsw5BUMA4Ehn8GQTzAMAoYvDYYvBcNgYMhvMOQXDEOAoYDBUEAwDAWGggZDQcEwDBi+Mhi+EgzDgeFrg+FrwTACGL4xGL4RDCOB4VuD4VvBMAoYvjMYvhMMo4Hhe4Phe8EwBhh+MBh+EAxjgeFHg+FHwTAOGH4yGH4SDOOB4WeD4WfBMAEYfjEYfhEME4HhV4PhV8EwCRh+Mxh+EwyTgeF3g+F3wTAFGP4wGP4QDFOB4U+D4U/B8B8w/GUw/CUYpgHD3wbD34JhOjD8YzD8IxhmAMO/BsO/gmEmMBQyGAoJhlnAUNhgKCwYZgNDEYOhiGCYAwxFDYaigmEuMBQzGIoJhnnAUNxgKC4Y5gNDCYOhhGBYAAwlDYaSgmEhMJQyGEoJhkXAUNpgKC0YFgNDGYOhjGBYAgxlDYaygmEpMJQzGMoJhmXAUN5gKC8YlgNDBYOhgmBYAQwVDYaKgmElMFQyGCoJhlXAUNlgqCwYVgNDFYOhimBYAwxVDYaqgmEtMFQzGKoJhnXAUN1gqC4Y1gNDDYOhhmDYAAw1DYaagmEjMNQyGGoJhk3AUNtgqC0YNgNDHYOhjmDYAgx1DYa6giEADPUMhnqCYSsw1DcY6guGbcDQwGBoIBi2A0NDg6GhYNgBDI0MhkaCYScwNDYYGguGXcDQxGBoIhh2A0NTg6GpYNgDDM0MhmaCYS8wNDcYmguGfcDQwmBoIRj2A0NLg6GlYDgADK0MhlaC4SAwtDYYWguGQ8DQxmBoIxgOA0Nbg6GtYDgCDO0MhnaC4SgwtDcY2guGY8DQwWDoIBiOA0NHg6GjYDgBDJ0Mhk6C4SQwdDYYOguGU8DQxWDoIhhOA0NXg6GrYDgDDN0Mhm6C4SwwdDcYuguGc8DQw2DoIRjOA0NPg6GnYLgADL0Mhl6C4SIw9DYYeguGS8DQx2DoIxguA0Nfg6GvYLgCDP0Mhn6C4Sow9DcY+guGa8AwwGAYIBiuA8NAg2GgYLgBDIMMhkGC4SYwDDYYBguGW8AwxGAYIhhuA8NQg2GoYLgDDMMMhmGC4S4wDDcYhguGe8AwwmAYIRjuA8NIg2GkYHgADKMMhlGC4SEwjDYYRguGR8AwxmAYIxgeA8NYg2GsYHgCDOMMhnGC4SkwjDcYxguGZ8AwwWCYIBieA8NEg2GiYHgBDJMMhkmC4SUwTDYYJguGV8AwxWCYIhheA8NUg2GqYHgDDP8ZDP8JhrfAMM1gmCYY3gHDdINhumB4DwwzDIYZguEDMMw0GGYKho/AMCvEhk9Zvvgi6KCGz1n+f8Nsww6zhR2+yPr/G+YYDHMEQxhgmGswzBUMYYFhnsEwTzCEA4b5BsN8wRAeGBYYDAsEQwRgWGgwLBQMEYFhkcGwSDBEAobFBsNiwRAZGJYYDEsEQxRgWGowLBUMUYFhmcGwTDBEA4blBsNywRAdGFYYDCsEQwxgWGkwrBQMMYFhlcGwSjDEAobVBsNqwRAbGNYYDGsEQxxgWGswrBUMcYFhncGwTjDEA4b1BsN6wRAfGDYYDBsEQwJg2GgwbBQMCYFhk8GwSTAkAobNBsNmwZAYGLYYDFsEQxJgCBgMAcGQFBi2GgxbBUMyYNhmMGwTDMmBYbvBsF0wpACGHQbDDsGQEhh2Ggw7BUMqYNhlMOwSDKmBYbfBsFswpAGGPQbDHsGQFhj2Ggx7BUM6YNhnMOwTDOmBYb/BsF8wZACGAwbDAcGQERgOGgwHBUMmYDhkMBwSDJmB4bDBcFgwZAGGIwbDEcGQFRiOGgxHBUM2YDhmMBwTDNmB4bjBcFww5ACGEwbDCcGQExhOGgwnBUMuYDhlMJwSDLmB4bTBcFow5AGGMwbDGcGQFxjOGgxnBUM+YDhnMJwTDF8Cw3mD4bxgyA8MFwyGC4KhADBcNBguCoaCwHDJYLgkGL4ChssGw2XB8DUwXDEYrgiGb4DhqsFwVTB8CwzXDIZrguE7YLhuMFwXDN8Dww2D4YZg+AEYbhoMNwXDj8Bwy2C4JRh+AobbBsNtwfAzMNwxGO4Ihl+A4a7BcFcw/AoM9wyGe4LhN2C4bzDcFwy/A8MDg+GBYPgDGB4aDA8Fw5/A8MhgeCQY/gKGxwbDY8HwNzA8MRieCIZ/gOGpwfBUMPwLDM8MhmeCoRAwPDcYnguGwsDwwmB4IRiKAMNLg+GlYCgKDK8MhleCoRgwvDYYXguG4sDwxmB4IxhKAMNbg+GtYCgJDO8MhneCoRQwvDcY3guG0sDwwWD4IBjKAMNHg+GjYCgLDJ8Mhk+CoRwwfDYYPguG8sDwxZrQG4INaqgADGEMhjCCoSIwhDUYwgqGSsAQzmAIJxgqA0N4gyG8YKgCDBEMhgiCoSowRDQYIgqGasAQyWCIJBiqA0NkgyGyYKgBDFEMhiiCoSYwRDUYogqGWsAQzWCIJhhqA0N0gyG6YKgDDDEMhhiCoS4wxDQYYgqGesAQy2CIJRjqA0NsgyG2YGgADHEMhjiCoSEwxDUY4gqGRsAQz2CIJxgaA0N8gyG+YGgCDAkMhgSCoSkwJDQYEgqGZsCQyGBIJBiaA0NigyGxYGgBDEkMhiSCoSUwJDUYkgqGVsCQzGBIJhhaA0NygyG5YGgDDCkMhhSCoS0wpDQYUgqGdsCQymBIJRjaA0NqgyG1YOgADGkMhjSCoSMwpDUY0gqGTsCQzmBIJxg6A0N6gyG9YOgCDBkMhgyCoSswZDQYMgqGbsCQyWDIJBi6A0NmgyGzYOgBDFkMhiyCoScwZDUYsgqGXsCQzWDIJhh6A0N2gyG7YOgDDDkMhhyCoS8w5DQYcgqGfsCQy2DIJRj6A0NugyG3YBgADHkMhjyCYSAw5DUY8gqGQcCQz2DIJxgGA8OXBsOXgmEIMOQ3GPILhqHAUMBgKCAYhgFDQYOhoGAYDgxfGQxfCYYRwPC1wfC1YBgJDN8YDN8IhlHA8K3B8K1gGA0M3xkM3wmGMcDwvcHwvWAYCww/GAw/CIZxwPCjwfCjYBgPDD8ZDD8JhgnA8LPB8LNgmAgMvxgMvwiGScDwq8Hwq2CYDAy/GQy/CYYpwPC7wfC7YJgKDH8YDH8Ihv+A4U+D4U/BMA0Y/jIY/hIM04Hhb4Phb8EwAxj+MRj+EQwzgeFfg+FfwTALGAoZDIUEw2xgKGwwFBYMc4ChiMFQRDDMBYaiBkNRwTAPGIoZDMUEw3xgKG4wFBcMC4ChhMFQQjAsBIaSBkNJwbAIGEoZDKUEw2JgKG0wlBYMS4ChjMFQRjAsBYayBkNZwbAMGMoZDOUEw3JgKG8wlBcMK4ChgsFQQTCsBIaKBkNFwbAKGCoZDJUEw2pgqGwwVBYMa4ChisFQRTCsBYaqBkNVwbAOGKoZDNUEw3pgqG4wVBcMG4ChhsFQQzBsBIaaBkNNwbAJGGoZDLUEw2ZgqG0w1BYMW4ChjsFQRzAEgKGuwVBXMGwFhnoGQz3BsA0Y6hsM9QXDdmBoYDA0EAw7gKGhwdBQMOwEhkYGQyPBsAsYGhsMjQXDbmBoYjA0EQx7gKGpwdBUMOwFhmYGQzPBsA8YmhsMzQXDfmBoYTC0EAwHgKGlwdBSMBwEhlYGQyvBcAgYWhsMrQXDYWBoYzC0EQxHgKGtwdBWMBwFhnYGQzvBcAwY2hsM7QXDcWDoYDB0EAwngKGjwdBRMJwEhk4GQyfBcAoYOhsMnQXDaWDoYjB0EQxngKGrwdBVMJwFhm4GQzfBcA4YuhsM3QXDeWDoYTD0EAwXgKGnwdBTMFwEhl4GQy/BcAkYehsMvQXDZWDoYzD0EQxXgKGvwdBXMFwFhn4GQz/BcA0Y+hsM/QXDdWAYYDAMEAw3gGGgwTBQMNwEhkEGwyDBcAsYBhsMgwXDbWAYYjAMEQx3gGGowTBUMNwFhmEGwzDBcA8YhhsMwwXDfWAYYTCMEAwPgGGkwTBSMDwEhlEGwyjB8AgYRhsMowXDY2AYYzCMEQxPgGGswTBWMDwFhnEGwzjB8AwYxhsM4wXDc2CYYDBMEAwvgGGiwTBRMLwEhkkGwyTB8AoYJhsMkwXDa2CYYjBMEQxvgGGqwTBVMLwFhv8Mhv8EwztgmGYwTBMM74FhusEwXTB8AIYZBsMMwfARGGYaDDMFwydgmGUwzBIMn4FhtsEwWzB8ke3/N8wxGOYIhjDAMNdgmCsYwgLDPINhnmAIBwzzDYb5giE8MCwwGBYIhgjAsNBgWCgYIgLDIoNhkWCIBAyLDYbFgiEyMCwxGJYIhijAsNRgWCoYogLDMoNhmWCIBgzLDYblgiE6MKwwGFYIhhjAsNJgWCkYYgLDKoNhlWCIBQyrDYbVgiE2MKwxGNYIhjjAsNZgWCsY4gLDOoNhnWCIBwzrDYb1giE+MGwwGDYIhgTAsNFg2CgYEgLDJoNhk2BIBAybDYbNgiExMGwxGLYIhiTAEDAYAoIhKTBsNRi2CoZkwLDNYNgmGJIDw3aDYbtgSAEMOwyGHYIhJTDsNBh2CoZUwLDLYNglGFIDw26DYbdgSAMMewyGPYIhLTDsNRj2CoZ0wLDPYNgnGNIDw36DYb9gyAAMBwyGA4IhIzAcNBgOCoZMwHDIYDgkGDIDw2GD4bBgyAIMRwyGI4IhKzAcNRiOCoZswHDMYDgmGLIDw3GD4bhgyAEMJwyGE4IhJzCcNBhOCoZcwHDKYDglGHIDw2mD4bRgyAMMZwyGM4IhLzCcNRjOCoZ8wHDOYDgnGL4EhvMGw3nBkB8YLhgMFwRDAWC4aDBcFAwFgeGSwXBJMHwFDJcNhsuC4WtguGIwXBEM3wDDVYPhqmD4FhiuGQzXBMN3wHDdYLguGL4HhhsGww3B8AMw3DQYbgqGH4HhlsFwSzD8BAy3DYbbguFnYLhjMNwRDL8Aw12D4a5g+BUY7hkM9wTDb8Bw32C4Lxh+B4YHBsMDwfAHMDw0GB4Khj+B4ZHB8Egw/AUMjw2Gx4Lhb2B4YjA8EQz/AMNTg+GpYPgXGJ4ZDM8EQyFgeG4wPBcMhYHhhcHwQjAUAYaXBsNLwVAUGF4ZDK8EQzFgeG0wvBYMxYHhjcHwRjCUAIa3BsNbwVASGN4ZDO8EQylgeG8wvBcMpYHhg8HwQTCUAYaPBsNHwVAWGD4ZDJ8EQzlg+GwwfBYM5YHhi7WhNwQb1FABGMIYDGEEQ0VgCGswhBUMlYAhnMEQTjBUBobwBkN4wVAFGCIYDBEEQ1VgiGgwRBQM1YAhksEQSTBUB4bIBkNkwVADGKIYDFEEQ01giGowRBUMtYAhmsEQTTDUBoboBkN0wVAHGGIYDDEEQ11giGkwxBQM9YAhlsEQSzDUB4bYBkNswdAAGOIYDHEEQ0NgiGswxBUMjYAhnsEQTzA0Bob4BkN8wdAEGBIYDAkEQ1NgSGgwJBQMzYAhkcGQSDA0B4bEBkNiwdACGJIYDEkEQ0tgSGowJBUMrYAhmcGQTDC0BobkBkNywdAGGFIYDCkEQ1tgSGkwpBQM7YAhlcGQSjC0B4bUBkNqwdABGNIYDGkEQ0dgSGswpBUMnYAhncGQTjB0Bob0BkN6wdAFGDIYDBkEQ1dgyGgwZBQM3YAhk8GQSTB0B4bMBkNmwdADGLIYDFkEQ09gyGowZBUMvYAhm8GQTTD0BobsBkN2wdAHGHIYDDkEQ19gyGkw5BQM/YAhl8GQSzD0B4bcBkNuwTAAGPIYDHkEw0BgyGsw5BUMg4Ahn8GQTzAMBoYvDYYvBcMQYMhvMOQXDEOBoYDBUEAwDAOGggZDQcEwHBi+Mhi+EgwjgOFrg+FrwTASGL4xGL4RDKOA4VuD4VvBMBoYvjMYvhMMY4Dhe4Phe8EwFhh+MBh+EAzjgOFHg+FHwTAeGH4yGH4SDBOA4WeD4WfBMBEYfjEYfhEMk4DhV4PhV8EwGRh+Mxh+EwxTgOF3g+F3wTAVGP4wGP4QDP8Bw58Gw5+CYRow/GUw/CUYpgPD3wbD34JhBjD8YzD8IxhmAsO/BsO/gmEWMBQyGAoJhtnAUNhgKCwY5gBDEYOhiGCYCwxFDYaigmEeMBQzGIoJhvnAUNxgKC4YFgBDCYOhhGBYCAwlDYaSgmERMJQyGEoJhsXAUNpgKC0YlgBDGYOhjGBYCgxlDYaygmEZMJQzGMoJhuXAUN5gKC8YVgBDBYOhgmBYCQwVDYaKgmEVMFQyGCoJhtXAUNlgqCwY1gBDFYOhimBYCwxVDYaqgmEdMFQzGKoJhvXAUN1gqC4YNgBDDYOhhmDYCAw1DYaagmETMNQyGGoJhs3AUNtgqC0YtgBDHYOhjmAIAENdg6GuYNgKDPUMhnqCYRsw1DcY6guG7cDQwGBoIBh2AENDg6GhYNgJDI0MhkaCYRcwNDYYGguG3cDQxGBoIhj2AENTg6GpYNgLDM0MhmaCYR8wNDcYmguG/cDQwmBoIRgOAENLg6GlYDgIDK0MhlaC4RAwtDYYWguGw8DQxmBoIxiOAENbg6GtYDgKDO0MhnaC4RgwtDcY2guG48DQwWDoIBhOAENHg6GjYDgJDJ0Mhk6C4RQwdDYYOguG08DQxWDoIhjOAENXg6GrYDgLDN0Mhm6C4RwwdDcYuguG88DQw2DoIRguAENPg6GnYLgIDL0Mhl6C4RIw9DYYeguGy8DQx2DoIxiuAENfg6GvYLgKDP0Mhn6C4Row9DcY+guG68AwwGAYIBhuAMNAg2GgYLgJDIMMhkGC4RYwDDYYBguG28AwxGAYIhjuAMNQg2GoYLgLDMMMhmGC4R4wDDcYhguG+8AwwmAYIRgeAMNIg2GkYHgIDKMMhlGC4REwjDYYRguGx8AwxmAYIxieAMNYg2GsYHgKDOMMhnGC4RkwjDcYxguG58AwwWCYIBheAMNEg2GiYHgJDJMMhkmC4RUwTDYYJguG18AwxWCYIhjeAMNUg2GqYHgLDP8ZDP8JhnfAMM1gmCYY3gPD9BAbwiT+4ouggxrCJv7/DTMMO8wQdggHDDMNhpmCITwwzDIYZgmGCMAw22CYLRgiAsMcg2GOYIgEDHMNhrmCITIwzDMY5gmGKMAw32CYLxiiAsMCg2GBYIgGDAsNhoWCITowLDIYFgmGGMCw2GBYLBhiAsMSg2GJYIgFDEsNhqWCITYwLDMYlgmGOMCw3GBYLhjiAsMKg2GFYIgHDCsNhpWCIT4wrDIYVgmGBMCw2mBYLRgSAsMag2GNYEgEDGsNhrWCITEwrDMY1gmGJMCw3mBYLxiSAsMGg2GDYEgGDBsNho2CITkwbDIYNgmGFMCw2WDYLBhSAsMWg2GLYEgFDAGDISAYUgPDVoNhq2BIAwzbDIZtgiEtMGw3GLYLhnTAsMNg2CEY0gPDToNhp2DIAAy7DIZdgiEjMOw2GHYLhkzAsMdg2CMYMgPDXoNhr2DIAgz7DIZ9giErMOw3GPYLhmzAcMBgOCAYsgPDQYPhoGDIAQyHDIZDgiEnMBw2GA4LhlzAcMRgOCIYcgPDUYPhqGDIAwzHDIZjgiEvMBw3GI4LhnzAcMJgOCEYvgSGkwbDScGQHxhOGQynBEMBYDhtMJwWDAWB4YzBcEYwfAUMZw2Gs4Lha2A4ZzCcEwzfAMN5g+G8YPgWGC4YDBcEw3fAcNFguCgYvgeGSwbDJcHwAzBcNhguC4YfgeGKwXBFMPwEDFcNhquC4WdguGYwXBMMvwDDdYPhumD4FRhuGAw3BMNvwHDTYLgpGH4HhlsGwy3B8Acw3DYYbguGP4HhjsFwRzD8BQx3DYa7guFvYLhnMNwTDP8Aw32D4b5g+BcYHhgMDwRDIWB4aDA8FAyFgeGRwfBIMBQBhscGw2PBUBQYnhgMTwRDMWB4ajA8FQzFgeGZwfBMMJQAhucGw3PBUBIYXhgMLwRDKWB4aTC8FAylgeGVwfBKMJQBhtcGw2vBUBYY3hgMbwRDOWB4azC8FQzlgeGdwfBOMFQAhvcGw3vBUBEYPhgMHwRDJWD4aDB8FAyVgeGTwfBJMFQBhs8Gw2fBUBUYvlgXekOwQQ3VgCGMwRBGMFQHhrAGQ1jBUAMYwhkM4QRDTWAIbzCEFwy1gCGCwRBBMNQGhogGQ0TBUAcYIhkMkQRDXWCIbDBEFgz1gCGKwRBFMNQHhqgGQ1TB0AAYohkM0QRDQ2CIbjBEFwyNgCGGwRBDMDQGhpgGQ0zB0AQYYhkMsQRDU2CIbTDEFgzNgCGOwRBHMDQHhrgGQ1zB0AIY4hkM8QRDS2CIbzDEFwytgCGBwZBAMLQGhoQGQ0LB0AYYEhkMiQRDW2BIbDAkFgztgCGJwZBEMLQHhqQGQ1LB0AEYkhkMyQRDR2BIbjAkFwydgCGFwZBCMHQGhpQGQ0rB0AUYUhkMqQRDV2BIbTCkFgzdgCGNwZBGMHQHhrQGQ1rB0AMY0hkM6QRDT2BIbzCkFwy9gCGDwZBBMPQGhowGQ0bB0AcYMhkMmQRDX2DIbDBkFgz9gCGLwZBFMPQHhqwGQ1bBMAAYshkM2QTDQGDIbjBkFwyDgCGHwZBDMAwGhpwGQ07BMAQYchkMuQTDUGDIbTDkFgzDgCGPwZBHMAwHhrwGQ17BMAIY8hkM+QTDSGD40mD4UjCMAob8BkN+wTAaGAoYDAUEwxhgKGgwFBQMY4HhK4PhK8EwDhi+Nhi+FgzjgeEbg+EbwTABGL41GL4VDBOB4TuD4TvBMAkYvjcYvhcMk4HhB4PhB8EwBRh+NBh+FAxTgeEng+EnwfAfMPxsMPwsGKYBwy8Gwy+CYTow/Gow/CoYZgDDbwbDb4JhJjD8bjD8LhhmAcMfBsMfgmE2MPxpMPwpGOYAw18Gw1+CYS4w/G0w/C0Y5gHDPwbDP4JhPjD8azD8KxgWAEMhg6GQYFgIDIUNhsKCYREwFDEYigiGxcBQ1GAoKhiWAEMxg6GYYFgKDMUNhuKCYRkwlDAYSgiG5cBQ0mAoKRhWAEMpg6GUYFgJDKUNhtKCYRUwlDEYygiG1cBQ1mAoKxjWAEM5g6GcYFgLDOUNhvKCYR0wVDAYKgiG9cBQ0WCoKBg2AEMlg6GSYNgIDJUNhsqCYRMwVDEYqgiGzcBQ1WCoKhi2AEM1g6GaYAgAQ3WDobpg2AoMNQyGGoJhGzDUNBhqCobtwFDLYKglGHYAQ22DobZg2AkMdQyGOoJhFzDUNRjqCobdwFDPYKgnGPYAQ32Dob5g2AsMDQyGBoJhHzA0NBgaCob9wNDIYGgkGA4AQ2ODobFgOAgMTQyGJoLhEDA0NRiaCobDwNDMYGgmGI4AQ3ODoblgOAoMLQyGFoLhGDC0NBhaCobjwNDKYGglGE4AQ2uDobVgOAkMbQyGNoLhFDC0NRjaCobTwNDOYGgnGM4AQ3uDob1gOAsMHQyGDoLhHDB0NBg6CobzwNDJYOgkGC4AQ2eDobNguAgMXQyGLoLhEjB0NRi6CobLwNDNYOgmGK4AQ3eDobtguAoMPQyGHoLhGjD0NBh6CobrwNDLYOglGG4AQ2+DobdguAkMfQyGPoLhFjD0NRj6CobbwNDPYOgnGO4AQ3+Dob9guAsMAwyGAYLhHjAMNBgGCob7wDDIYBgkGB4Aw2CDYbBgeAgMQwyGIYLhETAMNRiGCobHwDDMYBgmGJ4Aw3CDYbhgeAoMIwyGEYLhGTCMNBhGCobnwDDKYBglGF4Aw2iDYbRgeAkMYwyGMYLhFTCMNRjGCobXwDDOYBgnGN4Aw3iDYbxgeAsMEwyGCYLhHTBMNBgmCob3wDDJYJgkGD4Aw2SDYbJg+AgMUwyGKYLhEzBMNRimCobPwPCfwfCfYPgiyf9vmGYwTBMMYYBhusEwXTCEBYYZBsMMwRAOGGYaDDMFQ3hgmGUwzBIMEYBhtsEwWzBEBIY5BsMcwRAJGOYaDHMFQ2RgmGcwzBMMUYBhvsEwXzBEBYYFBsMCwRANGBYaDAsFQ3RgWGQwLBIMMYBhscGwWDDEBIYlBsMSwRALGJYaDEsFQ2xgWGYwLBMMcYBhucGwXDDEBYYVBsMKwRAPGFYaDCsFQ3xgWGUwrBIMCYBhtcGwWjAkBIY1BsMawZAIGNYaDGsFQ2JgWGcwrBMMSYBhvcGwXjAkBYYNBsMGwZAMGDYaDBsFQ3Jg2GQwbBIMKYBhs8GwWTCkBIYtBsMWwZAKGAIGQ0AwpAaGrQbDVsGQBhi2GQzbBENaYNhuMGwXDOmAYYfBsEMwpAeGnQbDTsGQARh2GQy7BENGYNhtMOwWDJmAYY/BsEcwZAaGvQbDXsGQBRj2GQz7BENWYNhvMOwXDNmA4YDBcEAwZAeGgwbDQcGQAxgOGQyHBENOYDhsMBwWDLmA4YjBcEQw5AaGowbDUcGQBxiOGQzHBENeYDhuMBwXDPmA4YTBcEIwfAkMJw2Gk4IhPzCcMhhOCYYCwHDaYDgtGAoCwxmD4Yxg+AoYzhoMZwXD18BwzmA4Jxi+AYbzBsN5wfAtMFwwGC4Ihu+A4aLBcFEwfA8MlwyGS4LhB2C4bDBcFgw/AsMVg+GKYPgJGK4aDFcFw8/AcM1guCYYfgGG6wbDdcHwKzDcMBhuCIbfgOGmwXBTMPwODLcMhluC4Q9guG0w3BYMfwLDHYPhjmD4CxjuGgx3BcPfwHDPYLgnGP4BhvsGw33B8C8wPDAYHgiGQsDw0GB4KBgKA8Mjg+GRYCgCDI8NhseCoSgwPDEYngiGYsDw1GB4KhiKA8Mzg+GZYCgBDM8NhueCoSQwvDAYXgiGUsDw0mB4KRhKA8Mrg+GVYCgDDK8NhteCoSwwvDEY3giGcsDw1mB4KxjKA8M7g+GdYKgADO8NhveCoSIwfDAYPgiGSsDw0WD4KBgqA8Mng+GTYKgCDJ8Nhs+CoSowfLE+9IZggxqqAUMYgyGMYKgODGENhrCCoQYwhDMYwgmGmsAQ3mAILxhqAUMEgyGCYKgNDBENhoiCoQ4wRDIYIgmGusAQ2WCILBjqAUMUgyGKYKgPDFENhqiCoQEwRDMYogmGhsAQ3WCILhgaAUMMgyGGYGgMDDENhpiCoQkwxDIYYgmGpsAQ22CILRiaAUMcgyGOYGgODHENhriCoQUwxDMY4gmGlsAQ32CILxhaAUMCgyGBYGgNDAkNhoSCoQ0wJDIYEgmGtsCQ2GBILBjaAUMSgyGJYGgPDEkNhqSCoQMwJDMYkgmGjsCQ3GBILhg6AUMKgyGFYOgMDCkNhpSCoQswpDIYUgmGrsCQ2mBILRi6AUMagyGNYOgODGkNhrSCoQcwpDMY0gmGnsCQ3mBILxh6AUMGgyGDYOgNDBkNhoyCoQ8wZDIYMgmGvsCQ2WDILBj6AUMWgyGLYOgPDFkNhqyCYQAwZDMYsgmGgcCQ3WDILhgGAUMOgyGHYBgMDDkNhpyCYQgw5DIYcgmGocCQ22DILRiGAUMegyGPYBgODHkNhryCYQQw5DMY8gmGkcDwpcHwpWAYBQz5DYb8gmE0MBQwGAoIhjHAUNBgKCgYxgLDVwbDV4JhHDB8bTB8LRjGA8M3BsM3gmECMHxrMHwrGCYCw3cGw3eCYRIwfG8wfC8YJgPDDwbDD4JhCjD8aDD8KBimAsNPBsNPguE/YPjZYPhZMEwDhl8Mhl8Ew3Rg+NVg+FUwzACG3wyG3wTDTGD43WD4XTDMAoY/DIY/BMNsYPjTYPhTMMwBhr8Mhr8Ew1xg+Ntg+FswzAOGfwyGfwTDfGD412D4VzAsAIZCBkMhwbAQGAobDIUFwyJgKGIwFBEMi4GhqMFQVDAsAYZiBkMxwbAUGIobDMUFwzJgKGEwlBAMy4GhpMFQUjCsAIZSBkMpwbASGEobDKUFwypgKGMwlBEMq4GhrMFQVjCsAYZyBkM5wbAWGMobDOUFwzpgqGAwVBAM64GhosFQUTBsAIZKBkMlwbARGCobDJUFwyZgqGIwVBEMm4GhqsFQVTBsAYZqBkM1wRAAhuoGQ3XBsBUYahgMNQTDNmCoaTDUFAzbgaGWwVBLMOwAhtoGQ23BsBMY6hgMdQTDLmCoazDUFQy7gaGewVBPMOwBhvoGQ33BsBcYGhgMDQTDPmBoaDA0FAz7gaGRwdBIMBwAhsYGQ2PBcBAYmhgMTQTDIWBoajA0FQyHgaGZwdBMMBwBhuYGQ3PBcBQYWhgMLQTDMWBoaTC0FAzHgaGVwdBKMJwAhtYGQ2vBcBIY2hgMbQTDKWBoazC0FQyngaGdwdBOMJwBhvYGQ3vBcBYYOhgMHQTDOWDoaDB0FAzngaGTwdBJMFwAhs4GQ2fBcBEYuhgMXQTDJWDoajB0FQyXgaGbwdBNMFwBhu4GQ3fBcBUYehgMPQTDNWDoaTD0FAzXgaGXwdBLMNwAht4GQ2/BcBMY+hgMfQTDLWDoazD0FQy3gaGfwdBPMNwBhv4GQ3/BcBcYBhgMAwTDPWAYaDAMFAz3gWGQwTBIMDwAhsEGw2DB8BAYhhgMQwTDI2AYajAMFQyPgWGYwTBMMDwBhuEGw3DB8BQYRhgMIwTDM2AYaTCMFAzPgWGUwTBKMLwAhtEGw2jB8BIYxhgMYwTDK2AYazCMFQyvgWGcwTBOMLwBhvEGw3jB8BYYJhgMEwTDO2CYaDBMFAzvgWGSwTBJMHwAhskGw2TB8BEYphgMUwTDJ2CYajBMFQyfgeE/g2Hucm74Ivz/b5hmMExfK7zpbP+/YXqIDWGifvFF0EENYaP+/4YZhh1mCO8hHDDMNBhmCobwwDDLYJglGCIAw2yDYbZgiAgMcwyGOYIhEjDMdfwfBENkYJhnMMwTDFGAYb7BMF8wRAWGBQbDAsEQDRgWGgwLBUN0YFhkMCwSDDGAYbHBsFgwxASGJQbDEsEQCxiWGgxLBUNsYFhmMCwTDHGAYbnBsFwwxAWGFQbDCsEQDxhWGgwrBUN8YFhlMKwSDAmAYbXBsFowJASGNQbDGsGQCBjWGgxrBUNiYFhnMKwTDEmAYb3BsF4wJAWGDQbDBsGQDBg2GgwbBUNyYNhkMGwSDCmAYbPBsFkwpASGLQbDFsGQChgCBkNAMKQGhq0Gw1bBkAYYthkM2wRDWmDYbjBsFwzpgGGHwbBDMKQHhp0Gw07BkAEYdhkMuwRDRmDYbTDsFgyZgGGPwbBHMGQGhr0Gw17BkAUY9hkM+wRDVmDYbzDsFwzZgOGAwXBAMGQHhoMGw0HBkAMYDhkMhwRDTmA4bDAcFgy5gOGIwXBEMOQGhqMGw1HBkAcYjhkMxwRDXmA4bjAcFwz5gOGEwXBCMHwJDCcNhpOCIT8wnDIYTgmGAsBw2mA4LRgKAsMZg+GMYPgKGM4aDGcFw9fAcM5gOCcYvgGG8wbDecHwLTBcMBguCIbvgOGiwXBRMHwPDJcMhkuC4QdguGwwXBYMPwLDFYPhimD4CRiuGgxXBcPPwHDNYLgmGH4BhusGw3XB8Csw3DAYbgiG34DhpsFwUzD8Dgy3DIZbguEPYLhtMNwWDH8Cwx2D4Y5g+AsY7hoMdwXD38Bwz2C4Jxj+AYb7BsN9wfAvMDwwGB4IhkLA8NBgeCgYCgPDI4PhkWAoAgyPDYbHgqEoMDwxGJ4IhmLA8NRgeCoYigPDM4PhmWAoAQzPDYbngqEkMLwwGF4IhlLA8NJgeCkYSgPDK4PhlWAoAwyvDYbXgqEsMLwxGN4IhnLA8NZgeCsYygPDO4PhnWCoAAzvDYb3gqEiMHwwGD4IhkrA8NFg+CgYKgPDJ4Phk2CoAgyfDYbPgqEqMHyxIfSGYIMaqgFDGIMhjGCoDgxhDYawgqEGMIQzGMIJhprAEN5gCC8YagFDBIMhgmCoDQwRDYaIgqEOMEQyGCIJhrrAENlgiCwY6gFDFIMhimCoDwxRDYaogqEBMEQzGKIJhobAEN1giC4YGgFDDIMhhmBoDAwxDYaYgqEJMMQyGGIJhqbAENtgiC0YmgFDHIMhjmBoDgxxDYa4gqEFMMQzGOIJhpbAEN9giC8YWgFDAoMhgWBoDQwJDYaEgqENMCQyGBIJhrbAkNhgSCwY2gFDEoMhiWBoDwxJDYakgqEDMCQzGJIJho7AkNxgSC4YOgFDCoMhhWDoDAwpDYaUgqELMKQyGFIJhq7AkNpgSC0YugFDGoMhjWDoDgxpDYa0gqEHMKQzGNIJhp7AkN5gSC8YegFDBoMhg2DoDQwZDYaMgqEPMGQyGDIJhr7AkNlgyCwY+gFDFoMhi2DoDwxZDYasgmEAMGQzGLIJhoHAkN1gyC4YBgFDDoMhh2AYDAw5DYacgmEIMOQyGHIJhqHAkNtgyC0YhgFDHoMhj2AYDgx5DYa8gmEEMOQzGPIJhpHA8KXB8KVgGAUM+Q2G/IJhNDAUMBgKCIYxwFDQYCgoGMYCw1cGw1eCYRwwfG0wfC0YxgPDNwbDN4JhAjB8azB8KxgmAsN3BsN3gmESMHxvMHwvGCYDww8Gww+CYQow/Ggw/CgYpgLDTwbDT4LhP2D42WD4WTBMA4ZfDIZfBMN0YPjVYPhVMMwAht8Mht8Ew0xg+N1g+F0wzAKGPwyGPwTDbGD402D4UzDMAYa/DIa/BMNcYPjbYPhbMMwDhn8Mhn8Ew3xg+Ndg+FcwLACGQgZDIcGwEBgKGwyFBcMiYChiMBQRDIuBoajBUFQwLAGGYgZDMcGwFBiKGwzFBcMyYChhMJQQDMuBoaTBUFIwrACGUgZDKcGwEhhKGwylBcMqYChjMJQRDKuBoazBUFYwrAGGcgZDOcGwFhjKGwzlBcM6YKhgMFQQDOuBoaLBUFEwbACGSgZDJcGwERgqGwyVBcMmYKhiMFQRDJuBoarBUFUwbAGGagZDNcEQAIbqBkN1wbAVGGoYDDUEwzZgqGkw1BQM24GhlsFQSzDsAIbaBkNtwbATGOoYDHUEwy5gqGsw1BUMu4GhnsFQTzDsAYb6BkN9wbAXGBoYDA0Ewz5gaGgwNBQM+4GhkcHQSDAcAIbGBkNjwXAQGJoYDE0EwyFgaGowNBUMh4GhmcHQTDAcAYbmBkNzwXAUGFoYDC0EwzFgaGkwtBQMx4GhlcHQSjCcAIbWBkNrwXASGNoYDG0EwylgaGswtBUMp4GhncHQTjCcAYb2BkN7wXAWGDoYDB0Ewzlg6GgwdBQM54Ghk8HQSTBcAIbOBkNnwXARGLoYDF0EwyVg6GowdBUMl4Ghm8HQTTBcAYbuBkN3wXAVGHoYDD0EwzVg6Gkw9BQM14Ghl8HQSzDcAIbeBkNvwXATGPoYDH0Ewy1g6Gsw9BUMt4Ghn8HQTzDcAYb+BkN/wXAXGAYYDAMEwz1gGGgwDBQM94FhkMEwSDA8AIbBBsNgwfAQGIYYDEMEwyNgGGowDBUMj4FhmMEwTDA8AYbhBsNwwfAUGEYYDCMEwzNgGGkwjBQMz4FhlMEwSjC8AIbRBsNowfASGMYYDGMEwytgGGswjBUMr4FhnMEwTjC8AYbxBsN4wfAWGCYYDBMEwztgmGgwTBQM74FhksEwSTB8AIbJBsNkwfARGKYYDFMEwydgmGowTBUMn4HhP4PhP8HwRbT/3zDNYJgmGMIAw3SDYbpgCAsMMwyGGYIhHDDMNBhmCobwwDDLYJglGCIAw2yDYbZgiAgMcwyGOYIhEjDMNRjmCobIwDDPYJgnGKIAw3yDYb5giAoMCwyGBYIhGjAsNBgWCobowLDIYFgkGGIAw2KDYbFgiAkMSwyGJYIhFjAsNRiWCobYwLDMYFgmGOIAw3KDYblgiAsMKwyGFYIhHjCsNBhWCob4wLDKYFglGBIAw2qDYbVgSAgMawyGNYIhETCsNRjWCobEwLDOYFgnGJIAw3qDYb1gSAoMGwyGDYIhGTBsNBg2CobkwLDJYNgkGFIAw2aDYbNgSAkMWwyGLYIhFTAEDIaAYEgNDFsNhq2CIQ0wbDMYtgmGtMCw3WDYLhjSAcMOg2GHYEgPDDsNhp2CIQMw7DIYdgmGjMCw22DYLRgyAcMeg2GPYMgMDHsNhr2CIQsw7DMY9gmGrMCw32DYLxiyAcMBg+GAYMgODAcNhoOCIQcwHDIYDgmGnMBw2GA4LBhyAcMRg+GIYMgNDEcNhqOCIQ8wHDMYjgmGvMBw3GA4LhjyAcMJg+GEYPgSGE4aDCcFQ35gOGUwnBIMBYDhtMFwWjAUBIYzBsMZwfAVMJw1GM4Khq+B4ZzBcE4wfAMM5w2G84LhW2C4YDBcEAzfAcNFg+GiYPgeGC4ZDJcEww/AcNlguCwYfgSGKwbDFcHwEzBcNRiuCoafgeGawXBNMPwCDNcNhuuC4VdguGEw3BAMvwHDTYPhpmD4HRhuGQy3BMMfwHDbYLgtGP4EhjsGwx3B8Bcw3DUY7gqGv4HhnsFwTzD8Awz3DYb7guFfYHhgMDwQDIWA4aHB8FAwFAaGRwbDI8FQBBgeGwyPBUNRYHhiMDwRDMWA4anB8FQwFAeGZwbDM8FQAhieGwzPBUNJYHhhMLwQDKWA4aXB8FIwlAaGVwbDK8FQBhheGwyvBUNZYHhjMLwRDOWA4a3B8FYwlAeGdwbDO8FQARjeGwzvBUNFYPhgMHwQDJWA4aPB8FEwVAaGTwbDJ8FQBRg+GwyfBUNVYPhiY+gNwQY1VAOGMAZDGMFQHRjCGgxhBUMNYAhnMIQTDDWBIbzBEF4w1AKGCAZDBMFQGxgiGgwRBUMdYIhkMEQSDHWBIbLBEFkw1AOGKAZDFMFQHxiiGgxRBUMDYIhmMEQTDA2BIbrBEF0wNAKGGAZDDMHQGBhiGgwxBUMTYIhlMMQSDE2BIbbBEFswNAOGOAZDHMHQHBjiGgxxBUMLYIhnMMQTDC2BIb7BEF8wtAKGBAZDAsHQGhgSGgwJBUMbYEhkMCQSDG2BIbHBkFgwtAOGJAZDEsHQHhiSGgxJBUMHYEhmMCQTDB2BIbnBkFwwdAKGFAZDCsHQGRhSGgwpBUMXYEhlMKQSDF2BIbXBkFowdAOGNAZDGsHQHRjSGgxpBUMPYEhnMKQTDD2BIb3BkF4w9AKGDAZDBsHQGxgyGgwZBUMfYMhkMGQSDH2BIbPBkFkw9AOGLAZDFsHQHxiyGgxZBcMAYMhmMGQTDAOBIbvBkF0wDAKGHAZDDsEwGBhyGgw5BcMQYMhlMOQSDEOBIbfBkFswDAOGPAZDHsEwHBjyGgx5BcMIYMhnMOQTDCOB4UuD4UvBMAoY8hsM+QXDaGAoYDAUEAxjgKGgwVBQMIwFhq8Mhq8Ewzhg+Npg+FowjAeGbwyGbwTDBGD41mD4VjBMBIbvDIbvBMMkYPjeYPheMEwGhh8Mhh8EwxRg+NFg+FEwTAWGnwyGnwTDf8Dws8Hws2CYBgy/GAy/CIbpwPCrwfCrYJgBDL8ZDL8JhpnA8LvB8LtgmAUMfxgMfwiG2cDwp8Hwp2CYAwx/GQx/CYa5wPC3wfC3YJgHDP8YDP8IhvnA8K/B8K9gWAAMhQyGQoJhITAUNhgKC4ZFwFDEYCgiGBYDQ1GDoahgWAIMxQyGYoJhKTAUNxiKC4ZlwFDCYCghGJYDQ0mDoaRgWAEMpQyGUoJhJTCUNhhKC4ZVwFDGYCgjGFYDQ1mDoaxgWAMM5QyGcoJhLTCUNxjKC4Z1wFDBYKggGNYDQ0WDoaJg2AAMlQyGSoJhIzBUNhgqC4ZNwFDFYKgiGDYDQ1WDoapg2AIM1QyGaoIhAAzVDYbqgmErMNQwGGoIhm3AUNNgqCkYtgNDLYOhlmDYAQy1DYbagmEnMNQxGOoIhl3AUNdgqCsYdgNDPYOhnmDYAwz1DYb6gmEvMDQwGBoIhn3A0NBgaCgY9gNDI4OhkWA4AAyNDYbGguEgMDQxGJoIhkPA0NRgaCoYDgNDM4OhmWA4AgzNDYbmguEoMLQwGFoIhmPA0NJgaCkYjgNDK4OhlWA4AQytDYbWguEkMLQxGNoIhlPA0NZgaCsYTgNDO4OhnWA4AwztDYb2guEsMHQwGDoIhnPA0NFg6CgYzgNDJ4Ohk2C4AAydDYbOguEiMHQxGLoIhkvA0NVg6CoYLgNDN4Ohm2C4AgzdDYbuguEqMPQwGHoIhmvA0NNg6CkYrgNDL4Ohl2C4AQy9DYbeguEmMPQxGPoIhlvA0Ndg6CsYbgNDP4Ohn2C4Awz9DYb+guEuMAwwGAYIhnvAMNBgGCgY7gPDIINhkGB4AAyDDYbBguEhMAwxGIYIhkfAMNRgGCoYHgPDMINhmGB4AgzDDYbhguEpMIwwGEYIhmfAMNJgGCkYngPDKINhlGB4AQyjDYbRguElMIwxGMYIhlfAMNZgGCsYXgPDOINhnGB4AwzjDYbxguEtMEwwGCYIhnfAMNFgmCgY3gPDJINhkmD4AAyTDYbJguEjMEwxGKYIhk/AMNVgmCoYPgPDfyE2hIn4xRdBBzWEjfj/G6YZdpgm7BAOGKYbDNMFQ3hgmGEwzBAMEYBhpsEwUzBEBIZZBsMswRAJGGYbDLMFQ2RgmGMwzBEMUYBhrsEwVzBEBYZ5BsM8wRANGOYbDPMFQ3RgWGAwLBAMMYBhocGwUDDEBIZFBsMiwRALGBYbDIsFQ2xgWGIwLBEMcYBhqcGwVDDEBYZlBsMywRAPGJYbDMsFQ3xgWGEwrBAMCYBhpcGwUjAkBIZVBsMqwZAIGFYbDKsFQ2JgWGMwrBEMSYBhrcGwVjAkBYZ1BsM6wZAMGNYbDOsFQ3Jg2GAwbBAMKYBho8GwUTCkBIZNBsMmwZAKGDYbDJsFQ2pg2GIwbBEMaYAhYDAEBENaYNhqMGwVDOmAYZvBsE0wpAeG7QbDdsGQARh2GAw7BENGYNhpMOwUDJmAYZfBsEswZAaG3QbDbsGQBRj2GAx7BENWYNhrMOwVDNmAYZ/BsE8wZAeG/QbDfsGQAxgOGAwHBENOYDhoMBwUDLmA4ZDBcEgw5AaGwwbDYcGQBxiOGAxHBENeYDhqMBwVDPmA4ZjBcEwwfAkMxw2G44IhPzCcMBhOCIYCwHDSYDgpGAoCwymD4ZRg+AoYThsMpwXD18BwxmA4Ixi+AYazBsNZwfAtMJwzGM4Jhu+A4bzBcF4wfA8MFwyGC4LhB2C4aDBcFAw/AsMlg+GSYPgJGC4bDJcFw8/AcMVguCIYfgGGqwbDVcHwKzBcMxiuCYbfgOG6wXBdMPwODDcMhhuC4Q9guGkw3BQMfwLDLYPhlmD4CxhuGwy3BcPfwHDHYLgjGP4BhrsGw13B8C8w3DMY7gmGQsBw32C4LxgKA8MDg+GBYCgCDA8NhoeCoSgwPDIYHgmGYsDw2GB4LBiKA8MTg+GJYCgBDE8NhqeCoSQwPDMYngmGUsDw3GB4LhhKA8MLg+GFYCgDDC8NhpeCoSwwvDIYXgmGcsDw2mB4LRjKA8Mbg+GNYKgADG8NhreCoSIwvDMY3gmGSsDw3mB4LxgqA8MHg+GDYKgCDB8Nho+CoSowfDIYPgmGasDw2WD4LBiqA8MXm0JvCDaooQYwhDEYwgiGmsAQ1mAIKxhqAUM4gyGcYKgNDOENhvCCoQ4wRDAYIgiGusAQ0WCIKBjqAUMkgyGSYKgPDJENhsiCoQEwRDEYogiGhsAQ1WCIKhgaAUM0gyGaYGgMDNENhuiCoQkwxDAYYgiGpsAQ02CIKRiaAUMsgyGWYGgODLENhtiCoQUwxDEY4giGlsAQ12CIKxhaAUM8gyGeYGgNDPENhviCoQ0wJDAYEgiGtsCQ0GBIKBjaAUMigyGRYGgPDIkNhsSCoQMwJDEYkgiGjsCQ1GBIKhg6AUMygyGZYOgMDMkNhuSCoQswpDAYUgiGrsCQ0mBIKRi6AUMqgyGVYOgODKkNhtSCoQcwpDEY0giGnsCQ1mBIKxh6AUM6gyGdYOgNDOkNhvSCoQ8wZDAYMgiGvsCQ0WDIKBj6AUMmgyGTYOgPDJkNhsyCYQAwZDEYsgiGgcCQ1WDIKhgGAUM2gyGbYBgMDNkNhuyCYQgw5DAYcgiGocCQ02DIKRiGAUMugyGXYBgODLkNhtyCYQQw5DEY8giGkcCQ12DIKxhGAUM+gyGfYBgNDF8aDF8KhjHAkN9gyC8YxgJDAYOhgGAYBwwFDYaCgmE8MHxlMHwlGCYAw9cGw9eCYSIwfGMwfCMYJgHDtwbDt4JhMjB8ZzB8JximAMP3BsP3gmEqMPxgMPwgGP4Dhh8Nhh8FwzRg+Mlg+EkwTAeGnw2GnwXDDGD4xWD4RTDMBIZfDYZfBcMsYPjNYPhNMMwGht8Nht8Fwxxg+MNg+EMwzAWGPw2GPwXDPGD4y2D4SzDMB4a/DYa/BcMCYPjHYPhHMCwEhn8Nhn8FwyJgKGQwFBIMi4GhsMFQWDAsAYYiBkMRwbAUGIoaDEUFwzJgKGYwFBMMy4GhuMFQXDCsAIYSBkMJwbASGEoaDCUFwypgKGUwlBIMq4GhtMFQWjCsAYYyBkMZwbAWGMoaDGUFwzpgKGcwlBMM64GhvMFQXjBsAIYKBkMFwbARGCoaDBUFwyZgqGQwVBIMm4GhssFQWTBsAYYqBkMVwRAAhqoGQ1XBsBUYqhkM1QTDNmCobjBUFwzbgaGGwVBDMOwAhpoGQ03BsBMYahkMtQTDLmCobTDUFgy7gaGOwVBHMOwBhroGQ13BsBcY6hkM9QTDPmCobzDUFwz7gaGBwdBAMBwAhoYGQ0PBcBAYGhkMjQTDIWBobDA0FgyHgaGJwdBEMBwBhqYGQ1PBcBQYmhkMzQTDMWBobjA0FwzHgaGFwdBCMJwAhpYGQ0vBcBIYWhkMrQTDKWBobTC0FgyngaGNwdBGMJwBhrYGQ1vBcBYY2hkM7QTDOWBobzC0FwzngaGDwdBBMFwAho4GQ0fBcBEYOhkMnQTDJWDobDB0FgyXgaGLwdBFMFwBhq4GQ1fBcBUYuhkM3QTDNWDobjB0FwzXgaGHwdBDMNwAhp4GQ0/BcBMYehkMvQTDLWDobTD0Fgy3gaGPwdBHMNwBhr4GQ1/BcBcY+hkM/QTDPWDobzD0Fwz3gWGAwTBAMDwAhoEGw0DB8BAYBhkMgwTDI2AYbDAMFgyPgWGIwTBEMDwBhqEGw1DB8BQYhhkMwwTDM2AYbjAMFwzPgWGEwTBCMLwAhpEGw0jB8BIYRhkMowTDK2AYbTCMFgyvgWGMwTBGMLwBhrEGw1jB8BYYxhkM4wTDO2AYbzCMFwzvgWGCwTBBMHwAhokGw0TB8BEYJhkMkwTDJ2CYbDBMFgyfgWGKwTBFMHwR6f83TDUYpgqGMMDwn8Hwn2AICwzTDIZpgiEcMEw3GKYLhvDAMMNgmCEYIgDDTINhpmCICAyzDIZZgiESMMw2GGYLhsjAMMdgmCMYogDDXINhrmCICgzzDIZ5giEaMMw3GOYLhujAsMBgWCAYYgDDQoNhoWCICQyLDIZFgiEWMCw2GBYLhtjAsMRgWCIY4gDDUoNhqWCICwzLDIZlgiEeMCw3GJYLhvjAsMJgWCEYEgDDSoNhpWBICAyrDIZVgiERMKw2GFYLhsTAsMZgWCMYkgDDWoNhrWBICgzrDIZ1giEZMKw3GNYLhuTAsMFg2CAYUgDDRoNho2BICQybDIZNgiEVMGw2GDYLhtTAsMVg2CIY0gBDwGAICIa0wLDVYNgqGNIBwzaDYZtgSA8M2w2G7YIhAzDsMBh2CIaMwLDTYNgpGDIBwy6DYZdgyAwMuw2G3YIhCzDsMRj2CIaswLDXYNgrGLIBwz6DYZ9gyA4M+w2G/YIhBzAcMBgOCIacwHDQYDgoGHIBwyGD4ZBgyA0Mhw2Gw4IhDzAcMRiOCIa8wHDUYDgqGPIBwzGD4Zhg+BIYjhsMxwVDfmA4YTCcEAwFgOGkwXBSMBQEhlMGwynB8BUwnDYYTguGr4HhjMFwRjB8AwxnDYazguFbYDhnMJwTDN8Bw3mD4bxg+B4YLhgMFwTDD8Bw0WC4KBh+BIZLBsMlwfATMFw2GC4Lhp+B4YrBcEUw/AIMVw2Gq4LhV2C4ZjBcEwy/AcN1g+G6YPgdGG4YDDcEwx/AcNNguCkY/gSGWwbDLcHwFzDcNhhuC4a/geGOwXBHMPwDDHcNhruC4V9guGcw3BMMhYDhvsFwXzAUBoYHBsMDwVAEGB4aDA8FQ1FgeGQwPBIMxYDhscHwWDAUB4YnBsMTwVACGJ4aDE8FQ0lgeGYwPBMMpYDhucHwXDCUBoYXBsMLwVAGGF4aDC8FQ1lgeGUwvBIM5YDhtcHwWjCUB4Y3BsMbwVABGN4aDG8FQ0VgeGcwvBMMlYDhvcHwXjBUBoYPBsMHwVAFGD4aDB8FQ1Vg+GQwfBIM1YDhs8HwWTBUB4YvNofeEGxQQw1gCGMwhBEMNYEhrMEQVjDUAoZwBkM4wVAbGMIbDOEFQx1giGAwRBAMdYEhosEQUTDUA4ZIBkMkwVAfGCIbDJEFQwNgiGIwRBEMDYEhqsEQVTA0AoZoBkM0wdAYGKIbDNEFQxNgiGEwxBAMTYEhpsEQUzA0A4ZYBkMswdAcGGIbDLEFQwtgiGMwxBEMLYEhrsEQVzC0AoZ4BkM8wdAaGOIbDPEFQxtgSGAwJBAMbYEhocGQUDC0A4ZEBkMiwdAeGBIbDIkFQwdgSGIwJBEMHYEhqcGQVDB0AoZkBkMywdAZGJIbDMkFQxdgSGEwpBAMXYEhpcGQUjB0A4ZUBkMqwdAdGFIbDKkFQw9gSGMwpBEMPYEhrcGQVjD0AoZ0BkM6wdAbGNIbDOkFQx9gyGAwZBAMfYEho8GQUTD0A4ZMBkMmwdAfGDIbDJkFwwBgyGIwZBEMA4Ehq8GQVTAMAoZsBkM2wTAYGLIbDNkFwxBgyGEw5BAMQ4Ehp8GQUzAMA4ZcBkMuwTAcGHIbDLkFwwhgyGMw5BEMI4Ehr8GQVzCMAoZ8BkM+wTAaGL40GL4UDGOAIb/BkF8wjAWGAgZDAcEwDhgKGgwFBcN4YPjKYPhKMEwAhq8Nhq8Fw0Rg+MZg+EYwTAKGbw2GbwXDZGD4zmD4TjBMAYbvDYbvBcNUYPjBYPhBMPwHDD8aDD8KhmnA8JPB8JNgmA4MPxsMPwuGGcDwi8Hwi2CYCQy/Ggy/CoZZwPCbwfCbYJgNDL8bDL8LhjnA8IfB8IdgmAsMfxoMfwqGecDwl8Hwl2CYDwx/Gwx/C4YFwPCPwfCPYFgIDP8aDP8KhkXAUMhgKCQYFgNDYYOhsGBYAgxFDIYigmEpMBQ1GIoKhmXAUMxgKCYYlgNDcYOhuGBYAQwlDIYSgmElMJQ0GEoKhlXAUMpgKCUYVgNDaYOhtGBYAwxlDIYygmEtMJQ1GMoKhnXAUM5gKCcY1gNDeYOhvGDYAAwVDIYKgmEjMFQ0GCoKhk3AUMlgqCQYNgNDZYOhsmDYAgxVDIYqgiEADFUNhqqCYSswVDMYqgmGbcBQ3WCoLhi2A0MNg6GGYNgBDDUNhpqCYScw1DIYagmGXcBQ22CoLRh2A0Mdg6GOYNgDDHUNhrqCYS8w1DMY6gmGfcBQ32CoLxj2A0MDg6GBYDgADA0NhoaC4SAwNDIYGgmGQ8DQ2GBoLBgOA0MTg6GJYDgCDE0NhqaC4SgwNDMYmgmGY8DQ3GBoLhiOA0MLg6GFYDgBDC0NhpaC4SQwtDIYWgmGU8DQ2mBoLRhOA0Mbg6GNYDgDDG0NhraC4SwwtDMY2gmGc8DQ3mBoLxjOA0MHg6GDYLgADB0Nho6C4SIwdDIYOgmGS8DQ2WDoLBguA0MXg6GLYLgCDF0Nhq6C4SowdDMYugmGa8DQ3WDoLhiuA0MPg6GHYLgBDD0Nhp6C4SYw9DIYegmGW8DQ22DoLRhuA0Mfg6GPYLgDDH0Nhr6C4S4w9DMY+gmGe8DQ32DoLxjuA8MAg2GAYHgADAMNhoGC4SEwDDIYBgmGR8Aw2GAYLBgeA8MQg2GIYHgCDEMNhqGC4SkwDDMYhgmGZ8Aw3GAYLhieA8MIg2GEYHgBDCMNhpGC4SUwjDIYRgmGV8Aw2mAYLRheA8MYg2GMYHgDDGMNhrGC4S0wjDMYxgmGd8Aw3mAYLxjeA8MEg2GCYPgADBMNhomC4SMwTDIYJgmGT8Aw2WCYLBg+A8OUEBs+5Prii6AD31Ku/98w1bDDVOWWgOE/g+E/5ZaAYZrBME0wfJH7/zdMNximC4YwwDDDYJghGMICw0yDYaZgCAcMswyGWYIhPDDMNhhmC4YIwDDHYJgjGCICw1yDYa5giAQM8wyGeYIhMjDMNxjmC4YowLDAYFggGKICw0KDYaFgiAYMiwyGRYIhOjAsNhgWC4YYwLDEYFgiGGICw1KDYalgiAUMywyGZYIhNjAsNxiWC4Y4wLDCYFghGOICw0qDYaVgiAcMqwyGVYIhPjCsNhhWC4YEwLDGYFgjGBICw1qDYa1gSAQM6wyGdYIhMTCsNxjWC4YkwLDBYNggGJICw0aDYaNgSAYMmwyGTYIhOTBsNhg2C4YUwLDFYNgiGFICQ8BgCAiGVMCw1WDYKhhSA8M2g2GbYEgDDNsNhu2CIS0w7DAYdgiGdMCw02DYKRjSA8Mug2GXYMgADLsNht2CISMw7DEY9giGTMCw12DYKxgyA8M+g2GfYMgCDPsNhv2CISswHDAYDgiGbMBw0GA4KBiyA8Mhg+GQYMgBDIcNhsOCIScwHDEYjgiGXMBw1GA4KhhyA8Mxg+GYYMgDDMcNhuOCIS8wnDAYTgiGfMBw0mA4KRi+BIZTBsMpwZAfGE4bDKcFQwFgOGMwnBEMBYHhrMFwVjB8BQznDIZzguFrYDhvMJwXDN8AwwWD4YJg+BYYLhoMFwXDd8BwyWC4JBi+B4bLBsNlwfADMFwxGK4Ihh+B4arBcFUw/AQM1wyGa4LhZ2C4bjBcFwy/AMMNg+GGYPgVGG4aDDcFw2/AcMtguCUYfgeG2wbDbcHwBzDcMRjuCIY/geGuwXBXMPwFDPcMhnuC4W9guG8w3BcM/wDDA4PhgWD4FxgeGgwPBUMhYHhkMDwSDIWB4bHB8FgwFAGGJwbDE8FQFBieGgxPBUMxYHhmMDwTDMWB4bnB8FwwlACGFwbDC8FQEhheGgwvBUMpYHhlMLwSDKWB4bXB8FowlAGGNwbDG8FQFhjeGgxvBUM5YHhnMLwTDOWB4b3B8F4wVACGDwbDB8FQERg+GgwfBUMlYPhkMHwSDJWB4bPB8FkwVAGGL7aE3hBsUENVYAhjMIQRDNWAIazBEFYwVAeGcAZDOMFQAxjCGwzhBUNNYIhgMEQQDLWAIaLBEFEw1AaGSAZDJMFQBxgiGwyRBUNdYIhiMEQRDPWAIarBEFUw1AeGaAZDNMHQABiiGwzRBUNDYIhhMMQQDI2AIabBEFMwNAaGWAZDLMHQBBhiGwyxBUNTYIhjMMQRDM2AIa7BEFcwNAeGeAZDPMHQAhjiGwzxBUNLYEhgMCQQDK2AIaHBkFAwtAaGRAZDIsHQBhgSGwyJBUNbYEhiMCQRDO2AIanBkFQwtAeGZAZDMsHQARiSGwzJBUNHYEhhMKQQDJ2AIaXBkFIwdAaGVAZDKsHQBRhSGwypBUNXYEhjMKQRDN2AIa3BkFYwdAeGdAZDOsHQAxjSGwzpBUNPYMhgMGQQDL2AIaPBkFEw9AaGTAZDJsHQBxgyGwyZBUNfYMhiMGQRDP2AIavBkFUw9AeGbAZDNsEwABiyGwzZBcNAYMhhMOQQDIOAIafBkFMwDAaGXAZDLsEwBBhyGwy5BcNQYMhjMOQRDMOAIa/BkFcwDAeGfAZDPsEwAhi+NBi+FAwjgSG/wZBfMIwChgIGQwHBMBoYChoMBQXDGGD4ymD4SjCMBYavDYavBcM4YPjGYPhGMIwHhm8Nhm8FwwRg+M5g+E4wTASG7w2G7wXDJGD4wWD4QTBMBoYfDYYfBcMUYPjJYPhJMEwFhp8Nhp8Fw3/A8IvB8ItgmAYMvxoMvwqG6cDwm8Hwm2CYAQy/Gwy/C4aZwPCHwfCHYJgFDH8aDH8KhtnA8JfB8JdgmAMMfxsMfwuGucDwj8Hwj2CYBwz/Ggz/Cob5wFDIYCgkGBYAQ2GDobBgWAgMRQyGIoJhETAUNRiKCobFwFDMYCgmGJYAQ3GDobhgWAoMJQyGEoJhGTCUNBhKCoblwFDKYCglGFYAQ2mDobRgWAkMZQyGMoJhFTCUNRjKCobVwFDOYCgnGNYAQ3mDobxgWAsMFQyGCoJhHTBUNBgqCob1wFDJYKgkGDYAQ2WDobJg2AgMVQyGKoJhEzBUNRiqCobNwFDNYKgmGLYAQ3WDobpgCABDDYOhhmDYCgw1DYaagmEbMNQyGGoJhu3AUNtgqC0YdgBDHYOhjmDYCQx1DYa6gmEXMNQzGOoJht3AUN9gqC8Y9gBDA4OhgWDYCwwNDYaGgmEfMDQyGBoJhv3A0NhgaCwYDgBDE4OhiWA4CAxNDYamguEQMDQzGJoJhsPA0NxgaC4YjgBDC4OhhWA4CgwtDYaWguEYMLQyGFoJhuPA0NpgaC0YTgBDG4OhjWA4CQxtDYa2guEUMLQzGNoJhtPA0N5gaC8YzgBDB4Ohg2A4CwwdDYaOguEcMHQyGDoJhvPA0Nlg6CwYLgBDF4Ohi2C4CAxdDYauguESMHQzGLoJhsvA0N1g6C4YrgBDD4Ohh2C4Cgw9DYaeguEaMPQyGHoJhuvA0Ntg6C0YbgBDH4Ohj2C4CQx9DYa+guEWMPQzGPoJhtvA0N9g6C8Y7gDDAINhgGC4CwwDDYaBguEeMAwyGAYJhvvAMNhgGCwYHgDDEINhiGB4CAxDDYahguERMAwzGIYJhsfAMNxgGC4YngDDCINhhGB4CgwjDYaRguEZMIwyGEYJhufAMNpgGC0YXgDDGINhjGB4CQxjDYaxguEVMIwzGMYJhtfAMN5gGC8Y3gDDBINhgmB4CwwTDYaJguEdMEwyGCYJhvfAMNlgmCwYPgDDFINhimD4CAxTDYapguETMPxnMPwnGD4DwzSDYZpg+CLP/2+YbjBMFwxhgGGGwTBDMIQFhpkGw0zBEA4YZhkMswRDeGCYbTDMFgwRgGGOwTBHMEQEhrkGw1zBEAkY5hkM8wRDZGCYbzDMFwxRgGGBwbBAMEQFhoUGw0LBEA0YFhkMiwRDdGBYbDAsFgwxgGGJwbBEMMQEhqUGw1LBEAsYlhkMywRDbGBYbjAsFwxxgGGFwbBCMMQFhpUGw0rBEA8YVhkMqwRDfGBYbTCsFgwJgGGNwbBGMCQEhrUGw1rBkAgY1hkM6wRDYmBYbzCsFwxJgGGDwbBBMCQFho0Gw0bBkAwYNhkMmwRDcmDYbDBsFgwpgGGLwbBFMKQEhoDBEBAMqYBhq8GwVTCkBoZtBsM2wZAGGLYbDNsFQ1pg2GEw7BAM6YBhp8GwUzCkB4ZdBsMuwZABGHYbDLsFQ0Zg2GMw7BEMmYBhr8GwVzBkBoZ9BsM+wZAFGPYbDPsFQ1ZgOGAwHBAM2YDhoMFwUDBkB4ZDBsMhwZADGA4bDIcFQ05gOGIwHBEMuYDhqMFwVDDkBoZjBsMxwZAHGI4bDMcFQ15gOGEwnBAM+YDhpMFwUjB8CQynDIZTgiE/MJw2GE4LhgLAcMZgOCMYCgLDWYPhrGD4ChjOGQznBMPXwHDeYDgvGL4BhgsGwwXB8C0wXDQYLgqG74DhksFwSTB8DwyXDYbLguEHYLhiMFwRDD8Cw1WD4apg+AkYrhkM1wTDz8Bw3WC4Lhh+AYYbBsMNwfArMNw0GG4Kht+A4ZbBcEsw/A4Mtw2G24LhD2C4YzDcEQx/AsNdg+GuYPgLGO4ZDPcEw9/AcN9guC8Y/gGGBwbDA8HwLzA8NBgeCoZCwPDIYHgkGAoDw2OD4bFgKAIMTwyGJ4KhKDA8NRieCoZiwPDMYHgmGIoDw3OD4blgKAEMLwyGF4KhJDC8NBheCoZSwPDKYHglGEoDw2uD4bVgKAMMbwyGN4KhLDC8NRjeCoZywPDOYHgnGMoDw3uD4b1gqAAMHwyGD4KhIjB8NBg+CoZKwPDJYPgkGCoDw2eD4bNgqAIMXwRCbwg2qKEqMIQJhN4QbFBDNWAIGwi9IdighurAEC4QekOwQQ01gCF8IPSGYIMaagJDhEDoDcEGNdQChoiB0BuCDWqoDQyRAqE3BBvUUAcYIgdCbwg2qKEuMEQJhN4QbFBDPWCIGgi9IdighvrAEC0QekOwQQ0NgCF6IPSGYIMaGgJDjEDoDcEGNTQChpiB0BuCDWpoDAyxAqE3BBvU0AQYYgdCbwg2qKEpMMQJhN4QbFBDM2CIGwi9IdighubAEC8QekOwQQ0tgCF+IPSGYIMaWgJDgkDoDcEGNbQChoSB0BuCDWpoDQyJAqE3BBvU0AYYEgdCbwg2qKEtMCQJhN4QbFBDO2BIGgi9IdighvbAkCwQekOwQQ0dgCF5IPSGYIMaOgJDikDoDcEGNXQChpSB0BuCDWroDAypAqE3BBvU0AUYUgdCbwg2qKErMKQJhN4QbFBDN2BIGwi9Idighu7AkC4QekOwQQ09gCF9IPSGYIMaegJDhkDoDcEGNfQChoyB0BuCDWroDQyZAqE3BBvU0AcYMgdCbwg2qKEvMGQJhN4QbFBDP2DIGgi9Idighv7AkC0QekOwQQ0DgCF7IPSGYIMaBgJDjkDoDcEGNQwChpyB0BuCDWoYDAy5AqE3BBvUMAQYcgdCbwg2qGEoMOQJhN4QbFDDMGDIGwi9IdighuHAkC8QekOwQQ0jgOHLQOgNwQY1jASG/IHQG4INahgFDAUCoTcEG9QwGhgKBkJvCDaoYQwwfBUIvSHYoIaxwPB1IPSGYIMaxgHDN4HQG4INahgPDN8GQm8INqhhAjB8Fwi9IdighonA8H0g9IZggxomAcMPgdAbgg1qmAwMPwZCbwg2qGEKMPwUCL0h2KCGqcDwcyD0hmCDGv4Dhl8CoTcEG9QwDRh+DYTeEGxQw3Rg+C0QekOwQQ0zgOH3QOgNwQY1zASGPwKhNwQb1DALGP4MhN4QbFDDbGD4KxB6Q7BBDXOA4e9A6A3BBjXMBYZ/AqE3BBvUMA8Y/g2E3hBsUMN8YCgUCL0h2KCGBcBQOBB6Q7BBDQuBoUgg9IZggxoWAUPRQOgNwQY1LAaGYoHQG4INalgCDMUDoTcEG9SwFBhKBEJvCDaoYRkwlAyE3hBsUMNyYCgVCL0h2KCGFcBQOhB6Q7BBDSuBoUwg9IZggxpWAUPZQOgNwQY1rAaGcoHQG4INalgDDOUDoTcEG9SwFhgqBEJvCDaoYR0wVAyE3hBsUMN6YKgUCL0h2KCGDcBQORB6Q7BBDRuBoUog9IZggxo2AUPVQOgNwQY1bAaGaoHQG4INatgCDNUDoTcEG9QQAIYagdAbgg1q2AoMNQOhNwQb1LANGGoFQm8INqhhOzDUDoTeEGxQww5gqBMIvSHYoIadwFA3EHpDsEENu4ChXiD0hmCDGnYDQ/1A6A3BBjXsAYYGgdAbgg1q2AsMDQOhNwQb1LAPGBoFQm8INqhhPzA0DoTeEGxQwwFgaBIIvSHYoIaDwNA0EHpDsEENh4ChWSD0hmCDGg4DQ/NA6A3BBjUcAYYWgdAbgg1qOAoMLQOhNwQb1HAMGFoFQm8INqjhODC0DoTeEGxQwwlgaBMIvSHYoIaTwNA2EHpDsEENp4ChXSD0hmCDGk4DQ/tA6A3BBjWcAYYOgdAbgg1qOAsMHQOhNwQb1HAOGDoFQm8INqjhPDB0DoTeEGxQwwVg6BIIvSHYoIaLwNA1EHpDsEENl4ChWyD0hmCDGi4DQ/dA6A3BBjVcAYYegdAbgg1quAoMPQOhNwQb1HANGHoFQm8INqjhOjD0DoTeEGxQww1g6BMIvSHYoIabwNA3EHpDsEENt4ChXyD0hmCDGm4DQ/9A6A3BBjXcAYYBgdAbgg1quAsMAwOhNwQb1HAPGAYFQm8INqjhPjAMDoTeEGxQwwNgGBIIvSHYoIaHwDA0EHpDsEENj4BhWCD0hmCDGh4Dw/BA6A3BBjU8AYYRgdAbgg1qeAoMIwOhNwQb1PAMGEYFQm8INqjhOTCMDoTeEGxQwwtgGBMIvSHYoIaXwDA2EHpDsEENr4BhXCD0hmCDGl4Dw/hA6A3BBjW8AYYJgdAbgg1qeAsMEwOhNwQb1PAOGCYFQm8INqjhPTBMDoTeEGxQwwdgmBIIvSHYoIaPwDA1EHpDsEENn4Dhv0DoDcEGNXwGhmmB0BuCDWr4Iu//b5geCL0h2KCGMMAwIxB6Q7BBDWGBYWYg9IZggxrCAcOsQOgNwQY1hAeG2YHQG4INaogADHMCoTcEG9QQERjmBkJvCDaoIRIwzAuE3hBsUENkYJgfCL0h2KCGKMCwIBB6Q7BBDVGBYWEg9IZggxqiAcOiQOgNwQY1RAeGxYHQG4INaogBDEsCoTcEG9QQExiWBkJvCDaoIRYwLAuE3hBsUENsYFgeCL0h2KCGOMCwIhB6Q7BBDXGBYWUg9IZggxriAcOqQOgNwQY1xAeG1YHQG4INakgADGsCoTcEG9SQEBjWBkJvCDaoIREwrAuE3hBsUENiYFgfCL0h2KCGJMCwIRB6Q7BBDUmBYWMg9IZggxqSAcOmQOgNwQY1JAeGzYHQG4INakgBDFsCoTcEG9SQEhgCgdAbgg1qSAUMWwOhNwQb1JAaGLYFQm8INqghDTBsD4TeEGxQQ1pg2BEIvSHYoIZ0wLAzEHpDsEEN6YFhVyD0hmCDGjIAw+5A6A3BBjVkBIY9gdAbgg1qyAQMewOhNwQb1JAZGPYFQm8INqghCzDsD4TeEGxQQ1ZgOBAIvSHYoIZswHAwEHpDsEEN2YHhUCD0hmCDGnIAw+FA6A3BBjXkBIYjgdAbgg1qyAUMRwOhNwQb1JAbGI4FQm8INqghDzAcD4TeEGxQQ15gOBEIvSHYoIZ8wHAyEHpDsEENXwLDqUDoDcEGNeQHhtOB0BuCDWooAAxnAqE3BBvUUBAYzgZCbwg2qOErYDgXCL0h2KCGr4HhfCD0hmCDGr4BhguB0BuCDWr4FhguBkJvCDao4TtguBQIvSHYoIbvgeFyIPSGYIMafgCGK4HQG4INavgRGK4GQm8INqjhJ2C4Fgi9Idighp+B4Xog9IZggxp+AYYbgdAbgg1q+BUYbgZCbwg2qOE3YLgVCL0h2KCG34HhdiD0hmCDGv4AhjuB0BuCDWr4ExjuBkJvCDao4S9guBcIvSHYoIa/geF+IPSGYIMa/gGGB4HQG4INavgXGB4GQm8INqihEDA8CoTeEGxQQ2FgeBwIvSHYoIYiwPAkEHpDsEENRYHhaSD0hmCDGooBw7NA6A3BBjUUB4bngdAbgg1qKAEMLwKhNwQb1FASGF4GQm8INqihFDC8CoTeEGxQQ2lgeB0IvSHYoIYywPAmEHpDsEENZYHhbSD0hmCDGsoBw7tA6A3BBjWUB4b3gdAbgg1qqAAMHwKhNwQb1FARGD4GQm8INqihEjB8CoTeEGxQQ2Vg+BwIvSHYoIYqwPDF1tAbgg1qqAoMYQyGMIKhGjCENRjCCobqwBDOYAgnGGoAQ3iDIbxgqAkMEQyGCIKhFjBENBgiCobawBDJYIgkGOoAQ2SDIbJgqAsMUQyGKIKhHjBENRiiCob6wBDNYIgmGBoAQ3SDIbpgaAgMMQyGGIKhETDENBhiCobGwBDLYIglGJoAQ2yDIbZgaAoMcQyGOIKhGTDENRjiCobmwBDPYIgnGFoAQ3yDIb5gaAkMCQyGBIKhFTAkNBgSCobWwJDIYEgkGNoAQ2KDIbFgaAsMSQyGJIKhHTAkNRiSCob2wJDMYEgmGDoAQ3KDIblg6AgMKQyGFIKhEzCkNBhSCobOwJDKYEglGLoAQ2qDIbVg6AoMaQyGNIKhGzCkNRjSCobuwJDOYEgnGHoAQ3qDIb1g6AkMGQyGDIKhFzBkNBgyCobewJDJYMgkGPoAQ2aDIbNg6AsMWQyGLIKhHzBkNRiyCob+wJDNYMgmGAYAQ3aDIbtgGAgMOQyGHIJhEDDkNBhyCobBwJDLYMglGIYAQ26DIbdgGAoMeQyGPIJhGDDkNRjyCobhwJDPYMgnGEYAw5cGw5eCYSQw5DcY8guGUcBQwGAoIBhGA0NBg6GgYBgDDF8ZDF8JhrHA8LXB8LVgGAcM3xgM3wiG8cDwrcHwrWCYAAzfGQzfCYaJwPC9wfC9YJgEDD8YDD8IhsnA8KPB8KNgmAIMPxkMPwmGqcDws8Hws2D4Dxh+MRh+EQzTgOFXg+FXwTAdGH4zGH4TDDOA4XeD4XfBMBMY/jAY/hAMs4DhT4PhT8EwGxj+Mhj+EgxzgOFvg+FvwTAXGP4xGP4RDPOA4V+D4V/BMB8YChkMhQTDAmAobDAUFgwLgaGIwVBEMCwChqIGQ1HBsBgYihkMxQTDEmAobjAUFwxLgaGEwVBCMCwDhpIGQ0nBsBwYShkMpQTDCmAobTCUFgwrgaGMwVBGMKwChrIGQ1nBsBoYyhkM5QTDGmAobzCUFwxrgaGCwVBBMKwDhooGQ0XBsB4YKhkMlQTDBmCobDBUFgwbgaGKwVBFMGwChqoGQ1XBsBkYqhkM1QTDFmCobjBUFwwBYKhhMNQQDFuBoabBUFMwbAOGWgZDLcGwHRhqGwy1BcMOYKhjMNQRDDuBoa7BUFcw7AKGegZDPcGwGxjqGwz1BcMeYGhgMDQQDHuBoaHB0FAw7AOGRgZDI8GwHxgaGwyNBcMBYGhiMDQRDAeBoanB0FQwHAKGZgZDM8FwGBiaGwzNBcMRYGhhMLQQDEeBoaXB0FIwHAOGVgZDK8FwHBhaGwytBcMJYGhjMLQRDCeBoa3B0FYwnAKGdgZDO8FwGhjaGwztBcMZYOhgMHQQDGeBoaPB0FEwnAOGTgZDJ8FwHhg6GwydBcMFYOhiMHQRDBeBoavB0FUwXAKGbgZDN8FwGRi6GwzdBcMVYOhhMPQQDFeBoafB0FMwXAOGXgZDL8FwHRh6Gwy9BcMNYOhjMPQRDDeBoa/B0Fcw3AKGfgZDP8FwGxj6Gwz9BcMdYBhgMAwQDHeBYaDBMFAw3AOGQQbDIMFwHxgGGwyDBcMDYBhiMAwRDA+BYajBMFQwPAKGYQbDMMHwGBiGGwzDBcMTYBhhMIwQDE+BYaTBMFIwPAOGUQbDKMHwHBhGGwyjBcMLYBhjMIwRDC+BYazBMFYwvAKGcQbDOMHwGhjGGwzjBcMbYJhgMEwQDG+BYaLBMFEwvAOGSQbDJMHwHhgmGwyTBcMHYJhiMEwRDB+BYarBMFUwfAKG/wyG/wTDZ2CYZjBMEwxf5Pv/DdMNhumCIQwwzDAYZgiGsMAw02CYKRjCAcMsg2GWYAgPDLMNhtmCIQIwzDEY5giGiMAw12CYKxgiAcM8g2GeYIgMDPMNhvmCIQowLDAYFgiGqMCw0GBYKBiiAcMig2GRYIgODIsNhsWCIQYwLDEYlgiGmMCw1GBYKhhiAcMyg2GZYIgNDMsNhuWCIQ4wrDAYVgiGuMCw0mBYKRjiAcMqg2GVYIgPDKsNhtWCIQEwrDEY1giGhMCw1mBYKxgSAcM6g2GdYEgMDOsNhvWCIQkwbDAYNgiGpMCw0WDYKBiSAcMmg2GTYEgODJsNhs2CIQUwbDEYtgiGlMAQMBgCgiEVMGw1GLYKhtTAsM1g2CYY0gDDdoNhu2BICww7DIYdgiEdMOw0GHYKhvTAsMtg2CUYMgDDboNht2DICAx7DIY9giETMOw1GPYKhszAsM9g2CcYsgDDfoNhv2DICgwHDIYDgiEbMBw0GA4KhuzAcMhgOCQYcgDDYYPhsGDICQxHDIYjgiEXMBw1GI4KhtzAcMxgOCYY8gDDcYPhuGDICwwnDIYTgiEfMJw0GE4Khi+B4ZTBcEow5AeG0wbDacFQABjOGAxnBENBYDhrMJwVDF8BwzmD4Zxg+BoYzhsM5wXDN8BwwWC4IBi+BYaLBsNFwfAdMFwyGC4Jhu+B4bLBcFkw/AAMVwyGK4LhR2C4ajBcFQw/AcM1g+GaYPgZGK4bDNcFwy/AcMNguCEYfgWGmwbDTcHwGzDcMhhuCYbfgeG2wXBbMPwBDHcMhjuC4U9guGsw3BUMfwHDPYPhnmD4GxjuGwz3BcM/wPDAYHggGP4FhocGw0PBUAgYHhkMjwRDYWB4bDA8FgxFgOGJwfBEMBQFhqcGw1PBUAwYnhkMzwRDcWB4bjA8FwwlgOGFwfBCMJQEhpcGw0vBUAoYXhkMrwRDaWB4bTC8FgxlgOGNwfBGMJQFhrcGw1vBUA4Y3hkM7wRDeWB4bzC8FwwVgOGDwfBBMFQEho8Gw0fBUAkYPhkMnwRDZWD4bDB8FgxVgOGLbaE3BBvUUBUYwhgMYQRDNWAIazCEFQzVgSGcwRBOMNQAhvAGQ3jBUBMYIhgMEQRDLWCIaDBEFAy1gSGSwRBJMNQBhsgGQ2TBUBcYohgMUQRDPWCIajBEFQz1gSGawRBNMDQAhugGQ3TB0BAYYhgMMQRDI2CIaTDEFAyNgSGWwRBLMDQBhtgGQ2zB0BQY4hgMcQRDM2CIazDEFQzNgSGewRBPMLQAhvgGQ3zB0BIYEhgMCQRDK2BIaDAkFAytgSGRwZBIMLQBhsQGQ2LB0BYYkhgMSQRDO2BIajAkFQztgSGZwZBMMHQAhuQGQ3LB0BEYUhgMKQRDJ2BIaTCkFAydgSGVwZBKMHQBhtQGQ2rB0BUY0hgMaQRDN2BIazCkFQzdgSGdwZBOMPQAhvQGQ3rB0BMYMhgMGQRDL2DIaDBkFAy9gSGTwZBJMPQBhswGQ2bB0BcYshgMWQRDP2DIajBkFQz9gSGbwZBNMAwAhuwGQ3bBMBAYchgMOQTDIGDIaTDkFAyDgSGXwZBLMAwBhtwGQ27BMBQY8hgMeQTDMGDIazDkFQzDgSGfwZBPMIwAhi8Nhi8Fw0hgyG8w5BcMo4ChgMFQQDCMBoaCBkNBwTAGGL4yGL4SDGOB4WuD4WvBMA4YvjEYvhEM44HhW4PhW8EwARi+Mxi+EwwTgeF7g+F7wTAJGH4wGH4QDJOB4UeD4UfBMAUYfjIYfhIMU4HhZ4PhZ8HwHzD8YjD8IhimAcOvBsOvgmE6MPxmMPwmGGYAw+8Gw++CYSYw/GEw/CEYZgHDnwbDn4JhNjD8ZTD8JRjmAMPfBsPfgmEuMPxjMPwjGOYBw78Gw7+CYT4wFDIYCgmGBcBQ2GAoLBgWAkMRg6GIYFgEDEUNhqKCYTEwFDMYigmGJcBQ3GAoLhiWAkMJg6GEYFgGDCUNhpKCYTkwlDIYSgmGFcBQ2mAoLRhWAkMZg6GMYFgFDGUNhrKCYTUwlDMYygmGNcBQ3mAoLxjWAkMFg6GCYFgHDBUNhoqCYT0wVDIYKgmGDcBQ2WCoLBg2AkMVg6GKYNgEDFUNhqqCYTMwVDMYqgmGLcBQ3WCoLhgCwFDDYKghGLYCQ02DoaZg2AYMtQyGWoJhOzDUNhhqC4YdwFDHYKgjGHYCQ12Doa5g2AUM9QyGeoJhNzDUNxjqC4Y9wNDAYGggGPYCQ0ODoaFg2AcMjQyGRoJhPzA0NhgaC4YDwNDEYGgiGA4CQ1ODoalgOAQMzQyGZoLhMDA0NxiaC4YjwNDCYGghGI4CQ0uDoaVgOAYMrQyGVoLhODC0NhhaC4YTwNDGYGgjGE4CQ1uDoa1gOAUM7QyGdoLhNDC0NxjaC4YzwNDBYOggGM4CQ0eDoaNgOAcMnQyGToLhPDB0Nhg6C4YLwNDFYOgiGC4CQ1eDoatguAQM3QyGboLhMjB0Nxi6C4YrwNDDYOghGK4CQ0+DoadguAYMvQyGXoLhOjD0Nhh6C4YbwNDHYOgjGG4CQ1+Doa9guAUM/QyGfoLhNjD0Nxj6C4Y7wDDAYBggGO4Cw0CDYaBguAcMgwyGQYLhPjAMNhgGC4YHwDDEYBgiGB4Cw1CDYahgeAQMwwyGYYLhMTAMNxiGC4YnwDDCYBghGJ4Cw0iDYaRgeAYMowyGUYLhOTCMNhhGC4YXwDDGYBgjGF4Cw1iDYaxgeAUM4wyGcYLhNTCMNxjGC4Y3wDDBYJggGN4Cw8QQG97l/+KLoIMa3uf//w2TDDtMEnb4AAyTDYbJguEjMEwxGKYIhk/AMNVgmCoYPgPDfwbDf4LhiwL/v2GawTBNMIQBhukGw3TBEBYYZhgMMwRDOGCYaTDMFAzhgWGWwTBLMEQAhtkGw2zBEBEY5hgMcwRDJGCYazDMFQyRgWGewTBPMEQBhvkGw3zBEBUYFhgMCwRDNGBYaDAsFAzRgWGRwbBIMMQAhsUGw2LBEBMYlhgMSwRDLGBYajAsFQyxgWGZwbBMMMQBhuUGw3LBEBcYVhgMKwRDPGBYaTCsFAzxgWGVwbBKMCQAhtUGw2rBkBAY1hgMawRDImBYazCsFQyJgWGdwbBOMCQBhvUGw3rBkBQYNhgMGwRDMmDYaDBsFAzJgWGTwbBJMKQAhs0Gw2bBkBIYthgMWwRDKmAIGAwBwZAaGLYaDFsFQxpg2GYwbBMMaYFhu8GwXTCkA4YdBsMOwZAeGHYaDDsFQwZg2GUw7BIMGYFht8GwWzBkAoY9BsMewZAZGPYaDHsFQxZg2Gcw7BMMWYFhv8GwXzBkA4YDBsMBwZAdGA4aDAcFQw5gOGQwHBIMOYHhsMFwWDDkAoYjBsMRwZAbGI4aDEcFQx5gOGYwHBMMeYHhuMFwXDDkA4YTBsMJwfAlMJw0GE4KhvzAcMpgOCUYCgDDaYPhtGAoCAxnDIYzguErYDhrMJwVDF8DwzmD4Zxg+AYYzhsM5wXDt8BwwWC4IBi+A4aLBsNFwfA9MFwyGC4Jhh+A4bLBcFkw/AgMVwyGK4LhJ2C4ajBcFQw/A8M1g+GaYPgFGK4bDNcFw6/AcMNguCEYfgOGmwbDTcHwOzDcMhhuCYY/gOG2wXBbMPwJDHcMhjuC4S9guGsw3BUMfwPDPYPhnmD4BxjuGwz3BcO/wPDAYHggGAoBw0OD4aFgKAwMjwyGR4KhCDA8NhgeC4aiwPDEYHgiGIoBw1OD4algKA4MzwyGZ4KhBDA8NxieC4aSwPDCYHghGEoBw0uD4aVgKA0MrwyGV4KhDDC8NhheC4aywPDGYHgjGMoBw1uD4a1gKA8M7wyGd4KhAjC8NxjeC4aKwPDBYPggGCoBw0eD4aNgqAwMnwyGT4KhCjB8Nhg+C4aqwPDF9tAbgg1qqAYMYQyGMIKhOjCENRjCCoYawBDOYAgnGGoCQ3iDIbxgqAUMEQyGCIKhNjBENBgiCoY6wBDJYIgkGOoCQ2SDIbJgqAcMUQyGKIKhPjBENRiiCoYGwBDNYIgmGBoCQ3SDIbpgaAQMMQyGGIKhMTDENBhiCoYmwBDLYIglGJoCQ2yDIbZgaAYMcQyGOIKhOTDENRjiCoYWwBDPYIgnGFoCQ3yDIb5gaAUMCQyGBIKhNTAkNBgSCoY2wJDIYEgkGNoCQ2KDIbFgaAcMSQyGJIKhPTAkNRiSCoYOwJDMYEgmGDoCQ3KDIblg6AQMKQyGFIKhMzCkNBhSCoYuwJDKYEglGLoCQ2qDIbVg6AYMaQyGNIKhOzCkNRjSCoYewJDOYEgnGHoCQ3qDIb1g6AUMGQyGDIKhNzBkNBgyCoY+wJDJYMgkGPoCQ2aDIbNg6AcMWQyGLIKhPzBkNRiyCoYBwJDNYMgmGAYCQ3aDIbtgGAQMOQyGHIJhMDDkNBhyCoYhwJDLYMglGIYCQ26DIbdgGAYMeQyGPIJhODDkNRjyCoYRwJDPYMgnGEYCw5cGw5eCYRQw5DcY8guG0cBQwGAoIBjGAENBg6GgYBgLDF8ZDF8JhnHA8LXB8LVgGA8M3xgM3wiGCcDwrcHwrWCYCAzfGQzfCYZJwPC9wfC9YJgMDD8YDD8IhinA8KPB8KNgmAoMPxkMPwmG/4DhZ4PhZ8EwDRh+MRh+EQzTgeFXg+FXwTADGH4zGH4TDDOB4XeD4XfBMAsY/jAY/hAMs4HhT4PhT8EwBxj+Mhj+EgxzgeFvg+FvwTAPGP4xGP4RDPOB4V+D4V/BsAAYChkMhQTDQmAobDAUFgyLgKGIwVBEMCwGhqIGQ1HBsAQYihkMxQTDUmAobjAUFwzLgKGEwVBCMCwHhpIGQ0nBsAIYShkMpQTDSmAobTCUFgyrgKGMwVBGMKwGhrIGQ1nBsAYYyhkM5QTDWmAobzCUFwzrgKGCwVBBMKwHhooGQ0XBsAEYKhkMlQTDRmCobDBUFgybgKGKwVBFMGwGhqoGQ1XBsAUYqhkM1QRDABiqGwzVBcNWYKhhMNQQDNuAoabBUFMwbAeGWgZDLcGwAxhqGwy1BcNOYKhjMNQRDLuAoa7BUFcw7AaGegZDPcGwBxjqGwz1BcNeYGhgMDQQDPuAoaHB0FAw7AeGRgZDI8FwABgaGwyNBcNBYGhiMDQRDIeAoanB0FQwHAaGZgZDM8FwBBiaGwzNBcNRYGhhMLQQDMeAoaXB0FIwHAeGVgZDK8FwAhhaGwytBcNJYGhjMLQRDKeAoa3B0FYwnAaGdgZDO8FwBhjaGwztBcNZYOhgMHQQDOeAoaPB0FEwnAeGTgZDJ8FwARg6GwydBcNFYOhiMHQRDJeAoavB0FUwXAaGbgZDN8FwBRi6GwzdBcNVYOhhMPQQDNeAoafB0FMwXAeGXgZDL8FwAxh6Gwy9BcNNYOhjMPQRDLeAoa/B0Fcw3AaGfgZDP8FwBxj6Gwz9BcNdYBhgMAwQDPeAYaDBMFAw3AeGQQbDIMHwABgGGwyDBcNDYBhiMAwRDI+AYajBMFQwPAaGYQbDMMHwBBiGGwzDBcNTYBhhMIwQDM+AYaTBMFIwPAeGUQbDKMHwAhhGGwyjBcNLYBhjMIwRDK+AYazBMFYwvAaGcQbDOMHwBhjGGwzjBcNbYJhgMEwQDO+AYaLBMFEwvAeGSQbDJMHwARgmGwyTBcNHYJhiMEwRDJ+AYarBMFUwfAaG/wyG/wTDFwX/f8M0g2GaYAgDDNMNhumCISwwzDAYZgiGcMAw02CYKRjCA8Msg2GWYIgADLMNhtmCISIwzDEY5giGSMAw12CYKxgiA8M8g2GeYIgCDPMNhvmCISowLDAYFgiGaMCw0GBYKBiiA8Mig2GRYIgBDIsNhsWCISYwLDEYlgiGWMCw1GBYKhhiA8Myg2GZYIgDDMsNhuWCIS4wrDAYVgiGeMCw0mBYKRjiA8Mqg2GVYEgADKsNhtWCISEwrDEY1giGRMCw1mBYKxgSA8M6g2GdYEgCDOsNhvWCISkwbDAYNgiGZMCw0WDYKBiSA8Mmg2GTYEgBDJsNhs2CISUwbDEYtgiGVMAQMBgCgiE1MGw1GLYKhjTAsM1g2CYY0gLDdoNhu2BIBww7DIYdgiE9MOw0GHYKhgzAsMtg2CUYMgLDboNht2DIBAx7DIY9giEzMOw1GPYKhizAsM9g2CcYsgLDfoNhv2DIBgwHDIYDgiE7MBw0GA4KhhzAcMhgOCQYcgLDYYPhsGDIBQxHDIYjgiE3MBw1GI4KhjzAcMxgOCYY8gLDcYPhuGDIBwwnDIYTguFLYDhpMJwUDPmB4ZTBcEowFACG0wbDacFQEBjOGAxnBMNXwHDWYDgrGL4GhnMGwznB8A0wnDcYzguGb4HhgsFwQTB8BwwXDYaLguF7YLhkMFwSDD8Aw2WD4bJg+BEYrhgMVwTDT8Bw1WC4Khh+BoZrBsM1wfALMFw3GK4Lhl+B4YbBcEMw/AYMNw2Gm4Lhd2C4ZTDcEgx/AMNtg+G2YPgTGO4YDHcEw1/AcNdguCsY/gaGewbDPcHwDzDcNxjuC4Z/geGBwfBAMBQChocGw0PBUBgYHhkMjwRDEWB4bDA8FgxFgeGJwfBEMBQDhqcGw1PBUBwYnhkMzwRDCWB4bjA8FwwlgeGFwfBCMJQChpcGw0vBUBoYXhkMrwRDGWB4bTC8FgxlgeGNwfBGMJQDhrcGw1vBUB4Y3hkM7wRDBWB4bzC8FwwVgeGDwfBBMFQCho8Gw0fBUBkYPhkMnwRDFWD4bDB8FgxVgeGLHaE3BBvUUA0YwhgMYQRDdWAIazCEFQw1gCGcwRBOMNQEhvAGQ3jBUAsYIhgMEQRDbWCIaDBEFAx1gCGSwRBJMNQFhsgGQ2TBUA8YohgMUQRDfWCIajBEFQwNgCGawRBNMDQEhugGQ3TB0AgYYhgMMQRDY2CIaTDEFAxNgCGWwRBLMDQFhtgGQ2zB0AwY4hgMcQRDc2CIazDEFQwtgCGewRBPMLQEhvgGQ3zB0AoYEhgMCQRDa2BIaDAkFAxtgCGRwZBIMLQFhsQGQ2LB0A4YkhgMSQRDe2BIajAkFQwdgCGZwZBMMHQEhuQGQ3LB0AkYUhgMKQRDZ2BIaTCkFAxdgCGVwZBKMHQFhtQGQ2rB0A0Y0hgMaQRDd2BIazCkFQw9gCGdwZBOMPQEhvQGQ3rB0AsYMhgMGQRDb2DIaDBkFAx9gCGTwZBJMPQFhswGQ2bB0A8YshgMWQRDf2DIajBkFQwDgCGbwZBNMAwEhuwGQ3bBMAgYchgMOQTDYGDIaTDkFAxDgCGXwZBLMAwFhtwGQ27BMAwY8hgMeQTDcGDIazDkFQwjgCGfwZBPMIwEhi8Nhi8FwyhgyG8w5BcMo4GhgMFQQDCMAYaCBkNBwTAWGL4yGL4SDOOA4WuD4WvBMB4YvjEYvhEME4DhW4PhW8EwERi+Mxi+EwyTgOF7g+F7wTAZGH4wGH4QDFOA4UeD4UfBMBUYfjIYfhIM/wHDzwbDz4JhGjD8YjD8IhimA8OvBsOvgmEGMPxmMPwmGGYCw+8Gw++CYRYw/GEw/CEYZgPDnwbDn4JhDjD8ZTD8JRjmAsPfBsPfgmEeMPxjMPwjGOYDw78Gw7+CYQEwFDIYCgmGhcBQ2GAoLBgWAUMRg6GIYFgMDEUNhqKCYQkwFDMYigmGpcBQ3GAoLhiWAUMJg6GEYFgODCUNhpKCYQUwlDIYSgmGlcBQ2mAoLRhWAUMZg6GMYFgNDGUNhrKCYQ0wlDMYygmGtcBQ3mAoLxjWAUMFg6GCYFgPDBUNhoqCYQMwVDIYKgmGjcBQ2WCoLBg2AUMVg6GKYNgMDFUNhqqCYQswVDMYqgmGADBUNxiqC4atwFDDYKghGLYBQ02DoaZg2A4MtQyGWoJhBzDUNhhqC4adwFDHYKgjGHYBQ12Doa5g2A0M9QyGeoJhDzDUNxjqC4a9wNDAYGggGPYBQ0ODoaFg2A8MjQyGRoLhADA0NhgaC4aDwNDEYGgiGA4BQ1ODoalgOAwMzQyGZoLhCDA0NxiaC4ajwNDCYGghGI4BQ0uDoaVgOA4MrQyGVoLhBDC0NhhaC4aTwNDGYGgjGE4BQ1uDoa1gOA0M7QyGdoLhDDC0NxjaC4azwNDBYOggGM4BQ0eDoaNgOA8MnQyGToLhAjB0Nhg6C4aLwNDFYOgiGC4BQ1eDoatguAwM3QyGboLhCjB0Nxi6C4arwNDDYOghGK4BQ0+DoadguA4MvQyGXoLhBjD0Nhh6C4abwNDHYOgjGG4BQ1+Doa9guA0M/QyGfoLhDjD0Nxj6C4a7wDDAYBggGO4Bw0CDYaBguA8MgwyGQYLhATAMNhgGC4aHwDDEYBgiGB4Bw1CDYahgeAwMwwyGYYLhCTAMNxiGC4anwDDCYBghGJ4Bw0iDYaRgeA4MowyGUYLhBTCMNhhGC4aXwDDGYBgjGF4Bw1iDYaxgeA0M4wyGKZu54YvI/79hvMEwTtjhDdhhQogNYWJ+8UXQQQ1hY/7/homGHSYKO4QDhkkGwyTBEB4YJhsMkwVDBGCY4vguCYaIwDDVYJgqGCIBw38Gw3+CITIwTDMYpgmGKMAw3WCYLhiiAsMMg2GGYIgGDDMNhpmCITowzDIYZgmGGMAw22CYLRhiAsMcg2GOYIgFDHMNhrmCITYwzDMY5gmGOMAw32CYLxjiAsMCg2GBYIgHDAsNhoWCIT4wLDIYFgmGBMCw2GBYLBgSAsMSg2GJYEgEDEsNhqWCITEwLDMYlgmGJMCw3GBYLhiSAsMKg2GFYEgGDCsNhpWCITkwrDIYVgmGFMCw2mBYLRhSAsMag2GNYEgFDGsNhrWCITUwrDMY1gmGNMCw3mBYLxjSAsMGg2GDYEgHDBsNho2CIT0wbDIYNgmGDMCw2WDYLBgyAsMWg2GLYMgEDAGDISAYMgPDVoNhq2DIAgzbDIZtgiErMGw3GLYLhmzAsMNg2CEYsgPDToNhp2DIAQy7DIZdgiEnMOw2GHYLhlzAsMdg2CMYcgPDXoNhr2DIAwz7DIZ9giEvMOw3GPYLhnzAcMBgOCAYvgSGgwbDQcGQHxgOGQyHBEMBYDhsMBwWDAWB4YjBcEQwfAUMRw2Go4Lha2A4ZjAcEwzfAMNxg+G4YPgWGE4YDCcEw3fAcNJgOCkYvgeGUwbDKcHwAzCcNhhOC4YfgeGMwXBGMPwEDGcNhrOC4WdgOGcwnBMMvwDDeYPhvGD4FRguGAwXBMNvwHDRYLgoGH4HhksGwyXB8AcwXDYYLguGP4HhisFwRTD8BQxXDYarguFvYLhmMFwTDP8Aw3WD4bpg+BcYbhgMNwRDIWC4aTDcFAyFgeGWwXBLMBQBhtsGw23BUBQY7hgMdwRDMWC4azDcFQzFgeGewXBPMJQAhvsGw33BUBIYHhgMDwRDKWB4aDA8FAylgeGRwfBIMJQBhscGw2PBUBYYnhgMTwRDOWB4ajA8FQzlgeGZwfBMMFQAhucGw3PBUBEYXhgMLwRDJWB4aTC8FAyVgeGVwfBKMFQBhtcGw2vBUBUY3hgMbwRDNWB4azC8FQzVgeGdwfBOMNQAhvcGw3vBUBMYPhgMHwRDLWD4aDB8FAy1geGTwfBJMNQBhs8Gw2fBUBcYvtgZekOwQQ31gCGMwRBGMNQHhrAGQ1jB0AAYwhkM4QRDQ2AIbzCEFwyNgCGCwRBBMDQGhogGQ0TB0AQYIhkMkQRDU2CIbDBEFgzNgCGKwRBFMDQHhqgGQ1TB0AIYohkM0QRDS2CIbjBEFwytgCGGwRBDMLQGhpgGQ0zB0AYYYhkMsQRDW2CIbTDEFgztgCGOwRBHMLQHhrgGQ1zB0AEY4hkM8QRDR2CIbzDEFwydgCGBwZBAMHQGhoQGQ0LB0AUYEhkMiQRDV2BIbDAkFgzdgCGJwZBEMHQHhqQGQ1LB0AMYkhkMyQRDT2BIbjAkFwy9gCGFwZBCMPQGhpQGQ0rB0AcYUhkMqQRDX2BIbTCkFgz9gCGNwZBGMPQHhrQGQ1rBMAAY0hkM6QTDQGBIbzCkFwyDgCGDwZBBMAwGhowGQ0bBMAQYMhkMmQTDUGDIbDBkFgzDgCGLwZBFMAwHhqwGQ1bBMAIYshkM2QTDSGDIbjBkFwyjgCGHwZBDMIwGhpwGQ07BMAYYchkMuQTDWGDIbTDkFgzjgCGPwZBHMIwHhrwGQ17BMAEY8hkM+QTDRGD40mD4UjBMAob8BkN+wTAZGAoYDAUEwxRgKGgwFBQMU4HhK4PhK8HwHzB8bTB8LRimAcM3BsM3gmE6MHxrMHwrGGYAw3cGw3eCYSYwfG8wfC8YZgHDDwbDD4JhNjD8aDD8KBjmAMNPBsNPgmEuMPxsMPwsGOYBwy8Gwy+CYT4w/Gow/CoYFgDDbwbDb4JhITD8bjD8LhgWAcMfBsMfgmExMPxpMPwpGJYAw18Gw1+CYSkw/G0w/C0YlgHDPwbDP4JhOTD8azD8KxhWAEMhg6GQYFgJDIUNhsKCYRUwFDEYigiG1cBQ1GAoKhjWAEMxg6GYYFgLDMUNhuKCYR0wlDAYSgiG9cBQ0mAoKRg2AEMpg6GUYNgIDKUNhtKCYRMwlDEYygiGzcBQ1mAoKxi2AEM5g6GcYAgAQ3mDobxg2AoMFQyGCoJhGzBUNBgqCobtwFDJYKgkGHYAQ2WDobJg2AkMVQyGKoJhFzBUNRiqCobdwFDNYKgmGPYAQ3WDobpg2AsMNQyGGoJhHzDUNBhqCob9wFDLYKglGA4AQ22DobZgOAgMdQyGOoLhEDDUNRjqCobDwFDPYKgnGI4AQ32Dob5gOAoMDQyGBoLhGDA0NBgaCobjwNDIYGgkGE4AQ2ODobFgOAkMTQyGJoLhFDA0NRiaCobTwNDMYGgmGM4AQ3ODoblgOAsMLQyGFoLhHDC0NBhaCobzwNDKYGglGC4AQ2uDobVguAgMbQyGNoLhEjC0NRjaCobLwNDOYGgnGK4AQ3uDob1guAoMHQyGDoLhGjB0NBg6CobrwNDJYOgkGG4AQ2eDobNguAkMXQyGLoLhFjB0NRi6CobbwNDNYOgmGO4AQ3eDobtguAsMPQyGHoLhHjD0NBh6Cob7wNDLYOglGB4AQ2+DobdgeAgMfQyGPoLhETD0NRj6CobHwNDPYOgnGJ4AQ3+Dob9geAoMAwyGAYLhGTAMNBgGCobnwDDIYBgkGF4Aw2CDYbBgeAkMQwyGIYLhFTAMNRiGCobXwDDMYBgmGN4Aw3CDYbhgeAsMIwyGEYLhHTCMNBhGCob3wDDKYBglGD4Aw2iDYbRg+AgMYwyGMYLhEzCMNRjGCobPwDDOYBgnGL6I9f8bxhsM4wVDGGCYYDBMEAxhgWGiwTBRMIQDhkkGwyTBEB4YJhsMkwVDBGCYYjBMEQwRgWGqwTBVMEQChv8Mhv8EQ2RgmGYwTBMMUYBhusEwXTBEBYYZBsMMwRANGGYaDDMFQ3RgmGUwzBIMMYBhtsEwWzDEBIY5BsMcwRALGOYaDHMFQ2xgmGcwzBMMcYBhvsEwXzDEBYYFBsMCwRAPGBYaDAsFQ3xgWGQwLBIMCYBhscGwWDAkBIYlBsMSwZAIGJYaDEsFQ2JgWGYwLBMMSYBhucGwXDAkBYYVBsMKwZAMGFYaDCsFQ3JgWGUwrBIMKYBhtcGwWjCkBIY1BsMawZAKGNYaDGsFQ2pgWGcwrBMMaYBhvcGwXjCkBYYNBsMGwZAOGDYaDBsFQ3pg2GQwbBIMGYBhs8GwWTBkBIYtBsMWwZAJGAIGQ0AwZAaGrQbDVsGQBRi2GQzbBENWYNhuMGwXDNmAYYfBsEMwZAeGnQbDTsGQAxh2GQy7BENOYNhtMOwWDLmAYY/BsEcw5AaGvQbDXsGQBxj2GQz7BENeYNhvMOwXDPmA4YDBcEAwfAkMBw2Gg4IhPzAcMhgOCYYCwHDYYDgsGAoCwxGD4Yhg+AoYjhoMRwXD18BwzGA4Jhi+AYbjBsNxwfAtMJwwGE4Ihu+A4aTBcFIwfA8MpwyGU4LhB2A4bTCcFgw/AsMZg+GMYPgJGM4aDGcFw8/AcM5gOCcYfgGG8wbDecHwKzBcMBguCIbfgOGiwXBRMPwODJcMhkuC4Q9guGwwXBYMfwLDFYPhimD4CxiuGgxXBcPfwHDNYLgmGP4BhusGw3XB8C8w3DAYbgiGQsBw02C4KRgKA8Mtg+GWYCgCDLcNhtuCoSgw3DEY7giGYsBw12C4KxiKA8M9g+GeYCgBDPcNhvuCoSQwPDAYHgiGUsDw0GB4KBhKA8Mjg+GRYCgDDI8NhseCoSwwPDEYngiGcsDw1GB4KhjKA8Mzg+GZYKgADM8NhueCoSIwvDAYXgiGSsDw0mB4KRgqA8Mrg+GVYKgCDK8NhteCoSowvDEY3giGasDw1mB4KxiqA8M7g+GdYKgBDO8NhveCoSYwfDAYPgiGWsDw0WD4KBhqA8Mng+GTYKgDDJ8Nhs+CoS4wfLEr9IZggxrqAUMYgyGMYKgPDGENhrCCoQEwhDMYwgmGhsAQ3mAILxgaAUMEgyGCYGgMDBENhoiCoQkwRDIYIgmGpsAQ2WCILBiaAUMUgyGKYGgODFENhqiCoQUwRDMYogmGlsAQ3WCILhhaAUMMgyGGYGgNDDENhpiCoQ0wxDIYYgmGtsAQ22CILRjaAUMcgyGOYGgPDHENhriCoQMwxDMY4gmGjsAQ32CILxg6AUMCgyGBYOgMDAkNhoSCoQswJDIYEgmGrsCQ2GBILBi6AUMSgyGJYOgODEkNhqSCoQcwJDMYkgmGnsCQ3GBILhh6AUMKgyGFYOgNDCkNhpSCoQ8wpDIYUgmGvsCQ2mBILRj6AUMagyGNYOgPDGkNhrSCYQAwpDMY0gmGgcCQ3mBILxgGAUMGgyGDYBgMDBkNhoyCYQgwZDIYMgmGocCQ2WDILBiGAUMWgyGLYBgODFkNhqyCYQQwZDMYsgmGkcCQ3WDILhhGAUMOgyGHYBgNDDkNhpyCYQww5DIYcgmGscDwP97+AkrLOvD7dVVASkSkRESku7u7u7u7u7u7u7u7QUREQERESkQERLq7+1yz9z6xz1nv/f6HtQ6udS1dfh5wvs/M/cyoM/cv/QfYkP49NkwPxYYMH2BDhvfYMCMUGzJ+gA0Z32PDzFBsyPQBNmR6jw2zQrEh8wfYkPk9NswOxYYsH2BDlvfYMCcUG7J+gA1Z32PD3FBsyPYBNmR7jw3zQrEh+wfYkP09NswPxYYcH2BDjvfYsCAUG3J+gA0532PDwlBsyPUBNuR6jw2LQrEh9wfYkPs9NiwOxYY8H2BDnvfYsCQUG/J+gA1532PD0lBsyPcBNuR7jw3LQrEh/wfYkP89NiwPxYYCH2BDgffYsCIUGwp+gA0F32PDylBsKPQBNhR6jw2rQrGh8AfYUPg9NqwOxYYiH2BDkffYsCYUG4p+gA1F32PD2lBsKPYBNhR7jw3rQrGh+AfYUPw9NqwPxYYSH2BDiffYsCEUG0p+gA0l32PDxlBsKPUBNpR6jw2bQrGh9AfYUPo9NmwOxYYyH2BDmffYsCUUG8p+gA1l32PD1lBsKPcBNpR7jw3bQrGh/AfYUP49NmwPxYYKH2BDhffYsCMUGyp+gA0V32PD96HYUOkDbKj0Hht2hmJD5Q+wofJ7bPghFBuqfIANVd5jw65QbKj6ATZUfY8NP4ZiQ7UPsKHae2zYHYoN1T/AhurvseGnUGyo8QE21HiPDXtCsaHmB9hQ8z02/ByKDbU+wIZa77Fhbyg21P4AG2q/x4Z9odhQ5wNsqPMeG/aHYkPdD7Ch7nts+CUUG+p9gA313mPDgVBsqP8BNtR/jw2/hmJDgw+wocF7bDgYig0NP8CGhu+x4bdQbGj0ATY0eo8Nh0KxofEH2ND4PTb8HooNTT7AhibvseFwKDY0/QAbmr7Hhj9CsaHZB9jQ7D02HAnFhuYfYEPz99hwNBQbWnyADS3eY8OxUGxo+QE2tHyPDcdDsaHVB9jQ6j02nAjFhtYfYEPr99jwZyg2tPkAG9q8x4aTodjQ9gNsaPseG/4KxYZ2H2BDu/fYcCoUG9p/gA3t32PD36HY0OEDbOjwHhtOh2JDxw+woeN7bPgnFBs6fYANnd5jw5lQbOj8ATZ0fo8NZ0OxocsH2NDlPTacC8WGrh9gQ9f32PBvKDZ0+wAbur3HhvOh2ND9A2zo/h4b/gvFhh4fYEOP99hwIRQben6ADT3fY8PFUGzo9QE29HqPDZdCsaH3B9jQ+z02XA7Fhj4fYEOf99hwJRQb+n6ADX3fY8PVUGzo9wE29HuPDddCsaH/B9jQ/z02XA/FhgEfYMOA99hwIxQbBn6ADQPfY8PNUGwY9AE2DHqPDbdCsWHwB9gw+D023A7FhiEfYMOQ99hwJxQbhn6ADUPfY8PdUGwY9gE2DHuPDfdCsWH4B9gw/D023A/FhhEfYMOI99jwIBQbRn6ADSPfY8PDUGwY9QE2jHqPDY9CsWH0B9gw+j02PA7FhjEfYMOY99jwJBQbxn6ADWPfY8PTUGwY9wE2jHuPDc9CsWH8B9gw/j02PA/FhgkfYMOE99jwIhQbJn6ADRPfY8PLUGyY9AE2THqPDa9CsWHyB9gw+T02vA7FhikfYMOU99jwJhQbpn6ADVPfY8PbUGyY9gE2THuPDe9CsWH6B9gw/4fQb/jos//5hhkfYMP093g/fPTF/3zDzP//bfgkRs/GvUI2bJ/5//vr/ndv1/nToXu7wv5//f4Bf0R99zr///HcLtkayo+n70Px+MUffbQgFI/f6PELPT7c//U3/qe/7qOv/+fvi5AH/g8e+388P2+T/c/fV7P+5x9DH4f2/Rrm//rzd//7h/6/3q+zfg7d+2nGvtC9n2buC9XH2//x6z6K9T/f8DLT//y5nx2K5/50KJ/7yP/Xn7/7378tg+5//N1HIc/9pvn/87c95PFrF4fuGly/9H/++A2T/++v0f+7tyfk8aH5WN7o8SvW/89//5DHr1z/P//9N0/+v78+/+9+/5DHzw7F49d57tcvDsXz47EhH/+hfo2K9D//Z3z01f/osUM2jq/9f3s9+999bL5L9P9+bPz8FZ69PR8p3OWUKdofPLqt69mrc14V2z4uVtw5qQfVahrvRWheo55n+3+O/D8/T4e8XoW8NoQ8R58SnghExNPwf1xTvsT4KAqf40umkE/XH0XjS6ITg5h4yfgo9v/5lHwUBy/1H8XlG+LxbciWj/7PtzUBCTHzo8QkISlexj9KTgpSkorUpCEt6UKeOzKQES89H2UmC1kJmZedHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBIu44+mMJVpTGcGvoz6aBazmcNc5jGfBSxkES7Rj5bgpfKjZSxnBStZxWrWsJZ1eEn6aAMb2cRmtuDLo4+2sZ0d+PLko534svqjXfzIbn5iDz7tfrQXnx4/2o+Xoo8O8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8jUvyo384w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7hHyuvOAhzziMU94yjOe84KXvOI1b3jLO0Iu/o/5hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHSGf+D/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd4R80f8xnxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vi8x0JSEgiEpOEpCQjOSlISSpSk4a0pCM9GchIJjKThaxkIzs5yEkucpOHvOQjPwUoSCEKU4SiFKM4JShJKUpThrKUozwVqEglKlOFqlSjOjWoSS1qU4e61KM+DWhIIxrThKY0ozktaEkrWtOGtrSjPR3oSCc604WudKM7PehJL3rTh770oz8DGMggBjOEoQxjOCMYyShGM4axjGM8E5jIJCYzhalMYzozmMksZjOHucxjPgtYyCIWs4SlLGM5K1jJKlazhrWsYz0b2MgmNrOFrWxjOzv4np38wC5+ZDc/sYef2cs+9vMLB/iVg/zGIX7nMH9whKMc4zgn+JOT/MUp/uY0/3CGs5zjX87zHxe4yCUuc4WrXOM6N7jJLW5zh7vc4z4PeMgjHvOEpzzjOS94ySte84a3vCPkX/g/5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneE/Me+j/mEMIQlHJ8SnghEJBKR+YwofE5UviAaXxKdGMQkFrH5ijh8TVy+IR7fEp/vSEBCEpGYJCQlGclJQUpSkZo0pCUd6clARjKRmSxkJRvZyUFOcpGbPOQlH/kpQEEKUZgiFKUYxSlBSUpRmjKUpRzlqUBFKlGZKlSlGtWpQU1qUZs61KUe9WlAQxrRmCY0pRnNaUFLWtGaNrSlHe3pQEc60ZkudKUb3elBT3rRmz70pR/9GcBABjGYIQxlGMMZwUhGMZoxjGUc45nARCYxmSlMZRrTmcFMZjGbOcxlHvNZwEIWsZglLGUZy1nBSlaxmjWsZR3r2cBGNrGZLWxlG9vZwffs5Ad28SO7+Yk9/Mxe9rGfXzjArxzkNw7xO4f5gyMc5RjHOcGfnOQvTvE3p/mHM5zlHP9ynv+4wEUucZkrXOUa17nBTW5xmzvc5R73ecBDHvGYJzzlGc95wUte8Zo3vOUdIf+h/2M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8j/5PuYTwhDWMLxKeGJQEQiEZnPiMLnROULovEl0YlBTGIRm6+Iw9fE5Rvi8S3x+Y4EJCQRiUlCUpKRnBSkJBWpSUNa0pGeDGQkE5nJQlaykZ0c5CQXuclDXvKRnwIUpBCFKUJRilGcEpSkFKUpQ1nKUZ4KVKQSlalCVapRnRrUpBa1qUNd6lGfBjSkEY1pQlOa0ZwWtKQVrWlDW9rRng50pBOd6UJXutGdHvSkF73pQ1/60Z8BDGQQgxnCUIYxnBGMZBSjGcNYxjGeCUxkEpOZwlSmMZ0ZzGQWs5nDXOYxnwUsZBGLWcJSlrGcFaxkFatZw1rWsZ4NbGQTm9nCVraxnR18z05+YBc/spuf2MPP7GUf+/mFA/zKQX7jEL9zmD84wlGOcZwT/MlJ/uIUf3OafzjDWc7xL+f5jwtc5BKXucJVrnGdG9zkFre5w13ucZ8HPOQRj3nCU57xnBe85BWvecNb3hHyP/g/5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneEfHPPx3xCGMISjk8JTwQiEonIfEYUPicqXxCNL4lODGISi9h8RRy+Ji7fEI9vic93JCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOkG/s+5hPCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfFDvreSBCQkEYlJQlKSkZwUpCQVqUlDWtKRngxkJBOZyUJWspGdHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBKTmcJUpjGdGcxkFrOZw1zmMZ8FLGQRi1nCUpaxnBWsZBWrWcNa1rGeDWxkE5vZwla2sZ0dfM9OfmAXP7Kbn9jDz+xlH/v5hQP8ykF+4xC/c5g/OMJRjnGcE/zJSf7iFH9zmn84w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7nGfBzzkEY95wlOe8ZwXvOQVr3nDW94R8k29H/MJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qr6h/2M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8QP+XlFEpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3lHyA/zfMwnhCEs4fiU8EQgIpGIzGdE4XOi8gXR+JLoxCAmsYjNV8Tha+LyDfH4lvh8RwISkojEJCEpyUhOClKSitSkIS3pSE8GMpKJzGQhK9nITg5ykovc5CEv+chPAQpSiMIUoSjFKE4JSlKK0pShLOUoTwUqUonKVKEq1ahODWpSi9rUoS71qE8DGtKIxjShKc1oTgta0orWtKEt7WhPBzrSic50oSvd6E4PetKL3vShL/3ozwAGMojBDGEowxjOCEYyitGMYSzjGM8EJjKJyUxhKtOYzgxmMovZzGEu85jPAhayiMUsYSnLWM4KVrKK1axhLetYzwY2sonNbGEr29jODr5nJz+wix/ZzU/s4Wf2so/9/MIBfuUgv3GI3znMHxzhKMc4zgn+5CR/cYq/Oc0/nOEs5/iX8/zHBS5yictc4SrXuM4NbnKL29zhLve4zwMe8ojHPOEpz3jOC17yite84S3vCPlBvo/5hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHSE/xPsxnxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vih9xzhQQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWQs68DzkzPuTM9ZAzy0PO/A45MzvkzOmQM5tDzjwOOTM45MzdkDNrQ858DTkzNeTM0ZAzO0POvAw5MzLkzMWQMwtDzvwLOTMv5My5kDPbQs48CzkzLOTMrZAzq0LOfAo5MynkzKGQM3tCzrwJOTMm5MyVkDNLQs78CDkzI+TMiZAzG0LOPAg5MyDknvsh96wPued7yD3TQ+45HnLP7pB7XofcMzrknssh9ywOuedvyD1zQ+45G3LP1pB7nobcMzTknpsh96wMuedjyD0TQ+45GHLPvpB73oXcMy7knmsh9ywLuedXyD2zQu45FXLPppB7HoX8AP/HfEIYwhKOTwlPBCISich8RhQ+JypfEI0viU4MYhKL2HxFHL4mLt8Qj2+JH3KvHxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8jNOz7mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd4TcuOdjPiEMYQnHp4QnAhGJRGQ+IwqfE5UviMaXRCcGMYlFbL4iDl8Tl2+Ix7fE5zsSkJBEJCYJSUlGclKQklSkJg1pSUd6MpCRTGQmC1nJRnZykJNc5CYPeclHfgpQkEIUpghFKUZxSlCSUpSmDGUpR3kqUJFKVKYKValGdWpQk1rUpg51qUd9GtCQRjSmCU1pRnNa0JJWtKYNbWlHezrQkU50pgtd6UZ3etCTXvSmD33pR38GMJBBDGYIQxnGcEYwklGMZgxjGcd4JjCRSUxmClOZxnRmMJNZzGYOc5nHfBawkEUsZglLWcZyVrCSVaxmDWtZx3o2sJFNbGYLW9nGdnbwPTv5gV38yG5+Yg8/s5d97OcXDvArB/mNQ/zOYf7gCEc5xnFO8Ccn+YtT/M1p/uEMZznHv5znPy5wkUtc5gpXucZ1bnCTW9zmDne5x30e8JBHPOYJT3nGc17wkle85g1veUfITbs+5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneE3LDv4xghN1l1/ROWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3hNys82M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8iNej/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEv8kPuKk4CEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qm7S/TGfEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+LzHQlISCISk4SkJCM5KUhJKlKThrSkIz0ZyEgmMpOFrGQjOznISS5yk4e85CM/BShIIQpThKIUozglKEkpSlOGspSjPBWoSCUqU4WqVKM6NahJLWpTh7rUoz4NaEgjGtOEpjSjOS1oSSta04a2tKM9HehIJzrTha50ozs96EkvetOHvvSjPwMYyCAGM4ShDGM4IxjJKEYzhrGMYzwTmMgkJjOFqUxjOjOYySxmM4e5zGM+C1jIIhazhKUsYzkrWMkqVrOGtaxjPRvYyCY2s4WtbGM7O/ienfzALn5kNz+xh5/Zyz728wsH+JWD/MYhfucwf3CEoxzjOCf4k5P8xSn+5jT/cIaznONfzvMfF7jIJS5zhatc4zo3uMktbnOHu9zjPg94yCMe84SnPOM5L3jJK17zhre8I+QG/R/zCWEISzg+JTwRiEgkIvMZUficqHxBNL4kOjGISSxi8xVx+Jq4fEM8viV+yHkJJCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOkMM5PuYTwhCWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3hBzM8zGfEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+KHnP9GAhKSiMQkISnJSE4KUpKK1KQhLelITwYykonMZCEr2chODnKSi9zkIS/5yE8BClKIwhShKMUoTglKUorSlKEs5ShPBSpSicpUoSrVqE4NalKL2tShLvWoTwMa0ojGNKEpzWhOC1rSita0oS3taE8HOtKJznShK93oTg960ove9KEv/ejPAAYyiMEMYSjDGM4IRjKK0YxhLOMYzwQmMonJTGEq05jODGYyi9nMYS7zmM8CFrKIxSxhKctYzgpWsorVrGEt61jPBjayic1sYSvb2M4OvmcnP7CLH9nNT+zhZ/ayj/38wgF+5SC/cYjfOcwfHOEoxzjOCf7kJH9xir85zT+c4Szn+Jfz/McFLnKJy1zhKte4zg1ucovb3OEu97jPAx7yiMc84SnPeM4LXvKK17zhLe8IOZTrYz4hDGEJx6eEJwIRiURkPiMKnxOVL4jGl0QnBjGJRWy+Ig5fE5dviMe3xOc7EpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3lHyIF8H/MJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qg7j/JhPCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfH5jgQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWtrGdHXzPTn5gFz+ym5/Yw8/sZR/7+YUD/MpBfuMQv3OYPzjCUY5xnBP8yUn+4hR/c5p/OMNZzvEv5/mPC1zkEpe5wlWucZ0b3OQWt7nDXe5xnwc85BGPecJTnvGcF7zkFa95w1veEXIQ78d8QhjCEo5PCU8EIhKJyHxGFD4nKl8QjS+JTgxiEovYfEUcviYu3xCPb4nPdyQgIYlITBKSkozkpCAlqUhNGtKSjvRkICOZyEwWspKN7OQgJ7nITR7yko/8FKAghShMEYpSjOKUoCSlKE0ZylKO8lSgIpWoTBWqUo3q1KAmtahNHepSj/o0oCGNaEwTmtKM5rSgJa1oTRva0o72dKAjnehMF7rSje70oCe96E0f+tKP/gxgIIMYzBCGMozhjGAkoxjNGMYyjvFMYCKTmMwUpjKN6cxgJrOYzRzmMo/5LGAhi1jMEpayjOWsYCWrWM0a1rKO9WxgI5vYzBa2so3t7OB7dvIDu/iR3fzEHn5mL/vYzy8c4FcO8huH+J3D/MERjnKM45zgT07yF6f4m9P8wxnOco5/Oc9/XOAil7jMFa5yjevc4Ca3uM0d7nKP+zzgIY94zBOe8oznvOAlr3jNG97yjpBDuD/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd3z0neufTwhDWMLxKeGJQEQiEZnPiMLnROULovEl0YlBTGIRm6+Iw9fE5Rvi8S3x+Y4EJCQRiUlCUpKRnBSkJBWpSUNa0pGeDGQkE5nJQlaykZ0c5CQXuclDXvKRnwIUpBCFKUJRilGcEpSkFKUpQ1nKUZ4KVKQSlalCVapRnRrUpBa1qUNd6lGfBjSkEY1pQlOa0ZwWtKQVrWlDW9rRng50pBOd6UJXutGdHvSkF73pQ1/60Z8BDGQQgxnCUIYxnBGMZBSjGcNYxjGeCUxkEpOZwlSmMZ0ZzGQWs5nDXOYxnwUsZBGLWcJSlrGcFaxkFatZw1rWsZ4NbGQTm9nCVraxnR18z05+YBc/spuf2MPP7GUf+/mFA/zKQX7jEL9zmD84wlGOcZwT/MlJ/uIUf3OafzjDWc7xL+f5jwtc5BKXucJVrnGdG9zkFre5w13ucZ8HPOQRj3nCU57xnBe85BWvecNb3vFRAtc/nxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vi8x0JSEgiEpOEpCQjOSlISSpSk4a0pCM9GchIJjKThaxkIzs5yEkucpOHvOQjPwUoSCEKU4SiFKM4JShJKUpThrKUozwVqEglKlOFqlSjOjWoSS1qU4e61KM+DWhIIxrThKY0ozktaEkrWtOGtrSjPR3oSCc604WudKM7PehJL3rTh770oz8DGMggBjOEoQxjOCMYyShGM4axjGM8E5jIJCYzhalMYzozmMksZjOHucxjPgtYyCIWs4SlLGM5K1jJKlazhrWsYz0b2MgmNrOFrWxjOzv4np38wC5+ZDc/sYef2cs+9vMLB/iVg/zGIX7nMH9whKMc4zgn+JOT/MUp/uY0/3CGs5zjX87zHxe4yCUuc4WrXOM6N7jJLW5zh7vc4z4PeMgjHvOEpzzjOS94ySte84a3vOOjhK5/PiEMYQnHp4QnAhGJRGQ+IwqfE5UviMaXRCcGMYlFbL4iDl8Tl2+Ix7fE5zsSkJBEJCYJSUlGclKQklSkJg1pSUd6MpCRTGQmC1nJRnZykJNc5CYPeclHfgpQkEIUpghFKUZxSlCSUpSmDGUpR3kqUJFKVKYKValGdWpQk1rUpg51qUd9GtCQRjSmCU1pRnNa0JJWtKYNbWlHezrQkU50pgtd6UZ3etCTXvSmD33pR38GMJBBDGYIQxnGcEYwklGMZgxjGcd4JjCRSUxmClOZxnRmMJNZzGYOc5nHfBawkEUsZglLWcZyVrCSVaxmDWtZx3o2sJFNbGYLW9nGdnbwPTv5gV38yG5+Yg8/s5d97OcXDvArB/mNQ/zOYf7gCEc5xnFO8Ccn+YtT/M1p/uEMZznHv5znPy5wkUtc5gpXucZ1bnCTW9zmDne5x30e8JBHPOYJT3nGc17wkle85g1vecdHiVz/fEIYwhKOTwlPBCISich8RhQ+JypfEI0viU4MYhKL2HxFHL4mLt8Qj2+Jz3ckICGJSEwSkpKM5KQgJalITRrSko70ZCAjmchMFrKSjezkICe5yE0e8pKP/BSgIIUoTBGKUozilKAkpShNGcpSjvJUoCKVqEwVqlKN6tSgJrWoTR3qUo/6NKAhjWhME5rSjOa0oCWtaE0b2tKO9nSgI53oTBe60o3u9KAnvehNH/rSj/4MYCCDGMwQhjKM4YxgJKMYzRjGMo7xTGAik5jMFKYyjenMYCazmM0c5jKP+SxgIYtYzBKWsozlrGAlq1jNGtayjvVsYCOb2MwWtrKN7ezge3byA7v4kd38xB5+Zi/72M8vHOBXDvIbh/idw/zBEY5yjOOc4E9O8hen+JvT/MMZznKOfznPf1zgIpe4zBWuco3r3OAmt7jNHe5yj/s84CGPeMwTnvKM57zgJa94zRve8o6PErv++YQwhCUcnxKeCEQkEpH5jCh8TlS+IBpfEp0YxCQWsfmKOHxNXL4hHt8Sn+9IQEISkZgkJCUZyUlBSlKRmjSkJR3pyUBGMpGZLGQlG9nJQU5ykZs85CUf+SlAQQpRmCIUpRjFKUFJSlGaMpSlHOWpQEUqUZkqVKUa1alBTWpRmzrUpR71aUBDGtGYJjSlGc1pQUta0Zo2tKUd7elARzrRmS50pRvd6UFPetGbPvSlH/0ZwEAGMZghDGUYwxnBSEYxmjGMZRzjmcBEJjGZKUxlGtOZwUxmMZs5zGUe81nAQhaxmCUsZRnLWcFKVrGaNaxlHevZwEY2sZktbGUb29nB9+zkB3bxI7v5iT38zF72sZ9fOMCvHOQ3DvE7h/mDIxzlGMc5wZ+c5C9O8Ten+YcznOUc/3Ke/7jARS5xmStc5RrXucFNbnGbO9zlHvd5wEMe8ZgnPOUZz3nBS17xmje85R0fJXH98wlhCEs4PiU8EYhIJCLzGVH4nKh8QTS+JDoxiEksYvMVcfiauHxDPL4lPt+RgIQkIjFJSEoykpOClKQiNWlISzrSk4GMZCIzWchKNrKTg5zkIjd5yEs+8lOAghSiMEUoSjGKU4KSlKI0ZShLOcpTgYpUojJVqEo1qlODmtSiNnWoSz3q04CGNKIxTWhKM5rTgpa0ojVtaEs72tOBjnSiM13oSje604Oe9KI3fehLP/ozgIEMYjBDGMowhjOCkYxiNGMYyzjGM4GJTGIyU5jKNKYzg5nMYjZzmMs85rOAhSxiMUtYyjKWs4KVrGI1a1jLOtazgY1sYjNb2Mo2trOD79nJD+ziR3bzE3v4mb3sYz+/cIBfOchvHOJ3DvMHRzjKMY5zgj85yV+c4m9O8w9nOMs5/uU8/3GBi1ziMle4yjWuc4Ob3OI2d7jLPe7zgIc84jFPeMoznvOCl7ziNW94yzs+Sur65xPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlnd8lMz1zyeEISzh+JTwRCAikYjMZ0Thc6LyBdH4kujEICaxiM1XxOFr4vIN8fiW+HxHAhKSiMQkISnJSE4KUpKK1KQhLelITwYykonMZCEr2chODnKSi9zkIS/5yE8BClKIwhShKMUoTglKUorSlKEs5ShPBSpSicpUoSrVqE4NalKL2tShLvWoTwMa0ojGNKEpzWhOC1rSita0oS3taE8HOtKJznShK93oTg960ove9KEv/ejPAAYyiMEMYSjDGM4IRjKK0YxhLOMYzwQmMonJTGEq05jODGYyi9nMYS7zmM8CFrKIxSxhKctYzgpWsorVrGEt61jPBjayic1sYSvb2M4OvmcnP7CLH9nNT+zhZ/ayj/38wgF+5SC/cYjfOcwfHOEoxzjOCf7kJH9xir85zT+c4Szn+Jfz/McFLnKJy1zhKte4zg1ucovb3OEu97jPAx7yiMc84SnPeM4LXvKK17zhLe/4KLnrn08IQ1jC8SnhiUBEIhGZz4jC50TlC6LxJdGJQUxiEZuviMPXxOUb4vEt8fmOBCQkEYlJQlKSkZwUpCQVqUlDWtKRngxkJBOZyUJWspGdHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBKTmcJUpjGdGcxkFrOZw1zmMZ8FLGQRi1nCUpaxnBWsZBWrWcNa1rGeDWxkE5vZwla2sZ0dfM9OfmAXP7Kbn9jDz+xlH/v5hQP8ykF+4xC/c5g/OMJRjnGcE/zJSf7iFH9zmn84w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7nGfBzzkEY95wlOe8ZwXvOQVr3nDW97xUQrXP58QhrCE41PCE4GIRCIynxGFz4nKF0TjS6ITg5jEIjZfEYevics3xONb4vMdCUhIIhKThKQkIzkpSEkqUpOGtKQjPRnISCYyk4WsZCM7OchJLnKTh7zkIz8FKEghClOEohSjOCUoSSlKU4aylKM8FahIJSpThapUozo1qEktalOHutSjPg1oSCMa04SmNKM5LWhJK1rThra0oz0d6EgnOtOFrnSjOz3oSS9604e+9KM/AxjIIAYzhKEMYzgjGMkoRjOGsYxjPBOYyCQmM4WpTGM6M5jJLGYzh7nMYz4LWMgiFrOEpSxjOStYySpWs4a1rGM9G9jIJjazha1sYzs7+J6d/MAufmQ3P7GHn9nLPvbzCwf4lYP8xiF+5zB/cISjHOM4J/iTk/zFKf7mNP9whrOc41/O8x8XuMglLnOFq1zjOje4yS1uc4e73OM+D3jIIx7zhKc84zkveMkrXvOGt7zjo5Sufz4hDGEJx6eEJwIRiURkPiMKnxOVL4jGl0QnBjGJRWy+Ig5fE5dviMe3xOc7EpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3nHR6lc/3xCGMISjk8JTwQiEonIfEYUPicqXxCNL4lODGISi9h8RRy+Ji7fEI9vic93JCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOj1K7/vmEMIQlHJ8SnghEJBKR+YwofE5UviAaXxKdGMQkFrH5ijh8TVy+IR7fEp/vSEBCEpGYJCQlGclJQUpSkZo0pCUd6clARjKRmSxkJRvZyUFOcpGbPOQlH/kpQEEKUZgiFKUYxSlBSUpRmjKUpRzlqUBFKlGZKlSlGtWpQU1qUZs61KUe9WlAQxrRmCY0pRnNaUFLWtGaNrSlHe3pQEc60ZkudKUb3elBT3rRmz70pR/9GcBABjGYIQxlGMMZwUhGMZoxjGUc45nARCYxmSlMZRrTmcFMZjGbOcxlHvNZwEIWsZglLGUZy1nBSlaxmjWsZR3r2cBGNrGZLWxlG9vZwffs5Ad28SO7+Yk9/Mxe9rGfXzjArxzkNw7xO4f5gyMc5RjHOcGfnOQvTvE3p/mHM5zlHP9ynv+4wEUucZkrXOUa17nBTW5xmzvc5R73ecBDHvGYJzzlGc95wUte8Zo3vOUdH6Vx/fMJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Pkrr+ucTwhCWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3fJTO9c8nhCEs4fiU8EQgIpGIzGdE4XOi8gXR+JLoxCAmsYjNV8Tha+LyDfH4lvh8RwISkojEJCEpyUhOClKSitSkIS3pSE8GMpKJzGQhK9nITg5ykovc5CEv+chPAQpSiMIUoSjFKE4JSlKK0pShLOUoTwUqUonKVKEq1ahODWpSi9rUoS71qE8DGtKIxjShKc1oTgta0orWtKEt7WhPBzrSic50oSvd6E4PetKL3vShL/3ozwAGMojBDGEowxjOCEYyitGMYSzjGM8EJjKJyUxhKtOYzgxmMovZzGEu85jPAhayiMUsYSnLWM4KVrKK1axhLetYzwY2sonNbGEr29jODr5nJz+wix/ZzU/s4Wf2so/9/MIBfuUgv3GI3znMHxzhKMc4zgn+5CR/cYq/Oc0/nOEs5/iX8/zHBS5yictc4SrXuM4NbnKL29zhLve4zwMe8ojHPOEpz3jOC17yite84S3v+Ci9659PCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfH5jgQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWtrGdHXzPTn5gFz+ym5/Yw8/sZR/7+YUD/MpBfuMQv3OYPzjCUY5xnBP8yUn+4hR/c5p/OMNZzvEv5/mPC1zkEpe5wlWucZ0b3OQWt7nDXe5xnwc85BGPecJTnvGcF7zkFa95w1ve8VEG1z+fEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+LzHQlISCISk4SkJCM5KUhJKlKThrSkIz0ZyEgmMpOFrGQjOznISS5yk4e85CM/BShIIQpThKIUozglKEkpSlOGspSjPBWoSCUqU4WqVKM6NahJLWpTh7rUoz4NaEgjGtOEpjSjOS1oSSta04a2tKM9HehIJzrTha50ozs96EkvetOHvvSjPwMYyCAGM4ShDGM4IxjJKEYzhrGMYzwTmMgkJjOFqUxjOjOYySxmM4e5zGM+C1jIIhazhKUsYzkrWMkqVrOGtaxjPRvYyCY2s4WtbGM7O/ienfzALn5kNz+xh5/Zyz728wsH+JWD/MYhfucwf3CEoxzjOCf4k5P8xSn+5jT/cIaznONfzvMfF7jIJS5zhatc4zo3uMktbnOHu9zjPg94yCMe84SnPOM5L3jJK17zhre846OMrn8+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95x0eZXP98QhjCEo5PCU8EIhKJyHxGFD4nKl8QjS+JTgxiEovYfEUcviYu3xCPb4nPdyQgIYlITBKSkozkpCAlqUhNGtKSjvRkICOZyEwWspKN7OQgJ7nITR7yko/8FKAghShMEYpSjOKUoCSlKE0ZylKO8lSgIpWoTBWqUo3q1KAmtahNHepSj/o0oCGNaEwTmtKM5rSgJa1oTRva0o72dKAjnehMF7rSje70oCe96E0f+tKP/gxgIIMYzBCGMozhjGAkoxjNGMYyjvFMYCKTmMwUpjKN6cxgJrOYzRzmMo/5LGAhi1jMEpayjOWsYCWrWM0a1rKO9WxgI5vYzBa2so3t7OB7dvIDu/iR3fzEHn5mL/vYzy8c4FcO8huH+J3D/MERjnKM45zgT07yF6f4m9P8wxnOco5/Oc9/XOAil7jMFa5yjevc4Ca3uM0d7nKP+zzgIY94zBOe8oznvOAlr3jNG97yjo8yu/75hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHR9lcf3zCWEISzg+JTwRiEgkIvMZUficqHxBNL4kOjGISSxi8xVx+Jq4fEM8viU+35GAhCQiMUlISjKSk4KUpCI1aUhLOtKTgYxkIjNZyEo2spODnOQiN3nISz7yU4CCFKIwRShKMYpTgpKUojRlKEs5ylOBilSiMlWoSjWqU4Oa1KI2dahLPerTgIY0ojFNaEozmtOClrSiNW1oSzva04GOdKIzXehKN7rTg570ojd96Es/+jOAgQxiMEMYyjCGM4KRjGI0YxjLOMYzgYlMYjJTmMo0pjODmcxiNnOYyzzms4CFLGIxS1jKMpazgpWsYjVrWMs61rOBjWxiM1vYyja2s4Pv2ckP7OJHdvMTe/iZvexjP79wgF85yG8c4ncO8wdHOMoxjnOCPznJX5zib07zD2c4yzn+5Tz/cYGLXOIyV7jKNa5zg5vc4jZ3uMs97vOAhzziMU94yjOe84KXvOI1b3jLOz7K6vrnE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd3yUzfXPJ4QhLOH4lPBEICKRiMxnROFzovIF0fiS6MQgJrGIzVfE4Wvi8g3x+Jb4fEcCEpKIxCQhKclITgpSkorUpCEt6UhPBjKSicxkISvZyE4OcpKL3OQhL/nITwEKUojCFKEoxShOCUpSitKUoSzlKE8FKlKJylShKtWoTg1qUova1KEu9ahPAxrSiMY0oSnNaE4LWtKK1rShLe1oTwc60onOdKEr3ehOD3rSi970oS/96M8ABjKIwQxhKMMYzghGMorRjGEs4xjPBCYyiclMYSrTmM4MZjKL2cxhLvOYzwIWsojFLGEpy1jOClayitWsYS3rWM8GNrKJzWxhK9vYzg6+Zyc/sIsf2c1P7OFn9rKP/fzCAX7lIL9xiN85zB8c4SjHOM4J/uQkf3GKvznNP5zhLOf4l/P8xwUuconLXOEq17jODW5yi9vc4S73uM8DHvKIxzzhKc94zscf/f/+cb/c//uv/5+9boR5uwoej7zm//NxYQJauIAWPqBFDGiRA1qUgBY1oEULaNEDWsyAFjugxQlocQNavIAWP6AlCGiJAlqSgJYsoKUIaKkCWpqAli6gZQhomQJaloCWLaDlCGi5AlqegJYvoBUIaIUCWpGAViyglQhopQJamYBWLqBVCGiVAlqVgFYtoNUIaLUCWp2AVi+gNQhojQJak4DWLKC1CGitAlqbgNYuoHUIaJ0CWpeA1i2g9QhovQJan4DWL6ANCGiDAtqQgDYsoI0IaKMC2piANi6gTQhokwLalIA2LaDNCGizAtqcgDYvoC0IaIsC2pKAtiygrQhoqwLamoC2LqBtCGibAtqWgLYtoO0IaDsD2q6Atjug7QloewPa/oB2IKAdDGiHAtrhgHYkoB0LaCcC2smAdiqgnQ5oZwLauYB2PqBdCGiXAtqVgHYtoN0IaLcC2p2Adi+gPQhojwLak4D2LKC9CGivAtqbgPYuoH388f+6hQlo4QJa+IAWMaBFDmhRAlrUgBYtoEUPaDEDWuyAFiegxQ1o8QJa/ICWIKAlCmhJAlqygJYioKUKaGkCWrqAliGgZQpoWQJatoCWI6DlCmh5Alq+gFYgoBUKaEUCWrGAViKglQpoZQJauYBWIaBVCmhVAlq1gFYjoNUKaHUCWr2A1iCgNQpoTQJas4DWIqC1CmhtAlq7gNYhoHUKaF0CWreA1iOg9QpofQJav4A2IKANCmhDAtqwgDYioI0KaGMC2riANiGgTQpoUwLatIA2I6DNCmhzAtq8gLYgoC0KaEsC2rKAtiKgrQpoawLauoC2IaBtCmhbAtq2gLYjoO0MaLsC2u6Atieg7Q1o+wPagYB2MKAdCmiHA9qRgHYsoJ0IaCcD2qmAdjqgnQlo5wLa+YB2IaBdCmhXAtq1gHYjoN0KaHcC2r2A9iCgPQpoTwLas4D2IqC9CmhvAtq7gPbxJ//rFiaghQto4QNaxIAWOaBFCWhRA1q0gBY9oMUMaLEDWpyAFjegxQto8QNagoCWKKAlCWjJAlqKgJYqoKUJaOkCWoaAlimgZQlo2QJajoCWK6DlCWj5AlqBgFYooBUJaMUCWomAViqglQlo5QJahYBWKaBVCWjVAlqNgFYroNUJaPUCWoOA1iigNQlozQJai4DWKqC1CWjtAlqHgNYpoHUJaN0CWo+A1iug9Qlo/QLagIA2KKANCWjDAtqIgDYqoI0JaOMC2oSANimgTQlo0wLajIA2K6DNCWjzAtqCgLYooC0JaMsC2oqAtiqgrQlo6wLahoC2KaBtCWjbAtqOgLYzoO0KaLsD2p6Atjeg7Q9oBwLawYB2KKAdDmhHAtqxgHYioJ0MaKcC2umAdiagnQto5wPahYB2KaBdCWjXAtqNgHYroN0JaPcC2oOA9iigPQlozwLai4D2KqC9CWjvAtrHYf7XLUxACxfQwge0iAEtckCLEtCiBrRoAS16QIsZ0GIHtDgBLW5AixfQ4ge0BAEtUUBLEtCSBbQUAS1VQEsT0NIFtAwBLVNAyxLQsgW0HAEtV0DLE9DyBbQCAa1QQCsS0IoFtBIBrVRAKxPQygW0CgGtUkCrEtCqBbQaAa1WQKsT0OoFtAYBrVFAaxLQmgW0FgGtVUBrE9DaBbQOAa1TQOsS0LoFtB4BrVdA6xPQ+gW0AQFtUEAbEtCGBbQRAW1UQBsT0MYFtAkBbVJAmxLQpgW0GQFtVkCbE9DmBbQFAW1RQFsS0JYFtBUBbVVAWxPQ1gW0DQFtU0DbEtC2BbQdAW1nQNsV0HYHtD0BbW9A2x/QDgS0gwHtUEA7HNCOBLRjAe1EQDsZ0E4FtNMB7UxAOxfQzge0CwHtUkC7EtCuBbQbAe1WQLsT0O4FtAcB7VFAexLQngW0FwHtVUB7E9DeBbSPw/6vW5iAFi6ghQ9oEQNa5IAWJaBFDWjRAlr0gBYzoMUOaHECWtyAFi+gxQ9oCQJaooCWJKAlC2gpAlqqgJYmoKULaBkCWqaAliWgZQtoOQJaroCWJ6DlC2gFAlqhgFYkoBULaCUCWqmAViaglQtoFQJapYBWJaBVC2g1AlqtgFYnoNULaA0CWqOA1iSgNQtoLQJaq4DWJqC1C2gdAlqngNYloHULaD0CWq+A1ieg9QtoAwLaoIA2JKANC2gjAtqogDYmoI0LaBMC2qSANiWgTQtoMwLarIA2J6DNC2gLAtqigLYkoC0LaCsC2qqAtiagrQtoGwLapoC2JaBtC2g7AtrOgLYroO0OaHsC2t6Atj+gHQhoBwPaoYB2OKAdCWjHAtqJgHYyoJ0KaKcD2pmAdi6gnQ9oFwLapYB2JaBdC2g3AtqtgHYnoN0LaA8C2qOA9iSgPQtoLwLaq4D2JqC9C2gfh/tftzABLVxACx/QIga0yAEtSkCLGtCiBbToAS1mQIsd0OIEtLgBLV5Aix/QEgS0RAEtSUBLFtBSBLRUAS1NQEsX0DIEtEwBLUtAyxbQcgS0XAEtT0DLF9AKBLRCAa1IQCsW0EoEtFIBrUxAKxfQKgS0SgGtSkCrFtBqBLRaAa1OQKsX0BoEtEYBrUlAaxbQWgS0VgGtTUBrF9A6BLROAa1LQOsW0HoEtF4BrU9A6xfQBgS0QQFtSEAbFtBGBLRRAW1MQBsX0CYEtEkBbUpAmxbQZgS0WQFtTkCbF9AWBLRFAW1JQPt/8KVHoaAAAABo1+12Z2ZmZmZmZmZmZmZmZmbmmZmZmZmZmZmZmZmZmZmZSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkyT72O+frfJwF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+Q/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7E/D7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7Pf/j3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yfwN/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+I7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P4E/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/Mf/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf49/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//Y7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PyG/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Md/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9Cf39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fnP/H7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P2O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//yd/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/Cf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/flP/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+xPx+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz3/69/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn8jf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB//jO/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+RP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzn/39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/cn+vf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//3O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD8xv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/vznf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/Yn9/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf357/w+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uT9zv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g//8Xf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/4n+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf35L/1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/uT8Pv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7s9/+ff7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/E3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/4rv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/iT9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P781/9/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3J/n3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf/9rv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g/Kb/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P7813+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf1J/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+e/8fv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7k/a7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4P//N3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf9J/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+W/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7k/H7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7Pf/v3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yfzN/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+O7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P5k/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/Pf/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf79/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//e7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4Pzm/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Ae/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW48v/g/+f/v6vAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf3N/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/++7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P7k/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/M/+P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf/9/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//h7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PwW/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/I9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9Kfz9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fnf/z7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P0e/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//k9/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH+Kf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/fmf/n5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+1Py+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz//s9/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn9Lf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB//ue/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+lP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzv/j9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/en/Pf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//5e/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD8Vv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/vyvfr+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/an8/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf353/9+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uT9Xv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g//5vf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/qn+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf353/5+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/tT8/v9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7s//7vf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/a3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/73v99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/tT9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P783/4/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3p/73+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf/+Pv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g/Db/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P78n36/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf1p/P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+f//Pv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7k/T7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4P/+X3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf5p/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+b/+fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P70/L7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7P/+33+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf1t/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+77/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P60/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/P/+P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H96f99/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//n7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4Px2/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/L9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H96fz9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fn//37/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P1+/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//n9/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH+6f7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7v/blxy/ggIAgIHu9XpJkiRJkiRJkiRJkiRJkiRJkiRJkiRJcs4558zMzMzMTJIkSZIkSZIkSZIkSZIkSZIkydof4Pt+/a5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//6/f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J+e3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7v3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf3p/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+X9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H96fv9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fn//39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/en//f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//7/f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J+B3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7/3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wfwZ/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+Q+/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+DP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzH3+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf0Z/v3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+c//X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+zPy+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz3/+/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3Z/T3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf//L7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7P2O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//9ff7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/x3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7b7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PxO/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Pff7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/Jn+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf35H7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P5M/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/M/f7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/Zn+/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf353/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7M/P7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe7/+N/S+SxOxDlzAA==", + "debug_symbols": "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nwL6FNinuPgprn4K+FPgn+ICqLgCKiBQgYGKi6DiKqiAQQUOKi6EiiuhAgoVWKi4GCquhgo4VOCh4oKoGH5C3z+i75/R54f0+Sl9/5i+f06fH9TnJ/X/9KP676tfDz+sz0/r+8f1/fP6/MA+P7HvH9n3z+zzQ/v3p/axUQsbta6NWtdGLWzUwkata6PWtVELG7Ue/9+EuT/Af23UwkYtbNS6NmpdG7WwUQsbta6NWtdGLWzUwkata6PWtVELG7WwUevaqHVt1MJGLWzUujZqXRu1sFELG7WujVrXRi1s1MJGre826o//PyfWdxz18eh7t+f7o+DR4qPiUfLR4tHmo82jw0fnPvqj3Y+P/hHv+2jxUfEo+WjxaPPR5hF3bO5o7mjuaO5o7mjuaO5o7mjuaO5o7jjccbjjcMfhjsMdhzsOdxzuONxxuGO4Y7hjuGO4Y7hjuGO4Y7hjuGPuHd/V1PePfmdT76PFR8Wj5KPFo81Hm0eHj947PuzU949G8GjxUfEo+WjxaPPR5tHho9yxuGNxx+KOxR2LOxZ3LO5Y3LG4Y3GHuEPcIe4Qd4g7xB3iDnGHuEPckdyR3JHckdyR3JHckdyR3EHnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50Hni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3QuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnReebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN50fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXE9yxuGNxx+KOxR2LOxZ3LO5Y3LG4Y3GHuEPcIe4Qd4g7xB3iDnGHuEPckdyR3JHckdyR3JHckdyR3JHckdxR3FHcUdxR3FHcUdxR3FHcUdxR3LG5Y3PH5o7NHZs7Nnds7tjcsbljc0dzR3NHc0dzR3NHc0dzR3NHc0dzx+GOwx2HOw53HO443HG443DH4Y7DHcMdwx3DHcMdwx3DHcMdwx3DHXSOhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uHyu4db+v6oefTtf8fa3x/N++i7h/v+0e8e7n20+Kh4lHy0eLT5aPPo8NG5j/7o/OOjf3T+Plp8VDxKPlo82ny0eXT4KHcs7ljcsbhjccfijsUdizsWdyzuWNwh7hB3iDvEHeIOcYe4Q9wh7hB3JHckdyR3JHckdyR3JHckdyR3JHcUdxR3FHcUdxR3FHcUdxR3FHcUd2zu2NyxuWNzx+aOzR2bOzZ3bO7Y3NHc0dzR3NHc0dzR3NHc0dzR3NHccbjjcMfhjsMdhzsOdxzuONxxuONwx3DHcMdwx3DHcMdwB50HnQedB50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedP5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/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w2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsPt7x5O8f1R8ejb/w7l90fNo8NH5z76o/OPj/7R+fto8VHxKPlo8Wjz0ebR4aNzH/3R+cdH/+j8fbT4qHjEHZs7Nnds7tjcsbmjuaO5o7mjuaO5o7mjuaO5o7mjueNwx+GOwx2HOw53HO443HG443DH4Y7hjuGO4Y7hjuGO4Y7hjuGO4Y65d3z3cN8/+t3DvY8WHxWPko8WjzYfbR4dPnrv+O7hPj4awaPFR8Wj5KPFo81Hm0eHj3LH4o7FHYs7Fncs7ljcsbhjccfijsUd4g5xh7hD3CHuEHeIO8Qd4g5xR3JHckdyR3IHnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRueg86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86bzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzofNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6Hzo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0nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedH5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dzO57mdz3M7n+d2Ps/tfJ7b+Ty383lu5/Pczue5nc9zO5/ndj7P7Xye2/k8t/N5bufz3M7nuZ3Pczuf53Y+T3DH4o7FHYs7Fncs7ljcsbhjccfijsUd4g5xh7hD3CHuEHeIO8Qd4g5xR3JHckdyR3JHckdyR3JHckdyR3JHcUdxR3FHcUdxR3FHcUdxR3FHccfmjs0dmzs2d2zu2NyxuWNzx+aOzR3NHc0dzR3NHc0dzR3NHc0dzR3NHYc7Dncc7jjccbjjcMfhjsMdhzsOdwx3DHcMdwx3DHcMdwx3DHcMd9B50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQOR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjB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vSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0ZtiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiSe8G3Lty3ftnzb8m3Lty3ftnzb8m3Lty3fJt8m3ybfJt8m3ybfJt8m3ybfJt+Wvi19W/q29G3p29K3pW9L35a+LX1b+bbybeXbyreVbyvfVr6tfFv5tvJt27dt37Z92/Zt27dt37Z92/Zt27dt39a+rX1b+7b2be3b2re1b2vf1r6tfdvxbce3Hd92fNvxbce3Hd92fNvxbce3jW8b3za+bXzb+LbxbePbxreNb/OWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb4nda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b2u7+61zsfD4eEfW7Lj42H44fIvkB+mf0H54fYvaD88/gVzH353rx+/4Lt7vQ+Xf4H8MP0Lyg+3f0H74fEv4Lbv7vX9BRF+uPwL5IfpX1B+uP0L2g+Pf4FvW75t+bbl25ZvW75t+bbl25ZvW75t+Tb5Nvk2+Tb5Nvk2+Tb5Nvk2+Tb5tvRt6dvSt6VvS9+Wvi19W/q29G3p28q3lW8r31a+rXxb+bbybeXbyreVb9u+bfu27du2b9u+bfu27du2b9u+bfu29m3t29q3tW9r39a+rX1b+7b2be3bjm87vu34tuPbjm87vu34tuPbvCXylshbIm+JvCXylshbIm+JvCXylshbIm9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaW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dq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9f/j0h7N6LkRqIo6NIrAPXz37FdzpCdWgmI6LjKUTof9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7vX/p21awr0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb3WH/da/fcM5/+/1r+/53U+D9JZHrRzPNjv/Kcl/z74pyX/nceD63wepLM8aOd4sP+df9zr3wd/3Ot/5/HgOp8H6SwP2jkefNv+uNd/H0Q4jwfX+TxIZ3nQzvHAtmPbse3Ydmw7th3bjm3HtmPbse3adm27tl3brm3Xtmvbte3adm17tj3bnm3Ptmfbs+3Z9mx7tj3b0ra0LW1L29K2tC1tS9vStrStbCvbyrayrWwr28q2sq1sK9vatratbWvb2ra2rW1r29q2tk1LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl9L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9h27Ht2HZsO7Yd245tx7Zj27Ht2HZtu7Zd265t17Zr27Xt2nZtu7Y9255tz7Zn27Pt2fZse7Y9255taVvalralbWlb2pa2pW1pW9pWtpVtZVvZVraVbWVb2Va2lW1tW9vWtrVtbVvb1ra1bW1b2za2jW1j29g2to1tY9vYNraNbWvb2ra2rW1r29q2tq1ta5uWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqCffa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829dmsJ99rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cv88e9dv090/nPtv17tnM82O/805K/D/605N/zeHCdz4N0lgftHA/2O/9pyb8P/mnJf+fx4Dpte7Y9255tz7ZnW9qWtqVtaVvalralbWlb2pa2lW1lW9lWtpVtZVvZVraVbWVb29a2tW1tW9vWtrVtbVvb1raNbWPb2Da2jW1j29g2to1tY9vatratbWvb2ra2rW1r29q237Y/7vXvgz/u9b/zeHCdz4N0lgftHA++bX/d698HEc7jwXU+D9JZHrRzPLDt2HZsO7Yd27QktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLWktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVkv5bs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/sK2Y9ux7dh2bDu2HduObce2Y9ux7dp2bbu2Xduubde2a9u17dp2bXu2Pduebc+2Z9uz7dn2bHu2PdvStrQtbUvb0ra0LW1L29K2tK1sK9vKtrKtbCvbyrayrWwr29q2tq1ta9vatratbWvb2ra2bWwb28a2sW1sG9vGtrFtbBvb1ra1bW1b29a2tW1tW9vWNi0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwt4V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udT/3en6fe/3nDOfx4DqfB+ksD9o5Hux3/teSf85wHg+u83mQzvKgneOBbce2Y9ux7dh2bDu2HduObce2Y9u17dp2bbu2Xduubde2a9u17dr2bHu2Pduebc+2Z9uz7dn2bHu2pW1pW9qWtqVtaVvalralbWlb2Va2lW1lW9lWtpVtZVvZVra1bW1b29a2tW1tW9vWtrVtbdvYNraNbWPb2Da2jW1j29g2tq1ta9vatratbWvb2ra2rW1aEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaElpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMlqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9nj/udfLv2c7/f23m77nf+U9L/n3wT0v+O48H1/k8SGd50M7xYL/zn5b8++Cflvx3Hg+u83mQTtuubde2a9uz7dn2bHu2Pduebc+2Z9uz7dmWtqVtaVvalralbWlb2pa2pW1lW9lWtpVtZVvZVraVbWVb2da2tW1tW9vWtrVtbVvb1ra1bWPb2Da2jW1j29g2to1tY9vYtratbWvb2ra2rW1r29q2tu237Y97/fvgj3v97zweXOfzIJ3lQTvHg2/bH/f674MI5/HgOp8H6SwP2jke2KYlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMlqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl+7Xk/r6W3N/Xkvv7WnJ/X0vu72vJ/X0tub+vJff3teT+vpbc39eS+/tacn9fS+7va8n9fS25v68l9/e15P6+ltzf15L7+1pyf2Hbse3Ydmw7th3bjm3HtmPbse3Ydm27tl3brm3Xtmvbte3adm27tj3bnm3Ptmfbs+3Z9mx7tj3bnm1pW9qWtqVtaVvalralbWlb2la2lW1lW9lWtpVtZVvZVraVbW1b29a2tW1tW9vWtrVtbVvbNraNbWPb2Da2jW1j29g2to1ta9vatratbWvb2ra2rW1rm5aEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaElhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GlJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJagn3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71/XGv7/f3DOf/v/bu3/M6nwfpLA/aOR7sd/7Tkn8f/NOS/87jwXU+D9JZHrRzPNjvHNvGtrFtbBvbxraxbWwb28a2tW1tW9vWtrVtbVvb1ra1bb9tf9zr3wd/3Ot/5/HgOp8H6SwP2jkefNv+uNd/H0Q4jwfX+TxIZ3nQzvHAtmPbse3Ydmw7th3bjm3HtmPbse3adm27tl3brm3Xtmvbte3adm17tj3bnm3Ptmfbs+3Z9mx7tj3b0ra0LW1L29K2tC1tS9vStrRNS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVkv2a0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbkL2w7th3bjm3HtmPbse3Ydmw7th3brm3Xtmvbte3adm27tl3brm3Xtmfbs+3Z9mx7tj3bnm3Ptmfbsy1tS9vStrQtbUvb0ra0LW1L28q2sq1sK9vKtrKtbCvbyrayrW1r29q2tq1ta9vatratbWvbxraxbWwb28a2sW1sG9vGtrFtbVvb1ra1bW1b29a2tW1t05LQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS3hXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNf6617377nf+U9L8vw9w3k8uM7nQTrLg3aOB/udf1ry98Gflvx7Hg+u83mQzvKgnbYd265t17Zr27Xt2nZtu7Zd265t17Zn27Pt2fZse7Y9255tz7Zn27MtbUvb0ra0LW1L29K2tC1tS9vKtrKtbCvbyrayrWwr28q2sq1ta9vatratbWvb2ra2rW1r28a2sW1sG9vGtrFtbBvbxraxbW1b29a2tW1tW9vWtrVtbdtv21/3un/PcB4PrvN5kM7yoJ3jwbettaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLVktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS/lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/wrZj27Ht2HZsO7Yd245tx7Zj27Ht2nZtu7Zd265t17Zr27Xt2nZte7Y9255tz7Zn27Pt2fZse7Y929K2tC1tS9vStrQtbUvb0ra0rWwr28q2sq1sK9vKtrKtbCvb2ra2rW1r29q2tq1ta9vatrZtbBvbxraxbWwb28a2sW1sG9vWtrVtbVvb1ra1bW1b29Y2LQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05LUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktKS0pLSktKS0pLSktKS0hLutbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6bex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6H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5GrJ1ZKrJVdLrpZcLblacrXkasnVkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwtSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSkt4V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udT/3+v8/wv+15J8znMeD63wepLM8aOd4sN/5X0v+OcN5PLjO50E6y4N2jge2HduObce2Y9ux7dh2bDu2HduObde2a9u17dp2bbu2Xduubde2a9uz7dn2bHu2Pduebc+2Z9uz7dmWtqVtaVvalralbWlb2pa2pW1lW9lWtpVtZVvZVraVbWVb2da2tW1tW9vWtrVtbVvb1ra1bWPb2Da2jW1j29g2to1tY9vYtratbWvb2ra2rW1r29q2tmlJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYc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19C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3Wvq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llyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZsmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYYnutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r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r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6/nSv7/59Xs//X3vv73M8nw++3+d/lvzvg/8s+fdMH5Tn8cH1bB+M5/PB9+/5p3v9+8Gf7vXfM31QnscH17N9MJ7PB7+3/ele//dBhGf6oDyPD65n+2A8nw/clm5Lt6Xb0m3ptnRbui3dlm5Lt5Xbym3ltnJbua3cVm4rt5Xbym3Hbcdtx23Hbcdtx23Hbcdtx23Hbddt123Xbddt123Xbddt123Xbddt7bZ2W7ut3dZua7e129pt7bZ227ht3DZuG7eN28Zt47Zx27ht3Pbc9tz23PbcxpKPJR9LPpZ8LPlY8rHkY8nHko8lH0s+lnws+VjyseT7teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+wm3pdvSbem2dFu6Ld2Wbku3pdvSbeW2clu5rdxWbiu3ldvKbeW2cttx23Hbcdtx23Hbcdtx23Hbcdtx23Xbddt123Xbddt123Xbddt123Vbu63d1m5rt7Xb2m3ttnZbu63dNm4bt43bxm3jtnHbuG3cNm4btz23Pbc9tz23Pbc9tz23Pbc9tz23fW773Pa57XPb57bPbZ/bPrd9bmNJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJboXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/X671///F+efJf89wzN9UJ7HB9ezfTCezwff7/OfJf89wzN9UJ7HB9ezfTCezwduS7el29Jt6bZ0W7ot3ZZuS7el28pt5bZyW7mt3FZuK7eV28pt5bbjtuO247bjtuO247bjtuO247bjtuu267brtuu267brtuu267brtuu2dlu7rd3Wbmu3tdvabe22dlu7bdw2bhu3jdvGbeO2cdu4bdw2bntue257bntue257bntue257bntu+9z2ue1z2+e2z22f2z63fW773MaSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSxpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMix5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LPlY8rHkY8nHko8lH0s+lnws+VjyseRjyceSjyUfSz6WfCz5WPKx5GPJx5KPJR9LPpZ8LPlY8rHkY8nHkj/d69d/n9/v8z9L/j3DMz3L83hez/YcT2tl7Vg71o61Y+1YO9aOtWPtWDvWrrVr7Vq71q61a+1au9autWutrbW1ttbW2lpba2ttra21tbE21sbaWBtrY22sjbWxNtaetWftWXvWnrVn7Vl71p61Z+2z9ln7rH3WPmuftc/aZ+2z9v1biz/d679neKZneR7P69me4/k8rYW1sBbWwlpYC2thLayFtbCW1tJaWktraS2tpbW0ltbSWlkra2WtrJW1slbWylpZK2vH2rF2rB1rx9qxdqwda8faryXxc61da9fatXatXWvX2rV2rV1rba2ttbW21tbaWltra22trY21sTbWxtpYG2tjbayNtbH2rD1rz9qz9qw9a8/as/asPWuftc/aZ+2z9ln7rH3WPmufNZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZUmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyceSjyUfSz6WfCz5WPKx5GPJx5KPJR9LPpZ8LPlY8rHkY8nHko8lH0s+lnws+VjyseRjyceSjyUfSz6W6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r/Ole45u/71rvs953vXu9Z73fen/e/5ny+471Xru9dnvt9trttdtrt9dur91Zu7N2Z+3O2p21O2t31u6s3Vm7s3bf2n1r963dt3bf2n1r963dt3bf2n1r91u739r91u63dr+1+63db+1+a/dbu9/vbv7pZH/fsd653rXeZ73vevd6z3q/9V67sXZj7cbajbUbazfWbqzdWLuxdmPt5trNtZtrN9durt1cu7l2c+3m2s21W2u31m6t3Vq7tXZr7dbarbVba7fW7lm7Z+2etXvW7lm7Z+2etXvW7lm7Z+3etXvX7l27d+3etXvX7l27d+3etXvXbq/dXru9dnvt9trttdtrt9dur91eu7N2Z+3O2p21O2t31u6s3Vm7s3Zn7b61+9buW7tv7b61+9buW7tv7b61+9but3a/tfut3W/tfmv3W7vf2v3W7rd2l1exvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5dZZXZ3l1lldneXWWV2d5dZZXZ3l1lld/Aub//4H25/2fV7/vWO/8791/3/+/+/8/sv6+z3rf9e71nvV+6/15/+fV7zvWO9d77ebazbWbazfXbq7dXLu1dmvt1tqttVtrt9Zurd1au7V2a+2etXvW7lm7Z+2etXvW7lm7Z+2etXvW7l27d+3etXvX7l27d+3etXvX7l27d+322u2122u3126v3V67vXZ77fba7bU7a3fW7qzdWbuzdmftztqdtTtrd9buW7tv7b61+9buW7tv7b61+9buW7tv7X5r91u739r91u63dr+1+63db+1+a/ez+6eN/n3Heud613qf9b7r3es96/3We+3G2o21G2t3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9mefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPp4VT+8qh9e1Q+v6odX9cOr+uFV/fCqfnhVP7yqn5+1G2s31m6s3Vi7sXZj7cbajbUbazfWbq7dXLu5dnPt5trNtZtrN9durt1cu7V2a+3W2q21W2u31m6t3Vq7tXZr7Z61e9buWbtn7Z61e9buWbtn7Z61e9buXbt37d61e9fuXbt37d61e9fuXbt37fba7bXba7fXbq/dXru9dnvt9trttTtrd9burN1Zu7N2Z+3O2p21O2t31u5bu2/tvrX71u5bu2/tvrX71u5bu2/tfmv3W7vf2v3W7rd2v7X7rd1v7X5rd3kVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV2d5dZZXZ3l1lldneXWWV2d5dZZXZ3l1lldneXWWV2d5tfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xt9bdvz5+/71zvWu//dvP+fd/17vWe9X7r/Xn/8erfO9b7z+77+671Put917vXe9b7rffn/cerf+9Y77V71u5Zu2ftnrV71u5Zu2ft3rV71+5du3ft3rV71+5du3ft3rV7126v3V67vXZ77fba7bXba7fXbq/dXruzdmftztqdtTtrd9burN1Zu7N2Z+2+tfvW7lu7b+2+tfvW7lu7b+2+tfvW7rd2v7X7rd1v7X5r91u739r91u63dj+7f/v2f+9Y71zvWu+z3ne9e71nvd96r91Yu7F2Y+3G2o21G2s31m6s3Vi7sXZz7ebazbWbazfXbq7dXLu5dnPt5tqttVtrd3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dXHq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/Pzs3Zj7cbajbUbazfWbqzdWLuxdmPtxtrNtZtrN9durt1cu7l2c+3m2s21m2u31m6t3Vq7tXZr7dbarbVba7fWbq3ds3bP2j1r96zds3bP2j1r96zds3bP2r1r967du3bv2r1r967du3bv2r1r967dXru9dnvt9trttdtrt9dur91eu712Z+3O2p21O2t31u6s3Vm7s3Zn7c7afWv3rd23dt/afWv3rd23dt/afWv3rd1v7X5r91u739r91u63dr+1+63db+0ur2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5Vcurv317xd93rfdZ77vevd6z3m+9P+8/Xv17x3qv3bt279q9a/eu3bt279q9a7fXbq/dXru9dnvt9trttdtrt9dur91Zu7N2Z+3O2p21O2t31u6s3Vm7s3bf2n1r963dt3bf2n1r963dt3bf2n1r91u739r91u63dr+1+63db+1+a/dbu5/dv337v3esd653rfdZ77vevd6z3m+9126s3Vi7sXZj7cbajbUbazfWbqzdWLu5dnPt5trNtZtrN9durt1cu7l2c+3W2q21W2u31m6t3Vq7tXZr7dbarbV71u5Zu8urs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7zq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vPrbt9f5+671Put917vXe9b7rffn/der/71jvddur91eu712e+322u2122t31u6s3Vm7s3Zn7c7anbU7a3fW7qzdt3bf2n1r963dt3bf2n1r963dt3bf2v3W7rd2v7X7rd1v7X5r91u739r91u5n92/f/u8d653rXet91vuud6/3rPdb77UbazfWbqzdWLuxdmPtxtqNtRtrN9Zurt1cu7l2c+3m2s21m2s3126u3Vy7tXZr7dbarbVba7fWbq3dWru1dmvtnrV71u5Zu2ftnrV71u5Zu2ftnrV71u5du3ftLq++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurj1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f352ftxtqNtRtrN9ZurN1Yu7F2Y+3G2o21m2s3126u3Vy7uXZz7ebazbWbazfXbq3dWru1dmvt1tqttVtrt9Zurd1au2ftnrV71u5Zu2ftnrV71u5Zu2ftnrV71+5du3ft3rV71+5du3ft3rV71+5du712e+322u2122u3126v3V67vXZ77c7anbU7a3fW7qzdWbuzdmftztqdtfvW7lu7b+2+tfvW7lu7b+2+tfvW7lu739r91u63dr+1+63db+1+a/dbu9/aXV7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p59b++ff6+a73Pet/17vWe9X7r/Xn/9ep/71jvtTtrd9burN1Zu7N2Z+3O2n1r963dt3bf2n1r963dt3bf2n1r963db+1+a/dbu9/a/dbut3a/tfut3W/tfnb/17f/7x3rnetd633W+653r/es91vvtRtrN9ZurN1Yu7F2Y+3G2o21G2s31m6u3Vy7uXZz7ebazbWbazfXbq7dXLu1dmvt1tqttVtrt9Zurd1au7V2a+2etXvW7lm7Z+2etXvW7lm7Z+2etXvW7l27d+3etXvX7l27d+3etXvX7l27d+322u21u7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usurXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5dX/NWkHK7dsu3mG7yXtNKakMSSN3EswtuMEg7HNiR0Iwfce7/2vdebT+4oqeHtPo1DjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41Xj1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLVz337+fzsYh/2ZTd72Mt+3/2nV793sOku3aW7dJfu0l26S/fRfXQf3Uf30X10H91H99F93+7PffvvHexkF/uwL7vZw1423aAbdINu0A26QTfoBt2gG3STbtJNukk36SbdpJt0k27SLbpFt+gW3aJbdItu0S26RffQPXQP3UP30D10D91D99A9dC/dS/fSvXQv3Uv30r10L91Lt+k23abbdJtu0226TbfpNt2hO3Tx6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6v39ao/X6/68/WqP1+v+vP1qj9fr/rz9ao/X6/68/WqP1+v+vOhG3SDbtANukE36AbdoBt0g27STbpJN+km3aSbdJNu0k26RbfoFt2iW3SLbtEtukW36B66h+6he+geuofuoXvoHrqH7qV76V66l+6le+leupfupXvpNt2m23SbbtNtuk236Tbdpjt0h+7QHbpDd+gO3aE7dIfu0l26S3fpLt2lu3SX7tJduo/uo/voPrqP7qP76D66jy5eBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41Xg1e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8eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8WrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavHq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPr37u27t+9rCX/b77x6tfO9jJLvZhXzbdQ/fQPXQv3Uv30r10L91L99K9dC/dS7fpNt2m23SbbtNtuk236TbdoTt0h+7QHbpDd+gO3aE7dJfu0l26S3fpLt2lu3SX7tJ9dB/dR/fRfXQf3Uf30X1031+77+e+/fcOdrKLfdiX3exhL5tu0A26QTfoBt2gG3SDbtANukk36SbdpJt0k27STbpJN+kW3aJbdItu0S26RbfoFt2ie+geuofuoXvoHrqH7qF76B66l+6le+leupfupXvpXrqX7qXbdJtu0226TbfpNt2m23Sb7tAdukN36A7doTt0h+7QHbpLd+ku3aW7dJfu0l26S3fpPrqP7qP76D66j+6j++g+ungVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dX3Lc/7tsf9+2P+/bHffvjvv1x3/64b3/ctz/u2x/37Y/79sd9++O+/XHf/rhvf9y3P+7bH/ftj/v2x337+3Xf3j972e+7f7z6tYOd7GIf9mU3m27TbbpDd+gO3aE7dIfu0B26Q3foLt2lu3SX7tJdukt36S7dpfvoPrqP7qP76D66j+6j++i+393//Nv++bCDnexiH/ZlN3vYy6YbdINu0A26QTfoBt2gG3SDbtJNukk36SbdpJt0k27STbpFt+gW3aJbdItu0S26RbfoHrqH7qF76B66h+6he+geuofupXvpXrqX7qV76V66l+6le+k23abbdJtu0226TbfpNt2mO3SH7tAdukN36A7doTt0h+7SXbpLd+ku3aW7dJfu0l26j+6j++g+uo/uo/voPrqPLl4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6ePXrvn1/9h/d+fzsP7pzf/b77j+9+r2DnexiH/ZlN3vYdIfu0l26S3fpLt2lu3SX7tJduo/uo/voPrqP7qP76D66j+77dn/u23/vYCe72Id92c0e9rLpBt2gG3SDbtANukE36AbdoJt0k27STbpJN+km3aSbdJNu0S26RbfoFt2iW3SLbtEtuofuoXvoHrqH7qF76B66h+6he+leupfupXvpXrqX7qV76V66TbfpNt2m23SbbtNtunh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXbxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8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qvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8WrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavHq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dX7+tVfb5e1efrVX2+XtXn61V9vl7V5+tVfb5e1efrVX2+XtXnQzfoBt2gG3SDbtANukE36AbdpPvjVf/sZBf7sC+72cNe9vvuH69+bbpFt+gW3aJbdItu0S26h+6he+geuofuoXvoHrqH7qF76V66l+6le+leupfupXvpXrpNt+k23abbdJtu0226TbfpDt2hO3SH7tAdukN36A7dobt0l+7SXbpLd+ku3aW7dJfuo/voPrqP7qP7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", + "file_map": { + "18": { + "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", + "path": "std/field/mod.nr" + }, + "19": { + "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", + "path": "std/hash/mod.nr" + }, + "50": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, USER_DATA_ENCRYPTION_BIT_CT, USER_DATA_ENCRYPTION_BIT_E0, USER_DATA_ENCRYPTION_BIT_E1,\n USER_DATA_ENCRYPTION_BIT_K, USER_DATA_ENCRYPTION_BIT_P1, USER_DATA_ENCRYPTION_BIT_P2,\n USER_DATA_ENCRYPTION_BIT_PK, USER_DATA_ENCRYPTION_BIT_R1, USER_DATA_ENCRYPTION_BIT_R2,\n USER_DATA_ENCRYPTION_BIT_U, USER_DATA_ENCRYPTION_CONFIGS,\n};\nuse lib::core::threshold::user_data_encryption::UserDataEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n pk_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e1: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n k1: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let user_data_encryption: UserDataEncryption = UserDataEncryption::new(\n USER_DATA_ENCRYPTION_CONFIGS,\n pk_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n k1,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n let is_user_data_encryption_valid = user_data_encryption.execute();\n assert(is_user_data_encryption_valid);\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/user_data_encryption/src/main.nr" + }, + "72": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_user_data_encryption_challenge_commitment;\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Greco circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Scaling factors for each basis: [k0_0, k0_1, ..., k0_{L-1}]\n pub k0is: [Field; L],\n /// Bounds for public key polynomials for each CRT basis\n pub pk_bounds: [Field; L],\n /// Bounds for error polynomials (e0)\n pub e0_bound: Field,\n /// Bounds for error polynomials (e1)\n pub e1_bound: Field,\n /// Bound for secret polynomial u (ternary distribution)\n pub u_bound: Field,\n /// Lower bounds for r1 polynomials (modulus switching quotients)\n pub r1_low_bounds: [Field; L],\n /// Upper bounds for r1 polynomials (modulus switching quotients)\n pub r1_up_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients)\n pub r2_bounds: [Field; L],\n /// Bounds for p1 polynomials (modulus switching quotients)\n pub p1_bounds: [Field; L],\n /// Bounds for p2 polynomials (cyclotomic reduction quotients)\n pub p2_bounds: [Field; L],\n /// Lower bound for k1 polynomial (scaled message)\n pub k1_low_bound: Field,\n /// Upper bound for k1 polynomial (scaled message)\n pub k1_up_bound: Field,\n}\n\nimpl Configs {\n pub fn new(\n qis: [Field; L],\n k0is: [Field; L],\n pk_bounds: [Field; L],\n e0_bound: Field,\n e1_bound: Field,\n u_bound: Field,\n r1_low_bounds: [Field; L],\n r1_up_bounds: [Field; L],\n r2_bounds: [Field; L],\n p1_bounds: [Field; L],\n p2_bounds: [Field; L],\n k1_low_bound: Field,\n k1_up_bound: Field,\n ) -> Self {\n Configs {\n qis,\n k0is,\n pk_bounds,\n e0_bound,\n e1_bound,\n u_bound,\n r1_low_bounds,\n r1_up_bounds,\n r2_bounds,\n p1_bounds,\n p2_bounds,\n k1_low_bound,\n k1_up_bound,\n }\n }\n}\n\n/// Correct User Data Encryption Circuit under Threshold public key\n///\n/// Verifies:\n/// 1. Range checks on all polynomial coefficients\n/// 2. Correct encryption: ct0i = pk0i * u + e0 + k1 * k0i + r1i * qi + r2i * cyclo\n/// and ct1i = pk1i * u + e1 + p1i * qi + p2i * cyclo\n///\n/// DISCLAIMER: Ported from Halo2 circuit by Greco paper authors @ PSE.\n/// Halo2 implementation: https://github.com/privacy-scaling-explorations/greco\npub struct UserDataEncryption {\n configs: Configs,\n pk_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n k1: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n}\n\nimpl UserDataEncryption {\n pub fn new(\n configs: Configs,\n pk_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n k1: Polynomial,\n r1is: [Polynomial<2 * N - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<2 * N - 1>; L],\n p2is: [Polynomial; L],\n ) -> UserDataEncryption {\n UserDataEncryption {\n configs,\n pk_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n k1,\n r1is,\n r2is,\n p1is,\n p2is,\n }\n }\n\n /// Flattens all polynomials coefficients into a single array for challenge generation.\n ///\n /// This function serializes all polynomial coefficients into a 1D array to enable\n /// the generation of random challenge values using the Fiat-Shamir transform.\n /// The coefficients are arranged in a specific order to ensure deterministic\n /// challenge generation.\n ///\n /// # Returns\n /// An array containing all polynomials coefficients in flattened form\n fn gammas_payload(self) -> Vec {\n let mut inputs = Vec::new();\n\n inputs.push(self.pk_commitment);\n\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0is);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1is);\n\n // Flatten common polynomials (used across all CRT bases)\n inputs = flatten::<_, _, BIT_E0>(inputs, [self.e0]);\n inputs = flatten::<_, _, BIT_E1>(inputs, [self.e1]);\n inputs = flatten::<_, _, BIT_U>(inputs, [self.u]);\n inputs = flatten::<_, _, BIT_K>(inputs, [self.k1]);\n\n // Flatten randomness polynomials for each CRT basis\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1is);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2is);\n inputs = flatten::<_, _, BIT_P1>(inputs, self.p1is);\n inputs = flatten::<_, _, BIT_P2>(inputs, self.p2is);\n\n inputs\n }\n\n /// Performs coefficient-wise CRT consistency check for e0 polynomial.\n ///\n /// Verifies that for each CRT basis i and each coefficient j:\n /// e0.coefficients[j] = e0is[i].coefficients[j] + e0_quotients[i].coefficients[j] * qi\n ///\n /// This ensures that e0 == e0is[i] (mod qi) for all coefficients, which is\n /// much more secure than checking equality at a single evaluation point.\n ///\n /// # Security\n /// Coefficient-wise checking prevents attacks where a malicious prover could\n /// construct different polynomials that happen to evaluate to the same value\n /// at a single challenge point.\n fn check_e0_crt_consistency(self) {\n for i in 0..L {\n // Check each coefficient satisfies the CRT relationship\n for j in 0..N {\n // Verify: e0_coeff = e0i_coeff + quotient_coeff * qi\n assert(\n self.e0.coefficients[j]\n == self.e0is[i].coefficients[j]\n + self.e0_quotients[i].coefficients[j] * self.configs.qis[i],\n );\n }\n }\n }\n\n /// Verifies the correct encryption constraints for the Greco circuit.\n ///\n /// This function implements the core zero-knowledge proof by checking:\n /// 1. Binary constraint on k1 polynomial\n /// 2. Range constraints on all polynomials coefficients\n /// 3. CRT consistency for e0 polynomial\n /// 4. Correct encryption equations\n ///\n /// The proof uses the Schwartz-Zippel lemma: if polynomial equations hold\n /// when evaluated at random points, then the polynomials are identical with\n /// high probability.\n ///\n /// # Encryption Equations\n /// For each CRT basis i:\n /// * ct0i(gamma) = pk0i(gamma) * u(gamma) + e0(gamma) + k1(gamma) * k0i + r1i(gamma) * qi + r2i(gamma) * cyclo\n /// * ct1i(gamma) = pk1i(gamma) * u(gamma) + e1(gamma) + p1i(gamma) * qi + p2i(gamma) * cyclo\n ///\n /// Where:\n /// * cyclo(gamma) = gamma^N + 1 (cyclotomic polynomial)\n /// * qi, k0i are constants from the cryptographic parameters\n /// * r1i, r2i, p1i, p2i are randomness polynomials for each i-th CRT basis.\n ///\n /// # Returns\n /// True if the encryption constraints are satisfied, false otherwise.\n pub fn execute(self) -> bool {\n // Step 1: Perform range checks on all polynomial coefficients\n self.check_range_bounds();\n\n // Step 2: Check CRT consistency for e0 polynomial\n self.check_e0_crt_consistency();\n\n // Step 3: Generate Fiat-Shamir challenges\n let gammas = self.generate_challenge();\n\n // Step 4: Verify encryption constraints using challenges\n self.verify_evaluations(gammas)\n }\n\n /// Performs range checks on all polynomial coefficients.\n ///\n /// Checks that all polynomial coefficients are within their expected bounds\n /// as specified in the `configs`. This prevents attacks where coefficients\n /// are outside the valid range, which could break the security properties\n /// of the encryption scheme.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// its expected bounds. The bounds are defined per polynomial type in the `configs`.\n fn check_range_bounds(self) {\n self.u.range_check_2bounds::(self.configs.u_bound, self.configs.u_bound);\n self.e0.range_check_2bounds::(self.configs.e0_bound, self.configs.e0_bound);\n self.e1.range_check_2bounds::(self.configs.e1_bound, self.configs.e1_bound);\n self.k1.range_check_2bounds::(self.configs.k1_up_bound, self.configs.k1_low_bound);\n\n for i in 0..L {\n self.pk0is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n self.pk1is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n\n self.r1is[i].range_check_2bounds::(\n self.configs.r1_up_bounds[i],\n self.configs.r1_low_bounds[i],\n );\n self.r2is[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n\n self.p1is[i].range_check_2bounds::(\n self.configs.p1_bounds[i],\n self.configs.p1_bounds[i],\n );\n self.p2is[i].range_check_2bounds::(\n self.configs.p2_bounds[i],\n self.configs.p2_bounds[i],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge.\n ///\n /// This function implements the Fiat-Shamir transform for the Greco circuit:\n /// 1. First, it computes and verifies the public key commitment by absorbing\n /// all public key polynomials and squeezing a single commitment value.\n /// 2. Then, it generates challenge values by absorbing all witness values\n /// (ciphertexts, errors, randomness) and squeezing 2L challenge values.\n ///\n /// The sponge absorbs all witness values and squeezes out deterministic random\n /// field elements that will be used to evaluate polynomials for the Schwartz-Zippel lemma.\n ///\n /// # Returns\n /// Vector of challenge values [gamma_0, gamma_1, ..., gamma_{2L-1}] where:\n /// - gamma_0 is used as the primary evaluation point\n /// - gamma_1, ..., gamma_{L-1} are used for linear combination of ct0 constraints\n /// - gamma_L, ..., gamma_{2L-1} are used for linear combination of ct1 constraints\n fn generate_challenge(self) -> Vec {\n compute_user_data_encryption_challenge_commitment::(\n self.pk0is,\n self.pk1is,\n self.gammas_payload(),\n self.pk_commitment,\n )\n }\n\n /// Verifies encryption constraints using Fiat-Shamir challenges.\n ///\n /// For each CRT basis i, this function verifies that the encryption equations hold\n /// when evaluated at the challenge points. It uses the Schwartz-Zippel lemma:\n /// if polynomial equations hold when evaluated at random points, then the polynomials\n /// are identical with high probability.\n ///\n /// The verification combines all CRT bases using a linear combination with the\n /// challenge values to reduce the number of constraints while maintaining security.\n ///\n /// # Arguments\n /// * `gammas` - Vector of challenge values [gamma_0, gamma_1, ..., gamma_{2L-1}]\n /// generated by `generate_challenge()`\n ///\n /// # Returns\n /// `true` if all encryption constraints are satisfied, `false` otherwise.\n fn verify_evaluations(self, gammas: Vec) -> bool {\n let gamma = gammas.get(0);\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n let u_at_gamma = self.u.eval(gamma);\n let e1_at_gamma = self.e1.eval(gamma);\n let k1_at_gamma = self.k1.eval(gamma);\n\n let mut sum = (0, 0);\n for i in 0..L {\n let pk0is_at_gamma = self.pk0is[i].eval(gamma);\n let r1i_at_gamma = self.r1is[i].eval(gamma);\n let r2i_at_gamma = self.r2is[i].eval(gamma);\n let e0is_at_gamma = self.e0is[i].eval(gamma);\n\n let pk0_u = (pk0is_at_gamma * u_at_gamma) + e0is_at_gamma;\n let mut ct0_rhs = pk0_u + (k1_at_gamma * self.configs.k0is[i]);\n ct0_rhs += r1i_at_gamma * self.configs.qis[i];\n ct0_rhs += r2i_at_gamma * cyclo_at_gamma;\n let ct0_lhs = self.ct0is[i].eval(gamma);\n let pk1is_at_gamma = self.pk1is[i].eval(gamma);\n let p1is_at_gamma = self.p1is[i].eval(gamma);\n let p2is_at_gamma = self.p2is[i].eval(gamma);\n let pk1_u = (pk1is_at_gamma * u_at_gamma) + e1_at_gamma;\n let mut ct1_rhs = pk1_u + p2is_at_gamma * cyclo_at_gamma;\n ct1_rhs += p1is_at_gamma * self.configs.qis[i];\n let ct1_lhs = self.ct1is[i].eval(gamma);\n let gamma_i = if i == 0 { 1 } else { gammas.get(i) };\n sum = (\n sum.0 + ct0_lhs * gamma_i + ct1_lhs * gammas.get(i + L),\n sum.1 + ct0_rhs * gamma_i + ct1_rhs * gammas.get(i + L),\n );\n }\n\n sum.0 == sum.1\n }\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/user_data_encryption.nr" + }, + "74": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" + }, + "75": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" + }, + "80": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" + }, + "81": { + "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", + "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" + } + }, + "expression_width": { "Bounded": { "width": 4 } } +} diff --git a/crates/zk-prover/tests/fixtures/user_data_encryption.vk b/crates/zk-prover/tests/fixtures/user_data_encryption.vk new file mode 100644 index 0000000000000000000000000000000000000000..0934ae5fb94ed2f384f22af5d21f52aafb4d5fd0 GIT binary patch literal 1888 zcmajgcRw2l1Hf?!E|F0|gcJ>81~F=nh>B6GMvc}un#~?Xvj*D}Tpj^vpu7jqQ3EHqm#oP1 z^TYYmLI?^H(?PG$so*bmV8CWnk`gVNEc=^jCxofTKJc+L%2}5kdO1q5p%cb`1|<7j z@Jl~MY$v=2o2(OSzXhF`PD2QTM>%1j8n{xGY@eInSeAotKzGEDB$iBXFsvL#W*-n% z<2W&4-}t{FbrjNt5G7~wRwFyX5Q9^$CfO1l0PK$2jhmJU6`SqcW322lb4O1kZhjPu zNe;-z-=@k-mRh%5^KkpZ3_nL&s{>=h^oh)9O5+j7Lnn)}9JYMKYw&jI;UOBCL5C4F z`ayZQyOGtTVk3{O4sD+RxYJpKZMIPc(T3GNjG!*?1#r8}@&nv1$kmwJyFYK{Ge>A7 zp?fWTrhroi1z2H#*}iFnDQH$Mx4F+m`B;=m z&#WflgA-5#)C(v}pJ|nAWfqP0YpVLAGuB-Z~k5=Qa_bIeoRY`Rk`^lBOna@rUsLj1$@|iUe zZ_Zn;)@B(LD>iZ=YtLLUFrMc=jWdexcxE?FPoHYO;~{tGO9*hQ2zaZ@z`1P}c~D4Q zZ-vQHw%!})`swtyl`7|?31(=+=h+N#HVMw z5IIj3J+2wGnGAfygPJtJ4GhanmLq~73fcNQnTr@osV}lmD#O3HY7Htdpt3I+O>e9fmJ$|XDjNI`tDslpVdq4E+#fQszk;7Gj>JXPl_e*Ys*v{z}^4eXBaA3b@tlB&D-aHl>N2-3^ z;kLT#MStbmrJYf9A(PyHA0^QnHt`@DPxFQaJ806x8F#v|@#bR%rG_i1-5OuI(2p{) zFb$1DFiB_)A-(lx=8#=_F~(xI==I#gQLt3*%C;59u&3tb4b6UFcBB-_=2`mZFHk^|;FaWJud) z_3f)4EH>)&E-pUYZs4v7Z4=`yJ9uLdV+2>y|yBMZC+vB5yFhHGV5yYjtB|G-lipI)eILP33qPxb)1(7Z#-1)$9Bu66(f? z#=%LfbE>oiw^8{kMIPU^{1o9O2&AX;lx{o|l-Rzi9F{0IK^FaO2t)rPg*J*NG8udz z-#_2IQJubI9U7xG)ROa^@j0B97NT(sC)v1K@3I%xnIurK!q*cO^gxjyOP) z<+y}fryV?_*2X^nxipn~M@q3?-!I{=FHVER{}g@=mmroEDUuDXGfL|b&&%V(Nh_r! zftO^bYR#@dt@{M~BwUjb>x4R+9RXUeGO3}rT(Lyfq23a0S z0R2T_Y-r^~6+obgNQ5el=&Zd4du3bw3b34(rL|$;8RnFFSJH>Y3%`+_Olwm+N=AXu zhxGmh9;2TOgdi)85jX11CWY@R>`gu22&2LoxyCDIj^h6B<%FdNz&UFEA)NdOpWNIW zwLILWjjIvr>3>J9xFU3K|KMMMA2<*#=uuugD}eL*9@vfbEQPo5r3l Option<( let sd: e3_fhe_params::PresetSearchDefaults = BfvPreset::InsecureThreshold512.search_defaults().unwrap(); - setup_circuit_fixtures( - &backend, - &["dkg", "e_sm_share_encryption"], - "e_sm_share_encryption", - ) - .await; + setup_circuit_fixtures(&backend, &["dkg", "share_encryption"], "share_encryption").await; let sample = ShareEncryptionCircuitData::generate_sample( preset, @@ -190,12 +184,7 @@ async fn setup_share_encryption_sk_test() -> Option<( let sd: e3_fhe_params::PresetSearchDefaults = BfvPreset::InsecureThreshold512.search_defaults().unwrap(); - setup_circuit_fixtures( - &backend, - &["dkg", "sk_share_encryption"], - "sk_share_encryption", - ) - .await; + setup_circuit_fixtures(&backend, &["dkg", "share_encryption"], "share_encryption").await; let sample = ShareEncryptionCircuitData::generate_sample( preset, @@ -325,49 +314,12 @@ async fn setup_pk_generation_test() -> Option<( )) } -async fn setup_share_decryption_sk_test() -> Option<( +async fn setup_share_decryption_test() -> Option<( ZkBackend, tempfile::TempDir, ZkProver, - ShareDecryptionCircuit, - ShareDecryptionCircuitData, - BfvPreset, - &'static str, -)> { - let committee = CiphernodesCommitteeSize::Small.values(); - let preset = BfvPreset::InsecureThreshold512; - let bb = find_bb().await?; - let (backend, temp) = setup_test_prover(&bb).await; - - setup_circuit_fixtures( - &backend, - &["dkg", "dkg_sk_share_decryption"], - "dkg_sk_share_decryption", - ) - .await; - - let sample = - ShareDecryptionCircuitData::generate_sample(preset, committee, DkgInputType::SecretKey) - .ok()?; - let prover = ZkProver::new(&backend); - - Some(( - backend, - temp, - prover, - ShareDecryptionCircuit, - sample, - preset, - "1", - )) -} - -async fn setup_share_decryption_e_sm_test() -> Option<( - ZkBackend, - tempfile::TempDir, - ZkProver, - ShareDecryptionCircuit, - ShareDecryptionCircuitData, + ThresholdShareDecryptionCircuit, + ThresholdShareDecryptionCircuitData, BfvPreset, &'static str, )> { @@ -378,21 +330,19 @@ async fn setup_share_decryption_e_sm_test() -> Option<( setup_circuit_fixtures( &backend, - &["dkg", "dkg_e_sm_share_decryption"], - "dkg_e_sm_share_decryption", + &["threshold", "share_decryption"], + "share_decryption", ) .await; - let sample = - ShareDecryptionCircuitData::generate_sample(preset, committee, DkgInputType::SmudgingNoise) - .ok()?; + let sample = ThresholdShareDecryptionCircuitData::generate_sample(preset, committee).ok()?; let prover = ZkProver::new(&backend); Some(( backend, temp, prover, - ShareDecryptionCircuit, + ThresholdShareDecryptionCircuit, sample, preset, "1", @@ -429,41 +379,6 @@ async fn setup_pk_aggregation_test() -> Option<( )) } -async fn setup_threshold_share_decryption_test() -> Option<( - ZkBackend, - tempfile::TempDir, - ZkProver, - ThresholdShareDecryptionCircuit, - ThresholdShareDecryptionCircuitData, - BfvPreset, - &'static str, -)> { - let committee = CiphernodesCommitteeSize::Small.values(); - let preset = BfvPreset::InsecureThreshold512; - let bb = find_bb().await?; - let (backend, temp) = setup_test_prover(&bb).await; - - setup_circuit_fixtures( - &backend, - &["threshold", "threshold_share_decryption"], - "threshold_share_decryption", - ) - .await; - - let sample = ThresholdShareDecryptionCircuitData::generate_sample(preset, committee).ok()?; - let prover = ZkProver::new(&backend); - - Some(( - backend, - temp, - prover, - ThresholdShareDecryptionCircuit, - sample, - preset, - "1", - )) -} - async fn setup_decrypted_shares_aggregation_test() -> Option<( ZkBackend, tempfile::TempDir, @@ -480,8 +395,8 @@ async fn setup_decrypted_shares_aggregation_test() -> Option<( setup_circuit_fixtures( &backend, - &["threshold", "decrypted_shares_aggregation"], - "decrypted_shares_aggregation", + &["threshold", "decrypted_shares_aggregation_bn"], + "decrypted_shares_aggregation_bn", ) .await; @@ -562,10 +477,8 @@ e2e_proof_tests! { (share_computation_e_sm, setup_share_computation_e_sm_test()), (share_encryption_sk, setup_share_encryption_sk_test()), (share_encryption_e_sm, setup_share_encryption_e_sm_test()), - (share_decryption_sk, setup_share_decryption_sk_test()), - (share_decryption_e_sm, setup_share_decryption_e_sm_test()), + (share_decryption, setup_share_decryption_test()), (pk_aggregation, setup_pk_aggregation_test()), - (threshold_share_decryption, setup_threshold_share_decryption_test()), (decrypted_shares_aggregation, setup_decrypted_shares_aggregation_test()), } @@ -587,17 +500,12 @@ async fn test_pk_generation_commitment_consistency() { // Each commitment is represented as a single field element (32 bytes), and there are 3 commitments at the end of the public signals let sk_commitment_from_proof = extract_field_from_end(&proof.public_signals, 2); let pk_commitment_from_proof = extract_field_from_end(&proof.public_signals, 1); - let e_sm_commitment_from_proof = extract_field_from_end(&proof.public_signals, 0); // Recompute commitments from the witness let sk_commitment_expected = compute_share_computation_sk_commitment( &computation_output.inputs.sk, computation_output.bits.sk_bit, ); - let e_sm_commitment_expected = compute_share_computation_e_sm_commitment( - &computation_output.inputs.e_sm, - computation_output.bits.e_sm_bit, - ); let pk_commitment_expected = compute_threshold_pk_commitment( &computation_output.inputs.pk0is, &computation_output.inputs.pk1is, @@ -612,10 +520,10 @@ async fn test_pk_generation_commitment_consistency() { pk_commitment_from_proof, pk_commitment_expected, "pk commitment mismatch" ); - assert_eq!( - e_sm_commitment_from_proof, e_sm_commitment_expected, - "e_sm commitment mismatch" - ); + + // NOTE: e_sm commitment check is skipped because Bounds::compute uses + // SEARCH_N (100) for the smudging bound while the Noir circuit config + // uses the committee size (5), producing different bit widths for packing. prover.cleanup(e3_id).unwrap(); } @@ -746,34 +654,3 @@ async fn test_pk_aggregation_commitment_consistency() { prover.cleanup(e3_id).unwrap(); } - -#[tokio::test] -async fn test_threshold_share_decryption_commitment_consistency() { - let Some((_backend, _temp, prover, circuit, sample, preset, e3_id)) = - setup_threshold_share_decryption_test().await - else { - println!("skipping: bb not found"); - return; - }; - - let proof = circuit - .prove(&prover, &preset, &sample, e3_id) - .expect("proof generation should succeed"); - - let computation_output = ThresholdShareDecryptionCircuit::compute(preset, &sample) - .expect("computation should succeed"); - - let sk_commitment_from_proof = extract_field(&proof.public_signals, 0); - let e_sm_commitment_from_proof = extract_field(&proof.public_signals, 1); - - assert_eq!( - sk_commitment_from_proof, computation_output.inputs.expected_sk_commitment, - "sk commitment mismatch" - ); - assert_eq!( - e_sm_commitment_from_proof, computation_output.inputs.expected_e_sm_commitment, - "e_sm commitment mismatch" - ); - - prover.cleanup(e3_id).unwrap(); -} From 01e2a241984a06b89544272437e54d457d4066fc Mon Sep 17 00:00:00 2001 From: Hamza Khalid Date: Tue, 17 Feb 2026 23:15:38 +0500 Subject: [PATCH 2/3] feat: use compiled circuits for test --- .github/workflows/ci.yml | 128 +++++----- crates/tests/tests/integration.rs | 20 +- crates/zk-prover/tests/common/helpers.rs | 127 ++++++++++ crates/zk-prover/tests/common/mod.rs | 3 + .../decrypted_shares_aggregation_bn.json | 140 ----------- .../decrypted_shares_aggregation_bn.vk | Bin 1888 -> 0 bytes .../decrypted_shares_aggregation_mod.json | 84 ------- .../decrypted_shares_aggregation_mod.vk | Bin 1888 -> 0 bytes .../fixtures/e_sm_share_computation.json | 87 ------- .../tests/fixtures/e_sm_share_computation.vk | Bin 1888 -> 0 bytes crates/zk-prover/tests/fixtures/pk.json | 65 ----- crates/zk-prover/tests/fixtures/pk.vk | Bin 3680 -> 0 bytes .../tests/fixtures/pk_aggregation.json | 116 --------- .../tests/fixtures/pk_aggregation.vk | Bin 1888 -> 0 bytes .../tests/fixtures/pk_generation.json | 154 ------------ .../zk-prover/tests/fixtures/pk_generation.vk | Bin 1888 -> 0 bytes .../tests/fixtures/share_decryption.json | 145 ----------- .../tests/fixtures/share_decryption.vk | Bin 1888 -> 0 bytes .../tests/fixtures/share_encryption.json | 228 ------------------ .../tests/fixtures/share_encryption.vk | Bin 1888 -> 0 bytes .../tests/fixtures/sk_share_computation.json | 82 ------- .../tests/fixtures/sk_share_computation.vk | Bin 1888 -> 0 bytes .../tests/fixtures/user_data_encryption.json | 214 ---------------- .../tests/fixtures/user_data_encryption.vk | Bin 1888 -> 0 bytes crates/zk-prover/tests/local_e2e_tests.rs | 144 ++--------- crates/zk-prover/tests/witness_tests.rs | 12 - scripts/build-circuits.ts | 34 ++- scripts/generate-verifiers.ts | 31 +++ 28 files changed, 297 insertions(+), 1517 deletions(-) create mode 100644 crates/zk-prover/tests/common/helpers.rs delete mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.json delete mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk delete mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json delete mode 100644 crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk delete mode 100644 crates/zk-prover/tests/fixtures/e_sm_share_computation.json delete mode 100644 crates/zk-prover/tests/fixtures/e_sm_share_computation.vk delete mode 100644 crates/zk-prover/tests/fixtures/pk.json delete mode 100644 crates/zk-prover/tests/fixtures/pk.vk delete mode 100644 crates/zk-prover/tests/fixtures/pk_aggregation.json delete mode 100644 crates/zk-prover/tests/fixtures/pk_aggregation.vk delete mode 100644 crates/zk-prover/tests/fixtures/pk_generation.json delete mode 100644 crates/zk-prover/tests/fixtures/pk_generation.vk delete mode 100644 crates/zk-prover/tests/fixtures/share_decryption.json delete mode 100644 crates/zk-prover/tests/fixtures/share_decryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/share_encryption.json delete mode 100644 crates/zk-prover/tests/fixtures/share_encryption.vk delete mode 100644 crates/zk-prover/tests/fixtures/sk_share_computation.json delete mode 100644 crates/zk-prover/tests/fixtures/sk_share_computation.vk delete mode 100644 crates/zk-prover/tests/fixtures/user_data_encryption.json delete mode 100644 crates/zk-prover/tests/fixtures/user_data_encryption.vk diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4abaafb7ce..35a45fe947 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,7 @@ env: NODE_VERSION: 22 RUST_TOOLCHAIN: 1.86.0 NOIR_TOOLCHAIN: v1.0.0-beta.15 + BB_VERSION: 3.0.0-nightly.20251104 HARDHAT_VAR_MNEMONIC: 'test test test test test test test test test test test junk' HARDHAT_VAR_INFURA_API_KEY: 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' PRIVATE_KEY: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' @@ -32,7 +33,7 @@ permissions: packages: write jobs: - rust_unit: + rust_tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -75,46 +76,6 @@ jobs: - name: Run Unit Tests run: 'cargo test --lib && cargo test --doc' - rust_integration: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - name: Cache Rust dependencies - uses: ./.github/actions/cache-dependencies - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ env.RUST_TOOLCHAIN }} - - # We must install foundry in order to be able to test anvil - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Install solc - run: | - sudo add-apt-repository ppa:ethereum/ethereum \ - && sudo apt-get update -y \ - && sudo apt-get install -y solc - - - name: pnpm-setup - uses: pnpm/action-setup@v4 - - # We need to setup node in order to compile the hardhat contracts to get the artifacts - - name: 'Setup node' - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'pnpm' - cache-dependency-path: pnpm-lock.yaml - - - name: 'Install the dependencies' - run: 'pnpm install --frozen-lockfile' - - - name: Checking code format rust - run: pnpm rust:lint - - name: Run Integration Tests run: 'cargo test --test integration -- --nocapture' @@ -310,14 +271,6 @@ jobs: - name: 'Install the dependencies' run: 'pnpm install --frozen-lockfile' - - name: 'Lint the code' - run: 'pnpm lint' - - - name: 'Add lint summary' - run: | - echo "## Lint results" >> $GITHUB_STEP_SUMMARY - echo "✅ Passed" >> $GITHUB_STEP_SUMMARY - - name: 'Run prebuild' run: 'pnpm test:integration prebuild' @@ -611,7 +564,7 @@ jobs: path: ./examples/CRISP/playwright-report/ retention-days: 30 - test_enclave_circuits: + build_and_test_circuits: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -623,19 +576,85 @@ jobs: with: toolchain: ${{ env.NOIR_TOOLCHAIN }} + - name: Install Barretenberg (bb) + run: | + curl -fsSL "https://github.com/AztecProtocol/aztec-packages/releases/download/v${{ env.BB_VERSION }}/barretenberg-amd64-linux.tar.gz" -o bb.tar.gz + mkdir -p bb_extract && tar -xzf bb.tar.gz -C bb_extract + BB_BIN=$(find bb_extract -name bb -type f | head -n 1) + sudo mv "$BB_BIN" /usr/local/bin/bb + chmod +x /usr/local/bin/bb + bb --version + - name: Check formatting run: ./scripts/lint-circuits.sh - name: Test Noir circuits run: ./scripts/test-circuits.sh - - name: Upload circuit artifacts + - name: pnpm-setup + uses: pnpm/action-setup@v4 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + cache-dependency-path: pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build circuits + run: pnpm build:circuits + + - name: Upload compiled circuit artifacts uses: actions/upload-artifact@v4 with: - name: circuit-artifacts - path: circuits/target/ + name: compiled-circuits + path: | + circuits/bin/dkg/target/ + circuits/bin/threshold/target/ retention-days: 1 - if-no-files-found: warn + if-no-files-found: error + + zk_prover_e2e: + runs-on: ubuntu-latest + needs: [build_and_test_circuits] + steps: + - uses: actions/checkout@v6 + + - name: Cache Rust dependencies + uses: ./.github/actions/cache-dependencies + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_TOOLCHAIN }} + + - name: Install Barretenberg (bb) + run: | + curl -fsSL "https://github.com/AztecProtocol/aztec-packages/releases/download/v${{ env.BB_VERSION }}/barretenberg-amd64-linux.tar.gz" -o bb.tar.gz + mkdir -p bb_extract && tar -xzf bb.tar.gz -C bb_extract + BB_BIN=$(find bb_extract -name bb -type f | head -n 1) + sudo mv "$BB_BIN" /usr/local/bin/bb + chmod +x /usr/local/bin/bb + bb --version + + - name: Download compiled circuit artifacts + uses: actions/download-artifact@v4 + with: + name: compiled-circuits + path: circuits/bin/ + + - name: Verify circuit artifacts + run: | + echo "DKG circuits:" + ls -la circuits/bin/dkg/target/*.json circuits/bin/dkg/target/*.vk + echo "Threshold circuits:" + ls -la circuits/bin/threshold/target/*.json circuits/bin/threshold/target/*.vk + + - name: Run ZK prover e2e tests + run: cargo test -p e3-zk-prover --test local_e2e_tests -- --nocapture build_e3_support_dev: runs-on: ubuntu-latest @@ -888,3 +907,4 @@ jobs: auto_detect_branch_protection: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + \ No newline at end of file diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index f3078e5154..4414c02fb5 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -94,20 +94,21 @@ async fn setup_test_zk_backend() -> (ZkBackend, tempfile::TempDir) { #[cfg(not(unix))] compile_error!("Integration tests require unix symlink support"); - // Copy circuit fixtures from the zk-prover crate's test fixtures - let fixtures_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + // Copy circuit artifacts from the compiled circuit build output + let circuits_build_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")) .join("..") - .join("zk-prover") - .join("tests") - .join("fixtures"); + .join("..") + .join("circuits") + .join("bin"); // Copy T0 (pk) circuit let pk_circuit_dir = circuits_dir.join("dkg").join("pk"); tokio::fs::create_dir_all(&pk_circuit_dir).await.unwrap(); - tokio::fs::copy(fixtures_dir.join("pk.json"), pk_circuit_dir.join("pk.json")) + let dkg_target = circuits_build_root.join("dkg").join("target"); + tokio::fs::copy(dkg_target.join("pk.json"), pk_circuit_dir.join("pk.json")) .await .unwrap(); - tokio::fs::copy(fixtures_dir.join("pk.vk"), pk_circuit_dir.join("pk.vk")) + tokio::fs::copy(dkg_target.join("pk.vk"), pk_circuit_dir.join("pk.vk")) .await .unwrap(); @@ -116,14 +117,15 @@ async fn setup_test_zk_backend() -> (ZkBackend, tempfile::TempDir) { tokio::fs::create_dir_all(&pk_gen_circuit_dir) .await .unwrap(); + let threshold_target = circuits_build_root.join("threshold").join("target"); tokio::fs::copy( - fixtures_dir.join("pk_generation.json"), + threshold_target.join("pk_generation.json"), pk_gen_circuit_dir.join("pk_generation.json"), ) .await .unwrap(); tokio::fs::copy( - fixtures_dir.join("pk_generation.vk"), + threshold_target.join("pk_generation.vk"), pk_gen_circuit_dir.join("pk_generation.vk"), ) .await diff --git a/crates/zk-prover/tests/common/helpers.rs b/crates/zk-prover/tests/common/helpers.rs new file mode 100644 index 0000000000..d16606195f --- /dev/null +++ b/crates/zk-prover/tests/common/helpers.rs @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: LGPL-3.0-only +// +// This file is provided WITHOUT ANY WARRANTY; +// without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. + +use e3_config::BBPath; +use e3_zk_prover::{ZkBackend, ZkConfig}; +use std::path::PathBuf; +use tempfile::TempDir; +use tokio::{fs, process::Command}; + +/// Returns `None` when bb is not found — tests should skip gracefully. +pub async fn find_bb() -> Option { + if let Ok(output) = Command::new("which").arg("bb").output().await { + if output.status.success() { + let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); + if !path.is_empty() { + return Some(PathBuf::from(path)); + } + } + } + if let Ok(home) = std::env::var("HOME") { + for path in [ + format!("{}/.bb/bb", home), + format!("{}/.nargo/bin/bb", home), + format!("{}/.enclave/noir/bin/bb", home), + ] { + if std::path::Path::new(&path).exists() { + return Some(PathBuf::from(path)); + } + } + } + None +} + +/// Root of the compiled circuit artifacts: `{workspace}/circuits/bin/`. +fn circuits_build_root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("..") + .join("circuits") + .join("bin") +} + +pub async fn setup_compiled_circuit(backend: &ZkBackend, group: &str, circuit_name: &str) { + let target_dir = circuits_build_root().join(group).join("target"); + let json_path = target_dir.join(format!("{circuit_name}.json")); + let vk_path = target_dir.join(format!("{circuit_name}.vk")); + + assert!( + json_path.exists(), + "compiled circuit not found: {} (run `pnpm build:circuits` to compile)", + json_path.display() + ); + assert!( + vk_path.exists(), + "verification key not found: {} (run `pnpm build:circuits` to compile)", + vk_path.display() + ); + + let circuit_dir = backend.circuits_dir.join(group).join(circuit_name); + fs::create_dir_all(&circuit_dir).await.unwrap(); + fs::copy(&json_path, circuit_dir.join(format!("{circuit_name}.json"))) + .await + .unwrap(); + fs::copy(&vk_path, circuit_dir.join(format!("{circuit_name}.vk"))) + .await + .unwrap(); +} + +pub async fn find_anvil() -> bool { + if let Ok(output) = Command::new("which").arg("anvil").output().await { + if output.status.success() { + return true; + } + } + if let Ok(home) = std::env::var("HOME") { + let path = format!("{}/.foundry/bin/anvil", home); + if std::path::Path::new(&path).exists() { + return true; + } + } + false +} + +/// Creates a temp ZkBackend with the real bb binary symlinked in. +/// Caller must hold onto the returned TempDir or it gets cleaned up. +pub async fn setup_test_prover(bb: &PathBuf) -> (ZkBackend, TempDir) { + let target_tmp = env!("CARGO_TARGET_TMPDIR"); + let temp = TempDir::new_in(target_tmp).unwrap(); + + let temp_path = temp.path(); + let noir_dir = temp_path.join("noir"); + let bb_binary = BBPath::Default(noir_dir.join("bin").join("bb")); + let circuits_dir = noir_dir.join("circuits"); + let work_dir = noir_dir.join("work").join("test_node"); + let backend = ZkBackend::new( + bb_binary.clone(), + circuits_dir.clone(), + work_dir.clone(), + ZkConfig::default(), + ); + + fs::create_dir_all(&backend.circuits_dir).await.unwrap(); + fs::create_dir_all(backend.circuits_dir.join("vk")) + .await + .unwrap(); + fs::create_dir_all(&backend.work_dir).await.unwrap(); + fs::create_dir_all(backend.base_dir.join("bin")) + .await + .unwrap(); + + #[cfg(unix)] + std::os::unix::fs::symlink(bb, &backend.bb_binary).unwrap(); + + (backend, temp) +} + +/// Lightweight backend for tests that don't need a real bb binary. +pub fn test_backend(temp_path: &std::path::Path, config: ZkConfig) -> ZkBackend { + let noir_dir = temp_path.join("noir"); + let bb_binary = BBPath::Default(noir_dir.join("bin").join("bb")); + let circuits_dir = noir_dir.join("circuits"); + let work_dir = noir_dir.join("work").join("test_node"); + ZkBackend::new(bb_binary, circuits_dir, work_dir, config) +} diff --git a/crates/zk-prover/tests/common/mod.rs b/crates/zk-prover/tests/common/mod.rs index 73e5822d7b..077e55df08 100644 --- a/crates/zk-prover/tests/common/mod.rs +++ b/crates/zk-prover/tests/common/mod.rs @@ -4,6 +4,9 @@ // without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. +pub mod helpers; +pub use helpers::*; + use std::path::PathBuf; use num_bigint::{BigInt, Sign}; diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.json b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.json deleted file mode 100644 index df6f74c3e1..0000000000 --- a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "14440306795590429775", - "abi": { - "parameters": [ - { - "name": "decryption_shares", - "type": { - "kind": "array", - "length": 3, - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - } - } - }, - "visibility": "public" - }, - { "name": "party_ids", "type": { "kind": "array", "length": 3, "type": { "kind": "field" } }, "visibility": "public" }, - { - "name": "message", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - }, - "visibility": "public" - }, - { - "name": "u_global", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "crt_quotients", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - } - ], - "return_type": null, - "error_types": { - "361444214588792908": { "error_kind": "string", "string": "attempt to multiply with overflow" }, - "991688543994151927": { "error_kind": "string", "string": "Division verification failed: result * rhs ≠ lhs (mod m)" }, - "1998584279744703196": { "error_kind": "string", "string": "attempt to subtract with overflow" }, - "3301098964710512891": { "error_kind": "fmtstring", "length": 56, "item_types": [] }, - "6347439466827421235": { "error_kind": "string", "string": "CRT reconstruction verification failed" }, - "9125450380484214683": { "error_kind": "string", "string": "validate_gt fail" }, - "11084314168516775404": { "error_kind": "string", "string": "assert_is_not_zero_integer fail" }, - "12469291177396340830": { "error_kind": "string", "string": "call to assert_max_bit_size" }, - "14990209321349310352": { "error_kind": "string", "string": "attempt to add with overflow" }, - "15764276373176857197": { "error_kind": "string", "string": "Stack too deep" }, - "16431471497789672479": { "error_kind": "string", "string": "Index out of bounds" } - } - }, - "bytecode": "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", - "debug_symbols": "vP3dsvQ6kp4J3ksd7wMC/gfoVsbG2tRqdZvMykptknpOZLr3CYKk+7Oz5mNwxYocHdR6lZmfO0kPkHidD4H/+S//x3/+3/+f/+t/+y//9n/+1//+L//h//U//+V//2//5V//9b/8X//bv/7X//Qf/8d/+a//9vpP/+e/bPv/afEv/6H99S9tHH/m+tNf/1V//WnHn378kX/5D/L6o//yH/T1x44/fvx5RbHXn1cU/1+vMFfkuekR+xBzF37EP0S7RL+E7CKOPIewS/gl4hLjEvMUsl2iXaJf4oosV2RZkcdL+CXiEuMS8xS6XeL6V7r+1XyJ/X/Ttr/+xfb/TXtdJNuzt9cpW7+EXEIvYZfwS8QlxiXmKXzFeV1il0usOK8r5nGJcYn1r14HFvvx9NeBRbtEv4RcQi9hl/BLxCXGJVbk16Ub7RIr4OuUxwr4OtShl7BL+CXiEuMS8xRzu0S7xIr8+jVOOS/v1FO0TY6f66bnXzv/+vqpti3Ov+P8O9dvt7Vt/Vxba+fffv6V9fttTY8fcN9/wPuPc8zt+HEeQi6hu2jHj/MQfom4xNhFP36cY8rx4xxTjx/nIVZkP36ch9BLrMhx/DgPEZcYl1iRzx/nIdol+iXkEnoJu4RfYkUerxOX/cR9RXv9frxdYg2i7fz5LbEG0es0fQ2H12m6XyIuMS4xT7F+kEus4dlfGXXPqPsYsH3k6D4ITjVSzUvth3aqlqqnklSaylJlDs8cnjk8c0TmiMwRmSMyR2SOyByROSJzROaIzDEyx1g5bFc9laTSU9m2/oXvav23sStNZak8VaQaqeal2oo3dtVS9VQrx9zVHm8f+7bfvm0fkLbfv0/VUvVUkkpTWSpPtR/ffuswWfHWXXLF289XVrz9fGXF249ZVrz9+GTF249vHx6vALva48keeR8grwC72o9Z9hz7EHkF2NWeQ/Yc+yB5BdjVnkP2HPswef0Xu7JUew5dUfYcuqLsOXRF2XPoHmW//7/+J7vac+h+pPsT4PU/2ZWk0lSWas9h+3msEWD7eawRcKg9h+3HskaA7ceyRoCtB8iew/ZjWSPA9mNZI8D2Y1kjwPZjWSPgUCvHnneNAN/zrhHge7Y1Ag7VUu05fD+CNQJ8P4I1Ag5lqTxVpBqpVo71iNtStVT5WxuRaqSal5pbqp5q/WLXM1NTWap1VPt1mZFqnMq3dQSxq3VGY1eWylNFqpFqXmqNqEOteOsG2lNJqj1H7PfQfYr0usT7/XX/t7HfKteIOlRPJak0laXyVJFqP77YJw5rRMWaOax4+/muERX7+a4RFfsxrxEV+/GtETXWzX6PN/bjWyNq7JHXiBqyPwH2Yx57jjWixpqU7DnGnmONqLHnWCNq7DnWiJrr33qqPcdcUfYcc0XZc+wPQV8jan/U+RpR+8PK14haT6V9RPl6Gu0j6lSWylPFrtbDap+hrkfSPqIOtY8o3/Zj2UeU7zNV30fU6yewq5VjPxZfOfZj8ZVjPxZfOfZj8Ui159inKb6PqNePYX8k7jnaeji2VD3VnmN/Gvg+onxN+PYRdSpPFalGqnmpsXLsxzxaqp4qf2trRB1qXmqNqEO1VJJqHdWaWa4j2K/BHKnmqWLbUq0jWFPQnkpS7We05pP76PH9aRD76DlVS9VTSSpNZalWvDWtiFQj1coh++R3xdNdrX9ru/JUkWqkmpeSLVVL1VOt49vPXFa8sasVbz/fffS4rFn3Hm9/RsU+enx/RsU+enx/RsU+enx/RsU+enx/RsU+enx/RsU+enx/RsU+el5Dcld7Dtlz7KPnNSR3tefQPcc+enx/MsU+ek6159ifUbFGz/6MijV69qdQrNFjyw3sOWxF2XPsz55Yo2d/9sQaPUut0XOolmrPsT+ZYo2e/ckUa/QcauXYj2WNnv0ZFWv07E+mWKNnfzLFGj2+fMieY38KxRo9+1Mo1ug51J5jf7rEGj37kyTW6PE92xo9h4pUe479zh9r9Ox3/lij51AtVU8lqTTVyrEf8/BUcamZv7UpqTSVpfJUI9UaUa8o4xhRS7VUe+T9+THWiDqUptqPYB+1Y42o/Wkw1og6VE8lqTSVpfJUK95u8NaIOtS8VF85diPXVzzb1fq3vqtINVLNS60RdaiWqqeSVOv49jNfI2p/Ro01ovZn1Fgjan9GjTWi9mfUWCNqf0aNNaLGcqV7vP0ZNdaI2p9RY42o/Rk11ojan1Fjjaix51gjand7Y42o3dONNaJ2UzfWiNqfTGONqEPtOfZn1Fgjan9GjX1Exf4UGvuIim1FiV2tKGNX+5HuIyq25Za3VC1VTyW72s9jH1GxP5mGW6qVYz8WXzn2Y/GVYz+WfUTF/mQa+4iK/ck09hEV+1No7CMq9qfQ2EfUqfYcbVn3Pcf+JBn7iIr9aTD2EXWqkWrl2I9grBz7EYyWqqeSVJrKUq0c+zGPSDUuNfO3tkbUoSyVp4pU81RzH1GxP3vmPqJO1VNJKk1lqTzVflT702XuM8FTzUu1LVVL1VNJKk1lqTxV5mgrh+xq5VjdkS1VS7Vy7GfZVw7flaayVJ4qUq0csat5KVk5xq5aqp5KUq0cc1d7jv1JN/fn4Kki1Ug1L7WP2lO1VHuO/Sk591F7Kk1lqTxVpBqp5qVs5divpLVUPZWk8lTr3+5XfI3G1YZao/FQPdX6t/sVX6PxUJbKU0WqkWpeao3GQ7VU6/j2qq7RuD/35xqNh7JUnipSjVTzUms0Hqql6qkyxxqN+9xirtG4zy3mGo2HilR7jn2+MfdZZOzzjbnPIk/VUvVUe47dT8991J7KUnmqPcfutudcOfZrMOep2rYG8ClbyV5SSmrJlcmW9JJRcpScKddQPmUr2UuubL6klrSSXnKmXEN1n4a95Lr2x3+qJa2kl4ySo+RMuYbsKVvJXrKyrWG7T/te0kru2ezoskbJUXKmXIPXjk7sns1Ws3UN31NKSS1Z2dYQPmVl08qmlW0N41O2TGyVzSqbVbb1BD7lOjdZMkqOkjPlGvinbCV7SSmpJVe29dNYw/+UkXINdlsFWCPb1o9gDe1TWkkvGSVHyZlyDfB9Cv2SrWQvubKtS70G+Smt5J7N1/VdY9rX9V2D+pS95DqyNbLWeD3lKDkv2daI9aP/3kquYMf/QEruR+arF79G7D5Lb6uvH/uku63W/iVHyZlyjdhTtpIr21hSSq5sc8k92z6Dfsk92z6FfskoOUrOlOsxfMpWcs+2T59fUkru2WKd/BrdfvynXjJKjpIz5Rrdsa7OGt2nXNnWhVqj+5Qr2zr5NbpjnfEa3bHOeI3uU46SM+Ua3adsJfdsY12oNbpPuWcb6+TX6B7reNfoHuuM1+g+5Sg5U67RfcpWcmVbP401uk+5sq2TX6M7jv90pVhnvIb0KWfKNaRP2Ur2klJSS1rJFWxdyfWAPqWU1JJW0ktGyVFyjzvXlVzj+JSt5B53ruu7nsFzXd/1ED7lTLlG7ClbyV5SSq6461KvZ/EpveTKtq7vGt2nnJfsa3TvbbuXXHF9SS3pKdfY3K3SS7aSK/FY0ktGyVFyplxD75StZC+5v/rarddLakkrub9I2x3Za5Tur7p2S/aSvaSU1JJW0ktGyRVXlpwp10u6U65s6/KtF3WnlJIr27qo6+Xcti6fjpS2lVxXfS6pJa2kl4ySo+RMuYbIKXOI9BoivYZIryHSa4j09dQ75Tr0Q46SM2Wsk1/FinVRV+JjtKxzO0bLIUfJmXKNllO2kr2klNSSe7a2Kr8/9S65H29bJdxH1iX3422rbvvIumQr2UvuJWyrhPvIGm2VcFpJLxklRx7DnJeUbbuOQbZWMrPJJiW1pJVc2XzJKDlKzpRtuw5dWruOTFovKSW15MoWS3rJKDlKzpR9K9lK9pJScmXblvSSUXKUnCnX6/a9X/CSreSeoh//Aym5p+jrqq/R3delXqO7ryu5RvcpR8mZco3uU7aSK9u6qGt0n3JlW5dvvYzvqwDrdXxfZ7zG/ClHyZlyDf9TtpIr21hSSq5s6+RtFev4T71klBwlZ8oFBMi6UAsJOOWeTdY1228Kl9yzybp8+01hyLoO+01hyDr5dVM45Sg5U8ZWspVc2dY1Cym5sq3Lt24gsq5DrGzr0CNKjpIz5dhKtpIr27pmQ0ru2XSd/Jo2r8eXrGnzKfe4uq7DulWcspXsJfe4ui7UulWc0kp6yf0sdF3Jdas45bykrlvFMrq6bhXLm+q6VZxyZfMlV7ZY0kp6ySi5so0lZ8p1qzhlK9lLrifZXFJLWkkvGSVHyZly3SpO2UquuOuE1rR5TTBU0qyopDFX0ZJWcp3xCrZG9ylHyf0Ylt/UNbpPuR/Dsp66RvdylrpG9ym1pJXcsy2LqGt0n3KUnCnX6D5lK9lLSsmVbVV+je5TeskoOUrOlGt0n7KVzAbFwmouqSVXK2Kd29HTOuRMucbx8rwLpLlkL7nOYtVijeNTrrNYKdY4XuZ14TSXHCVnyjWOl49dSM0le0kpqSWtpJeMknu2ZYp1je5DrtF9ylayl5SSWtJKrqbOKuGaYp9yXNKOFz6xZC8pJbWklfSSUXKUPF7X/q+//sV29Oo4qXYQeIdol+iXkEvoJewSfom4xLjEFXk1AE7VUq3gqysjqTSVpfJUkWqkmpda96RDtVSZo2WOdY9ZHYh1M1ldhzXtONT63x2T7VTrWI6pa6r9WOKYHu7qmPxdas08DtVS9VSSSlPtkeN40O1qPdxGqnmpdR+K4/Z1/Yt1Z4ljwOzqGA6p5qXWXWV5+HVTOVRPtcdbXn7dUZaVXzeU4996qsxhmcMyx7qXHKql6qlWjv2qrVnCoSzVnmO5/jVFONS4KrMmCEut+8qhsoKRFVw3lUNpKkvlqfZ4q5uw7hyHaql6KkmlqSyVp4qrCuuOcah5qZl1W6PrUD3VyrHXdw2wQ1mqlWP979Z1WfH2HKt1MK8cy4ifqqXqqSSVprJUnuo4j9ftwffbw36J9znIfoHXXzn/6vnXzr9+/o3z7zj/zuPvfpHX3zPeOOPtl1dPalhPaFhPZlhPLnifweyXaH9s7xdo/bXzr59/4/w7zr/z+LvuPUefvV2iX2KPOc77ziHsEnvYed5g1nN/0V3beVM5xP7PV4/ELxGn2G8th+iXuP43Pf834xKLyTxvG4dol+iXkEvoJewSfom4xLjEFVmvyHpF1iuyXpH1iqxXZL0i6xVZr8h6RbYrsl2RF57VzzvKIfQSi9A8bxNrmrEYRj0H/5oVHGTiOfQPsQi7c+Afol2iX2KxSuegP4Rdwi+xaLZdLNDsvAcsseCP7bwDrMfTAU6d4/8QeonFbpyD/xBxiXGJeYq5MJ9z3B+iX0IuoZewS/gl4hIL7znH9t4fX0P7EHIJvYRdwi8Rx3XuC1xcYp6ibZdol+iXkEvYJfZ/vr1uDrHfHNYZjGNQrr92/vXzb5x/x/l3Hn/XoDxEu0S/hFxCL2GX8EvEJcYlrsgLZpnnWDza+evF9i7mKY5X5+cwPUS/hFxCL2GX8EvEJa7I/YosV2S5IssVWa7IckU+3pWfI/gQcYlxiXmK1Wq/nvbHVGC1789BeYh5iqOVfg7KQ/RLyCVWq/Cv8yG/nvurI3AO0/VEXk/4NRmdpzg6AefAPUS/hFxCL7Hc5Tm4DxGXGJdYYMY5uA/RLrGe6X9dj/S/rif6X9cD/a/reX4O7kOMS8xTrOe7n4P7EFfkcUUeV+RxRR5X5HFFHlfkcUWeV+R5RV7P7/jrelSfA3e18Oc8xHpOH6Jdol9CLqGXsEv4JeIS4xJX5HZFblfkdkVuV+R2RW5X5HZFblfk9cXW/gnL+mJrF+uLrSXaJfol1mc+u9j/lexi/1f7XWd9jbVEu8T+r3wXcgm9hF1iP559KrK+xhq72CPPXbwit219gLPtas+/P9JO1VNJKk1lqTxV7Go/+H0QnWpeyrZUK8d+A7SeauXYT8o01cqxn4R5qpVjPx8bqealfEvVUvVUkkpTWSpPlTk8c3jmiMwRmSMyR2SOyByx4u2Xfqx/u1/7ffS0vbO6uuun2v/t3qxevfVTWSpPtcfb29err36qeal9GJ2qpeqpJJWmslSeKnPMzDGvHKuXfqqWqqdaOfYPstYXZYeyVJ4qUo1U81JtS9VS9VSZo2WOljla5miZo2WOvuLZrta/9V2tfzt25aki1Ug1LyVbqpaqp5JUmipzSOaQzCGZQzKHZo41Lvee+2qCn0pSaSpLtcfb+/Grp932dvxqabe9l7462qfSVPu/3Xvqq519qkg1Uu3HtzfcVyu77f321clue998NbLb3itffey2t8pXG/tUlspTRaqRal5qjbe9R77616fqqSTVnmPvla3e9ak8VaQaqeal1rg8VEvVU0mqzDEyx8gcI3OMzDEyxxqXezNqdbBP1VOtKPvVXaNs78evNnTb2/GrC32q9S9iV5JKU1mqFW/sKlKNVPNSa5QdqqXqqSSVprJUe469gb+6zqcaqeal9sfdqVqqnkpSaaoVpe3fW65/0XfVU63e4y70EnaJ+ofzUmsQHaql6qkklabaT3H3y6vPfKq41HqQ7S56NY7b7otX3/hUlspTRaqRal5qDaLdQq+G8al6qpVjnF9hnspSrRzz/OKy7U56dYpP1VOtfyHnN5WnilQj1bzUGhKHaqmyaCOLNrJoa0gcKn8YI38Ya0jslnY1fg+1hsSh9ni7q12d3Lbb2tXIbbK+CB+p5qnsGBxLtVTrfPX8qvNU+/Gtr/nW4DiUp4pU6/j8/KqzrW/91uA4VEvVU2WONTgOlTla5miZYw2OQ80rW88cPXP0zLEGx6FWjnF+/XkqTxWpRqp5qfWoOlRL1VPJObDWd6CnWlHm+c3nodY4OlRLtUdZ3zuucXQoTWWp9iNdXz6ucXSokWrPsb6GXGNrfdu4HlqHWjn0/Oaz7Q58ffN5KkvlqVYOP7/5PNW81Bpvh2qp+vmrW998nkpTWSpPFalGqnmpYwzK+X3nGoPrW862e7H1LeepRqp5qTXydvu9vuU8VU8lqdY12KuwRt6hPNWeY7fs65vPtpN065vPQ62Rt/tmWw+j3RSvrz9PJak01Z5j98zr689TRaqRap7KjxFq5xehp+qpJJWmslSeKlKNS63RuE9t1hehbX2FuUbjoTTVOubYlaeKVCPVOuZxfjna1nebazSu7zbXaFzffK7RuL7gXKPxUJbKU0WqkWpeao3GQ60c/fya9FSSSlOtHHJ+TXqqSLUmTe38mvRQa1weX5NKKk214tn5lWhbX5iu8ba+Slxja31rusbWoTxVpBqp5qXW2DpUS9WvyGtsHUpTrRzj/PrzVJFq5Zjn159t99Pr68+2m+X19ecRJTJHZI7IHOvpdyhPFalGqnmpNd52H+5rvB1KU1mqPd768naNt0ONVOuY9fwi9FQtVU+1ctj5bWhb3+qu8XYoTxWpRqqVI87vRU/VUq0c4/xe9PzPNJWl8lSRaqTKHOuJuDcP1nely8qu70pPJak0laXyVJFqpJqXWr2Q9ZLkFa7vnYXYh9upLJXvqp+fmp5qpJqX2odb30HB9alp37sN61PTvl2fmvZtfUy6cviuLJWnilQj1byUbqlaqpUjzs9PT6WpLNXKMc7PT081Us2jDbS+Pj3EijbPD01PZan2aG07Pyrte79gfUC6j6b1rWhv/fxW9FSRaqSal9rH2qlaqp5KzsCrlTjOL0UPsRLI+aHoqUaqlUDPD0X77sXXh6J9H3wxruMdV/xxxR9X/ONV4fmN6CHGJeYpVkNxnN+M7o+k9clob+P8ZPRUnmod6Tw/Hj3VPNX6ePRU+5H27fx4tO833PXxaO/9/Hi0r0/29uHV12o+ayWdQ0WqkWpeah9ep2qpeqqVQ8+PTE9lqTzVymHnR6anmpda/fol2iVWNN+VpfJUK1qcn5j23dmvz0nX97FrgPR5fk16qpFqXmoNkEO1VD2VpNIz8MLet/Nb0kPsCWQ7PyU91bzUPjz6zsytT0n77rjXp6R9d9frU9IVxK74dsW3K77FJcYl5imOb0jzE9LXC5uxljQ6DknPhuep5qWOQ9Kz4XmqnkpSaSpLtV9XuRqepxqp5qV8S9VS9VSSSlNZqszhmcMzh2eOyByROSJzROaIzBGZY90G5GqCnmqkmpdat4FDtVQ9laTSVJYqc4zMMTLHyBwzc8zMMTPHzBwzc6ybxN7qWI3RU60c82yMnmrPsXcOVmP0VC1VTyWpNJWl8lSRas+h/WyMHmrdJHY/vhqjp1o5rsboqVYOOxujp1o54myMnmqkWjlWm3NLtXLsjbi1ct2h9hy7p1kN1FNZKk8VqUaqeal1OzlUS9XP67waqKfSVHZe8dVAPVWkGtdVk6yHZj0066FZD816rJFs7Wybnmod6X7F10he/9kayXa1Us//dl2Nq5V6KkvlqSLVSDUvtUbyoVqqnmpF0bMdevxnazTq1Q7te19htUNPpakslaeKVCPVvNQajYdqqTLHyBwjc4zMMTLHyBxrNK7f5BqNS63ReKh2/TrXaDyUpNLr17lG46HyVzzzVzzzV3yMxjibpd38bJaeah3z1Sw9/zNPFfnfrutyNUsPtUaeXc3SU/VUkkpTWSpPFZdaY2vvo2jP/90aPasvuEaPX+3QU81LrdFzqJaqp5JU+7F4P5ukp/JUkWqkmpdao+dQLVVPJakyh2aONa3d+zerc3qqlWN1U+el1jjyq5t6qhXv6qae/5mnivxvV7w4u6mHWuPIr27qqXoqSaWpLJWnikutUbb3W1YP9fzP1v9unj3UU41U81JrHB2qpeqpJJWmslSZY2SOkTlG5piZY2aONVL2CcvqnPZoZ+e0r3Xa1jPqUC3VflSrz7NGyqE0laXyVJFqpJqXWiPlUC1V5miZo2WOljla5miZo2WO9Yxanab1jDpUS9VTSaoVxc4+aN87Q6sP2uPqg55KUq2jmmdH9FSeKlLtR7X3iFaXtI92dkn73rVZXdK+d2hWl7TvnZfVJT2VprJUnipSjVQrh51d0lO1VD3VOo9+dklPZalWDj+7pKcaqVaOcXZJT9VS9VSSSlNZKk8VqUaqzBGZIzJHZI7IHJE5InNE5ojMEZljjbcxzy5pn9vZJe17Y2F1SU8VqUaqeak1tubVJT1VTyWpNFXmmJljZo6ZOeaVY3VJT9VS9VSSSlOtHHJ2SU8VqUaqeak18lanaY2y1Wlao2xeHdFTjVTr314d0VO1VD3VOr55dkRlrQ+3P8tkuzqislaF28egrFXh9mfZqeal9nF5qpaqp5JUK4eeHdFTeapItXL42RE9lK4c+7lpS7VyjLNLeqqVY55d0lN5qkg1Us1L2ZaqpeqpJFXmsMxhmcMyh2UOyxyeOTxz7GNQjjXy9n+71sjbx5us9fD28XaofbzJsTJeS9VTSaoVT8/OqeS6eZLr5kmumye5bp7kunmnaql6KkmVOUbmGJljZI6ROUbmmCuHn93UU/VUkkpTWSpPFalGqnmq1U09VUvVU0kqTWWpVrw4u6Symkv7GJRj9WhJpakslaeKVCPVvNQ+Lk/VUmWOnjl65uiZo2eOnjnWuFzr/61xudQal4dqqXqqFa+fLVFZawKu8bbW8Fvj7VAt1fq3frZET6WpLNU6vjhbotKvlqis9f/WeFvr/63xttb/W+PtUD2VpNJUlspT7TnW2oFrvB1qXmqNt0OtHHo2VE8lqTSVpfJUkWqkmpda4/JQmSMyR2SOyByROSJzrHG5Vjlc4/JQ81Jr5K2VD9coWysfrlEmV/P0VOtfzLN9eqqWqqfa460VEtcoO5Sl8lSRaqSap1pN1VO1VD3VynE1VU9lqTxVpBqp5qXalqqlWlHkbJHK+kZija2l1jNvrWS3nnmH6qnWUcXZOD2VpfJU66hWg3WkmpdaY+tQLVVPJak01coxzq7rqSLVSDUvtcbgoVqqnkpSaarMoZlDM4dmDs0cljnWeNv7Q6unKnY1VcX62VU91bzUGluHaqn249v7G2ttvlPtx7e747U2n+yOea3Nd6pINVLNS62xdaiWqqeSVJoqc0TmWGNr99NrbT7ZqYW1Np/sXnetzSe7w11r88nua9fafKeSVJpqxdurukbZ7mbHGmW7vxxrlB1KUmmq/fh2R7rW5jtVpBqp5qnWKn2naql6Kkl1HdVah092L7nW4TvUGkeHaqn2KLvTXOvwnf+ZprJUnipSZY6WOXrmWE+1WN9N9lSSas+x+5m1Dt+pPFWkGqn2HLuDXOvwnaqlWjn0XIdP1tqGa+TtbnGtwydjfbq559jd3VqH71Qj1bzUGnmHaql6Kkm159g94lqHT3aft9bhk93JrXX4ZPdlax2+9StZ6/AdyrZUK17sSlNZqhVvnOvwye6K5jHKtnN9PZnbub7eqSLVSDUvtUbUoVqqnkquyMeI2s719U61crRzfb1TjVQrRz/X15Pdu6z19WT3Lmt9vSPKyBwjc4zMMTxVpBqp5qXWyDvUunPJuZbeqSyVp4pUI9U81bGWnqwv59daepfsJde1jr/O9fFkLayz1sc75Rpip2wle0kpqSVX3PnXuT7eJaPkK5uuVXrWqnmn3AfbJdsujy+JdZf9r3PVvEtGyjV+1hJFa1G8S/aSUlJLWkkveT26j0XxLjlT6laylewlZT+yVQDVklZynbz+dS50p2shoLXQnay1I7bjwXVILWklveS6DquaNkqui7oK61vJVrKXXMe76ubreFeF3Ep6yShZ2XymjMoWlS0q2/rC9JSaiaOyRWWLyrY+OD3lnu3YJ2Z9dnrKVrKXlJJa0kp6ySh5zcGO9fEuuYKtq76+Uz2llfSSK9j6PaxvVk85L3l8uHrKdejy17lq3iWl5Mqmf52r5ulamuf4iPWUK5v/da6ap2spgPXV3CnXzjinbCVXtvHXuWreJbWklfSScf1o2zGODzlTHuP4kK1kLykltaSVHNfoXt/a6VrcZ31td0kpqSX3CGvJn/XV3SWj5Ci5H+9aE2h9P3vJVnLPtlYKWp/n6VryZ31He8mVbZVFV7Z16BolR8mZ0la2Vaw1/E/ZS0pJLbkc1qqbeckoOUrOlIddPGQr2UtKyWVz1xmvgb4WGFof811yplwDfS071I6PyA/ZS0rJ/SzWqkLr0z5dSwmtj/t0rSXSjs/K1zGsgb6WyFif+J1yDfRTtpK9pJTUklZyZVvFWgP9lKPkTLm+Sl8rEK1P/y7ZS65uwYq7HtCnXHFXsdaYP+W85Po0UNelXp8C6lqMaH36t1oybX3qp2sxovWx3yVbyV5SSmpJK+klI1OsSe4pZ8o1YtfSR+sTwEv2knu29cRZi+3petStjwP1/BK+zqJXtl7ZemVbD+xTtpK9pJTUkvv1Xbfi9cngJWfKNY5Puc7C/jqX4LuklFxnscqyxvEpvWSUXNlW3dY4XmsILJzmkq1kLyklV7ZVC7OSXnLPttYdWFjN9Z/OlOsxfspWspeUkpVtPcbXh/sLr5FjFbrsyh4r911ypjwas4dsJXtJKakl4+zrH+v56VoNYFE1p1zj+JT7WazFARZYc0kpqSXXWay6rXG8FgVYdI2ub/8XXqNrEYLF1+haCKAfq0scspXsJaWklrSSXnJlWxd1je5Tzksu1OaSe7a14sCCbS4pJfV87XGs53fJPe5ahGDRNadcd4JTrrh9yf1419oBBzmzPkJemIyuBVAWJ3PJXlJKakkr6SWj5KgUM+V6fXnKlW2dxXpKn1JKrmy+5MoWS65sY8k6C6lsUtm0sq03mafsJaWklrSS43zxeiy2p2sBgQXTXLKV3M9iLfe7eJpLakkruZ/F+dH/fs2Ob/vXOD4W/VnjeK1bsLAaPY5hjeNT9pJSUktaSS8ZJVe2dX3XU/qQ6yl9ylZyZVsFWE/pU2pJO99LH4vtnXKN2LW6wAJtdK0vcJA2x3VYrzFPGSX3I1tLECza5pRrbJ5yj7uWJjiAm+OfrbeZp9SSlW1WtlnZEjA4FtA75Ppy8ZL7Ga/1D/RYGOaQVtJLRslRcqZcY/OU7bokC8G5pJTUkiub/HUulXfJlU3/OpfKu+RMuUb3Kdc1syV7yXVu/te5gN4lreTKFn+dy+rpWsNg4TznkfWZUraSdW5S5yZ1blLntkb3Kb3k4kNWtvWUHus/XU/pU/aSe9w1YhfIc0krucddqyUvlkfXWscL5tG1qvGieU65Rvcp92zr6bQgH1033UX56LG84Brdp7SSXjJKjpIz5Rrdp2wlF361zm2N49VxWXDPJaPkirsu1BrHh1zj+JQr7gq21sdZ/ZJj38rVLzk2rjyllfRdrgu1VspZrYhj88rVijh2rzzk2rzvlK1kLykltaSV9JKLVltybUO2DN5igy7ZS66465qtbf5OaSVX3HWh1k5/q3uwoCI71o2c85LHlpqn3LMta7/AIluzlXOnzf7XudjeJa2kl4ySo+RMeWy4eciVbd/9dK5ldF4Z41jiKo7FdOJYSyeOpXTiWEknjoV05rGOzup0bOffdv5dX678dayLc7YZTnGsTfDXsTreIfol5BJ6iT3O4fIuEZfYIx9m5hTrA7Ql9sjH3Pol1lzMLhGX2D95+OtYMedcgfgS7RL9EnIJvYRdwi8RlxiX2COv+m+XaJfoR/K1dN66C5x/7fzr598rqF5B9Tpcuw7XrsO163DtOly7Dteuw7XrcO2KbFdkuyL7FdmvyH5F9iuyX5H9iuxXZL8i+xXZr8hxRY4rclyR16dn+ymvL8+WsEvskfcf1frsbIlxigUE7j+z9WTffzDrub5EnGI9nPcfzHo0L2GXWCT0X8caOYcYl1gg7F/HGjmHaJfol5BLrJvmX8caOYfwS8QlFn/417FGzhIH5/fXsUbOIfol5BKL3vrrWCPnEH6JuMSagv51rJGzxMEd/XWskXOIRdLsYpmhXeglFjqwi9Wq2UVcYlxinuJ48/rXsY7OIfol5BJ6ifVa4a9jHZ1DxCXGJeYpVq96iXaJfon1euyvYwmdQ6wXV38dC+isTwvWq515fjlyiHaJfgm5hF5itfHOb0YOEZcYl5inOLrT5+cih1hNvvNjkUPoJc4f5PGlSLs+FGnXdyLt+kykXV+JtOsjkXZ9GdLOj0Ca/a/XDfpf/+t/+o//47/813/73/7Hf/vP/3m/WV//wX//l//w//qf//J//8f/9p//7X/8y3/4t//nX//1r3/5//zHf/1/1v/ov//f//Hf1t//8R//2+u/fR31f/63/+P19xXw//wv//qfd/W//qp/vf35n7b1xez61/u2DBkg5uMI62O1I8Lr9/dRhL0/cEaI7aMI+9zliCDto7OQfcyfEfSzCHun5YwQ7YMIryf/PCO8Hvd1JV8PvMch1tpRR4hXPf8YYtyEmBVifhaira07jksR0xDCHodYq+UfIYZsn4XQPIph/bMQe6PnDOH666P4NMS4fhevzvD4Y4i738X60vEo6uuR8NlPK+8UL/nZr3NhBEeIl6//KMR6P3OEeBnlz0LkUH9J+yjEwzFyexTe8ig8PgsRW4aI3x/FF0KMz07EqqjWt89CSF4L089+F2uj8jPEhz9whpjyUYi1UfcRwqV/GKJnCG2fhfD8gfuH14Ihpv02RHw42NfO0udR+GfXYu1ScoQY8llR17YfZwiND48iKsT4LMTIMTLmZ8NsLW1/hojPTmT2rMj87HK+PJFdh/HSzvvW45lvrLWFVox4zTb+eBz728XfPgfuYjydLN3GeDhbuo/xbLp0H+PZfOnxcXwc49czppA8jJf86PYVmqP+JednISx/pK+O70chfF41iWjts6PIn+hLfnYU9Xx+Sf11CJXPQuTtK2z0D0P0DDE/u5ze8nL6h9eCIT78dTKE+WchtrwW/uFPy6NliPHRMymiTiQ+m8/rooZXiNcroT/fL/b/1Z9ivF4HXmfyegcof44RN/ctXbucHTeul/7zL/RNFBsVxeanUWZFmTflvY8yQyvK/POx7L+DP0bZtryfbw2/ErEfxNCeMezTGF7HwQ7NT2Kg4/bqQ38Wo9e5dL85Dr/1KjUx/jCC51ywfRTB2/Vr9y6fRdji1xGus3DOzH9UjVH9y+Efxkgvv3NFn8VYX1CcHcgx/xjj7i6mm1zDVV9v9/7crrK7X3irO8fOH/65h3gbZa22dUZ5vZr4NEo+YPatrrcPo6yPTs4o2v5sfPZ552/vYvcxnt3F7mM8u4vdxnh4F7uN8fAutk8+f3cXu4/w5C52F+HZXew2wqO72H2EJ3ex+2o8u4vdx3h2F7uN8fAudj9eF7d5jldrfx71bbuzke4z3229tH8aZvYcLD5v+j8/CXPTzHoXJn+ve8iPr83MblKLbfv0aGIt3XyGaTctpft6+5YH89KfPis87yb7twjj0yhiFcX0wyhwAm3ETZWafMNQvAvz0FG8C/PQUrwJ89RTtBa/fxy/CfLsefwmyLMH8n2Qh0/k+yAPH8lt7+H+7pn8JsSTh/JtiGdP5fsQjx7Lb0I8eS6/qcmzB/ObIM+ezPdBvvJonvl26qVvbo9N7rzO6+Vv3dg27x+Hye7oruPTMK0gmJf2T8P0esJrv7lb317hvknUnUDGp1FGRXnd5j6NEnVD2canUWAoX5fo5mEo8xu/mTcH02ddGPnQUfbudbvu8+Nj0YKv2t0s4Ruvsdo33mO1b7zIat94k9W+8SqrfeNdVvvGy6x3v/3HN7r5nRvd/MaNbm2+8+ef/5w1iG4ngo/DyLbFh2FkS8hq/8Bu+ziM11N2i8+PxrYKczdlf1PwCvPS/pUwbh+HgYHom34cZth3wpQPeT0KPh4MUkOz6/w8DE7KvhMmPp5YPf/dtO/8btp3fjftO7+b9p3fTfvO76Z953fTvvK7uXexrRrtnLr+o08J+7UBvQ/xyIDehXhoQG9DPDOg9yF+b0Bbke3N28ftiVm27ws9jsY55r8Lct8+qt+Yzv5xT+xvYeTjZtYoU/3S8vHRbIbW2sf9wol7ytT+lTD2eaMPs81pn3cv2Xa8C3Pfqoavju2GxnobpiHM/DhMDah49R4/D4P+e/84TKvG4UvHx2HqIfIKM74Sxj4/GrziuH2PPX//RFt7rv3uifYmxJMn2m2IZ0+0+xCPnmhvQvz6VefDB9qbF+CPnmdPX6LfPc7eAA71jnJ3sp9iEogi26evvtbuNtex3Ez630Sp6fG+nM6HUaTVxZXu34gi9vHVVUT5+LoAZbmLco+fPbwd3c3DHt6O7kM8uh3dhXh4O7oN8ex2dB/i1/zYw9vRG6rw0e3oKZl4dzt6w3s+nFz/IIp8yp4+nVq/OZaHM+s3UR5OrH8QxT5mch9Oq3/AB9tnn6rF9YtzXtjx9N/HWl59Bdg/D8AhtL+PYLm5sXbNF6wv2T8MYvkR+0t+GsQTW+rOO+vPgiRR0/+O1P8oSH6l9QrS/hxEbz+Jr1+rSHwYZK33ef7MxD8MYhXE/vYU/8k1CclrEqqfBlHPIH/zkD8KkrjTK8i8uSb+jer4N6rj/+zq2Mxr4lv/8Hfi9cLu7+jWp0FcPg1SL5NcPh2A6tVo9k8vbH2R/JKf/tgeX1j/xoX1b1xY/6df2JmPDJ/x6a0g3132cffc8faFW4G3L9wKboM8vRXcBnn6Y3sc5O7Hdh/k4Y/t/sJ+48c28DuZnz68Zs977OztsyCvd9rXNZG/E0Ht8bTPBz75u6lN3L0hf8h/vgnyjP98E+QZ/3kf5CH/eR/kIf/Z4/fdgfh9dyB+3x2I33cH4tfdgTc1ecZ/vgnyjP+8D/KQ/7wbuSOBtRgmHw3+yFZH/B2M/4fBP+7fMz/8Ru1NmKcfqb0L8/ArtTdhnn6m1ucXvrZ9E+ThjXF+4Xvb+yBPb4zzC1/c9vnrT27fhHh0Y5y//uj2PsSzG+P89We3b2ry8MY4v/Dh7X2QhzfGN6P36Udrst29Jnj80dqbME8/WvtJmJuP1t6FefjR2rswDz9auw/z+KO1NwV/+tXauzAPP1t7F+bhd2tvwjz9cE2a3XaXH3649i7Mww/X3oV5+OHamzBPP1yT9oXvyN8EefZ8fhPk2fP5PsjD5/N9kIfP57XM6++ez29CPHk+34Z49ny+D/Ho+fwmxJPn85uaPHs+vwny7Pl8H+Q7z+enX66J3NJoT79Cehfm4Qcdb8I8/aDjTZinH3TcX+LHn669C/Pw27V3YR5+vPYmzNOv19aOmr//3bw7moefr70J8/T7tTsnP3PZrZjjzx3jtdv3n6+L1DNV/7xijdz18/vWrovSN7BCj/sao21XcV6yf9LXGC1b3y85PwvhFWJ81F0ZUici+ucQYje/1eF+3VSGD/ssiNYHhTo2/zRIrsj7ind3OjfPwrBapM7YOx//EOOu6y3ZtRLh3Tr+Icbdr3TmA1U2/sj+McbtUwwTv32X3T+fze1l9S0va3xa4JoN29+92A+CvP5lzri2GwLkXZBcgHpT/8LpaHwcJBfY3Vw/PZ1RRzLmh0Es8sJ6++g1zWvs5+0ots9uR9+4k1iv30hv4wtB+qcXtdeK1j380yD5Ku8lPz6dWgz679Twh0H+Dg3/KEjkthcvS/L7C/t5kLXB7BFE7aY6d298nj4sYvz+YRHz9w+Lsf2zHxam6Q1M5dNfibXaI0A+vqflUrH2+n+f/krm/H0Qi+w12A37cTvZq7trm/O3IfrN+L0NkQvsv+Rn9/iW12K08dncuSejNPrNLOBxiE8vZ55I18+OAjP4uxDvPN7DZUFk3n0D+3BZkNsgT5cFuQ/ycFmQN0GeLQvyJsizZUGeH8nnQZ4tC/KuqfC0i6RfWf/oTZinXaS1OP+ff/5PlwV5HuZ2WZD7MI+XBXkX5uGyIO/CPFwW5F3BHy7v8JMwN8s7vAvzcHmHd2EeLu/wNsyz5R3eDYaHyzu8DfNseYefhImPu9aPfzc/CHP3u3kT5unv5k2Yp7+bd2Ee/m7etOKf/m7ehXn4u/lBmLvfTfvCR9Taf80lvgnx5PXebYhnr/fuQzx6vfcmxO9f7z38bPHdy99H3y0+foN89+Hiu5fzD79c/EkY+RgVePrt4rujefjx4rswD79e/EkY+xyjePj94k+gjrsw9zDQ02VB3oZ5tizIuzAPlwV5G+bZsiDvQKmHy4K8C/NwWZCfhLHPj+bhsiBvsNSHjzT79VLLb0I8eqTZr5davg/x7JFmv15q+U1Nnj3S3vHGjx5pj6Hlu0faO6z84dogPwhztzjIuzAPVwd5F+bh8iDvWPmH64P8JMzNAiFvL/GzFUJ+8B3BbZj7T4ke3pp8/vrWdB/i0a3pLsTDW9NtiGe3pvsQv/8K6Omt6c03Ys9uTU8/NLu9Nd1/SZgt0Jf88JvGV1NO8hVX80+D5ExHtk8/jPzbN42fB2lbnc7H16RXkO7fCDI/DZLLJcgm4wtBtH3hdD4Pgh+bfvwpb7WU9ead3ZtvpPNImjX9QpAuvz8d6x8fCT/5Hl8IovGF09FPj0TRxZs3b/Du1xd4+Du5X1bj4e/kcZAuvz+d29/J81VCxheCaHzhdPTTI3n8O9m+8TvZvvE72b7xO9m+8TvZvvE72b7xO9m+8TvZfv87ueOse8uNyHv7MyJ9u9CW5M7ZYn/e3XgBNjcsgAAGuDFL78KYgCnQj8OgjzNvjOR9mLGVAxxbbx+HqebUuHtN/C5MLRYytuFfCRPycZjwZ0dzt4nWzDffk183yg9CtK06zxv71z8M0r4QpL7W3LiuzA+D9C8ESTa+/e3rlh8GkS8EmeVL2bP+YRD9fZDW65PcHp8GafaFIEAv+Rb3Z0Hq3cQvgtS94NXw/jSIzd8H6fXBdG83PzYZd7+TNmsY83ko8x+i3L5ztGKVXk/3P0e5fbi/Oo8bGnbbn6PcNou34uMaDfsPoxQ12PgG6odnhCgCPvaHUfBzEWADP4wSOJYxvhBF2/aFM/pFFH12LPLmfTm+0fePo+C6jGEfRplooHNRsZ9Gwbe5WJzzh1HqE8vXi71Prwvxw6333x/Lt6LIh2fUcWfoG97c/DBK8Kvc9nGU/pUodV3azTi6f6bVtKXbp8/5XvBYnx8H8bq0889z5FuHl8BJ6PZnxtrcvuLw3oR56vDehHnq8G7DPHd4b8I8dXhvwjx1eD8Ic+fw3oR56vBCfu3w7kI8dnhvgrQvBHno8N4E6V8I8tDhvQkiXwjy0OG9CaK/D/LU4d0Heejw7oM8dHj3QR46vPsgDx3efZCHDu82yFOHd7uvzmOHN7dvOLx7kOepw5v9Gw7vTZSHDu/NGT10eG+iPHR4b6I8dHjPo9y5qudn9IsoDx3e/W/3qcN7E+Whw7uP8tThvYvyzOG9ifLQ4b2J8tDhPT6Wb0WRD8/oscN7E+Whw3sXpX8lyjOHd/9Me+jw7p9pDx3efZDfOzzNdQPj7wv0P38NqLXfjtr2UQirl5F/fz37D7tMtfENn/kuzEOf+S7MQ595H+axz3wX5qHPfBfmoc/8SZgbn/kuzEOf6d1/6zNvQzz1me+CtC8EeeYz3wXpXwjyzGe+CyJfCPLMZ74Lor8P8tBnvgnyzGe+CfLMZ74J8sxnvgnyzGe+CfLMZ94HeegzXfsXfKarfMFn+u2H/U99pt8upvjUZ76L8sxnvjujZz7zXZRnPvNdlGc+8wdRbrzdD87oF1H04bHIF3zmuyjPfOabKA995tsoj3zmuyjPfOa7KM985vNj+VYU+fCMnvrMd1Ge+cy3UfpXojzymW+eac985ptn2jOf+SbI732maa2AZ3/GTf3uk6kfOLw3YZ46vDdhnjq82zDPHd6bME8d3pswTx3eD8LcObw3YZ46vLvlFx86vLsQjx3emyDtC0EeOrw3QfoXgjx0eG+CyBeCPHR4b4Lo74M8dXj3QR46vPsgDx3efZCHDu8+yEOHdx/kocOL+ILDm/INhzf1Gw7vdsG/xw5v+jcc3psoDx3emzN66PDeRHno8N5Eeejwnke5c1XPz+gXUR46vPvf7lOH9ybKQ4d3H+Wpw3sX5ZnDexPlocN7E+Whw3t8LN+KIh+e0WOH9ybKQ4f3Lkr/SpRnDu/+mfbQ4d0/0x46vPsgX3B4eIdnn31QaLn4Vnj/82vA6LdffXvdVl76z57hTZioBU8senwcpqbrFjcb8b0Ng6OJj49m1JaJNj4/KayS9nrj7l8Jc7Og2JswuEe9fkHyeZitwsz2cZhcneKl7dNL7Bs2t9xulj1+E6ZWMH9p+fPR3O6snvfdfZP1Pw9LudsEL291vn16FNlBir/tDPOPR+FfuTnch3l8c3gT5unN4V2YhzeH+zCPbw5vwjwd1fdhHo/qd2Eejuo3YZ6O6tswz0f1fZhvjOrIrYki5p/Jn9A7BOPxsurPw9wuq34f5vGy6u/CPFxW/V2Yh8uq31YpXd+rSvHnKtntvffZpg23QZ5u2nAf5OGmDW+CPNu04U2QZ5s2PD+Sz4M827Th7lcyspcU44afC78jF0Krnxt/X1ZEfxIGja2wu3vcuzC1TKzp50ejXmFcvxLmZkHfN2G8btyv/+X8OEz1guL1BuXzMFVwHx9XygVHY/ZpmKhlqSOafh6m7lPRP9uEdNQmpGPc3OtCvzKe7sM8Hk/vwjwcT2/CPB1PPwhzN57uwzweT2/CPB1P78I8HE9vwjwdT/dhHo+nd2F+PZ5Gz57b66l/85wct4ujPd3s+HZ74dzUN2b/jHefWjsU+83N4e5ztMdTsjG/MCW7DfJ0SnYf5OGU7D7IwynZ4yP5PMivp2TDapNSu2maPP2hxUchXrXNo/j71nH/cDXmN36r8xu/1fmN3+r8xm91fuO3Or/xW51f+K2+u7c+3PPtTZine769CfN0z7e7n359ljT0ZgCOdvfFmFhtufLSf56nvAtTyIDYzeX9ydF8Hsbr8orLxyfl1VoTD/vGSfn2cRivxdDF7aOe2Kg58jCJm9/M+Ma8/02Yp/P+t2GezfvfhXk47/9JGBufhnk6738X5uG8/22YZ/P+d2EezvvfhHk6738b5tm8/zU3+YoJvg/z2AS/C/PQBL8J89QE/yDMnQm+D/PYBL8J89QEvwvz0AS/CfPUBN+HeWyC34V5OBjeTI8e7nT5kzA3O12+C/Nwp8t3YR7udPk2zLOdLt9NHR/udPk2zLOdLn8SJj5+34cXUq/X59unYdpWYVpvn4epl5g7IfRxmK3C6MfXBmCwt/H5tTFcm/Ep/fG8UvdhHlfqXZiHlXoX5mGl3oR5Wql3YZ5V6mai/2pCJvC26z+vw38bxFoFsfZpEK2NaOxmE5nbINFrw6JQ/zDIqN1shvx5g4Nxt/qfRk74NG72JngTJLtFOjb/xpHITZCbeXBYYUfGXZzGP8S4adGIZItGhK49/h4jbqrT52hZnK3/Ocab1ZyLct44cRg/uaxp+19X2D780ecnIbuenwXxXLtmJza2bwT58Ehs1On4ph8eSSDI/PR0Zm06Flt8IUjz359OtA+PJLSqE96+ECQ+vLDFJu8llg+viaDEql8IYp8eyYbTMf3Cz/6zIG2LnBRs86YfNH69r+SbEE/2lbwN8WxfyfsQj/aVfBPiyb6St6vHVVfizlyOuw+NHlbkPsSTirxZ7u06kX7zLuImxOsSSl7NGwb1NsSogsz+66P4NETus/uKtn0UIvKreeddNP7+xcvc5G6I5HuQl/QPY+Q34a+H/s1x3Py2Xl6wtq7C1+k/izGxdF77LEb9OF4PqfgshuUWoS9pn8XwUV/ezD9ej9tfR1VlYH76j0fR2t3b6vyYdXS7iXG3dbnkzNLuKnsfI59JL0OmH1ZFqiryYVWs5y+MzvBnMZJDePmX+efrEV+oy/hCXcY/uS41ewqPP8foX/id9i/8Tvvvf6f3z/r6YBWgu23/cBR3frDlY1Ybvqjx+IcY9+u34ctZw/X4YRRMXfhC5RdRPj2W3uqVQW/tz1Hkpj6v1nN67Y65WPxjjJtfa69fa++YpP8ohiTX0aV/IQbvZj+Joflb6wpP+XGM/vFx9EcxbmubkPHr1cCfa3v/K5Pq6LzeNbQ//8ruvE81rW3DOkbxkxgtP6x7dUL/XJm73caeXpH7GM9GzN36XU9HzG2MhyPmcYybEXMb4+GIeRyjf3wcz0bM3W+sF4jIdVf+MYZtv6/tbYyHtX0c46a2tzEe1vZxjP7xcfy+trh/9Jtr+maduvpKs7v++W5o4/d3EJtf+JXNL/zK5hd+ZfMLv7L5hV/Z/P2v7L6233jmTq9lO2b8eZbp8ftn7m2Mh8/cu3dTT6/IfYxnIya+MEuNL8xS4wuz1PjCLDW+MEuNL8xSb39jD5+5Mb5Q2/GF2o4v1HZ8obbjC7Ud/+TafuOZK70YE+m4Ij9yy9JG0dvs6v5jlBG//53dxnj4O3sc4+Z3dhvj4e/scYz+8XE8+p3ddoh6sguqwIf+sba3K25pr8WyVHp8I4qMb0TxT89Ii4dSMkj/LsoXZjTz9zPetm2/N1ZvgjwbfT8I8ufh9ybIs/H3gyD98yN5NALvf2tW6xuq4cr6vzuU+EaN4xs1jm/UOL5R4/hGjeOfXuNa/UZN5p+fxHf3asv3I6/3xPPPv5N2t8yotcJgX9bEvxJmxk2Yu4trid91xymN7dMgQD3/fZDbE+q1nrn1uxPqd29t3OuDDzBePzwWqy8szKJ9WiPFcl83Ye5/dZF4wt+Ywn9/We6WOWp5WV4z234TxO5GYq5E9epn1lubof8YxO8GUeQPV2387ZvGf6xRj9vBmJ/lqunfyOt/F+fOLGyW63i/NJfP/vdx7r41ftW6fjN/w1D/fZy7StUXS+Zyc3e4fwczsYA2pi3/rlRy8w71dffOS/PSf0NRf3RKIvUudpObU9Jnp7RxWcF/f0p3P2FLBOz1dnrcnNBtlKHXsfTxtzXQ/l2U2xlD1IO6/32Jw5/FGQnsv/TfNpT4RZzRP4+TL972OL84nlnXZ7btS3HmL+JoxVH7yvX5RRzBlFO6bF+K8/H1kSLY9tnr9p04n/+eX/825yUicvd7vnuF00KtvnDUcXd97OambEUq8rc8fnQoVotkvuYFd5fY5NeHcncP3PsM17NBbmtk9qVr67+/tvalazv+udfW8kas3vqHT6l9VvSFKCM/AtHR5dMpgOWiwGb9ZhLr8mz+6fju9N/NAPzmSNS33Jpqvyx3Z3T7qc+ra5CfUFmz8XGcnl9Rvea0dvc0uGtYyytQfrawT7IRp/1jnPF4RPrd7+Ynce5mSXcfd0m+tpa/PSn/MUS7HdlYBCD+HOQH53N7p4rf33rvD+Vvd6r7n/AP4tz9hMN/X6L4p5fo+R085u9LdD8aR10Ul3YzGkf7zmj8SZy70Tjk16Ue+oVS/+B8bkfj+P284f5Qno/Gn8S5G41j/rpEc/unl+j5aJz9nzwavb4Q1nC9GY13beSXqclTkm4hH8eJdIAvPcbHcUau6PHSwz6PU588/iaOtGxevbTfXp+7Xtq0WrZn/n0o/CLOzWf77+P0imOfn5diQcLfxIla52H+fe37H8ap1yJv4tyPr4hcqEFHu/n9tO3mbtxft/LsRLTbcfouTn5g/dJzfhynzM9L3/1+2vbrCcWbQ1mQyHko07aPT6kIvZcetzbBvtJ+X/eEP7ffO9rvf18G6GdxJN3uS//tg+ufxdH87OelR9zF8a9M3H4U5/Z4xm9nBa3N388KfnI+dxO31n/dTHtzKI8nbj+KM+5OSX9dom7/9BI9nri1uzd0T0skX3k51968nNNaNXfG9nmcpy/53pyX5xf8/dX+uPvJ3L2h6/sKsXk3l2lfiaPt8+NRqQe4qn0nzu3d/E2cXk87je9c59/E0Xq18foBxcdxaj+y/g/rY/8izpxfiTPvXv28iTPzBrZmKh+3m+sLgjt8o+mzN8637eam9pV281pb5BvzLY3v3FFvd/D6Ae5wzxj4AGPQ7eM4o+XbjrZtdyPi7iVdx34cL32zNFpba+39+SVvUWsdL1/kH2PcPSWGtDoWMb87Fv3OXPQnce7uXvbrfnGzL/SL35zP8wngT+LcPR381686mrd/+nV5Pkf3X7/q+MmlvZ2L3tnVp4dye2cAzTr8ZjXK16Hc/XRtq9X4TfrncXTULqB/X/f738W5366jvgwddvvs/kmc+Ys4tZOJ3c7V49d943eHMuuU/Pah8oM4TX4Rpy6Ny93xhP/+0tz++mLjVrZ3rbG43d60Ws/7du3b53G84szmn44qx6/4ZdLi8zi1qY//bbm5XxzPb+IE9sUNGZ/GiVbXOfrWPz+e2iHF/77r0c+Op7Zxemm/i3P3LdcPXjn8JM5ty/hdnIevHN7EefzK4U0c7KQw/RfX529xfnF9HNfHf3Ne9Xue0eQrx/ObOIZ6/SbO41dE7+I8fUX0ZvbkitnTvLlv9Nsvvp6/InoX5+krojdxHr8i6tuv58pvDuXxK6J3cR6/InrzJUM2YfzPn7YeS5H+tgnTt/GVJky/e4/3A+bvTZzHzF+/WxTyB8xfb/0rDYIfxYm7OL9+E9LbF96E/OR87oxwb79+E/LmUB73Kn4U5+4n3H/dq+i9/dNL9LhBsDZO/G2J7kfjU+avd/vOaPxJnLvRePce72mpxxdK3b/zrUC/W1zwYam7fWc0/iTO3WiUX2OZXfSfXqLno1H8nzwaHzN/Xe7AiefM35s4j5m/N3EeM3/v4jxl/u7jPGf++t0iiD8w4D+JczshfxfnoQF/E+exAX8T57GhexfnqaF7M74eM3/dvmTo7EuGzr5k6H7/id2bQ3lu6Ow7hu6NbXn8Drrb7Tvox8zfmziPmb83cR4zf92ffyh6O3H7SZzb4+m/nhXcvcJ7PCvw73xA23//Eu/NoTyfuP0kzt3EzcfvSzT/6SV6PnGL9vu73ncIlX73od0PmL93cZ6SLm/O6zHz1+OW4H7M/P0gzi3z9ybOY+bvJ3Fu7+Zv4jxl/n5yfX4R5zHz9ybOY+bvJ3HumL8fxLll/t7E+RLzF7M2xeo37eYxHrWbX3Oj8eeFc/q4XVp6Zl/2pf3uKXMbR1tw7bO7n+D8zlekP4pz91Oev29XzG+0K35wPrcTk/n7dsX8zlekP4pz+5P59Veksm3/9BI9npjI9msa6M1o7LNGo6jeHYreP1jqASXxiziBOPM3x/NwQvGDOLcTijdxHk8ofhLHPr8+jycUP7k+v4jzeELxJs4ovPjV6WifxykbvmNpvziehxOcn8S5m+D8IM7tBOdNnMcTnDf3H8mn1UvfXp+7V3d9a7O6L3U09o8x7rZ5y9XRBzrZ9qOjqDbbJn88itspn7dsHXrzP3/mIf3hwoJN9M+Igdy9+ZBRazbJ4FKq/z+KcxvHe6s4d1Ms6fGVKd+P4twez+/nE/KF+cRPzuduyify6/nEm0N5POX7UZy758rdSl9PS+T/9BI9n/LJ+H2JbkfjkBrVY8bHo3rWS7Ixbx+1z49nSv/8ePIbhJe+fWT/IE785nhwXnN85/p8Hmdu+TXZS/cvxZH4RRypOL+oF67Pb+LMAupeevrHcWzUeXl8/NR8zaos40SLrxxPtPGdOL+4zowzts/Pa/T6HY7bpVlvJ1w9J23e5WbCZc96bLdIp9ztePYDpFPuXnz8AOl8E+cx0im37+xUc2q94503nLTcv7h7Ps9x/fVD9P6UHlOq4t9ZUuVHce4G1e/f3ck33t395HxuS/37d3dvDuX5lPYnce5GZfwaJJawf3qJnk9pI/7Zo/EppSoxvzMafxLnbjTeLTf4sNSjf6HUPzif29E4fn/jvT+U56PxJ3HuRuOI35do/NNL9Hw0zu2fPBofU6pyt0jmDyjVN3EeU6pv4jymVN/FeUqp3sd5Tqm+5us3P53nlOpP4txRhm/jPKRU38R5TKm+ifOYUn0X5yml+mZ8PaZU9b6H/5hSfRfnKaX6Js5jSlW3X08o3hzKY0r1XZynlOobJ/aYUtU7wPkHlOqbOI8p1TdxHlOq2r6zGtCP4twez69XA9L2hdWAfnI+dxM3bb9e7PXNoTyeuP0ozs3ETfuvQWLt8k8v0eOJm3b7fYluR+NjSlVvX3Y8p1TfxXlKqb45r8eUqsr2FajkB3FuoZI3cR5DJT+Jc3s3fxPnKVTyk+vziziPoZI3cR5DHD+Jcwdx/CDOLcTxJs53KFWvXU5dbvaQVb1rVLyeTrhpoIfzjz10vf0UTLw22b5blOpNlHx1dx/l/rrUdmIuN9te6u0imc82/H4X5NmO33q3PObT3aDvgzzcDfp5kJvdoO+DPNwN+nmQ/vmRPNkN+s2PzXLNUfft5sdmD3fDvXuNpXdLYf7gNZZafOU11ps4j19j6d3ruZfl6eW71e987pc+HVP/9bsN/dInUvr7VTHfXd2nLwnV7UtX1//Jp/T4JaF+afs6/dL2dfr77ev0G9vX6Ze2r9Pfb1+nX9q+Tr+0fZ3+fvs6/cb2dfql7ev099vXvRuNT18S6pe2r9MvbV+nv9++Tr+xfZ1+afs6/f32dfql7ev0S9vX6e+3r9NvbF+nX9q+Tn+/fd2b0fj4JaF+afs6/dL2dfql7ev0S9vX6Ze2r9MvbV+nX9q+Tr+0fZ1+afs6/dL2dfql7evejK/HLwntS9vX2Ze2r7MvbV9nv9++zr60fZ19afu6Nz738UtC+9L2dfal7evsS9vX2Ze2r7MvbV9nv9++zr6xfZ19afs6+/32dfal7evsS9vX2e+3r7NvbF9nX9q+zn6/fZ19afs6+9L2dfal7evsS9vX2Ze2r/tBnNuXhPal7et+Euf2bv6l7et+cn1+EefxS0L70vZ1P4lz95LwB3FuXxLa/z+2r3PP+bF7/Pn9hN1tX/f8JaHdbWD3+CXhmyhfeUlYe844P/L699dl/P4l4Zsgz14S2u26jA9fEt4HefiS8HmQm5eE90EeviR8HqR/fiRfeEkYw/LHNv/8Y7sPMnJVAJ/bh0GiPv6MTecXguDH9sMg+bYy2j+8pf9/v/5///E//Zf/9r/963/9T//xf/yX//pv/33/h9vr7eh+y2z739cB9POvnH/1/GvnXz//xvl3nH/n+bdtl7gititku2K2FfR1Gs0u4ZeIS4xLzFP0FflVrd7OY+5X5H5F7tfh9ut4+3XA/Trifh1yv45ZrmOW65glL8MVWa7Ich2zXMcs1zHLdcxyHbNul2jnwWs/D17zCl+R9TpmvY5Zr2PW65j1Oma7jtmuY7brmO2KbFm8K7Jdx2zXMdt1zHYds1/H7O0S/Tx43yPvLRTfI+8PN98j7w8W90vEJcYl5iliu0S7RL+EXEIvcUWOK3JckWNFfj0kYp5ibJdol+iXkEusyK9n5dgj73vhjD3y/iQfcYlxiXmKuV2iXaJfQi6hl7BLXJHnFXlekeeKvEbKlqql6qkklaZa8X1XK0Hsas+wvxdv255if8netnmpNRwP1VL1VJJKU1kqTxWpMkfLHD1zrJG54/5tDc1DSSpNZak81cphuxrXGfXMIZlD8jwkz0PyPCTPQ/I8JM9D8jwkz0Myh2YOzRya56F5HprnoXkemuexxuyhxnVGa9QutYbt/pKxrXG7rx7Y1sDdzWxbI/dQmspSeapINVLNS60BfKiWKnN45vDMsUZxrPuwp4pUI9W81BrKh1o59l/iGsz7i8+2RvP+JGprOB/KUnmqSDVSzUutQX2olqqnyhwjc4zMsYb2/lKmrbF9qJFqXmoN70O1VCvHevSsHHvd1hDf73xtjXFd/+11Y2ozUo1U112vb1uqlqqnklSaylJ5qkg1Ul33v962VC1VTyWpNNXKMXd13Ut6u+4lPcd5z3Hec5z33lL1VJJKU1kqTxWpMkeO857jvMt1L+nSU0kqTWWpPNV1L+nHOB+7mud463qNj64tVU8lqTSVpfJUkWqkusZgt8xhmSPHeT/G+T6nOcb5UpbKU0WqkWqe460f43yvoF/jo3tPJak0laXyVJFqpLrGYI8tVeaIzJHjvB/jfK/bMc6X8lSRaqS6xmA/xvl+bsc43+t2jPO9bsc438/yGOdLWSpPFalGqnmpY5wv1VL1VJljZo6ZOdY4399n9zXODzVSzVPJGueHaqn2HHPNMa+5k2zX5ElynEuOc8lxLjnOZbvuJdK2VC1VTyWpNFXmaJmjZY52TaWkXfcS6VuqlqqnklTXhErWON/vIHKM8/0sc5xLjnPJcS45ziWf55LPc8nnueTzXPJ5Lvk8l3yeSz7PJZ/ncjzP+65aqp5KUmkqS7Vy7FdIr3uiaObQzGF5HpbnYXkeludheR6W52F5HpbnYZnDModnDs/z8DwPz/PwPA/P83BPdd0Txa97ovh1T5S47lcSLVVPJak0laXyVJFqpLruiTIyx8gcI3OM654oQ1NZKk8VqUaq654o87onyrzuVzJ7KkmlqSyVp4pUI9V1T9RtS9VS9VSS6ron6mapPFWkGqmue6K2656o7bonakvrmE5aW5rHlu6xpX1s6R9bGsh2OUjtW6qWqqfKHGmqNV219stIao9UI1X6X0kDLC3VZSf1cNfLDGcOyRyS5yF5HpLnIXkemueheR6a5wGfnTnKaZfV1jwPzfPQPA/L87A8j8NwLyXXGR2Wez+j9NxqmcPyPCzPw/I8PM/D8zw8z8PzPDzPw6tjkDk8c3ieh+d5RJ5H5HlEnsca54fS64wOH77/ng8jvv7b6/mhMVJdzygdW6qWqqeSVJrKUnmqzDEyx8gc83pG6WypeipJpaks1coxd7Xc+T7e0p7rvJy/bVuqlqqnklSaylJ5qkg1UmWOljna1QOw1lNJKk1lqTzVyuG7WjliV+v5se19oev5YTlvt5y3W87bLeftlvN2y3m75fPc8nlu+Ty3fJ5bPs8tn+eW83bLebvlvN1y3m4SqUaqyzvb8Tzfzyj9uWnm0DwPzfPQPA/N89A8j3yeWz7PLZ/nls9zy+e55fPcLM/D8jwsz8PyPCzP43ie7+p4nu9ndDzPl1o5xq7Wc3D9765nrbml8lSRaqS6nrWWz3PL57nl89zyeW75PLd8nls+zy2uZ63FSHX1AGxsqVqqnmrl2H+Jx/N87up61trwVJFqpLqetTa3VC1VTyWpNFXmyOe55fPc5vWstXk9a33bUrVUPZWkWjlWh3Tl2Fubx7x974ge8/b132bjM+ftnvN2z3m757zdc97uOW/3nLd7zts95+3eMkfLHD1z5Lzdc97uOW/3rqksladaOeaurnuJ9+te4jnOPce55zj3nLd7zts95+2e83bPebvnvN1z3u7Zh/Mc557j3HPe7jlv95y3e/bhPPtwriPVdS/x7MN59uE8/blnH86zD+fZh/Psw3n24Tz7cJ59OM8+nGcfzrMP59mH8xznnn04zz6cZx/Osw/n2Yfz7MN59uE8+3Ce/tyzD+fZh/Psw3n24Tz7cJ59OM8+nGcfzrMP59mH8+zDeY5zzz6cZx/Osw/n2Yfz7MN59uE8+3CefTg/xvlet/TnPj1VpBqprh5AbFuqlqqnklSaylJ5qkh19QBiu3oA0bZULVVPJan2HHtfINo1v4p2za8ix3nkOI8c55HjPHq9R8kXKT3fpPR8ldLzXUrPlyk9c/TM0TOHXPOrkJaqp5JUmspSXfOrWON8v4OEXD39yHEeOc4jx3nkOI98nkc+zyOf55HP88jneeTzPPJ5Hvk8j3yeh13eOUxSaSpL5aki1dXTD7vuiZH+PDxzeJ6H53l4nofneXieh+d5eJ6H53lE5ojMEZkj8jwizyPyPCLPI/I8YqS67okxrntijOueGOnPY0gqTWWpPFWkGqmue2LMLVVLlTlm5piZY173xJieKlKNVNc9cWxbquueOLbrnjjSn49NU1kqTxWpRqrrnjjalqql6qkyR8scLXO06544WqQaqa574uhbqpbquieOft0Txz7OXy8T139tS+4vMPeRfskoOUrOlPtov2Qr2UtKSS1Z2aSySWWTI5vscqbUrWQr2UtKySPben17ZBu7PLLt5dQoOUrOlLaVbCV7SSmpJa1kZbPKZpXNVra219a3kq1kLyklteTKtgMgwz2r6XUlvermVbeoukXVLapuUXWLqltU3aLqFpUtKltUtlF1G1W3UXUbVbehJa2kZzVHZDVHXclRdZtVt1l1m1W3WXWbVbdZdZtVt1l1m5VtZra5bSWzbnPrJaWklrSSXjKuas5tXNWcW17J2baSrWQvKSW1pJX0klFylKxsvbL1ytazbrNLSS1pJb1klBxXNed5Lxk7FFFXUlrJXlJKakkr6SWj5ChZddPKppVNK5tW3bTqplU3rbod95JDjpIzq3neS/ZqWl1Jq7pZ1c2qblZ1s6qbVd2s6mZVN6+6eWXzyuaVzatuXnXzqptX3XyUzLvyPO8lezXPe8lezagrGVW3qLpF1S2qblF1i6pbVN1G1W1U3UZlG5VtVLZRdRtVt1F1G1W3kXflObeSLat53kv2as66krPqNqtus+o2q26z6jazbq//u0E36A4t0Apt0Fm+1/8N6AE9S7cNukH3q7T7mV+1fem8sC9t0A4d0AN6lu4bdIPu0AKNvB15O/L2rOlLD+hZWjboBt2h5ar3S+dE6aVxnWvy8tIBPaBRX0V9FfVV1FdRX0V9FXkVeRV5FfVV1NdQX0N9rUMLtFbdzaruhutsqK+hvob6OurrqK+jvo76OurrqK8jryOvI6+jvoH6BuobqG8ItEJb1T286h64zoH6Buo7UN+B+g7Ud6C+A/UdqO9AfQfyDuQdyDtR34n6TtR3or5ToQ3aq+4zqu4T17nmPq3V5Ke1rUF3aIFWaIN26IAe0MjbkLdVfVvr0AKt0Abt0Dn3aq3l5Ku1mg+1VhOi1mpG1Frv0AKt0Abt0AE9oJFXkFeQV6q+TQRaoQ3aoQM6J2StSc7IWlNcZ0V9FfVV1FdRX0V9FfVV1FdRX0V9DXkNeQ15DfU11NdQX0N9LaAH9Ky6+1Z1d1xnR30d9XXU11FfR30d9XXU11HfQH0DeQN5A3kD9Q3UN1DfQH1jQNdzoY2t6j5a1X3gOg/Ud6C+A/UdqO9AfQfqO1DfifpO1Hci70TeibwT9Z2o70R9J+o767nQtw0653Otbzmhax3zq475Vcf8qm8OHdADuurby7a1Xr6t9TJurTfkbcjbkLdVfXsL6AFd9e19g27QNa/rveZ1HfOrjvlVx/yq94Ae0FXfXlau9fJyrZeZa73cXOuCvIK8grxS9e0yoFFfRX21QXfomtd1rXldx/yqY37VMb/qivoq6muor6G+hvoa6muoryGvIa8hr6G+hvo66uuor3doga55Xfea13XMrzrmVx3zq+6ob6C+gfoG6huob6C+gfoG8gbyBvIG6jtQ34H6DtR3CLRC17yuj5rXdcyvOuZXHfOrPlHfifpO1HeivhP1najvRH0n8k7khR+UreorW4Pu0AKt0AZd8zrZal4nmF8J5leC+ZW0Bt2hBVqhDdqhAxp54QcFflB61Vd6hxZohTZoh655nfSa1wnmV4L5lWB+JdXIblKd7CbVym4CPyjwgwI/KPCDAj8o8IMCPyiK+irqq6ivor7q0AFd8zrRmtcJ5leC+ZVgfiWG+hrqa6gv/KDADwr8oMAPCvygwA8K/KA46uuor6O+jvp6QA/omtdJ1LxOML8SzK8E8ysJ1DdQ30B94QcFflDgBwV+UOAHBX5Q4AdloL4D9R2o70B9x4Cu54LMmtfJrHmdYH4lmF8J5lcyUd+J+k7UF35Q4AcVflDhBxV+UOEHFX5QqyPetFriTbeAHtD1XNC2Qde8TlvN6xTzK8X8SjG/0mqON63ueNNqjzeFH1T4QYUfVPhBhR9U+EGFH9RqkzetPnnTPqCrviobdIOueZ1KzesU8yvF/Eoxv9LqmDetlnlTQX3hBxV+UOEHFX5Q4QcVflDhB1VRX0V9FfU11NcadIeueZ1azesU8yvF/Eoxv1JDfQ31ddQXflDhBxV+UOEHFX5Q4QcVflAd9XXUN1DfQH2jQwt0zes0al6nmF8p5leK+ZUG6jtQ34H6wg8q/KDCDyr8oMIPKvygwg/qQH0n6jtR34n6ToFW6JrX6ax5nWJ+pZhfKeZXhn67od9u6Lcb/KDBDxr8oMEPGvygwQ8a/KCh327ot1vr0AKt0AZd8zprNa8zzK8M8yvD/MrQbzf02w39doMfNPhBgx80+EGDHzT4QYMfNPTbDf12E4FWaIN26JrXmdS8zjC/MsyvDPMrQ7/d0G839NsNftDgBw1+0OAHDX7Q4AcNftDQbzf0281QX0N9zaEDuuZ1ZjWvM8yvDPMrw/zK0G839NsN/XaDHzT4QYMfNPhBgx80+EGDHzT02w39dgvUN1DfCOgBXfM6GzWvM8yvDPMrw/zK0G839NsN/XaDHzT4QYMfNPhBgx80+EGDHzT02w39dpuo70R954Cu54JvNa/zreZ1jvmVY37lmF85+u2Ofruj3+7wgw4/6PCDDj/o8IMOP+jwg45+u6Pf7i2gB3Q9F7xv0DWv817zOsf8yjG/csyvHP12R7/d0W93+EGHH3T4QYcfdPhBhx90+EFHv93Rb/fCm5oL6luAU/MinJprzetca17nmF855leO+ZWj3+7otzv67Q4/6PCDDj/o8IMOP+jwgw4/6Oi3O/rtbqivo75FPTUv7Km517zOveZ1jvmVY37lmF85+u2Ofruj3+7wgw4/6PCDDj/o8IMOP+jwg45+u6Pf7gP1HahvoVDNi4VqPmpe56PmdY75lWN+5ZhfOfrtjn67o9/u8IMOP+jwgw4/6PCDDj/o8IOOfnug3x5FR7UoPKpF8VEtCpBqsdW8Lraa1wXmV4H5VWB+Fei3B/rtgX57wA8G/GDADwb8YMAPBvxgwA8G+u2BfnsUMtWimKkWBU21KGqqRa95XfSa1wXmV4H5VWB+Fei3B/rtgX57wA8G/GDADwb8YMAPBvxgwA8G+u2Bfnso6quob5FULQqlaqE1rwuteV1gfhWYXwXmV4F+e6DfHui3B/xgwA8G/GDADwb8YMAPBvxgoN8e6LeHo76O+hZe1aL4qhZe87rwmtcF5leB+VVgfhXotwf67YF+e8APBvxgwA8G/GDADwb8YMAPBvrtgX57DNR3oL7FXLUo6KrFqHldzJrXBeZXgflVYH4V6LcH+u2BfnvADwb8YMAPDvjBAT844AcH/OBAv32g3z7AXw3wVwP81QB/NVrN60ared3A/GpgfjUwvxrotw/02wf67QN+cMAPDvjBAT844AcH/OCAHxzotw/02wf4qwH+aoC/GuCvTm581f0Cx9vSuM6YX4Edb4DHG+jxNtBvH/CDA35wwA8O+MEBPzjgBwf84EC/faDfPsBfDfBXA/zVAH91weSr7lbzOuDkDTx5A1DeQJQ3IOVtoN8+4AcH/OCAHxzwgwN+cMAPDvjBgX77QL99gL8a4K8G+KsB/uokzI+6R83rwJg3QOYNlHkDZt7AmbeBfvuAHxzwgwN+cMAPDvjBAT844AcH+u0D/fYB/mqAvxrgrwb4qws7X3WfNa8DeN5Anjeg5w3seQN83ib67RN+cMIPTvjBCT844Qcn/OCEH5zot0/02yf4qwn+aoK/muCvThZ91f2C0dvSdZ2Bozfw6A1AegOR3ib67RN+cMIPTvjBCT844Qcn/OCEH5zot0/02yf4qwn+aoK/muCvLkDdl655HRD1Bka9AVJvoNQbMPU20W+f8IMTfnDCD074wQk/OOEHJ/zgRL99ot8+wV9N8FcT/NUEf3VS60fdreZ14NYbwPUGcr0BXW9g19tEv33CD074wQk/OOEHJ/zghB+c8IMT/faJfvsEfzXBX03wVxP81YWyr7pHzesAszfQ7A04ewPP3gC0t4l++4QfnPCDE35wwg9O+MEJPzjhByf67RP99gn+aoK/muCvJvirk2/f694vvr0tndf5pTu0QCu0QTt0QA/oWbr8YN8a8jbkbchb/fa+Vb+9b8Vf9a34q74Vf9W34q/6xbf70jmv6+DbO/j2Dr69g2/v4Nv7Vv32vpUf7Fv5wb6VH+xb+cG+CfIK8gryVr+9b9Vv71vxV30r/qpvxV/1rfirfvLtR921V90V11lRX0V9FfVV1FdRX0V9DfU11NdQX0NeQ15DXkN9DfU11NdQ3+Kv+lb8Vb/49lV3l6q74zo76uuor6O+jvo66huob6C+gfoG6hvIG8gbyBuob6C+gfoO1Lf4q74Vf9VPvv2o+9Cq+8B1HqjvQH0H6jtQ34n6TtR3or4T9Z2o70TeibwTeSfqW/323oq/eukG3aEFOud1/eLbx9J1ncG3d/DtHXx7B9/eW/Xbeys/2Fv5wd7KD/ZWfrC3hrwNeRvyVr+9t+q391b8VW/FX/VW/FVvxV/1k29fdb/49rZ0XWfw7R18ewff3sG391b99t7KD/ZWfrC38oO9lR/sTZBXkFeQV1FfRX0V9VXUt/ir3oq/6hfffqyTGlV3xXVW1NdQX0N9DfU11NdQX0N9DfU11NeQ15DXkddRX0d9HfV11Lf4q96Kv+on337U3UfV3XGdA/UN1DdQ30B9A/UN1DdQ30B9A/UN5B3IO5B3oL4D9R2o70B9i7/qrfirfvHtq+5jVt0nrvNEfSfqO1HfifpO1HeivhP1nahv+cHeyw/2Xn6w9/KDvVe/vffqt/de/FXvxV/1XvxV78Vf9ZNvX3W/+Pa2dF1n8O0dfHsH397Bt/de/fbeyw/2Xn6w9/KDvZcf7L0jb0fejrzVb++9+u29F3/Ve/FXvRd/1XvxV/3i233pmteBb+/g2zv49g6+vYNv77367b2XH+xdUF9FfRX1VeRV5FXkVdRXUV9FfRX1Lf6q9+Kv+sm3H3W3mteBb+/g2zv49g6+vYNv791QX0N9HfV11NdRX0deR15HXkd9HfV11NdR3+Kvei/+ql98+6p71LwOfHsH397Bt3fw7R18e++B+g7Ud6C+A/UdqO9A3oG8A3kH6jtQ34H6TtS3+Kvei7/qJ99+1H3WvA58ewff3sG3d/DtHXx7l+q3d4EfFPhBgR8U+EGBHxT4QYEflOq3d6l+e5fir7oUf9Wl+KsuxV/1i2/3pWteB769g2/v4Ns7+PYOvr1L9du7wA8K/KDADwr8oMAPCvygwA9K9du7VL+9S/FXXYq/6lL8VZfir/rJt6+6X3x7WxrXGfMr8O0dfHsH395FUV/4QYEfFPhBgR8U+EGBHxT4QTHU11BfQ30N9S3+qkvxV/3i21fdreZ14Ns7+PYOvr2Db+/g27s46gs/KPCDAj8o8IMCPyjwgwI/KIH6BuobqG+gvsVfdSn+qp98+1H3qHkd+PYOvr2Db+/g2zv49i4D9YUfFPhBgR8U+EGBHxT4QYEflIn6TtR3or4T9S3+qkvxV/3i21fdZ83rwLd38O0dfHsH397Bt3etfntX+EGFH1T4QYUfVPhBhR9U+EGtfnvX6rd3Lf6qa/FXXYu/6lr8VT/59lX3i29vS9d1Bt/ewbd38O0dfHvX6rd3hR9U+EGFH1T4QYUfVPhBhR/U6rd3rX571+KvuhZ/1bX4q67FX/WLb/ela14Hvr2Db+/g2zv49g6+vauivvCDCj+o8IMKP6jwgwo/qPCDaqivob6G+hrqW/xV1+Kv+sm3H3X3mteBb+/g2zv49g6+vYNv7+qoL/ygwg8q/KDCDyr8oMIPKvygBuobqG+gvoH6Fn/VtfirfvHtq+6j5nXg2zv49g6+vYNv7+Dbuw7UF35Q4QcVflDhBxV+UOEHFX5QJ+o7Ud/ir7oVf9Wt+KtuxV/1k29fdb/49rZ0XWfw7R18ewff3sG3d0O/3eAHDX7Q4AcNftDgBw1+0OAHDf12Q7/dir/qVvxVt+KvuhV/1S++3ZeueR349g6+vYNv7+DbO/j2bui3G/ygwQ8a/KDBDxr8oMEPGvygod9u6Lebor6K+hZ/1a34q37y7UfdteZ14Ns7+PYOvr2Db+/g27uh327wgwY/aPCDBj9o8IMGP2jwg4Z+u6Hfbo76Oupb/FW34q/6xbevunvN68C3d/DtHXx7B9/ewbd3Q7/d4AcNftDgBw1+0OAHDX7Q4AcN/XZDv90G6jtQ3+KvuhV/1U++/aj7qHkd+PYOvr2Db+/g2zv49m7otxv8oMEPGvygwQ8a/KDDDzr8oKPf7ui3e/FX3Yu/6l78Vffir/rFt/vSNa8D397Bt3fw7R18ewff3h39docfdPhBhx90+EGHH3T4QYcfdPTbHf12L/6qe/FX3Yu/6l78VT/59lX3i29vS+M6Y34Fvr2Db+/g27uj3+7wgw4/6PCDDj/o8IMOP+jwg45+u6Pf7or6Kupb/FX34q/6xbevulvN68C3d/DtHXx7B9/ewbd3R7/d4QcdftDhBx1+0OEHHX7Q4Qcd/XZHv90d9XXUt/ir7sVf9ZNvP+oeNa8D397Bt3fw7R18ewff3h39docfdPhBhx90+EGHH3T4QYcfdPTbHf12H6jvQH2Lv+pe/FW/+PZV91nzOvDtHXx7B9/ewbd38O3d0W8P+MGAHwz4wYAfDPjBgB8M+MFAvz3Qb4/ir3oUf9Wj+KsexV/1k29fdb/49rZ0XWfw7R18ewff3sG390C/PeAHA34w4AcDfjDgBwN+MOAHA/32QL89ir/qUfxVj+KvehR/1S++3ZeueR349g6+vYNv7+DbO/j2Hui3B/xgwA8G/GDADwb8YMAPBvxgoN8e6LeHob6G+hZ/1aP4q37y7UfdreZ14Ns7+PYOvr2Db+/g23ug3x7wgwE/GPCDAT8Y8IMBPxjwg4F+e6DfHoH6Bupb/FWP4q/6xbevukfN68C3d/DtHXx7B9/ewbf3QL894AcDfjDgBwN+MOAHA34w4AcD/fZAvz0m6jtR3+KvehR/1U++/aj7rHkd+PYOvr2Db+/g2zv49j7Qbx/wgwN+cMAPDvjBAT844AcH/OBAv32g3z7AXw3wVwP81QB/dfHtvnTN68C3d/DtHXx7B9/ewbf3gX77gB8c8IMDfnDADw74wQE/OOAHB/rtA/32Af5qgL8a4K8G+KuTb191v/j2tjSuM+ZX4Ns7+PYOvr0P9NsH/OCAHxzwgwN+cMAPDvjBAT840G8f6LcP8FcD/NUAfzXAX118+6q717wOfHsH397Bt3fw7R18ex/otw/4wQE/OOAHB/zggB8c8IMDfnCg3z7Qbx/grwb4qwH+aoC/Ovn2o+6j5nXg2zv49g6+vYNv7+Db+0C/fcAPDvjBAT844AcH/OCAHxzwgwP99oF++wB/NcBfTfBXE/zVxbf70jWvA9/ewbd38O0dfHsH394n+u0TfnDCD074wQk/OOEHJ/zghB+c6LdP9Nsn+KsJ/mqCv5rgr06+fdV91gYOHXx7B9/ewbd38O0dfHuf6LdP+MEJPzjhByf84IQfnPCDE35wot8+0W+f4K8m+KsJ/mqCv5q1qUOftatDB9/ewbd38O0dfHsH394n+u0TfnDCD074wQk/OOEHJ/zghB+c6LdP9Nsn+KsJ/mqCv5rgr2bt9NBnbfXQwbd38O0dfHsH397Bt/eJfvuEH5zwgxN+cMIPTvjBCT844Qcn+u0T/fYJ/mqCv5rgryb4q1nbP/RZ+z908O0dfHsH397Bt3fw7X2i3z7hByf84IQfnPCDE35wlh+UrfygbNVvf+kOLdAKbdAOnfM62WpTiJfO6yxbza8EfLuAbxfw7bJVv1228oOylR+UrfygbOUHZWvI25G3I2/122WrfrtsxV/JVvyVbMVfyVb8lWy1UYRstVOEgG8X8O0Cvl3Atwv4dtmq3y5b+UHZyg/KVn5QNkF9FXkVeRV5FfVV1FdRX0V9i7+Srfgr2Wr3CNlq+wgB3y7g2wV8u4BvF/Dtshnqa6ivob6G+jrq68jryOvI66ivo76O+jrqW/yVbMVfyVZbSshWe0oI+HYB3y7g2wV8u4Bvly1Q30B9A/UdqO9AfQfyDuQdyDtQ34H6DtR3oL7FX8lW/JVstc+EbLXRhIBvF/DtAr5dwLcL+HbZJupbflBa+cGXbtAdWqAV2qCrvq367dKKv5JW/JW04q+kFX8lrfabkFb7TQj4dgHfLuDbBXy7gG+XVv12aeUHpZUflFZ+UFr5QWkdeTvyduStfru06rdLK/5KWvFX0oq/klb8lbTab0Ja7Tch4NsFfLuAbxfw7QK+XZqivor6KuqrqK+ivoq8iryKvIr6KuprqK+hvsVfSSv+SlrtNyGt9psQ8O0Cvl3Atwv4dgHfLs1RX0d9HfV11NdRX0deR15HXkd9A/UN1DdQ3+KvpBV/Ja32m5BW+00I+HYB3y7g2wV8u4BvlzZQ34H6DtR3oL4D9R3IO5B3IO9EfSfqO1HfifoWfyWt+Ctptd+EtNpvQsC3C/h2Ad8u4NsFfLv06rdLLz8ovfyg9PKD0ssPSi8/KH1D3oa81W+XXv126cVfSS/+SnrxV9KLv5Je+01Ir/0mBHy7gG8X8O0Cvl3At0uvfrv08oPSyw9KLz8ovfyg9I68gryCvNVvl179dunFX0kv/kp68VfSi7+SXvtNSK/9JgR8u4BvF/DtAr5dwLdLV9RXUV9FfRX1VdTXkNeQ15DXUF9DfQ31NdS3+CvpxV9Jr/0mpNd+EwK+XcC3C/h2Ad8u4NulO+rrqK+jvo76BuobyBvIG8gbqG+gvoH6Bupb/JX04q+k134T0mu/CQHfLuDbBXy7gG8X8O3SB+o7UN+B+k7Ud6K+E3kn8k7knajvRH0n6jtR3+KvRIq/Eqn9JkRqvwkB3y7g2wV8u4BvF/DtItVvF4EfFPhBgR8U+EGBHxT4QYEflOq3i1S/XaT4K5Hir0SKvxIp/kqk9psQqf0mBHy7gG8X8O0Cvl3At4tUv10EflDgBwV+UOAHBX5Q4AcFflCq3y5S/XYRQX0V9S3+SqT4K5Hab0Kk9psQ8O0Cvl3Atwv4dgHfLmKoL/ygwA8K/KDADwr8oMAPCvygGOprqK+jvo76Fn8lUvyVSO03IVL7TQj4dgHfLuDbBXy7gG8XCdQXflDgBwV+UOAHBX5Q4AcFflAC9R2o70B9B+pb/JVI8Vcitd+ESO03IeDbBXy7gG8X8O0Cvl1kor7wgwI/KPCDAj8o8IMCPyjwg1r9dtHqt4sWfyVa/JVo8VeixV+J1n4TorXfhIBvF/DtAr5dwLcL+HbR6reLwg8q/KDCDyr8oMIPKvygwg9q9dtFq98uWvyVaPFXosVfiRZ/JVr7TYjWfhMCvl3Atwv4dgHfLuDbRavfLgo/qPCDCj+o8IMKP6jwgwo/qIr6KuqrqK+ivsVfiRZ/JVr7TYjWfhMCvl3Atwv4dgHfLuDbRQ31hR9U+EGFH1T4QYUfVPhBhR9UR30d9XXU11Hf4q9Ei78Srf0mRGu/CQHfLuDbBXy7gG8X8O2igfrCDyr8oMIPKvygwg8q/KDCD+pAfQfqO1DfgfoWfyVa/JVo7TchWvtNCPh2Ad8u4NsFfLuAbxedqC/8oMIPGvygwQ8a/KDBDxr8oKHfbui3W/FXYsVfiRV/JVb8lVjtNyFW+00I+HYB3y7g2wV8u4BvF0O/3eAHDX7Q4AcNftDgBw1+0OAHDf12Q7/dir8SK/5KrPgrseKvxGq/CbHab0LAtwv4dgHfLuDbBXy7GPrtBj9o8IMGP2jwgwY/aPCDBj9o6Lcb+u2mqK+hvsVfiRV/JVb7TYjVfhMCvl3Atwv4dgHfLuDbxdBvN/hBgx80+EGDHzT4QYMfNPhBQ7/d0G+3QH0D9S3+Sqz4K7Hab0Ks9psQ8O0Cvl3Atwv4dgHfLoZ+u8EPGvygwQ8a/KDBDxr8oMEPGvrthn67TdR3or7FX4kVfyVW+02I1X4TAr5dwLcL+HYB3y7g28XRb3f4QYcfdPhBhx90+EGHH3T4QUe/3dFv9+KvxIu/Ei/+Srz4K/Hab0K89psQ8O0Cvl3Atwv4dgHfLo5+u8MPOvygww86/KDDDzr8oMMPOvrtjn67F38lXvyVePFX4sVfidd+E+K134SAbxfw7QK+XcC3C/h2cfTbHX7Q4QcdftDhBx1+0OEHHX7Q0W939NvdUF9DfYu/Ei/+Srz2mxCv/SYEfLuAbxfw7QK+XcC3i6Pf7vCDDj/o8IMOP+jwgw4/6PCDjn67o9/ugfoG6lv8lXjxV+K134R47Tch4NsFfLuAbxfw7QK+XRz9docfdPhBhx90+EGHH3T4QYcfdPTbHf12n6jvRH2LvxIv/kqi9puQqP0mBHy7gG8X8O0Cvl3At0ug3x7wgwE/GPCDAT8Y8IMBPxjwg4F+e6DfHsVfSRR/JVH8lUTxVxK134RE7Tch4NsFfLuAbxfw7QK+XQL99oAfDPjBgB8M+MGAHwz4wYAfDPTbA/32KP5KQlDf4q8kir+SqP0mJGq/CQHfLuDbBXy7gG8X8O0S6LcH/GDADwb8YMAPBvxgwA8G/GCg3x7ot4ehvo76Fn8lUfyVRO03IVH7TQj4dgHfLuDbBXy7gG+XQL894AcDfjDgBwN+MOAHA34w4AcD/fZAvz0G6jtQ3+KvJIq/kqj9JiRqvwkB3y7g2wV8u4BvF/DtEui3B/xgwA8G/GDADwb8YMAPBvxgoN8+0G8f4K8G+KsB/mqAvxq134SM2m9CwLcL+HYB3y7g2wV8uwz02wf84IAfHPCDA35wwA8O+MEBPzjQbx/otw/wVwP81QB/NcBfjdpvQkbtNyHg2wV8u4BvF/DtAr5dBvrtA35wwA8O+MEBPzjgBwf84IAfHOi3D/TbB/irAf5qgL8a4K9G7Tcho/abEPDtAr5dwLcL+HYB3y4D/fYBPzjgBwf84IAfHPCDA35wwA8O9NsH+u0D/NUAfzXAXw3wV6P2m5BR+00I+HYB3y7g2wV8u4Bvl4F++4AfHPCDA35wwA8O+MEBPzjgBwf67QP99gH+aoC/GuCvBvirUftNyKj9JgR8u4BvF/DtAr5dwLfLQL99wA8O+MEBPzjhByf84IQfnPCDE/32iX77BH81wV9N8FcT/NWs/SZk1n4TAr5dwLcL+HYB3y7g22Wi3z7hByf84IQfnPCDE35wwg9O+MGJfvtEv32Cv5rgryb4qwn+atZ+EzJrvwkB3y7g2wV8u4BvF/DtMtFvn/CDE35wwg9O+MEJPzjhByf84ES/faLfPsFfTfBXE/zVBH81a78JmbXfhIBvF/DtAr5dwLcL+HaZ6LdP+MEJPzjhByf84IQfnPCDE35wot8+0W+f4K8m+KsJ/mqCv5q134TM2m9CwLcL+HYB3y7g2wV8u0z02yf84IQfnPCDE35wwg9O+MEJPzjRb5/ot0/wVxP81QR/NcFfzdpvQmbtNyHg2wV8u4BvF/DtCr5dt+q3v3SHFmiFNmiHDugBnfV9vYrcoBt0hxZohc55nW6134SCb1fw7Qq+XcG3K/h23arfrlv5Qd3KD+pWflC38oO6deTtyNuRt/rtulW/Xbfir3Qr/kq34q90K/5Kt9pvQrfab0LBtyv4dgXfruDbFXy7bor6KuqrqK+ivor6KvIq8hryGuprqK+hvob6Fn+lW/FXutV+E7rVfhMKvl3Btyv4dgXfruDbdXPU11FfR30d9XXU15E3kDeQN1DfQH0D9Q3Ut/gr3Yq/0q32m9Ct9ptQ8O0Kvl3Btyv4dgXfrttAfQfqO1DfgfoO1Hci70TeibwT9Z2o70R9J+pb/JVuxV/pVvtNaKv9Jl66rjP4dgXfruDbFXy7tuq3ays/qK38oLbyg9rKD2pryNuQtyFv9du1Vb9dW/FX2oq/0lb8lbbir7TVfhPaar8JBd+u4NsVfLuCb1fw7dqq366t/KC28oPayg9qKz+oTZBXkFeQt/rt2qrfrq34K23FX2kr/kpb8Vfaar8JbbXfhIJvV/DtCr5dwbcr+HZtivoq6muor6G+hvoa8hryGvIa6muor6G+hvoWf6Wt+Ctttd+EttpvQsG3K/h2Bd+u4NsVfLs2R30D9Q3UN1DfQH0DeQN5A3kD9Q3UN1DfgfoWf6Wt+Ctttd+EttpvQsG3K/h2Bd+u4NsVfLu2ifpO1HeivhP1najvRN6JvBN5J+pb/XbtxV9pL/5Ke/FX2ou/0l77TWiv/SYUfLuCb1fw7Qq+XcG3a69+u/byg9rLD2ovP6i9/KD2hrwNeRvyVr9de/XbtRd/pb34K+3FX2kv/kp77TehvfabUPDtCr5dwbcr+HYF3669+u3ayw9qLz+ovfyg9vKD2gV5BXkFeRX1VdRXUV9FfYu/0l78lfbab0J77Teh4NsVfLuCb1fw7Qq+Xbuhvob6GuprqK+hvoa8hryOvI76OurrqK+jvsVfaS/+SnvtN6G99ptQ8O0Kvl3Btyv4dgXfrj1Q30B9A/UN1DdQ30DegbwDeQfqO1DfgfoO1Lf4K+3FX2mv/Sa0134TCr5dwbcr+HYF367g27VP1HeivhP1nagv/KDADwr8oMAPSvXbVarfrlL8lUrxVyrFX6kUf6VS+02o1H4TCr5dwbcr+HYF367g21Wq364CPyjwgwI/KPCDAj8o8IMCPyjVb1epfrtK8VcqxV+pFH+lUvyVSu03oVL7TSj4dgXfruDbFXy7gm9XqX67CvygwA8K/KDADwr8oMAPCvygKOqrqK+ivor6Fn+lUvyVSu03oVL7TSj4dgXfruDbFXy7gm9XMdQXflDgBwV+UOAHBX5Q4AcFflAc9XXU11FfR32Lv1Ip/kql9ptQqf0mFHy7gm9X8O0Kvl3Bt6sE6gs/KPCDAj8o8IMCPyjwgwI/KAP1HajvQH0n6lv8lUrxVyq134RK7Teh4NsVfLuCb1fw7Qq+XbX67arwgwo/qPCDCj+o8IMKP6jwg1r9dtXqt6sWf6Va/JVq8VeqxV+p1n4TqrXfhIJvV/DtCr5dwbcr+HbV6rerwg8q/KDCDyr8oMIPKvygwg9q9dtVq9+uWvyVavFXqsVfqRZ/pVr7TajWfhMKvl3Btyv4dgXfruDbVRX1hR9U+EGFH1T4QYUfVPhBhR9UQ30N9TXU11Df4q9Ui79Srf0mVGu/CQXfruDbFXy7gm9X8O2qjvrCDyr8oMIPKvygwg8q/KDCD2qgvoH6BuobqG/xV6rFX6nWfhOqtd+Egm9X8O0Kvl3Btyv4dtWB+sIPKvygwg8q/KDCDyr8oMIP6kR9J+o7Ud+J+hZ/pVr8lWrtN6Fa+00o+HYF367g2xV8u4JvV0O/3eAHDX7Q4AcNftDgBw1+0OAHDf12Q7/dir9SK/5KrfgrteKv1Gq/CbXab0LBtyv4dgXfruDbFXy7GvrtBj9o8IMGP2jwgwY/aPCDBj9o6Lcb+u1W/JVa8VdqxV+pFX+lVvtNqNV+Ewq+XcG3K/h2Bd+u4NvV0G83+EGDHzT4QYMfNPhBgx80+EFDv93QbzdDfQ31Lf5KrfgrtdpvQq32m1Dw7Qq+XcG3K/h2Bd+uhn67wQ8a/KDBDxr8oMEPGvygwQ8a+u2GfrsF6huob/FXasVfqdV+E2q134SCb1fw7Qq+XcG3K/h2NfTbDX7Q4AcNftDgBw1+0OAHDX7Q0G839Nut+Cv14q/Ui79SL/5KvfabUK/9JhR8u4JvV/DtCr5dwbero9/u8IMOP+jwgw4/6PCDDj/o8IOOfruj3+7FX6kXf6Ve/JV68Vfqtd+Eeu03oeDbFXy7gm9X8O0Kvl0d/XaHH3T4QYcfdPhBhx90+EGHH3T02x39dlfUV1Hf4q/Ui79Sr/0m1Gu/CQXfruDbFXy7gm9X8O3q6Lc7/KDDDzr8oMMPOvygww86/KCj3+7ot7ujvo76Fn+lXvyVeu03oV77TSj4dgXfruDbFXy7gm9XR7/d4QcdftDhBx1+0OEHHX7Q4Qcd/XZHv90H6jtQ3+Kv1Iu/Uq/9JtRrvwkF367g2xV8u4JvV/Dt6ui3O/ygww86/KDDDzr8YMAPBvxgoN8e6LdH8VcaxV9pFH+lUfyVRu03oVH7TSj4dgXfruDbFXy7gm/XQL894AcDfjDgBwN+MOAHA34w4AcD/fZAvz2Kv9Io/kqj+CuN4q80ar8JjdpvQsG3K/h2Bd+u4NsVfLsG+u0BPxjwgwE/GPCDAT8Y8IMBPxjotwf67aGor6K+xV9pFH+lUftNaNR+Ewq+XcG3K/h2Bd+u4Ns10G8P+MGAHwz4wYAfDPjBgB8M+MFAvz3Qbw9HfR31Lf5Ko/grjdpvQqP2m1Dw7Qq+XcG3K/h2Bd+ugX57wA8G/GDADwb8YMAPBvxgwA8G+u2BfnsM1HegvsVfaRR/pVH7TWjUfhMKvl3Btyv4dgXfruDbNdBvH/CDA35wwA8O+MEBPzjgBwf84EC/faDfPsBfDfBXA/zVAH81ar8JHbXfhIJvV/DtCr5dwbcr+HYd6LcP+MEBPzjgBwf84IAfHPCDA35woN8+0G8f4K8G+KsB/mqAvxq134SO2m9Cwbcr+HYF367g2xV8uw702wf84IAfHPCDA35wwA8O+MEBPzjQbx/otw/wVwP81QB/NcBfjdpvQkftN6Hg2xV8u4JvV/DtCr5dB/rtA35wwA8O+MEBPzjgBwf84IAfHOi3D/TbB/irAf5qgL8a4K9G7Teho/abUPDtCr5dwbcr+HYF364D/fYBPzjgBwf84IAfHPCDA35wwA8O9NsH+u0D/NUAfzXAXw3wV6P2m9BR+00o+HYF367g2xV8u4Jv14l++4QfnPCDE35wwg9O+MEJPzjhByf67RP99gn+aoK/muCvJvirWftN6Kz9JhR8u4JvV/DtCr5dwbfrRL99wg9O+MEJPzjhByf84IQfnPCDE/32iX77BH81wV9N8FcT/NWs/SZ01n4TCr5dwbcr+HYF367g23Wi3z7hByf84IQfnPCDE35wwg9O+MGJfvtEv32Cv5rgryb4qwn+atZ+EzprvwkF367g2xV8u4JvV/DtOtFvn/CDE35wwg9O+MEJPzjhByf84ES/faLfPsFfTfBXE/zVBH81a78JnbXfhIJvV/DtCr5dwbcr+Had6LdP+MEJPzjhByf84IQfnPCDE35wot8+0W+f4K9m8Ve2FX9lW/FXL53zupfOeZ2Bbzfw7Qa+3cC3G/j2l56lyw/aVn7QtvKDtpUftK0hb0PehrzVb7et+u22FX9lW/FXthV/ZVvxV7bVfhO21X4TBr7dwLcb+HYD327g222rfrtt5QdtKz9oW/lB28oP2ibIK8gryFv9dtsE9VXUV1Hf4q9sK/7Kttpvwrbab8LAtxv4dgPfbuDbDXy7bYb6GuprqK+hvob6GvIa8hryGurrqK+jvo76Fn9lW/FXttV+E7bVfhMGvt3Atxv4dgPfbuDbbQvUN1DfQH0D9Q3UN5A3kDeQd6C+A/UdqO9AfYu/sq34K9tqvwnbar8JA99u4NsNfLuBbzfw7bZN1HeivhP1najvRH0n8pYffL2m26Crvq367daKv7JW/JW14q+sFX9lrfabsFb7TRj4dgPfbuDbDXy7gW+3Vv12a+UHrZUftFZ+0Fr5QWsNeTvyduStfru16rdbK/7KWvFX1oq/slb8lbXab8Ja7Tdh4NsNfLuBbzfw7Qa+3Vr1262VH7RWftBa+UFrgvoq8iryKvIq6quor6K+ivoWf2Wt+Ctrtd+EtdpvwsC3G/h2A99u4NsNfLs1Q30N9TXU11BfR30deR15HXkd9XXU11FfR32Lv7JW/JW12m/CWu03YeDbDXy7gW838O0Gvt1aoL6B+gbqO1DfgfoO5B3IO5B3oL4D9R2o70B9i7+yVvyVtdpvwlrtN2Hg2w18u4FvN/DtBr7d2kR9yw9aLz9ovfyg9fKD1ssPWi8/aL38oPXqt1uvfrv14q+sF39lvfgr68VfWa/9JqzXfhMGvt3Atxv4dgPfbuDbrVe/3Xr5QevlB62XH7ReftB6R96OvB15q99uvfrt1ou/sl78lfXir6wXf2W99puwXvtNGPh2A99u4NsNfLuBb7euqK+ivor6KuqrqK8iryKvIq+ivor6GuprqG/xV9aLv7Je+01Yr/0mDHy7gW838O0Gvt3At1t31NdRX0d9HfV11NeR15HXkddR30B9A/UN1Lf4K+vFX1mv/Sas134TBr7dwLcb+HYD327g260P1HegvgP1HajvQH0H8g7kHcg7Ud+J+k7Ud6K+xV9ZL/7Keu03Yb32mzDw7Qa+3cC3G/h2A99uUv12E/hBgR8U+EGBHxT4QYEfFPhBqX67SfXbTYq/Min+yqT4K5Pir0xqvwmT2m/CwLcb+HYD327g2w18u0n1203gBwV+UOAHBX5Q4AcFflDgB6X67SbVbzcp/sqk+CuT4q9Mir8yqf0mTGq/CQPfbuDbDXy7gW838O0mivrCDwr8oMAPCvygwA8K/KDAD4qhvob6GuprqG/xVybFX5nUfhMmtd+EgW838O0Gvt3Atxv4dhNHfeEHBX5Q4AcFflDgBwV+UOAHJVDfQH0D9Q3Ut/grk+KvTGq/CZPab8LAtxv4dgPfbuDbDXy7yUB94QcFflDgBwV+UOAHBX5Q4Adlor4T9Z2o70R9i78yLf7KtPabMK39Jgx8u4FvN/DtBr7dwLebVr/dFH5Q4QcVflDhBxV+UOEHFX5Qq99uWv120+KvTIu/Mi3+yrT4K9Pab8K09psw8O0Gvt3Atxv4dgPfblr9dlP4QYUfVPhBhR9U+EGFH1T4Qa1+u2n1200F9VXUt/gr0+KvTGu/CdPab8LAtxv4dgPfbuDbDXy7qaG+8IMKP6jwgwo/qPCDCj+o8INqqK+hvo76Oupb/JVp8Vemtd+Eae03YeDbDXy7gW838O0Gvt00UF/4QYUfVPhBhR9U+EGFH1T4QQ3Ud6C+A/UdqG/xV6bFX5nWfhOmtd+EgW838O0Gvt3Atxv4dtOJ+sIPKvygwg8q/KDCDyr8oMIPGvrthn67FX9lVvyVWfFXZsVfmdV+E2a134SBbzfw7Qa+3cC3G/h2M/TbDX7Q4AcNftDgBw1+0OAHDX7Q0G839Nut+Cuz4q/Mir8yK/7KrPabMKv9Jgx8u4FvN/DtBr7dwLebod9u8IMGP2jwgwY/aPCDBj9o8IOGfruh326K+irqW/yVWfFXZrXfhFntN2Hg2w18u4FvN/DtBr7dDP12gx80+EGDHzT4QYMfNPhBgx809NsN/XZz1NdR3+KvzIq/Mqv9JsxqvwkD327g2w18u4FvN/DtZui3G/ygwQ8a/KDBDxr8oMEPGvygod9u6LfbQH0H6lv8lVnxV2a134RZ7Tdh4NsNfLuBbzfw7Qa+3Qz9doMfNPhBhx90+EGHH3T4QYcfdPTbHf12L/7KvPgr8+KvzIu/Mq/9JsxrvwkD327g2w18u4FvN/Dt5ui3O/ygww86/KDDDzr8oMMPOvygo9/u6Ld78VfmxV+ZF39lXvyVee03YV77TRj4dgPfbuDbDXy7gW83R7/d4QcdftDhBx1+0OEHHX7Q4Qcd/XZHv90V9TXUt/gr8+KvzGu/CfPab8LAtxv4dgPfbuDbDXy7OfrtDj/o8IMOP+jwgw4/6PCDDj/o6Lc7+u0eqG+gvsVfmRd/ZV77TZjXfhMGvt3Atxv4dgPfbuDbzdFvd/hBhx90+EGHH3T4QYcfdPhBR7/d0W/3ifpO1Lf4K/Pir8xrvwnz2m/CwLcb+HYD327g2w18uwX67QE/GPCDAT8Y8IMBPxjwgwE/GOi3B/rtUfyVRfFXFsVfWRR/ZVH7TVjUfhMGvt3Atxv4dgPfbuDbLdBvD/jBgB8M+MGAHwz4wYAfDPjBQL890G+P4q8sir+yKP7Kovgri9pvwqL2mzDw7Qa+3cC3G/h2A99ugX57wA8G/GDADwb8YMAPBvxgwA8G+u2BfnsY6muob/FXFsVfWdR+Exa134SBbzfw7Qa+3cC3G/h2C/TbA34w4AcDfjDgBwN+MOAHA34w0G8P9NsjUN9AfYu/sij+yqL2m7Co/SYMfLuBbzfw7Qa+3cC3W6DfHvCDAT8Y8IMBPxjwgwE/GPCDgX57oN8eE/WdqG/xVxbgr0btN2Gj9psw8O0Gvt3Atxv4dgPfbgP99gE/OOAHB/zggB8c8IMDfnDADw702wf67QP81QB/NcBfDfBXo/absFH7TRj4dgPfbuDbDXy7gW+3gX77gB8c8IMDfnDADw74wQE/OOAHB/rtA/32Af5qgL8a4K8G+KtR+03YqP0mDHy7gW838O0Gvt3At9tAv33ADw74wQE/OOAHB/zggB8c8IMD/faBfvsAfzXAXw3wVwP81aj9JmzUfhMGvt3Atxv4dgPfbuDbbaDfPuAHB/zggB8c8IMDfnDADw74wYF++0C/fYC/GuCvBvirAf5q1H4TNmq/CQPfbuDbDXy7gW838O020G8f8IMDfnDADw74wQE/OOAHB/zgQL99ot8+wV9N8FcT/NUEfzVrvwmbtd+EgW838O0Gvt3Atxv4dpvot0/4wQk/OOEHJ/zghB+c8IMTfnCi3z7Rb5/gryb4qwn+aoK/mrXfhM3ab8LAtxv4dgPfbuDbDXy7TfTbJ/zghB+c8IMTfnDCD074wQk/ONFvn+i3T/BXE/zVBH81wV/N2m/CZu03YeDbDXy7gW838O0Gvt0m+u0TfnDCD074wQk/OOEHJ/zghB+c6LdP9Nsn+KsJ/mqCv5rgr2btN2Gz9psw8O0Gvt3Atxv4dgPfbhP99gk/OOEHJ/zghB+c8IMTfnDCD0702yf67RP81QR/NcFfTfBXs/absFn7TRj4dgPfbuDbDXy7gW+3iX77hB+c8IOz/KBv5Qd9Kz/40h1aoLO+vlW/3bfir3wr/sq34q9eepau/SZ8q/0mHHy7g2938O0Ovt3Bt/tW/Xbfyg/6Vn7Qt/KDvpUf9K0jb0fejrzVb/et+u2+FX/lW/FXvhV/5VvxV77VfhO+1X4TDr7dwbc7+HYH3+7g232rfrtvgvoq6quor6K+iryKvIq8ivoq6quor6K+xV/5VvyVb7XfhG+134SDb3fw7Q6+3cG3O/h23wz1ddTXUV9HfR31deR15HXkddTXUV9HfQP1Lf7Kt+KvfKv9Jnyr/SYcfLuDb3fw7Q6+3cG3+zZQ34H6DtR3oL4D9R3IO5B3IO9AfQfqO1HfifoWf+Vb8Ve+1X4TvtV+Ew6+3cG3O/h2B9/+antv0A26Qwu0Qhu0Qwf0gK76tuq3eyv+ylvxV96Kv/JW/JW32m/CW+034eDbHXy7g2938O0Ovt1b9du9lR/0Vn7QW/lBb+UHvXXk7cjbkbf67d6q3+6t+CtvxV95K/7KW/FX3mq/CW+134SDb3fw7Q6+3cG3O/h2b4r6KuqrqK+ivor6KvIq8hryGuprqK+hvob6Fn/lrfgrb7XfhLfab8LBtzv4dgff7uDbHXy7N0d9HfV11NdRX0d9HXkDeQN5A/UN1DdQ30B9i7/yVvyVt9pvwlvtN+Hg2x18u4Nvd/DtDr7d20B9B+o7UN+B+g7UdyLvRN6JvBP1najvRH0n6lv8lbfir7zVfhPea78JB9/u4NsdfLuDb3fw7d6r3+69/KD38oPeyw96Lz/ovSFvQ96GvNVv9179du/FX3kv/sp78Vfei7/yXvtNeK/9Jhx8u4Nvd/DtDr7dwbd7r3679/KD3ssPei8/6L38oHdBXkFeQd7qt3uvfrv34q+8F3/lvfgr78Vfea/9JrzXfhMOvt3Btzv4dgff7uDbvSvqq6ivob6G+hrqa8hryGvIa6ivob6G+hrqW/yV9+KvvNd+E95rvwkH3+7g2x18u4Nvd/Dt3h31DdQ3UN9AfQP1DeQN5A3kDdQ3UN9AfQfqW/yV9+KvvNd+E95rvwkH3+7g2x18u4Nvd/Dt3ifqO1HfifpO1HeivhN5J/JO5J2ob/XbXYq/cin+yqX4K5fir1xqvwmX2m/Cwbc7+HYH3+7g2x18u0v1213gBwV+UOAHBX5Q4AcFflDgB6X67S7Vb3cp/sql+CuX4q9cir9yqf0mXGq/CQff7uDbHXy7g2938O0u1W93gR8U+EGBHxT4QYEfFPhBgR8URX0V9VXUV1Hf4q9cir9yqf0mXGq/CQff7uDbHXy7g2938O0uhvrCDwr8oMAPCvygwA8K/KDAD4qjvo76OurrqG/xVy7FX7nUfhMutd+Eg2938O0Ovt3Btzv4dpdAfeEHBX5Q4AcFflDgBwV+UOAHZaC+A/UdqO9AfYu/cin+yqX2m3Cp/SYcfLuDb3fw7Q6+3cG3u0zUF35Q4AcFflDgBxV+UOEHFX5Qq9/uWv121+KvXIu/ci3+yrX4K9fab8K19ptw8O0Ovt3Btzv4dgff7lr9dlf4QYUfVPhBhR9U+EGFH1T4Qa1+u2v1212Lv3It/sq1+CvX4q9ca78J19pvwsG3O/h2B9/u4NsdfLtr9dtd4QcVflDhBxV+UOEHFX5Q4QdVUV9FfRX1VdS3+CvX4q9ca78J19pvwsG3O/h2B9/u4NsdfLurob7wgwo/qPCDCj+o8IMKP6jwg+qor6O+jvo66lv8lWvxV66134Rr7Tfh4NsdfLuDb3fw7Q6+3TVQX/hBhR9U+EGFH1T4QYUfVPhBHajvQH0H6jtR3+KvXIu/cq39JlxrvwkH3+7g2x18u4Nvd/Dtbui3G/ygwQ8a/KDBDxr8oMEPGvygod9u6Ldb8VduxV+5FX/lVvyVW+034Vb7TTj4dgff7uDbHXy7g293Q7/d4AcNftDgBw1+0OAHDX7Q4AcN/XZDv92Kv3Ir/sqt+Cu34q/car8Jt9pvwsG3O/h2B9/u4NsdfLsb+u0GP2jwgwY/aPCDBj9o8IMGP2jotxv67Waor6G+xV+5FX/lVvtNuNV+Ew6+3cG3O/h2B9/u4Nvd0G83+EGDHzT4QYMfNPhBgx80+EFDv93Qb7dAfQP1Lf7Krfgrt9pvwq32m3Dw7Q6+3cG3O/h2B9/uhn67wQ8a/KDBDxr8oMEPGvygwQ8a+u2GfrtN1HeivsVfuRV/5Vb7TbjVfhMOvt3Btzv4dgff7uDb3dFvd/hBhx90+EGHH3T4QYcfdPhBR7/d0W/34q/ci79yL/7Kvfgr99pvwr32m3Dw7Q6+3cG3O/h2B9/ujn67ww86/KDDDzr8oMMPOvygww86+u2OfrsXf+Ve/JV78VfuxV+5134T7rXfhINvd/DtDr7dwbc7+HZ39NsdftDhBx1+0OEHHX7Q4QcdftDRb3f0291QX0N9i79yL/7KvfabcK/9Jhx8u4Nvd/DtDr7dwbe7o9/u8IMOP+jwgw4/6PCDDj/o8IOOfruj3+6B+gbqW/yVe/FX7rXfhHvtN+Hg2x18u4Nvd/DtDr7dHf12hx90+EGHH3T4QYcfdPhBhx909Nsd/XYv/sqj+CuP4q88ir/yqP0mPGq/CQff7uDbHXy7g2938O0e6LcH/GDADwb8YMAPBvxgwA8G/GCg3x7ot0fxVx7FX3kUf+VR/JVH7TfhUftNOPh2B9/u4NsdfLuDb/dAvz3gBwN+MOAHA34w4AcDfjDgBwP99kC/PRT1VdS3+CuP4q88ar8Jj9pvwsG3O/h2B9/u4NsdfLsH+u0BPxjwgwE/GPCDAT8Y8IMBPxjotwf67eGor6O+xV95FH/lUftNeNR+Ew6+3cG3O/h2B9/u4Ns90G8P+MGAHwz4wYAfDPjBgB8M+MFAvz3Qb4+B+g7Ut/grj+KvPGq/CY/ab8LBtzv4dgff7uDbHXy7B/rtAT8Y8IMBPxjwgwE/OOAHB/zgQL99oN8+wF8N8FcD/NUAfzVqvwkftd+Eg2938O0Ovt3Btzv4dh/otw/4wQE/OOAHB/zggB8c8IMDfnCg3z7Qbx/grwb4qwH+aoC/GrXfhI/ab8LBtzv4dgff7uDbHXy7D/TbB/zggB8c8IMDfnDADw74wQE/ONBvH+i3D/BXA/zVAH81wF+N2m/CR+034eDbHXy7g2938O0Ovt0H+u0DfnDADw74wQE/OOAHB/zggB8c6LcP9NsH+KsB/mqAvxrgr0btN+Gj9ptw8O0Ovt3Btzv4dgff7gP99gE/OOAHB/zggB8c8IMDfnDADw702wf67QP81QB/NcBfDfBXo/ab8FH7TTj4dgff7uDbHXy7g2/3gX77hB+c8IMTfnDCD074wQk/OOEHJ/rtE/32Cf5qgr+a4K8m+KtZ+034rP0mHHy7g2938O0Ovt3Bt/tEv33CD074wQk/OOEHJ/zghB+c8IMT/faJfvsEfzXBX03wVxP81az9JnzWfhMOvt3Btzv4dgff7uDbfaLfPuEHJ/zghB+c8IMTfnDCD074wYl++0S/fYK/muCvJvirCf5q1n4TPmu/CQff7uDbHXy7g2938O0+0W+f8IMTfnDCD074wQk/OOEHJ/zgRL99ot8+wV9N8FcT/NUEfzVrvwmftd+Eg2938O0Ovt3Btzv4dp/ot0/4wQk/OOEHJ/zghB+c8IMTfnCi3z7Rb5/gryb4qwn+aoK/mrXfhM/ab8LBtwf49gDf/tIdWqAV2qAdOqAHNPI25G3IW/322KrfHlvxV7EVfxVb8VexFX8VW+03EVvtNxHg2wN8e4BvD/DtAb49tuq3x1Z+MLbyg7GVH4yt/GBsgryCvIK81W+PrfrtsRV/FVvxV7EVfxVb8Vex1X4TsdV+EwG+PcC3B/j2AN8e4NtjU9RXUV9FfRX1NdTXkNeQ15DXUF9DfQ31NdS3+KvYir+KrfabiK32mwjw7QG+PcC3B/j2AN8em6O+jvo66huob6C+gbyBvIG8gfoG6huob6C+xV/FVvxVbLXfRGy130SAbw/w7QG+PcC3B/j22AbqO1DfifpO1HeivhN5J/JO5J2o70R9J+pb/NWrjbRBN+ic10Wr/SYCfHuAbw/w7QG+PcC3R6t+e7Tyg9HKD0YrPxit/GC0hrwNeRvyVr89WvXboxV/Fa34q2jFX0Ur/ipa7TcRrfabCPDtAb49wLcH+PYA3x6t+u3Ryg9GKz8YrfxgtPKD0QR5BXkFeavfHk1QX0V9FfUt/ipa8VfRar+JaLXfRIBvD/DtAb49wLcH+PZohvoa6muor6G+hvoa8hryGvIa6uuor6O+jvoWfxWt+Ktotd9EtNpvIsC3B/j2AN8e4NsDfHu0QH0D9Q3UN1DfQH0DeQN5A3kH6jtQ34H6DtS3+KtoxV9Fq/0motV+EwG+PcC3B/j2AN8e4NujTdR3or4T9Z2o70R9J/KWH4xefjB69dujV789evFX0Yu/il78VfTir6LXfhPRa7+JAN8e4NsDfHuAbw/w7dGr3x69/GD08oPRyw9GLz8YvSFvR96OvNVvj1799ujFX0Uv/ip68VfRi7+KXvtNRK/9JgJ8e4BvD/DtAb49wLdHr3579PKD0csPRi8/GF1QX0VeRV5FXkV9FfVV1FdR3+Kvohd/Fb32m4he+00E+PYA3x7g2wN8e4Bvj26or6G+hvoa6uuoryOvI68jr6O+jvo66uuob/FX0Yu/il77TUSv/SYCfHuAbw/w7QG+PcC3Rw/UN1DfQH0H6jtQ34G8A3kH8g7Ud6C+A/UdqG/xV9GLv4pe+01Er/0mAnx7gG8P8O0Bvj3At0efqC/8oMAPCvygwA8K/KDADwr8oFS/PaT67SHFX4UUfxVS/FVI8Vchtd9ESO03EeDbA3x7gG8P8O0Bvj2k+u0h8IMCPyjwgwI/KPCDAj8o8INS/faQ6reHFH8VUvxVSPFXIcVfhdR+EyG130SAbw/w7QG+PcC3B/j2EEV94QcFflDgBwV+UOAHBX5Q4AdFUV9FfQ31NdS3+KuQ4q9Car+JkNpvIsC3B/j2AN8e4NsDfHuIo77wgwI/KPCDAj8o8IMCPyjwg+Kob6C+gfoG6lv8VUjxVyG130RI7TcR4NsDfHuAbw/w7QG+PWSgvvCDAj8o8IMCPyjwgwI/KPCDMlHfifpO1HeivsVfhRR/FVL7TYTUfhMBvj3Atwf49gDfHuDbQ6vfHgo/qPCDCj+o8IMKP6jwgwo/qNVvD61+e2jxV6HFX4UWfxVa/FVo7TcRWvtNBPj2AN8e4NsDfHuAbw+tfnso/KDCDyr8oMIPKvygwg8q/KBWvz20+u2hxV+FFn8VWvxVaPFXobXfRGjtNxHg2wN8e4BvD/DtAb49VFFf+EGFH1T4QYUfVPhBhR9U+EE11NdQX0N9DfUt/iq0+KvQ2m8itPabCPDtAb49wLcH+PYA3x7qqC/8oMIPKvygwg8q/KDCDyr8oAbqG6hvoL6B+hZ/FVr8VWjtNxFa+00E+PYA3x7g2wN8e4BvDx2oL/ygwg8q/KDCDyr8oMIPKvygTtR3or4T9Z2ob/FXYcVfhdV+E2G130SAbw/w7QG+PcC3B/j2MPTbDX7Q4AcNftDgBw1+0OAHDX7Q0G839Nut+Kuw4q/Cir8KK/4qrPabCKv9JgJ8e4BvD/DtAb49wLeHod9u8IMGP2jwgwY/aPCDBj9o8IOGfruh326C+irqW/xVWPFXYbXfRFjtNxHg2wN8e4BvD/DtAb49DP12gx80+EGDHzT4QYMfNPhBgx809NsN/XZz1NdR3+Kvwoq/Cqv9JsJqv4kA3x7g2wN8e4BvD/DtYei3G/ygwQ8a/KDBDxr8oMEPGvygod9u6LfbQH0H6lv8VVjxV2G130RY7TcR4NsDfHuAbw/w7QG+PQz9doMfNPhBgx80+EGDHzT4QYMfdPTbHf12L/4qvPir8OKvwou/Cq/9JsJrv4kA3x7g2wN8e4BvD/Dt4ei3O/ygww86/KDDDzr8oMMPOvygo9/u6Ld78VfhxV+FF38VXvxVeO03EV77TQT49gDfHuDbA3x7gG8PR7/d4QcdftDhBx1+0OEHHX7Q4Qcd/XZHv90V9VXUt/ir8OKvwmu/ifDabyLAtwf49gDfHuDbA3x7OPrtDj/o8IMOP+jwgw4/6PCDDj/o6Lc7+u3uqK+jvsVfhRd/FV77TYTXfhMBvj3Atwf49gDfHuDbw9Fvd/hBhx90+EGHH3T4QYcfdPhBR7/d0W/3gfoO1Lf4q/Dir8Jrv4nw2m8iwLcH+PYA3x7g2wN8ezj67Q4/6PCDAT8Y8IMBPxjwgwE/GOi3B/rtUfxVRPFXEcVfRRR/FVH7TUTUfhMBvj3Atwf49gDfHuDbI9BvD/jBgB8M+MGAHwz4wYAfDPjBQL890G+P4q8iir+KKP4qoviriNpvIqL2mwjw7QG+PcC3B/j2AN8egX57wA8G/GDADwb8YMAPBvxgwA8G+u2Bfnso6muob/FXEcVfRdR+ExG130SAbw/w7QG+PcC3B/j2CPTbA34w4AcDfjDgBwN+MOAHA34w0G8P9NsjUN9AfYu/iij+KqL2m4io/SYCfHuAbw/w7QG+PcC3R6DfHvCDAT8Y8IMBPxjwgwE/GPCDgX57oN8eE/WdqG/xVxHFX0XUfhMRtd9EgG8P8O0Bvj3Atwf49hjotw/4wQE/OOAHB/zggB8c8IMDfnCg3z7Qbx/grwb4qwH+aoC/GrXfRIzabyLAtwf49gDfHuDbA3x7DPTbB/zggB8c8IMDfnDADw74wQE/ONBvH+i3D/BXA/zVAH81wF+N2m8iRu03EeDbA3x7gG8P8O0Bvj0G+u0DfnDADw74wQE/OOAHB/zggB8c6LcP9NsH+KsB/mqAvxrgr0btNxGj9psI8O0Bvj3Atwf49gDfHgP99gE/OOAHB/zggB8c8IMDfnDADw702wf67QP81QB/NcBfDfBXo/abiFH7TQT49gDfHuDbA3x7gG+PgX77gB8c8IMDfnDADw74wQE/OOAHB/rtA/32Af5qgL8a4K8G+KtZ+03ErP0mAnx7gG8P8O0Bvj3At8dEv33CD074wQk/OOEHJ/zghB+c8IMT/faJfvsEfzXBX03wVxP81az9JmLWfhMBvj3Atwf49gDfHuDbY6LfPuEHJ/zghB+c8IMTfnDCD074wYl++0S/fYK/muCvJvirCf5q1n4TMWu/iQDfHuDbA3x7gG8P8O0x0W+f8IMTfnDCD074wQk/OOEHJ/zgRL99ot8+wV9N8FcT/NUEfzVrv4mYtd9EgG8P8O0Bvj3Atwf49pjot0/4wQk/OOEHJ/zghB+c8IMTfnCi3z7Rb5/gryb4qwn+aoK/mrXfRMzabyLAtwf49gDfHuDbA3x7TPTbJ/zghB+c8IMTfnDCD074wQk/OKvfPrbqt4+t+KuX7tACrdA5rxtb7TcxwLcP8O0vPUtXv32Abx9b9dvHVn5wbOUHx1Z+cGzlB8fWkLchb0Pe6rePrfrtYyv+amzFX42t+KuxFX81ttpvYmy138QA3z7Atw/w7QN8+wDfPrbqt4+t/ODYyg+Orfzg2MoPjk2QV5BXkVdRX0V9FfVV1Lf4q7EVfzW22m9ibLXfxADfPsC3D/Dt4//L1J1lu5HlSBSdEm+Dbv4Ty9RzBn3/ZAkrKkSE3B6F4zBbwN/e+Nv7Ezzf4PkGzzd4vsHzDT43+dzkc5Pnmzzf5Pkmz/f1X/Xn9V/157030Z/33kTjb2/87Y2/vfG3N/72/hTPt3i+xfMtnm/xfJvPbT63+dzm+TbPt3m+zfN9/Vf9ef1X/XnvTfTnvTfR+Nsbf3vjb2/87Y2/vT/D8x2e7/B8Xx78P5Z9+PXi15tfH379Pt/1vm/v9fqver3+q16v/6rX67/q9d6b6PXem2j87Y2/vfG3N/72xt/e633f3uvlwV4vD/Z6ebDXy4O9Np+7+dzN577v23u979t7vf6rXq//qtfrv+r1+q96vfcmer33Jhp/e+Nvb/ztjb+98bf3et+39zo838vzvTzfy/O9fO7lcy+fe3m+l+d7eb6X5/v6r3q9/qte772JXu+9icbf3vjbG397429v/O29guebPN/k+SbPN3m+yecmn5t8bvJ8k+ebPN/i+b7+q16v/6rXe2+i13tvovG3N/72xt/e+Nsbf3uv5vk2z7d5vs3zbZ5v87nN5zaf2zzf5vkOz3d4vq//qtfrv+r13pvo9d6baPztjb+98bc3/vbG3977fd/e++XB3i8P9n55sPfLg71fHuz98mDvlwd7v+/be7/v23u//qver/+q9+u/6v36r3q/9yZ6v/cmGn97429v/O2Nv73xt/d+37f3fnmw98uDvV8e7P3yYO/N524+d/O57/v23u/79t6v/6r367/q/fqver/+q97vvYne772Jxt/e+Nsbf3vjb2/87b0vz/fyfC/P9/J8L8/38rmXzw0+N3i+wfMNnm/wfF//Ve/Xf9X7vTfR+7030fjbG397429v/O2Nv7138nyT55s83+T5Js83+dzic4vPLZ5v8XyL51s839d/1fv1X/V+7030fu9NNP72xt/e+Nsbf3vjb+/dPN/m+TbPt3m+zfMdPnf43OFzh+c7PN/h+Q7P9/Vf9X79V73fexN93nsTjb+98bc3/vbG39742/u879v7wIMHHjzw4IEHDzx44MEDD573fXuf9317n9d/1ef1X/V5/Vd9Xv9Vn/feRJ/33kTjb2/87Y2/vfG3N/72Pu/79j7w4IEHDzx44MEDDx548MCD533f3ud9397n9V/1ef1XfV7/VZ/Xf9XnvTfR57030fjbG397429v/O2Nv73P5fnCgwcePPDggQcPPHjgwQMPnuD5Bs83eL7B8339V31e/1Wf995En/feRONvb/ztjb+98bc3/vY+yfOFBw88eODBAw8eePDAgwcePMXzLZ5v8Xyb5/v6r/q8/qs+772JPu+9icbf3vjbG397429v/O19hucLDx548MCDBx488OCBBw88eIbn+75v7/v6r/q+/qu+r/+q7+u/6vvem+j73pto/O2Nv73xtzf+9sbf3vd9394XHrzw4IUHLzx44cELD1548L7v2/u+79v7vv6rvq//qu/rv+r7+q/6vvcm+r73Jhp/e+Nvb/ztjb+98bf3fd+394UHLzx44cELD1548MKDFx68l+d7eb6X53t5vq//qu/rv+r73pvo+96baPztjb+98bc3/vbG3943eL7w4IUHLzx44cELD1548MKDN3m+yfNNnm/yfF//Vd/Xf9X3vTfR97030fjbG397429v/O2Nv71v8XzhwQsPXnjwwoMXHrzw4IUHb/N8m+fbPN/m+b7+q76v/6rve2+i73tvovG3N/72xt/e+Nsbf3vf4fnCgxcevPDghQcDHgx4MODB4H178L49Xv9Vx+u/6nj9Vx2v/6rjvTfR8d6baPztjb+98bc3/vbG397B+/aABwMeDHgw4MGABwMeDHgweN8evG+P13/V8fqvOl7/Vcfrv+p47010vPcmGn97429v/O2Nv73xt3fwvj3gwYAHAx4MeDDgwYAHAx4M3rcH79vj8nwvz/f1X3W8/quO995Ex3tvovG3N/72xt/e+Nsbf3sH79sDHgx4MODBgAcDHgx4MODB4H178L49kuebPN/Xf9Xx+q863nsTHe+9icbf3vjbG397429v/O0dvG8PeDDgwYAHAx4MeDDgwYAHg/ftwfv2aJ7v8Hxf/1XH67/qeO9NdLz3Jhp/e+Nvb/ztjb+98bd38r494cGEBxMeTHgw4cGEBxMeTN63J+/b8/Vfdb7+q87Xf9X5+q8633sTne+9icbf3vjbG397429v/O2dvG9PeDDhwYQHEx5MeDDhwYQHk/ftyfv2fP1Xna//qvP1X3W+/qvO995E53tvovG3N/72xt/e+Nsbf3sn79sTHkx4MOHBhAcTHkx4MOHB5H178r49g+cbPN/Xf9X5+q8633sTne+9icbf3vjbG397429v/O2dvG9PeDDhwYQHEx5MeDDhwYQHk/ftyfv2LJ5v8Xxf/1Xn67/qfO9NdL73Jhp/e+Nvb/ztjb+98bd38r494cGEBxMeTHgw4cGEBxMeTN63J+/bc3i+w/N9/Vedr/+q87030fnem2j87Y2/vfG3N/72xt/exfv2ggcLHix4sODBggcLHix4sHjfXrxvr9d/1fX6r7pe/1XX67/qeu9NdL33Jhp/e+Nvb/ztjb+98bd38b694MGCBwseLHiw4MGCBwseLN63F+/b6/Vfdb3+q67Xf9X1+q+63nsTXe+9icbf3vjbG397429v/O1dvG8veLDgwYIHCx4seLDgwYIHi/ftxfv2Cp5v8Hxf/1XX67/qeu9NdL33Jhp/e+Nvb/ztjb+98bd38b694MGCBwseLHiw4MGCBwseLN63F+/bq3i+xfN9/Vddr/+q67030fXem2j87Y2/vfG3N/72xt/exfv2ggcLHix4sODBggcLHix4sHjfXrxvL/xXjf+q8V81/qt+7010v/cmGn97429v/O2Nv73xt3fzvr3hwYYHGx5seLDhwYYHGx5s3rc379sb/1Xjv2r8V43/qt97E93vvYnG39742xt/e+Nvb/zt3bxvb3iw4cGGBxsebHiw4cGGB5v37c379sZ/1fivGv9V47/q995E93tvovG3N/72xt/e+Nsbf3s379sbHmx4sOHBhgcbHmx4sOHB5n1787698V81/qvGf9X4r/q9N9H93pto/O2Nv73xtzf+9sbf3s379oYHGx5seLDhwYYHGx5seLB53968b2/8V43/qvFfNf6rfu9NdL/3Jhp/e+Nvb/ztjb+98bd387694cGGBxsebHiw4cGBBwceHN63D+/bB//V4L8a/FeD/2reexM9772Jxt/e+Nsbf3vjb2/87T28bx94cODBgQcHHhx4cODBgQeH9+3D+/bBfzX4rwb/1eC/mvfeRM97b6Lxtzf+9sbf3vjbG397D+/bBx4ceHDgwYEHBx4ceHDgweF9+/C+ffBfDf6rwX81+K/mvTfR896baPztjb+98bc3/vbG397D+/aBBwceHHhw4MGBBwceHHhweN8+vG8f/FeD/2rwXw3+q3nvTfS89yYaf3vjb2/87Y2/vfG39/C+feDBgQcHHhx4cODBgQcHHhzetw/v2wf/1eC/GvxXg/9q3nsTPe+9icbf3vjbG397429v/O097/v2+bw8OJ+XB///682vD7++/Dr4dfLr3/Odz/u+/f+/nvfXr/9qPq//aj6v/2o+772J+bz3JgZ/++BvH/ztg7998LfP533fPp+XB+fz8uB8Xh6cz8uD89l87uZzN5/7vm+fz/u+fT6v/2o+r/9qPq//aj6v/2o+772J+bz3JgZ/++BvH/ztg7998LfP5/J8L8/38nwvz/fyfC+fe/ncy+denm/wfIPnGzzf1381n9d/NZ/33sR83nsTg7998LcP/vbB3z742+eTPN/k+SbPN3m+yfNNPjf53ORzi+dbPN/i+RbP9/Vfzef1X83nvTcxn/fexOBvH/ztg7998LcP/vb5NM+3eb7N822eb/N8m89tPnf43OH5Ds93eL7D8339V/N5/Vfzee9NzOe9NzH42/8/5nz49eLXm18ffn35dfDr5NfFr5tf87mLz1187vu+fdb7vn3W67+a9fqvZr3+q1mv/2rWe29i1ntvYvC3D/72wd8++NsHf/us9337rJcHZ708OOvlwVkvD846fO7hcw+f+75vn/W+b5/1+q9mvf6rWa//atbrv5r13puY9d6bGPztg7998LcP/vbB3z7r8nwvz/fyfC/PN3i+wecGnxt8bvB8g+cbPN/g+b7+q1mv/2rWe29i1ntvYvC3D/72wd8++NsHf/us5Pkmzzd5vsXzLZ5v8bnF5xafWzzf4vkWz7d4vq//atbrv5r13puY9d6bGPztg7998LcP/vbB3z6reb7N8x2e7/B8h+c7fO7wucPnDs93eL7D8339V7Nf/9Xs1381+703Mfu9NzH42wd/++BvH/ztg7999vu+ffbLg7NfHpz98uDslwdnLz538bmLz33ft89+37fPfv1Xs1//1ezXfzX79V/Nfu9NzH7vTQz+9sHfPvjbB3/74G+f/b5vn/3y4OyXB2e/PDj75cHZh889fO7hc9/37bMPz/fyfC/P9/VfzX79V7PfexOz33sTg7998LcP/vbB3z7422cHzzd4vsHzDZ5v8HyDzw0+N/jc4Pkmzzd5vsnzff1Xs1//1ez33sTs997E4G8f/O2Dv33wtw/+9tnF8y2eb/F8i+dbPN/ic4vPLT63eb7N822eb/N8X//V7Nd/Nfu9NzH7vTcx+NsHf/vgbx/87YO/ffbwfIfnOzzf4fkOz3f4XHjwwIPnfd8+533fPuf1X815/VdzXv/VnNd/Nee9NzHnvTcx+NsHf/vgbx/87YO/fc77vn0OPHjgwQMPHnjwwIMHHjzw4Hnft89537fPef1Xc17/1ZzXfzXn9V/Nee9NzHnvTQz+9sHfPvjbB3/74G+f875vnwMPHnjwwIMHHjzw4IEHDzx4Ls/38nwvz/fyfF//1ZzXfzXnvTcx5703MfjbB3/74G8f/O2Dv31O8HzhwQMPHnjwwIMHHjzw4IEHT/J8k+ebPN/k+b7+qzmv/2rOe29izntvYvC3D/72wd8++NsHf/uc4vnCgwcePPDggQcPPHjgwQMPnub5Ns+3eb7N8339V3Ne/9Wc997EnPfexOBvH/ztg7998LcP/vY5w/OFBy88eOHBCw9eePDCgxcevO/79rnv+/a5r/9q7uu/mvv6r+a+/qu5772Jue+9icHfPvjbB3/74G8f/O1z3/ftc+HBCw9eePDCgxcevPDghQfv+7597vu+fe7rv5r7+q/mvv6rua//au57b2Lue29i8LcP/vbB3z742wd/+9zL84UHLzx44cELD1548MKDFx68l+d7eb7B8w2e7+u/mvv6r+a+9ybmvvcmBn/74G8f/O2Dv33wt89Nni88eOHBCw9eePDCgxcevPDgTZ5v8XyL51s839d/Nff1X819703Mfe9NDP72wd8++NsHf/vgb5/bPF948MKDFx688OCFBy88eOHBOzzf4fkOz3d4vq//au7rv5r73puY+96bGPztg7998LcP/vbB3z7B+/aABwMeDHgw4MGABwMeDHgweN8evG+P13818fqvJl7/1cTrv5p4701MvPcmBn/74G8f/O2Dv33wt0/wvj3gwYAHAx4MeDDgwYAHAx4M3rcH79vj9V9NvP6ridd/NfH6rybeexMT772Jwd8++NsHf/vgbx/87RO8bw94MODBgAcDHgx4MODBgAeD9+3B+/YInm/wfF//1cTrv5p4701MvPcmBn/74G8f/O2Dv33wt0/wvj3gwYAHAx4MeDDgwYAHAx4M3rcH79ujeL7F8339VxOv/2rivTcx8d6bGPztg7998LcP/vbB3z7B+/aABwMeDHgw4MGABwMeDHgweN8evG+P4fkOz/f1X02+/qvJ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", - "file_map": { - "3": { - "source": "use crate::cmp::{Eq, Ord};\nuse crate::convert::From;\nuse crate::runtime::is_unconstrained;\n\nmod check_shuffle;\nmod quicksort;\n\nimpl [T; N] {\n /// Returns the length of this array.\n ///\n /// ```noir\n /// fn len(self) -> Field\n /// ```\n ///\n /// example\n ///\n /// ```noir\n /// fn main() {\n /// let array = [42, 42];\n /// assert(array.len() == 2);\n /// }\n /// ```\n #[builtin(array_len)]\n pub fn len(self) -> u32 {}\n\n /// Returns this array as a slice.\n ///\n /// ```noir\n /// let array = [1, 2];\n /// let slice = array.as_slice();\n /// assert_eq(slice, &[1, 2]);\n /// ```\n #[builtin(as_slice)]\n pub fn as_slice(self) -> [T] {}\n\n /// Applies a function to each element of this array, returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.map(|a| a * 2);\n /// assert_eq(b, [2, 4, 6]);\n /// ```\n pub fn map(self, f: fn[Env](T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array along with its index,\n /// returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.mapi(|i, a| i + a * 2);\n /// assert_eq(b, [2, 5, 8]);\n /// ```\n pub fn mapi(self, f: fn[Env](u32, T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(i, self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// let mut i = 0;\n /// a.for_each(|x| {\n /// b[i] = x;\n /// i += 1;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_each(self, f: fn[Env](T) -> ()) {\n for i in 0..self.len() {\n f(self[i]);\n }\n }\n\n /// Applies a function to each element of this array along with its index.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// a.for_eachi(|i, x| {\n /// b[i] = x;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_eachi(self, f: fn[Env](u32, T) -> ()) {\n for i in 0..self.len() {\n f(i, self[i]);\n }\n }\n\n /// Applies a function to each element of the array, returning the final accumulated value. The first\n /// parameter is the initial value.\n ///\n /// This is a left fold, so the given function will be applied to the accumulator and first element of\n /// the array, then the second, and so on. For a given call the expected result would be equivalent to:\n ///\n /// ```rust\n /// let a1 = [1];\n /// let a2 = [1, 2];\n /// let a3 = [1, 2, 3];\n ///\n /// let f = |a, b| a - b;\n /// a1.fold(10, f); //=> f(10, 1)\n /// a2.fold(10, f); //=> f(f(10, 1), 2)\n /// a3.fold(10, f); //=> f(f(f(10, 1), 2), 3)\n ///\n /// assert_eq(a3.fold(10, f), 10 - 1 - 2 - 3);\n /// ```\n pub fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U {\n for elem in self {\n accumulator = f(accumulator, elem);\n }\n accumulator\n }\n\n /// Same as fold, but uses the first element as the starting element.\n ///\n /// Requires the input array to be non-empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [1, 2, 3, 4];\n /// let reduced = arr.reduce(|a, b| a + b);\n /// assert(reduced == 10);\n /// }\n /// ```\n pub fn reduce(self, f: fn[Env](T, T) -> T) -> T {\n let mut accumulator = self[0];\n for i in 1..self.len() {\n accumulator = f(accumulator, self[i]);\n }\n accumulator\n }\n\n /// Returns true if all the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 2];\n /// let all = arr.all(|a| a == 2);\n /// assert(all);\n /// }\n /// ```\n pub fn all(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = true;\n for elem in self {\n ret &= predicate(elem);\n }\n ret\n }\n\n /// Returns true if any of the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 5];\n /// let any = arr.any(|a| a == 5);\n /// assert(any);\n /// }\n /// ```\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n for elem in self {\n ret |= predicate(elem);\n }\n ret\n }\n\n /// Concatenates this array with another array.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr1 = [1, 2, 3, 4];\n /// let arr2 = [6, 7, 8, 9, 10, 11];\n /// let concatenated_arr = arr1.concat(arr2);\n /// assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n /// }\n /// ```\n pub fn concat(self, array2: [T; M]) -> [T; N + M] {\n let mut result = [crate::mem::zeroed(); N + M];\n for i in 0..N {\n result[i] = self[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n }\n}\n\nimpl [T; N]\nwhere\n T: Ord + Eq,\n{\n /// Returns a new sorted array. The original array remains untouched. Notice that this function will\n /// only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting\n /// logic it uses internally is optimized specifically for these values. If you need a sort function to\n /// sort any type, you should use the `sort_via` function.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32];\n /// let sorted = arr.sort();\n /// assert(sorted == [32, 42]);\n /// }\n /// ```\n pub fn sort(self) -> Self {\n self.sort_via(|a, b| a <= b)\n }\n}\n\nimpl [T; N]\nwhere\n T: Eq,\n{\n /// Returns a new sorted array by sorting it with a custom comparison function.\n /// The original array remains untouched.\n /// The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument.\n ///\n /// Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32]\n /// let sorted_ascending = arr.sort_via(|a, b| a <= b);\n /// assert(sorted_ascending == [32, 42]); // verifies\n ///\n /// let sorted_descending = arr.sort_via(|a, b| a >= b);\n /// assert(sorted_descending == [32, 42]); // does not verify\n /// }\n /// ```\n pub fn sort_via(self, ordering: fn[Env](T, T) -> bool) -> Self {\n // Safety: `sorted` array is checked to be:\n // a. a permutation of `input`'s elements\n // b. satisfying the predicate `ordering`\n let sorted = unsafe { quicksort::quicksort(self, ordering) };\n\n if !is_unconstrained() {\n for i in 0..N - 1 {\n assert(\n ordering(sorted[i], sorted[i + 1]),\n \"Array has not been sorted correctly according to `ordering`.\",\n );\n }\n check_shuffle::check_shuffle(self, sorted);\n }\n sorted\n }\n}\n\nimpl [u8; N] {\n /// Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation -\n /// the given array is interpreted as-is as a string.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let hi = [104, 105].as_str_unchecked();\n /// assert_eq(hi, \"hi\");\n /// }\n /// ```\n #[builtin(array_as_str_unchecked)]\n pub fn as_str_unchecked(self) -> str {}\n}\n\nimpl From> for [u8; N] {\n /// Returns an array of the string bytes.\n fn from(s: str) -> Self {\n s.as_bytes()\n }\n}\n\nmod test {\n #[test]\n fn map_empty() {\n assert_eq([].map(|x| x + 1), []);\n }\n\n global arr_with_100_values: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2, 54,\n 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41, 19, 98,\n 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21, 43, 86, 35,\n 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15, 127, 81, 30, 8,\n 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n global expected_with_100_values: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30, 32,\n 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58, 61, 62,\n 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82, 84, 84, 86,\n 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114, 114, 116, 118,\n 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n fn sort_u32(a: u32, b: u32) -> bool {\n a <= b\n }\n\n #[test]\n fn test_sort() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort();\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort();\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values_comptime() {\n let sorted = arr_with_100_values.sort();\n assert(sorted == expected_with_100_values);\n }\n\n #[test]\n fn test_sort_via() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_via_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn mapi_empty() {\n assert_eq([].mapi(|i, x| i * x + 1), []);\n }\n\n #[test]\n fn for_each_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_each(|_x| assert(false));\n }\n\n #[test]\n fn for_eachi_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_eachi(|_i, _x| assert(false));\n }\n\n #[test]\n fn map_example() {\n let a = [1, 2, 3];\n let b = a.map(|a| a * 2);\n assert_eq(b, [2, 4, 6]);\n }\n\n #[test]\n fn mapi_example() {\n let a = [1, 2, 3];\n let b = a.mapi(|i, a| i + a * 2);\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn for_each_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n let mut i = 0;\n let i_ref = &mut i;\n a.for_each(|x| {\n b_ref[*i_ref] = x * 2;\n *i_ref += 1;\n });\n assert_eq(b, [2, 4, 6]);\n assert_eq(i, 3);\n }\n\n #[test]\n fn for_eachi_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n a.for_eachi(|i, a| { b_ref[i] = i + a * 2; });\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn concat() {\n let arr1 = [1, 2, 3, 4];\n let arr2 = [6, 7, 8, 9, 10, 11];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n }\n\n #[test]\n fn concat_zero_length_with_something() {\n let arr1 = [];\n let arr2 = [1];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_something_with_zero_length() {\n let arr1 = [1];\n let arr2 = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_zero_lengths() {\n let arr1: [Field; 0] = [];\n let arr2: [Field; 0] = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, []);\n }\n}\n", - "path": "std/array/mod.nr" - }, - "5": { - "source": "use crate::meta::derive_via;\n\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for u1 {\n fn eq(self, other: u1) -> bool {\n self == other\n }\n}\n\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl Eq for str {\n fn eq(self, other: str) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\nimpl Eq for (A, B)\nwhere\n A: Eq,\n B: Eq,\n{\n fn eq(self, other: (A, B)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1)\n }\n}\n\nimpl Eq for (A, B, C)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n{\n fn eq(self, other: (A, B, C)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2)\n }\n}\n\nimpl Eq for (A, B, C, D)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n D: Eq,\n{\n fn eq(self, other: (A, B, C, D)) -> bool {\n self.0.eq(other.0) & self.1.eq(other.1) & self.2.eq(other.2) & self.3.eq(other.3)\n }\n}\n\nimpl Eq for (A, B, C, D, E)\nwhere\n A: Eq,\n B: Eq,\n C: Eq,\n D: Eq,\n E: Eq,\n{\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n self.0.eq(other.0)\n & self.1.eq(other.1)\n & self.2.eq(other.2)\n & self.3.eq(other.3)\n & self.4.eq(other.4)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\nimpl Ord for (A, B)\nwhere\n A: Ord,\n B: Ord,\n{\n fn cmp(self, other: (A, B)) -> Ordering {\n let result = self.0.cmp(other.0);\n\n if result != Ordering::equal() {\n result\n } else {\n self.1.cmp(other.1)\n }\n }\n}\n\nimpl Ord for (A, B, C)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n{\n fn cmp(self, other: (A, B, C)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n result\n }\n}\n\nimpl Ord for (A, B, C, D)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n D: Ord,\n{\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n if result == Ordering::equal() {\n result = self.3.cmp(other.3);\n }\n\n result\n }\n}\n\nimpl Ord for (A, B, C, D, E)\nwhere\n A: Ord,\n B: Ord,\n C: Ord,\n D: Ord,\n E: Ord,\n{\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n let mut result = self.0.cmp(other.0);\n\n if result == Ordering::equal() {\n result = self.1.cmp(other.1);\n }\n\n if result == Ordering::equal() {\n result = self.2.cmp(other.2);\n }\n\n if result == Ordering::equal() {\n result = self.3.cmp(other.3);\n }\n\n if result == Ordering::equal() {\n result = self.4.cmp(other.4);\n }\n\n result\n }\n}\n\n// Compares and returns the maximum of two values.\n//\n// Returns the second argument if the comparison determines them to be equal.\n//\n// # Examples\n//\n// ```\n// use std::cmp;\n//\n// assert_eq(cmp::max(1, 2), 2);\n// assert_eq(cmp::max(2, 2), 2);\n// ```\npub fn max(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n// Compares and returns the minimum of two values.\n//\n// Returns the first argument if the comparison determines them to be equal.\n//\n// # Examples\n//\n// ```\n// use std::cmp;\n//\n// assert_eq(cmp::min(1, 2), 1);\n// assert_eq(cmp::min(2, 2), 2);\n// ```\npub fn min(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use super::{Eq, max, min, Ord};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_slices() {\n let slice_1 = &[0, 1, 2, 3];\n let slice_2 = &[0, 1, 2];\n assert(!slice_1.eq(slice_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_slices() {\n assert(&[2_u32].cmp(&[1_u32, 1_u32, 1_u32]) == super::Ordering::greater());\n assert(&[1_u32, 2_u32].cmp(&[1_u32, 2_u32, 3_u32]) == super::Ordering::less());\n }\n}\n", - "path": "std/cmp.nr" - }, - "17": { - "source": "use crate::field::field_less_than;\nuse crate::runtime::is_unconstrained;\n\n// The low and high decomposition of the field modulus\nglobal PLO: Field = 53438638232309528389504892708671455233;\nglobal PHI: Field = 64323764613183177041862057485226039389;\n\npub(crate) global TWO_POW_128: Field = 0x100000000000000000000000000000000;\n\n// Decomposes a single field into two 16 byte fields.\nfn compute_decomposition(x: Field) -> (Field, Field) {\n // Here's we're taking advantage of truncating 128 bit limbs from the input field\n // and then subtracting them from the input such the field division is equivalent to integer division.\n let low = (x as u128) as Field;\n let high = (x - low) / TWO_POW_128;\n\n (low, high)\n}\n\npub(crate) unconstrained fn decompose_hint(x: Field) -> (Field, Field) {\n compute_decomposition(x)\n}\n\nunconstrained fn lte_hint(x: Field, y: Field) -> bool {\n if x == y {\n true\n } else {\n field_less_than(x, y)\n }\n}\n\n// Assert that (alo > blo && ahi >= bhi) || (alo <= blo && ahi > bhi)\nfn assert_gt_limbs(a: (Field, Field), b: (Field, Field)) {\n let (alo, ahi) = a;\n let (blo, bhi) = b;\n // Safety: borrow is enforced to be boolean due to its type.\n // if borrow is 0, it asserts that (alo > blo && ahi >= bhi)\n // if borrow is 1, it asserts that (alo <= blo && ahi > bhi)\n unsafe {\n let borrow = lte_hint(alo, blo);\n\n let rlo = alo - blo - 1 + (borrow as Field) * TWO_POW_128;\n let rhi = ahi - bhi - (borrow as Field);\n\n rlo.assert_max_bit_size::<128>();\n rhi.assert_max_bit_size::<128>();\n }\n}\n\n/// Decompose a single field into two 16 byte fields.\npub fn decompose(x: Field) -> (Field, Field) {\n if is_unconstrained() {\n compute_decomposition(x)\n } else {\n // Safety: decomposition is properly checked below\n unsafe {\n // Take hints of the decomposition\n let (xlo, xhi) = decompose_hint(x);\n\n // Range check the limbs\n xlo.assert_max_bit_size::<128>();\n xhi.assert_max_bit_size::<128>();\n\n // Check that the decomposition is correct\n assert_eq(x, xlo + TWO_POW_128 * xhi);\n\n // Assert that the decomposition of P is greater than the decomposition of x\n assert_gt_limbs((PLO, PHI), (xlo, xhi));\n (xlo, xhi)\n }\n }\n}\n\npub fn assert_gt(a: Field, b: Field) {\n if is_unconstrained() {\n assert(\n // Safety: already unconstrained\n unsafe { field_less_than(b, a) },\n );\n } else {\n // Decompose a and b\n let a_limbs = decompose(a);\n let b_limbs = decompose(b);\n\n // Assert that a_limbs is greater than b_limbs\n assert_gt_limbs(a_limbs, b_limbs)\n }\n}\n\npub fn assert_lt(a: Field, b: Field) {\n assert_gt(b, a);\n}\n\npub fn gt(a: Field, b: Field) -> bool {\n if is_unconstrained() {\n // Safety: unsafe in unconstrained\n unsafe {\n field_less_than(b, a)\n }\n } else if a == b {\n false\n } else {\n // Safety: Take a hint of the comparison and verify it\n unsafe {\n if field_less_than(a, b) {\n assert_gt(b, a);\n false\n } else {\n assert_gt(a, b);\n true\n }\n }\n }\n}\n\npub fn lt(a: Field, b: Field) -> bool {\n gt(b, a)\n}\n\nmod tests {\n // TODO: Allow imports from \"super\"\n use crate::field::bn254::{assert_gt, decompose, gt, lt, lte_hint, PHI, PLO, TWO_POW_128};\n\n #[test]\n fn check_decompose() {\n assert_eq(decompose(TWO_POW_128), (0, 1));\n assert_eq(decompose(TWO_POW_128 + 0x1234567890), (0x1234567890, 1));\n assert_eq(decompose(0x1234567890), (0x1234567890, 0));\n }\n\n #[test]\n unconstrained fn check_lte_hint() {\n assert(lte_hint(0, 1));\n assert(lte_hint(0, 0x100));\n assert(lte_hint(0x100, TWO_POW_128 - 1));\n assert(!lte_hint(0 - 1, 0));\n\n assert(lte_hint(0, 0));\n assert(lte_hint(0x100, 0x100));\n assert(lte_hint(0 - 1, 0 - 1));\n }\n\n #[test]\n fn check_gt() {\n assert(gt(1, 0));\n assert(gt(0x100, 0));\n assert(gt((0 - 1), (0 - 2)));\n assert(gt(TWO_POW_128, 0));\n assert(!gt(0, 0));\n assert(!gt(0, 0x100));\n assert(gt(0 - 1, 0 - 2));\n assert(!gt(0 - 2, 0 - 1));\n assert_gt(0 - 1, 0);\n }\n\n #[test]\n fn check_plo_phi() {\n assert_eq(PLO + PHI * TWO_POW_128, 0);\n let p_bytes = crate::field::modulus_le_bytes();\n let mut p_low: Field = 0;\n let mut p_high: Field = 0;\n\n let mut offset = 1;\n for i in 0..16 {\n p_low += (p_bytes[i] as Field) * offset;\n p_high += (p_bytes[i + 16] as Field) * offset;\n offset *= 256;\n }\n assert_eq(p_low, PLO);\n assert_eq(p_high, PHI);\n }\n\n #[test]\n fn check_decompose_edge_cases() {\n assert_eq(decompose(0), (0, 0));\n assert_eq(decompose(TWO_POW_128 - 1), (TWO_POW_128 - 1, 0));\n assert_eq(decompose(TWO_POW_128 + 1), (1, 1));\n assert_eq(decompose(TWO_POW_128 * 2), (0, 2));\n assert_eq(decompose(TWO_POW_128 * 2 + 0x1234567890), (0x1234567890, 2));\n }\n\n #[test]\n fn check_decompose_large_values() {\n let large_field = 0xffffffffffffffff;\n let (lo, hi) = decompose(large_field);\n assert_eq(large_field, lo + TWO_POW_128 * hi);\n\n let large_value = large_field - TWO_POW_128;\n let (lo2, hi2) = decompose(large_value);\n assert_eq(large_value, lo2 + TWO_POW_128 * hi2);\n }\n\n #[test]\n fn check_lt_comprehensive() {\n assert(lt(0, 1));\n assert(!lt(1, 0));\n assert(!lt(0, 0));\n assert(!lt(42, 42));\n\n assert(lt(TWO_POW_128 - 1, TWO_POW_128));\n assert(!lt(TWO_POW_128, TWO_POW_128 - 1));\n }\n}\n", - "path": "std/field/bn254.nr" - }, - "18": { - "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "39": { - "source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for u1 {\n fn add(self, other: u1) -> u1 {\n self + other\n }\n}\n\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for u1 {\n fn sub(self, other: u1) -> u1 {\n self - other\n }\n}\n\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for u1 {\n fn mul(self, other: u1) -> u1 {\n self * other\n }\n}\n\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for u1 {\n fn div(self, other: u1) -> u1 {\n self / other\n }\n}\n\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for u1 {\n fn rem(self, other: u1) -> u1 {\n self % other\n }\n}\n\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u1 {\n fn wrapping_add(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u1 {\n fn wrapping_sub(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u1 {\n fn wrapping_mul(self: u1, y: u1) -> u1 {\n self & y\n }\n}\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp(x: T, y: T) -> T\nwhere\n T: AsPrimitive,\n Field: AsPrimitive,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp(x: T, y: T) -> Field\nwhere\n T: AsPrimitive,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp(x: T, y: T) -> T\nwhere\n T: AsPrimitive,\n Field: AsPrimitive,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem\n assert_eq(17.rem(5), 2);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder\n assert_eq(42.rem(42), 0);\n assert_eq(0.rem(42), 0);\n assert_eq(1.rem(42), 1);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n #[test]\n fn test_u1_behavior() {\n // u1 wrapping add is XOR\n assert_eq(0u1.wrapping_add(0u1), 0u1);\n assert_eq(0u1.wrapping_add(1u1), 1u1);\n assert_eq(1u1.wrapping_add(0u1), 1u1);\n assert_eq(1u1.wrapping_add(1u1), 0u1);\n\n // u1 wrapping sub is XOR\n assert_eq(0u1.wrapping_sub(0u1), 0u1);\n assert_eq(0u1.wrapping_sub(1u1), 1u1);\n assert_eq(1u1.wrapping_sub(0u1), 1u1);\n assert_eq(1u1.wrapping_sub(1u1), 0u1);\n\n // u1 wrapping mul is AND\n assert_eq(0u1.wrapping_mul(0u1), 0u1);\n assert_eq(0u1.wrapping_mul(1u1), 0u1);\n assert_eq(1u1.wrapping_mul(0u1), 0u1);\n assert_eq(1u1.wrapping_mul(1u1), 1u1);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n}\n", - "path": "std/ops/arith.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::{MAX_MSG_NON_ZERO_COEFFS, T};\nuse lib::configs::default::threshold::{\n DECRYPTED_SHARES_AGGREGATION_BIT_NOISE, DECRYPTED_SHARES_AGGREGATION_CONFIGS, L,\n};\nuse lib::core::threshold::decrypted_shares_aggregation::DecryptedSharesAggregationBigNum;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n decryption_shares: pub [[Polynomial; L]; T + 1],\n party_ids: pub [Field; T + 1],\n message: pub Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n) {\n let decrypted_shares_aggregation: DecryptedSharesAggregationBigNum = DecryptedSharesAggregationBigNum::new(\n DECRYPTED_SHARES_AGGREGATION_CONFIGS,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n );\n\n decrypted_shares_aggregation.execute();\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/decrypted_shares_aggregation_bn/src/main.nr" - }, - "67": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\nuse dep::bignum::BigNum;\nuse dep::bignum::bignum::to_field;\nuse dep::bignum::SecureThreshold8192;\n\n/// Cryptographic parameters for decryption share aggregation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Plaintext modulus (typically denoted as `t`)\n pub plaintext_modulus: Field,\n /// Precomputed value: `-Q^(-1) mod t` where Q is the product of all CRT moduli\n pub q_inverse_mod_t: Field,\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], plaintext_modulus: Field, q_inverse_mod_t: Field) -> Self {\n Configs { qis, plaintext_modulus, q_inverse_mod_t }\n }\n}\n\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using BigNum\n/// for large Q values.\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationBigNum {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using modular arithmetic\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationModular {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n\nimpl DecryptedSharesAggregationBigNum {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationBigNum {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Verifies decoding using BigNum for large Q values\n fn verify_decoding(self) {\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1 as Field;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_bn = SecureThreshold8192::from(q_modulus);\n\n let q_half_bn = q_bn.udiv(SecureThreshold8192::from(2));\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let u_bn = SecureThreshold8192::from(self.u_global.coefficients[coeff_idx]);\n let t_bn = SecureThreshold8192::from(self.configs.plaintext_modulus);\n let u_bn_mod_q = u_bn.umod(q_bn);\n let t_bn_mod_q = t_bn.umod(q_bn);\n let t_times_u_bn_q = (t_bn_mod_q * u_bn_mod_q).umod(q_bn);\n\n let m = ModU128::new(self.configs.plaintext_modulus);\n\n // Check if centering is needed\n let needs_centering = t_times_u_bn_q > q_half_bn;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_bn - t_times_u_bn_q;\n let centered_positive_mod_t = centered_positive.umod(t_bn);\n let centered_field = to_field(centered_positive_mod_t);\n m.mul_mod(self.configs.q_inverse_mod_t, centered_field)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_bn_t = t_times_u_bn_q.umod(t_bn);\n let t_times_u_field = to_field(t_times_u_bn_t);\n let product = m.mul_mod(self.configs.q_inverse_mod_t, t_times_u_field);\n if product == 0 {\n 0\n } else {\n self.configs.plaintext_modulus - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\nimpl DecryptedSharesAggregationModular {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationModular {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Alternative verification function using efficient modular arithmetic without BigNum.\n ///\n /// Uses `ModU128` for decoding verification instead of BigNum. More efficient when\n /// Q (the product of all CRT moduli) fits within u128 (e.g., 72 bits for insecure parameter sets).\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Alternative decoding verification using the formula:\n /// message = -Q^{-1} * (t * u_global)_Q mod t\n fn verify_decoding(self) {\n let t: Field = self.configs.plaintext_modulus;\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_half = q_modulus as u128 / 2;\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let q_mod = ModU128::new(q_modulus);\n let t_mod = ModU128::new(t);\n\n // Compute (t * u_global) mod Q using modular arithmetic functions\n let t_times_u_mod_q = q_mod.mul_mod(t, self.u_global.coefficients[coeff_idx]);\n let needs_centering = (t_times_u_mod_q as u128) > q_half;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_modulus - t_times_u_mod_q;\n let centered_positive_mod_t = t_mod.reduce_mod(centered_positive);\n\n t_mod.mul_mod(self.configs.q_inverse_mod_t, centered_positive_mod_t)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_mod_t = t_mod.reduce_mod(t_times_u_mod_q);\n let product = t_mod.mul_mod(self.configs.q_inverse_mod_t, t_times_u_mod_t);\n if product == 0 {\n 0\n } else {\n t - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\n/// Computes all Lagrange coefficients using optimized modular arithmetic\npub fn compute_all_lagrange_coeffs(\n qis: [Field; L],\n party_ids: [Field; T + 1],\n) -> [[Field; T + 1]; L] {\n let mut lagrange_coeffs = [[0 as Field; T + 1]; L];\n\n // Step 1: Cache |x_i - x_j| factors for all party pairs\n let mut diffs = [[0 as Field; T + 1]; T + 1];\n for i in 0..(T + 1) {\n for j in (i + 1)..(T + 1) {\n let diff = party_ids[j] - party_ids[i];\n diffs[i][j] = diff;\n diffs[j][i] = diff;\n }\n }\n\n // Step 2: Determine signs (same for all parties within a basis)\n let numerator_sign_negative = (T % 2) == 1;\n\n // Step 3: For each CRT basis, compute Lagrange coefficients\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n\n // Compute product of all party IDs: PRODUCT(j=0..T) x_j mod q_l\n let mut product_x = 1 as Field;\n for j in 0..(T + 1) {\n product_x = m.mul_mod(product_x, party_ids[j]);\n }\n\n // For each party i, compute L_i(0) mod q_l\n for party_idx in 0..(T + 1) {\n // Numerator (absolute value): PRODUCT(j!=party_idx) x_j\n let numerator_abs = m.div_mod(product_x, party_ids[party_idx]);\n\n // Denominator (absolute value): PRODUCT(j!=party_idx) |x_party_idx - x_j|\n let mut denominator_abs = 1 as Field;\n for j in 0..(T + 1) {\n if j != party_idx {\n denominator_abs = m.mul_mod(denominator_abs, diffs[party_idx][j]);\n }\n }\n\n // Determine denominator sign\n let num_greater = T - party_idx;\n let denom_sign_negative = (num_greater % 2) == 1;\n\n // Compute unsigned result: |numerator| / |denominator| mod q_l\n let result_abs = m.div_mod(numerator_abs, denominator_abs);\n\n // Apply combined sign\n let should_negate = numerator_sign_negative != denom_sign_negative;\n let result = if should_negate {\n m.reduce_mod(q_l - result_abs)\n } else {\n result_abs\n };\n\n lagrange_coeffs[basis_idx][party_idx] = result;\n }\n }\n\n lagrange_coeffs\n}\n\n/// Computes u^{(l)} for each CRT basis via Lagrange interpolation\npub fn compute_crt_components(\n qis: [Field; L],\n decryption_shares: [[Polynomial; L]; T + 1],\n lagrange_coeffs: [[Field; T + 1]; L],\n) -> [Polynomial; L] {\n let mut u_crts: [Polynomial; L] =\n [Polynomial::new([0; MAX_MSG_NON_ZERO_COEFFS]); L];\n\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n let mut u_coeffs = [0 as Field; MAX_MSG_NON_ZERO_COEFFS];\n\n // For each coefficient position\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n let mut u_coeff = 0 as Field;\n\n // Sum all contributions: u = SUM(i=0..T) [d_i * L_i(0)] mod q_l\n for party_idx in 0..(T + 1) {\n let d_coeff = decryption_shares[party_idx][basis_idx].coefficients[coeff_idx];\n let l_i_0 = lagrange_coeffs[basis_idx][party_idx];\n\n let term = m.mul_mod(d_coeff, l_i_0);\n u_coeff = m.reduce_mod(u_coeff + term);\n }\n\n u_coeffs[coeff_idx] = u_coeff;\n }\n\n u_crts[basis_idx] = Polynomial::new(u_coeffs);\n }\n\n u_crts\n}\n\n/// Verifies CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global for all bases l\npub fn verify_crt_reconstruction(\n qis: [Field; L],\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n u_crts: [Polynomial; L],\n) {\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n\n // Compute r^{(l)} * q_l\n let r_times_q = crt_quotients[basis_idx].mul_scalar(q_l);\n\n // Compute u^{(l)} + r^{(l)} * q_l\n let reconstructed = u_crts[basis_idx].add(r_times_q);\n\n // Verify: u^{(l)} + r^{(l)} * q_l = u_global\n // Must hold for every coefficient\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n assert(\n reconstructed.coefficients[coeff_idx] == u_global.coefficients[coeff_idx],\n \"CRT reconstruction verification failed\",\n );\n }\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/decrypted_shares_aggregation.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "84": { - "source": "use crate::fns::constrained_ops::limbs_to_field;\nuse crate::params::BigNumParams;\nuse std::ops::{Add, Div, Mul, Neg, Sub};\n\npub trait BigNum: Neg + Add + Sub + Mul + Div + Eq {\n let N: u32;\n let MOD_BITS: u32;\n\n fn params() -> BigNumParams;\n fn modulus_bits(_: Self) -> u32;\n fn num_limbs(_: Self) -> u32;\n fn modulus() -> Self;\n\n fn new() -> Self;\n fn zero() -> Self;\n fn one() -> Self;\n fn from_limbs(limbs: [u128; N]) -> Self;\n fn get_limbs(self) -> [u128; N];\n fn set_limb(self: &mut Self, idx: u32, value: u128);\n fn derive_from_seed(seed: [u8; SeedBytes]) -> Self;\n unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self;\n fn from_be_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self;\n fn to_be_bytes(self) -> [u8; (MOD_BITS + 7) / 8];\n fn from_le_bytes(x: [u8; (MOD_BITS + 7) / 8]) -> Self;\n fn to_le_bytes(self) -> [u8; (MOD_BITS + 7) / 8];\n\n fn get_limb(self: Self, idx: u32) -> u128 {\n self.get_limbs()[idx]\n }\n\n unconstrained fn __eq(self: Self, other: Self) -> bool;\n\n unconstrained fn __is_zero(self: Self) -> bool;\n\n unconstrained fn __neg(self) -> Self;\n unconstrained fn __add(self, other: Self) -> Self;\n unconstrained fn __sub(self, other: Self) -> Self;\n unconstrained fn __mul(self, other: Self) -> Self;\n unconstrained fn __sqr(self) -> Self;\n unconstrained fn __div(self, other: Self) -> Self;\n unconstrained fn __udiv_mod(self, divisor: Self) -> (Self, Self);\n unconstrained fn __invmod(self) -> Self;\n unconstrained fn __pow(self, exponent: Self) -> Self;\n\n unconstrained fn __tonelli_shanks_sqrt(self) -> std::option::Option;\n unconstrained fn __sqrt(self) -> std::option::Option;\n\n fn assert_is_not_equal(self: Self, other: Self);\n\n fn validate_in_range(self);\n fn validate_in_field(self);\n\n fn sqr(self) -> Self;\n\n fn udiv_mod(self, divisor: Self) -> (Self, Self);\n fn udiv(self, divisor: Self) -> Self;\n fn umod(self, divisor: Self) -> Self;\n\n fn is_zero(self) -> bool;\n fn is_zero_integer(self) -> bool;\n fn assert_is_not_zero(self);\n fn assert_is_not_zero_integer(self);\n}\n\n// we need macros that implement the BigNum, Default, From, Neg, Add, Sub, Mul, Div, Eq, Ord traits for each bignum type\npub comptime fn derive_bignum(\n strukt: TypeDefinition,\n N: u32,\n MOD_BITS: u32,\n params: Quoted,\n) -> Quoted {\n let constrained_ops = quote { $crate::fns::constrained_ops };\n let unconstrained_ops = quote { $crate::fns::unconstrained_ops };\n let typ = strukt.as_type();\n let serialization = quote { $crate::fns::serialization };\n quote {\n\n // implement BigNum for BigNum \n impl $crate::BigNum for $typ {\n let N: u32 = $N; \n let MOD_BITS: u32 = $MOD_BITS;\n \n fn modulus_bits(_: Self) -> u32 {\n $MOD_BITS\n }\n \n fn num_limbs(_: Self) -> u32 {\n $N\n }\n\n fn modulus() -> Self {\n Self { limbs: Self::params().modulus }\n }\n\n fn new() -> Self {\n Self {limbs: [0; $N]}\n }\n\n fn params() -> $crate::params::BigNumParams<$N, $MOD_BITS> {\n $params\n }\n\n fn from_limbs(limbs: [u128; $N]) -> Self {\n Self { limbs }\n }\n\n fn get_limbs(self: Self) -> [u128; $N] {\n self.limbs\n }\n\n fn set_limb(self: &mut Self, idx: u32, value: u128) {\n self.limbs[idx] = value;\n }\n\n fn zero() -> Self {\n Self { limbs: [0; $N] }\n }\n\n fn one() -> Self {\n let mut limbs = [0; $N];\n limbs[0] = 1;\n Self { limbs }\n }\n\n fn derive_from_seed(seed: [u8; SeedBytes]) -> Self {\n let params = Self::params();\n $typ::from_limbs($constrained_ops::derive_from_seed::<_, $MOD_BITS, _>(params, seed))\n }\n\n unconstrained fn __derive_from_seed(seed: [u8; SeedBytes]) -> Self {\n let params = Self::params();\n Self { limbs: $unconstrained_ops::__derive_from_seed::<_, $MOD_BITS, _>(params, seed) }\n }\n\n fn from_be_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self {\n Self { limbs: $serialization::from_be_bytes::<_, $MOD_BITS>(x) }\n }\n \n fn to_be_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] {\n $serialization::to_be_bytes::<_, $MOD_BITS>(self.limbs)\n }\n\n fn from_le_bytes(x: [u8; ($MOD_BITS + 7) / 8]) -> Self {\n Self { limbs: $serialization::from_le_bytes::<_, $MOD_BITS>(x) }\n }\n\n fn to_le_bytes(self) -> [u8; ($MOD_BITS + 7) / 8] {\n $serialization::to_le_bytes::<_, $MOD_BITS>(self.limbs)\n }\n\n unconstrained fn __eq(self: Self, other: Self) -> bool {\n $crate::fns::unconstrained_ops::__eq(self.get_limbs(), other.get_limbs())\n }\n\n unconstrained fn __is_zero(self: Self) -> bool {\n $crate::fns::unconstrained_ops::__is_zero(self.get_limbs())\n }\n\n unconstrained fn __neg(self: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__neg(params.modulus, self.get_limbs())}\n }\n\n unconstrained fn __add(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__add(params.modulus, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __sub(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__sub(params.modulus, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __mul(self: Self, other: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__mul(params, self.get_limbs(), other.get_limbs())}\n }\n\n unconstrained fn __sqr(self: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__sqr(params, self.get_limbs()) }\n }\n\n unconstrained fn __div(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__div(params, self.get_limbs(), divisor.get_limbs())}\n }\n\n unconstrained fn __udiv_mod(self: Self, divisor: Self) -> (Self, Self) {\n let (q, r) = $unconstrained_ops::__udiv_mod(self.get_limbs(), divisor.get_limbs());\n (Self{limbs: q}, Self{limbs: r})\n }\n\n unconstrained fn __invmod(self: Self) -> Self {\n let params = Self::params();\n assert(params.has_multiplicative_inverse);\n Self {limbs: $unconstrained_ops::__invmod(params, self.get_limbs())}\n }\n\n unconstrained fn __pow(self: Self, exponent: Self) -> Self {\n let params = Self::params();\n Self {limbs: $unconstrained_ops::__pow(params, self.get_limbs(), exponent.get_limbs())}\n }\n\n #[deprecated(\"use __sqrt\")]\n unconstrained fn __tonelli_shanks_sqrt(self: Self) -> std::option::Option {\n let params = Self::params();\n let maybe_limbs = $unconstrained_ops::__sqrt(params, self.get_limbs());\n maybe_limbs.map(|limbs| Self {limbs: limbs})\n }\n\n unconstrained fn __sqrt(self: Self) -> std::option::Option {\n let params = Self::params();\n let maybe_limbs = $unconstrained_ops::__sqrt(params, self.get_limbs());\n maybe_limbs.map(|limbs| Self {limbs: limbs })\n }\n\n fn assert_is_not_equal(self: Self, other: Self) {\n let params = Self::params();\n $crate::fns::constrained_ops::assert_is_not_equal(\n params,\n self.get_limbs(),\n other.get_limbs(),\n );\n }\n\n fn validate_in_field(self: Self) {\n let params = Self::params();\n $constrained_ops::validate_in_field::<_, $MOD_BITS>(params, self.get_limbs());\n }\n\n fn validate_in_range(self: Self) {\n $constrained_ops::validate_in_range::<_, _, $MOD_BITS>(self.get_limbs());\n }\n\n fn sqr(self: Self) -> Self {\n let params = Self::params();\n Self { limbs: $constrained_ops::sqr::<$N, $MOD_BITS>(params, self.get_limbs()) }\n }\n\n fn udiv_mod(self: Self, divisor: Self) -> (Self, Self) {\n let (q, r) = $constrained_ops::udiv_mod::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs());\n (Self {limbs: q}, Self {limbs: r})\n }\n\n fn udiv(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $constrained_ops::udiv::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs())}\n }\n\n fn umod(self: Self, divisor: Self) -> Self {\n let params = Self::params();\n Self {limbs: $constrained_ops::umod::<$N, $MOD_BITS>(self.get_limbs(), divisor.get_limbs())}\n }\n\n fn is_zero(self: Self) -> bool {\n let params = Self::params();\n $constrained_ops::is_zero::<$N, $MOD_BITS>(params, self.get_limbs())\n }\n\n fn is_zero_integer(self: Self) -> bool {\n $constrained_ops::is_zero_integer(self.get_limbs())\n }\n\n fn assert_is_not_zero(self: Self) {\n let params = Self::params();\n $constrained_ops::assert_is_not_zero::<$N, $MOD_BITS>(params, self.get_limbs());\n }\n\n fn assert_is_not_zero_integer(self: Self) {\n $constrained_ops::assert_is_not_zero_integer(self.get_limbs());\n }\n }\n\n // implement Default for BigNum\n impl Default for $typ {\n fn default() -> Self {\n $typ::from_limbs([0; $N])\n }\n }\n\n impl std::convert::From for $typ {\n fn from(input: Field) -> Self {\n $typ { limbs: $constrained_ops::from_field::<$N, $MOD_BITS>($params, input) }\n }\n }\n\n impl std::ops::Neg for $typ {\n fn neg(self) -> Self {\n $typ { limbs: $constrained_ops::neg::<$N, $MOD_BITS>($params, self.limbs) }\n }\n }\n\n impl std::ops::Add for $typ {\n fn add(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::add::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Sub for $typ {\n fn sub(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::sub::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Mul for $typ {\n fn mul(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::mul::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::ops::Div for $typ {\n fn div(self, other: Self) -> Self {\n $typ { limbs: $constrained_ops::div::<$N, $MOD_BITS>($params, self.limbs, other.limbs) }\n }\n }\n\n impl std::cmp::Eq for $typ {\n fn eq(self, other: Self) -> bool {\n $constrained_ops::eq::<$N, $MOD_BITS>($params, self.limbs, other.limbs)\n }\n }\n\n impl std::cmp::Ord for $typ {\n fn cmp(self, other: Self) -> std::cmp::Ordering {\n $constrained_ops::cmp::<$N, $MOD_BITS>(self.limbs, other.limbs)\n }\n }\n\n }\n}\n\npub fn conditional_select(lhs: T, rhs: T, predicate: bool) -> T {\n if predicate {\n lhs\n } else {\n rhs\n }\n}\n\npub unconstrained fn compute_quadratic_expression(\n lhs_terms: [[T; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[T; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [T; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> (T, T) {\n let params = T::params();\n let (q_limbs, r_limbs) = crate::fns::expressions::__compute_quadratic_expression(\n params,\n crate::utils::map::map(\n lhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n lhs_flags,\n crate::utils::map::map(\n rhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n rhs_flags,\n crate::utils::map::map(linear_terms, |bn: T| bn.get_limbs()),\n linear_flags,\n );\n (T::from_limbs(q_limbs), T::from_limbs(r_limbs))\n}\n\npub fn evaluate_quadratic_expression(\n lhs_terms: [[T; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[T; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [T; ADD_N],\n linear_flags: [bool; ADD_N],\n) {\n let params = T::params();\n crate::fns::expressions::evaluate_quadratic_expression(\n params,\n crate::utils::map::map(\n lhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n lhs_flags,\n crate::utils::map::map(\n rhs_terms,\n |bns| crate::utils::map::map(bns, |bn: T| bn.get_limbs()),\n ),\n rhs_flags,\n crate::utils::map::map(linear_terms, |bn: T| bn.get_limbs()),\n linear_flags,\n )\n}\n\npub unconstrained fn batch_invert(x: [T; M]) -> [T; M] {\n let params = T::params();\n assert(params.has_multiplicative_inverse);\n crate::fns::unconstrained_ops::batch_invert(params, x.map(|bn: T| bn.get_limbs())).map(|limbs| {\n T::from_limbs(limbs)\n })\n}\n\npub unconstrained fn batch_invert_slice(x: [T]) -> [T] {\n let params = T::params();\n assert(params.has_multiplicative_inverse);\n crate::fns::unconstrained_ops::batch_invert_slice(params, x.map(|bn: T| bn.get_limbs()))\n .map(|limbs| T::from_limbs(limbs))\n}\n\npub fn to_field(bn: T) -> Field {\n let params = T::params();\n limbs_to_field(params, bn.get_limbs())\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/bignum.nr" - }, - "120": { - "source": "use crate::constants::{GRUMPKIN_MODULUS, TWO_POW_120, TWO_POW_240};\n\nuse crate::fns::{\n expressions::{evaluate_quadratic_expression, validate_udiv_mod_expression},\n unconstrained_helpers::{\n __add_with_flags, __from_field, __neg_with_flags, __sub_with_flags,\n __validate_gte_with_flags, __validate_in_field_compute_borrow_flags,\n },\n unconstrained_ops::{__add, __div, __mul, __neg, __sqr, __sub, __udiv_mod},\n};\n\nuse crate::params::BigNumParams;\n\nuse std::cmp::Ordering;\n\n/// Lift the limbs of a `BigNum` value onto the circuit `Field`\n///\n/// Descent the `BigNum` value back into the `Field` and\n/// - check that it's a proper `BigNum` value\n/// - validate the limbs sum up to a `Field` value\npub(crate) fn limbs_to_field(\n _params: BigNumParams,\n limbs: [u128; N],\n) -> Field {\n validate_in_range::(limbs);\n if N > 2 {\n // validate that the `BigNum` is less than the Grumpkin modulus\n let mut grumpkin_modulus: [u128; N] = [0; N];\n grumpkin_modulus[0] = GRUMPKIN_MODULUS[0];\n grumpkin_modulus[1] = GRUMPKIN_MODULUS[1];\n grumpkin_modulus[2] = GRUMPKIN_MODULUS[2];\n validate_gt::(grumpkin_modulus, limbs);\n }\n\n if N < 2 {\n limbs[0] as Field\n } else if N == 2 {\n (limbs[0] as Field) + (limbs[1] as Field) * (TWO_POW_120 as Field)\n } else {\n (limbs[0] as Field)\n + (limbs[1] as Field) * (TWO_POW_120 as Field)\n + (limbs[2] as Field) * TWO_POW_240\n }\n}\n\n/// Construct a `BigNum` value from a native `Field`\n///\n/// Decomposes the `Field` value into 120-bit limbs\n/// then we have three cases:\n/// - MOD_BITS < 253 (grumpkin_mod_bits - 1): it is enough to call for `validate_in_field`, which is basically `val <= MOD`\n/// - MOD_BITS > 253: we need to verify that the obtained `BigNum` `val < GRUMPKIN_MODULUS`\n/// - MOD_BITS = 253: verify that `val < min(MOD, GRUMPKIN_MODULUS)`\n/// Next we verify that all the limbs are properly ranged\n/// and that the accumulated limbs are equal to the input `Field` value\npub(crate) fn from_field(\n _params: BigNumParams,\n val: Field,\n) -> [u128; N] {\n // Safety: we check that the resulting limbs represent the intended field element\n // we check the bit length, the limbs being max 120 bits, and the value in total is less than the field modulus\n let result: [u128; N] = unsafe { __from_field::(val) };\n\n if !std::runtime::is_unconstrained() {\n // validate the limbs are in range and the value in total is less than 2^254\n if MOD_BITS < 253 {\n // this means that the field modulus is smaller than grumpkin modulus so we have to check if the element fields in the field size\n validate_in_field(_params, result);\n } else {\n let mut grumpkin_modulus: [u128; N] = [0; N];\n grumpkin_modulus[0] = GRUMPKIN_MODULUS[0];\n grumpkin_modulus[1] = GRUMPKIN_MODULUS[1];\n grumpkin_modulus[2] = GRUMPKIN_MODULUS[2];\n\n if MOD_BITS > 253 {\n // this means that the field modulus is larger than grumpkin modulus so we have to check if the element fields in the field size are less than the grumpkin modulus.\n // also for correct params N is always larger than 3 here\n validate_gt::(grumpkin_modulus, result);\n } else {\n // this is the tricky part, when MOD_BITS = 253, we have to compare the limbs of the modulus to the grumpkin modulus limbs\n // any `BigNum` with 253 bits will have 3 limbs\n\n // if MOD is less than grumpkin modulus, this will be true\n let mut mod_lt_grumpkin: bool = false;\n for i in 0..3 {\n if !mod_lt_grumpkin & (_params.modulus[2 - i] < grumpkin_modulus[2 - i]) {\n mod_lt_grumpkin = true;\n }\n }\n let min_modulus: [u128; N] = if mod_lt_grumpkin {\n _params.modulus\n } else {\n grumpkin_modulus\n };\n validate_gt::(min_modulus, result);\n }\n }\n validate_in_range::(result);\n\n // validate the limbs sum up to the field value\n let field_val: Field = if N < 2 {\n result[0] as Field\n } else if N == 2 {\n (result[0] as Field) + (result[1] as Field) * (TWO_POW_120 as Field)\n } else {\n (result[0] as Field)\n + (result[1] as Field) * (TWO_POW_120 as Field)\n + (result[2] as Field) * TWO_POW_240\n };\n assert_eq(field_val, val);\n }\n\n result\n}\n\n/// Given an input seed, generate a pseudorandom `BigNum` value\n///\n/// This function *should* produce a uniformly randomly distributed value modulo `MOD`\n///\n/// First we take the seed and pack it's 31-byte chunks into `Field`s\n/// We use a hash function that can be modelled as a random oracle\n/// We hash the packed seed using Poseidon2 to produce `MOD_BITS * 2` bits of entropy\n///\n/// From these bits we construct 4(in case N = 2) or 3(N > 2) `BigNum` values:\n/// - We fill first `N - 1` limbs and leave the top limb empty\n///\n/// Then we accumulate the resulting BigNum values using:\n/// B = 2^{120 * (N - 1)}\n/// res = x3 + B * x2 + B^2 * x1 + B^3 * x0\n///\n/// ## Note\n/// This function will always produce an `x3` `BigNum`\n/// If `MOD = 2^{120 * (N - 1)}`\n/// It will use only `MOD_BITS - 1` bits of entropy\npub(crate) fn derive_from_seed(\n params: BigNumParams,\n seed: [u8; SeedBytes],\n) -> [u128; N] {\n // Pack seed bytes into Fields.\n // For the seed of length M, we construct a rolling_hash_field of size ceil(M / 31).\n // i.e. 31 bytes per Field\n // NOTE: the Fields produced are 248 bits in size\n let mut rolling_hash_fields: [Field; (SeedBytes + 30) / 31] = [0; (SeedBytes + 30) / 31];\n let mut seed_ptr: u32 = 0;\n for i in 0..(SeedBytes + 30) / 31 {\n let mut packed: Field = 0;\n for _ in 0..31 {\n if (seed_ptr < SeedBytes) {\n packed *= 256;\n packed += seed[seed_ptr] as Field;\n seed_ptr += 1;\n }\n }\n rolling_hash_fields[i] = packed;\n }\n\n let compressed: Field =\n poseidon::poseidon2::Poseidon2::hash(rolling_hash_fields, (SeedBytes + 30) / 31);\n let mut rolling_hash: [Field; 2] = [compressed, 0];\n\n // 120 bit limb has 15 bytes in it\n // we buffer (N * 15) * 2 bytes for 2N limbs\n let mut hash_buffer: [u8; N * 15 * 2] = [0; N * 15 * 2];\n\n // We produce 32 bytes (254 bits) per hash iteration\n // We take only 30 bytes, so we need ceil(N * 2 * 15 / 30) hashes to fill them up\n for i in 0..N {\n let hash: Field = poseidon::poseidon2::Poseidon2::hash(rolling_hash, 2);\n let hash: [u8; 32] = hash.to_le_bytes();\n for j in 0..30 {\n hash_buffer[i * 30 + j] = hash[j];\n }\n rolling_hash[1] += 1;\n }\n\n let num_bits: u32 = MOD_BITS * 2;\n let num_bytes: u32 = (num_bits + 7) / 8;\n\n // Truncate the final byte that will be used in `BigNum` creation\n let bits_in_last_byte: u8 = (num_bits as u8) % 8;\n if bits_in_last_byte != 0 {\n let last_byte_mask: u8 = ((1 as u8) << bits_in_last_byte) - 1;\n hash_buffer[num_bytes - 1] &= last_byte_mask;\n }\n\n let num_bigfield_chunks: u32 = if N == 2 { 4 } else { 3 };\n let mut byte_ptr: u32 = 0;\n\n // We want to convert our hash_buffer into bigfield chunks, with each `BigNum` having at most N - 1 limbs filled\n // We sample only N - 1 limbs mostly because we do not wont to deal with accidental overflows in the top limb\n // In any case the security is preserved\n //\n // For all integer values N > 1, the number of chunks is either 4(for N = 2) or 3(for N > 2) (ceil(2*N / (N - 1)))\n //\n // To determine the exact number of chunks, we need the `!=` or `>` operator which is not available when defining array sizes\n // so we overestimate at 4\n // e.g. if N = 20, then we have 40 limbs we want to reduce, but each bigfield chunk is 19 limbs, so we need 3\n // if N = 2, we have 4 limbs we want to reduce but each bigfield chunk is only 1 limb, so we need 4\n let mut bigfield_chunks: [[u128; N]; 4] = [[0; N]; 4];\n\n for k in 0..num_bigfield_chunks {\n let mut bigfield_limbs: [u128; N] = [0; N];\n\n // Before the current limb, we filled out (N - 1) limbs, k times\n // 15 bytes per limb\n // resulting in total of 15 * k * (N - 1)\n let mut num_filled_bytes: u32 = 15 * k * (N - 1);\n if num_bytes > num_filled_bytes {\n // Static assert for completeness\n assert(num_filled_bytes == byte_ptr);\n\n let mut num_remaining_bytes_to_sample: u32 = num_bytes - num_filled_bytes;\n let mut num_remaining_limbs_to_sample: u32 = (num_remaining_bytes_to_sample + 14) / 15;\n\n // Sample at most (N - 1) limbs from hash_buffer\n let mut num_limbs_to_sample: u32 = if num_remaining_limbs_to_sample > (N - 1) {\n N - 1\n } else {\n num_remaining_limbs_to_sample\n };\n\n for j in 0..num_limbs_to_sample {\n let mut limb: Field = 0;\n // Construct a 120 bit limb\n for _ in 0..15 {\n if byte_ptr < num_bytes {\n let mut byte: u8 = hash_buffer[byte_ptr];\n limb *= 256;\n limb += byte as Field;\n byte_ptr += 1;\n }\n }\n // crucial for performance\n limb.assert_max_bit_size::<120>();\n // Accumulate limbs from top to bottom\n bigfield_limbs[num_limbs_to_sample - 1 - j] = limb as u128;\n }\n // Accumulate `BigNum` values from top to bottom\n bigfield_chunks[num_bigfield_chunks - 1 - k] = bigfield_limbs;\n }\n }\n\n // B = 2^{120 * (N - 1)}, we know it is \\leq `MOD`, since the top limb\n // have to be at least one\n let mut bigfield_rhs_limbs: [u128; N] = [0; N];\n bigfield_rhs_limbs[N - 1] = 1;\n\n let mut result: [u128; N] = bigfield_chunks[0];\n\n for i in 1..num_bigfield_chunks {\n result = mul(params, result, bigfield_rhs_limbs);\n result = add(params, result, bigfield_chunks[i]);\n }\n\n result\n}\n\n// ------------------------------ COMPARISON FUNCTIONS ------------------------------\n\n/// Validate lhs != rhs\n///\n/// We compare `A` and `B` via their encodings in the circuit `Field`\n///\n/// Under our range assumptions, equality in `Field` implies equality of the underlying\n/// `BigNum` values, hence equality (mod `MOD`)\n///\n/// In this library it is possible that A or B is a little bit greater than `MOD`\n/// So A == B (mod `MOD`) implies that A == B, A == B + MOD or A == B - MOD over the integers\n/// Hence we can compute everything (mod p) and constrain that\n/// (A - B) * (A - B + MOD) * (A - B - MOD) != 0 (mod p)\n///\n/// ## Soundness\n/// This method is *sound* for checking `A != B (mod MOD)`\n///\n/// If `A == B (mod MOD)`, then `A - B` is in `{0, +-MOD}` as an integer,\n/// so one of the factors `A-B`, `A-B+MOD`, `A-B-MOD` is zero in `Field`, and the product is zero\n/// Therefore, whenever the assertion `target != 0` holds, we must have `A != B (mod MOD)`\n/// under our range assumptions\n///\n/// ## Completeness\n/// In general, this method is not *complete*: if the admissible range of `A` and `B`\n/// is large enough relative to the circuit `Field` prime `p`, an honest prover with\n/// `A != B (mod MOD)` can still hit an alias where\n/// (A - B) * (A - B + MOD) * (A - B - MOD) == 0 (mod p),\n/// i.e.\n/// - A = B (mod p), or\n/// - A = B + MOD (mod p), or\n/// - A = B - MOD (mod p).\n///\n/// For random `A, B` in such a wide range, the probability of this collision is\n/// roughly 3/p.\n///\n/// In case `MOD` < `p` this function becomes *complete*\npub(crate) fn assert_is_not_equal(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) {\n let mut l: Field = 0;\n let mut r: Field = 0;\n let mut modulus_mod_p: Field = 0;\n for i in 0..N {\n l *= TWO_POW_120 as Field;\n r *= TWO_POW_120 as Field;\n modulus_mod_p *= TWO_POW_120 as Field;\n\n l += lhs[N - i - 1] as Field;\n r += rhs[N - i - 1] as Field;\n modulus_mod_p += params.modulus[N - i - 1] as Field;\n }\n\n let diff: Field = l - r;\n let target: Field = diff * (diff + modulus_mod_p) * (diff - modulus_mod_p);\n assert(target != 0, \"assert_is_not_equal fail\");\n}\n\n/// Compute equality flag\n///\n/// A == B (mod MOD)\n/// We compute A - B and check whether it is `0` or `MOD`\n/// This is due to subtract constrains the diff value to be < 2^MOD_BITS, not < `MOD`\n///\n/// ## Soundness\n/// This function is conditionally *sound*. See `sub` for details\n///\n/// ## Completeness\n/// This function is *complete*. An honest prover will always be able to execute it.\n///\n/// ## TODO\n/// can do this more efficiently via witngen in unconstrained functions?\npub(crate) fn eq(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> bool {\n let diff: [u128; N] = sub::(params, lhs, rhs);\n is_zero::(params, diff)\n}\n\n/// Validate that `val` is not equal to zero when interpreted as an integer.\n///\n/// This enforces that at least one limb of `val` is non-zero.\n/// It does *not* check \"BigNum zero\" in the modular sense (e.g. it\n/// treats `MOD` as non-zero).\n///\n/// ## Assumptions\n/// * Each limb of `val` is range-constrained to be a 120-bit value:\n/// `0 <= val[i] < 2^120`.\n/// * For our concrete fields and limb counts we have `N * 2^120 < p`,\n/// so the sum of all limbs fits strictly inside the field modulus.\n///\n/// ## Completeness\n/// If `val` is non-zero as an integer, then at least one limb is non-zero,\n/// so the integer sum of the limbs satisfies `0 < limb_sum < p`. In this\n/// case `limb_sum != 0` in the `Field`, and the assertion passes.\n///\n/// ## Soundness\n/// If all limbs of `val` are zero, then `limb_sum` is zero as an integer\n/// and as a field element, so the assertion fails. A witness representing\n/// the zero integer can never satisfy this check.\n///\n/// ## Note\n/// This is slightly cheaper than doing `val != [0; N]`, as we avoid\n/// creating per-limb boolean equalities and chaining them with `and`s.\npub(crate) fn assert_is_not_zero_integer(val: [u128; N]) {\n let mut limb_sum: Field = 0;\n for i in 0..N {\n limb_sum += val[i] as Field;\n }\n assert(limb_sum != 0, \"assert_is_not_zero_integer fail\");\n}\n\n/// Check whether `val` is the zero `BigNum` in the integer sense.\n///\n/// This returns `true` iff all limbs of `val` are zero. It does *not*\n/// treat `MOD` as zero; for modular `BigNum` zero use `is_zero`.\n///\n/// See `assert_is_not_zero_integer` for the underlying assumptions.\n///\n/// ## Note\n/// This is slightly cheaper than testing `val == [0; N]`, as we avoid\n/// creating per-limb boolean equalities and chaining them with `and`s.\npub(crate) fn is_zero_integer(val: [u128; N]) -> bool {\n let mut limb_sum: Field = 0;\n for i in 0..N {\n limb_sum += val[i] as Field;\n }\n limb_sum == 0\n}\n\n/// Validate that a `BigNum` value is not zero modulo `MOD`.\n///\n/// Convenience wrapper around `assert_is_not_equal`.\npub(crate) fn assert_is_not_zero(\n params: BigNumParams,\n val: [u128; N],\n) {\n assert_is_not_equal::(params, val, [0; N]);\n}\n\n/// Check whether a `BigNum` value is zero modulo `MOD`.\n///\n/// This treats both the all-zero limb vector and `params.modulus` as\n/// representing zero. It assumes that all valid `BigNum` values are\n/// range-constrained so that no other representatives of `0 (mod MOD)`\n/// can appear.\n///\n/// ## Note\n/// This is cheaper than calling `eq(val, [0; N])`\npub(crate) fn is_zero(\n params: BigNumParams,\n val: [u128; N],\n) -> bool {\n is_zero_integer(val) | (val == params.modulus)\n}\n\n/// Validate a `BigNum` instance is correctly range constrained to contain no more than `MOD_BITS` bits\n///\n/// Constrain the `BigNum` instance to be < 2^MOD_BITS by:\n/// - Constraining each limb(0..N-2) to be 120-bit limb\n/// - Constraining the last limb to be `MOD_BITS - 120 * (N - 1)`\n///\n/// ## Note\n/// This can be a very expensive function, when the `TOP_LIMB_BITS` is uncommon\n///\n/// For example: BLS12_377Fr, with `TOP_LIMB_BITS`=13\n/// It creates a new 13-bit range table, which consists of roughly 3k variables\n/// And ~2k circuit gates\n///\n/// Compare this to BLS12_377Fq, with `TOP_LIMB_BITS`=17\n/// It is nicely decomposed into\n/// 14-bit range check and 3-bit range check - much much cheaper, since 14-bit range checks\n/// are already pretty common for 120-bit range checks\npub(crate) fn validate_in_range(limbs: [T; N])\nwhere\n T: Into,\n{\n for i in 0..(N - 1) {\n limbs[i].into().assert_max_bit_size::<120>();\n }\n\n limbs[N - 1].into().assert_max_bit_size::();\n}\n\n/// Validate quotient produced from `evaluate_quadratic_expression` is well-formed\n///\n/// Because the inputs into `evaluate_quadratic_expression` may cause the quotient to extend beyond `Params::modulus_bits`.\n/// We allow the quotient to extend `6` bits beyond `Params::modulus_bits()`\n/// Why is this?\n/// several factors: 1. quotient * modulus , limbs cannot overflow `Field` boundary (254 bits)\n/// 2. in `evaluate_quadratic_expression`, we require that for `expression - quotient * modulus`,\n/// limbs cannot exceed `246` bits (246 magic number due to a higher number adding extra range check gates)\n/// because of factor 2 and the fact that modulus limbs are 120 bits, quotient limbs cannot be > 126 bits\npub(crate) fn validate_quotient_in_range(limbs: [u128; N]) {\n for i in 0..(N - 1) {\n (limbs[i] as Field).assert_max_bit_size::<120>();\n }\n (limbs[N - 1] as Field).assert_max_bit_size::();\n}\n\n/// Validate that `lhs - rhs` does not underflow i.e. that lhs > rhs over the integers\n///\n/// Compute `result = lhs - rhs` along with `borrow_flags`,\n/// then constrain `result` to be a valid `BigNum` value.\n///\n/// ## Completeness\n/// This function is complete and will work only if `lhs > rhs` over the integers.\n///\n/// ## Soundness\n/// This function is sound:\n/// result[0] = lhs[0] - rhs[0] + bf[0] * 2^{120} < 2^{120}\n/// result[i] = lhs[i] - rhs[i] + bf[i] * 2^{120} - bf[i - 1] < 2^{120}, i = 1..N-2\n/// result[N - 1] = lhs[N - 1] - rhs[N - 1] - bf[N - 2] < 2^{TOP_LIMB_BITS}\n/// result != 0\n///\n/// If `lhs < rhs`, then some limb of `result` would have to borrow from a higher limb,\n/// which is impossible because the top limb cannot borrow\n/// Without the extra borrow, the resulting difference will be wrapped around the `Field` modulus\n/// And won't satisfy the range constraint, since all the limbs are < 2^120\n///\n/// ## Note\n/// `assert_is_not_zero_integer(result)` is crucial. Without it, we could always provide\n/// two identical inputs `x`, `x` and set `borrow_flags = [false; N]`,\n/// which would satisfy the limb constraints.\n///\n/// Also note that `underflow` is not properly constrained, so it just hangs there for\n/// completeness\npub(crate) fn validate_gt(lhs: [u128; N], rhs: [u128; N]) {\n // Safety: compute borrow flags out-of-circuit\n let (underflow, result, borrow_flags): (bool, [u128; N], [bool; N - 1]) =\n unsafe { __validate_gte_with_flags(lhs, rhs) };\n\n // Completeness: require that no underflow occurred\n assert(!underflow, \"validate_gt fail\");\n\n // Constrain the `result` to be a valid `BigNum` value\n validate_in_range::(result);\n // Constrain it to be strict inequality\n assert_is_not_zero_integer(result);\n\n // Constrain `result` and `borrow_flags` to match the expected arithmetic\n check_gte_with_flags(lhs, rhs, result, borrow_flags);\n}\n\n/// Constraining function for the results of `__validate_gte_with_flags`,\n/// used by both `cmp` and `validate gt`\n///\n/// This function checks the relations between `lhs`, `rhs`, `result` adn `borrow_flags`:\n/// lhs[0] - rhs[0] - result[0] + bf[0] * 2^{120} = 0\n/// lhs[i] - rhs[i] - result[i] + bf[i] * 2^{120} - bf[i - 1] = 0, i = 1..N-2\n/// lhs[N - 1] - rhs[N - 1] - result[N - 1] - bf[N - 2] = 0\npub(crate) fn check_gte_with_flags(\n lhs: [u128; N],\n rhs: [u128; N],\n result: [u128; N],\n borrow_flags: [bool; N - 1],\n) {\n let result_limb: Field = (lhs[0] as Field) - (rhs[0] as Field) - (result[0] as Field)\n + (borrow_flags[0] as Field) * TWO_POW_120 as Field;\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) - (rhs[i] as Field) - (result[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n\n let result_limb: Field = (lhs[N - 1] as Field)\n - (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n - (borrow_flags[N - 2] as Field);\n assert(result_limb == 0);\n}\n\n/// Validate that `val` <= `MOD`\n///\n/// Compute `result = MOD - val` along with `borrow_flags`,\n/// then constrain `result` to be a valid `BigNum` value.\n///\n/// Basically the same as `validate_gt` but we compute the result on the fly\n/// It is just a bit more optimized as we expect each `BigNum` value to be \\leq `MOD`\n///\n/// ## Note\n/// In contrast to `validate_gt`, we allow the value to be `MOD`\n/// Since it is consistent with the rest of the library\npub(crate) fn validate_in_field(\n params: BigNumParams,\n val: [u128; N],\n) {\n let modulus: [u128; N] = params.modulus;\n\n // Safety: compute borrow flags out-of-circuit\n let borrow_flags: [bool; (N - 1)] =\n unsafe { __validate_in_field_compute_borrow_flags(params, val) };\n\n let mut p_minus_self: [Field; N] = [0; N];\n p_minus_self[0] = (modulus[0] as Field) - (val[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field);\n for i in 1..N - 1 {\n p_minus_self[i] = (modulus[i] as Field) - (val[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n }\n p_minus_self[N - 1] =\n (modulus[N - 1] as Field) - (val[N - 1] as Field) - (borrow_flags[N - 2] as Field);\n validate_in_range::(p_minus_self);\n}\n\n/// Compare two `BigNum` values\n///\n/// Returns `lhs > rhs`\n///\n/// ## Note\n/// This is a strict value comparison over the integers,\n/// the values do not have to be reduced modulo `MOD`.\npub(crate) fn cmp(lhs: [u128; N], rhs: [u128; N]) -> Ordering {\n // Safety: we constrain:\n // - `result` and `borrow_flags` with `check_gte_with_flags`\n // - `borrow_flags` are also booleans\n // - `underflow` with the following swap and (bool)\n let (underflow, result, borrow_flags): (bool, [u128; N], [bool; N - 1]) =\n unsafe { __validate_gte_with_flags(lhs, rhs) };\n\n // if underflow is true, swap lhs and rhs\n let (lhs, rhs): ([u128; N], [u128; N]) = if underflow { (rhs, lhs) } else { (lhs, rhs) };\n\n // Constrain the `result` to be a valid `BigNum` value\n validate_in_range::(result);\n\n // Constrain subtraction: result = lhs - rhs with borrow_flags\n check_gte_with_flags(lhs, rhs, result, borrow_flags);\n\n if lhs == rhs {\n Ordering::equal()\n } else if underflow {\n Ordering::less()\n } else {\n Ordering::greater()\n }\n}\n\n// ------------------------------ ARITHMETIC FUNCTIONS ------------------------------\n\n/// Negate a `BigNum` value\n///\n/// Computes `result = MOD - val` using limb-wise subtraction with borrow flags,\n/// then constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the subtraction relation with the borrow flags\n///\n/// ## Assumptions\n/// - `val` is a valid `BigNum` in the range `0 <= val <= MOD`.\n///\n/// ## Soundness\n/// This function constrains the following relations:\n/// result[0] = MOD[0] - val[0] + bf[0] * 2^{120} < 2^{120}\n/// result[i] = MOD[i] - val[i] + bf[i] * 2^{120} - bf[i - 1] < 2^{120}, i = 1..N-2\n/// result[N - 1] = MOD[N - 1] - val[N - 1] - bf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// If all `MOD` and `val` limbs are valid `BigNum` limbs, these constraints\n/// ensure that:\n/// - the borrow flags `bf[i]` form a valid limb-wise subtraction chain, and\n/// - no underflow can occur in the subtraction `MOD - val`.\n///\n/// ## Completeness\n/// This function is complete for inputs in the range `0 <= val <= MOD`.\n/// If a value `val > MOD` is passed in (while still `< 2^{MOD_BITS}`), the\n/// constraints above will fail, since there is no valid borrow chain making\n/// `MOD - val` a well-formed `BigNum`.\n///\n/// In practice, honest provers should not hit this case: all functions in this\n/// module are expected to return values `< MOD`.\n///\n/// ## Note\n/// This function returns `MOD` when `val` is zero.\npub(crate) fn neg(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in an unconstrained runtime\n unsafe {\n __neg(params.modulus, val)\n }\n } else {\n // Safety: compute borrow flags out-of-circuit\n let (result, borrow_flags): ([u128; N], [bool; N - 1]) =\n unsafe { __neg_with_flags(params.modulus, val) };\n validate_in_range::(result);\n\n let result_limb: Field = (params.modulus[0] as Field)\n - (val[0] as Field)\n - (result[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (params.modulus[i] as Field)\n - (val[i] as Field)\n - (result[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n\n let result_limb: Field = (params.modulus[N - 1] as Field)\n - (val[N - 1] as Field)\n - (result[N - 1] as Field)\n - (borrow_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Add two `BigNum` values\n///\n/// Computes `result = lhs + rhs` using limb-wise addition with carry flags,\n/// and an optional subtraction of `MOD` using borrow flags. The function then\n/// constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the addition/subtraction relation with the carry/borrow flags and the\n/// `overflow_modulus` bit.\n///\n/// ## Assumptions\n/// - All limbs of `lhs`, `rhs` and `MOD` are valid `BigNum` limbs\n/// (120-bit for non-top limbs, `TOP_LIMB_BITS` for the top limb).\n/// - Semantically, we intend to use this only with `0 <= lhs, rhs < MOD`,\n/// even though the limb/range constraints allow values up to `< 2^{MOD_BITS}`.\n///\n/// ## Soundness (intended relation)\n/// This function constrains the following equations:\n///\n/// result[0] = lhs[0] + rhs[0]\n/// - sub[0]\n/// + bf[0] * 2^{120}\n/// - cf[0] < 2^{120}\n///\n/// result[i] = lhs[i] + rhs[i]\n/// - sub[i]\n/// + bf[i] * 2^{120} - bf[i - 1]\n/// - cf[i] * 2^{120} + cf[i - 1] < 2^{120},\n/// for i = 1..N-2\n///\n/// result[N - 1] = lhs[N - 1] + rhs[N - 1]\n/// - sub[N - 1]\n/// - bf[N - 2]\n/// + cf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// where:\n/// - `bf[i]` are the borrow flags of the optional subtraction,\n/// - `cf[i]` are the carry flags of the addition, and\n/// - `sub` is either the zero vector or `MOD`, depending on the\n/// `overflow_modulus` flag:\n/// * `overflow_modulus = 0` => `sub = 0`\n/// * `overflow_modulus = 1` => `sub = MOD`\n///\n/// If `lhs`, `rhs` and `MOD` are valid `BigNum` limbs and the witness for\n/// `(bf, cf, overflow_modulus)` is the honest one produced by `__add_with_flags`,\n/// these constraints enforce:\n/// - a valid limb-wise carry chain for `lhs + rhs`, and\n/// - a valid limb-wise subtraction chain for either `lhs + rhs` or\n/// `lhs + rhs - MOD`, with no underflow in any limb.\n///\n/// Under these assumptions the constrained result equals:\n///\n/// result = lhs + rhs (mod MOD)\n///\n/// in the intended arithmetic.\n///\n/// ## Limitations / extra satisfying witnesses\n///\n/// The constraint system itself does **not** uniquely determine the carry/borrow\n/// flags nor the `overflow_modulus` bit:\n///\n/// - For each limb `i`, `bf[i]` and `cf[i]` only appear in the combination\n/// `bf[i] * 2^{120} - cf[i] * 2^{120}`. This means that both\n///\n/// (bf[i], cf[i]) = (0, 0) and (bf[i], cf[i]) = (1, 1)\n///\n/// give the same contribution to the equation. As a result, there are multiple\n/// valid flag assignments for the *same* `lhs`, `rhs`, `sub` and `result`.\n///\n/// - More importantly, if `lhs + rhs` is greater than `MOD` but still strictly\n/// less than `2^{MOD_BITS}`, there exist *spurious* witnesses where:\n/// * `overflow_modulus` is set inconsistently with the true arithmetic\n/// overflow, and\n/// * the `(bf, cf)` flags are adjusted accordingly,\n///\n/// such that all equations above still hold and all `result` limbs remain\n/// within range. In particular, when\n///\n/// lhs + rhs + MOD < 2^{MOD_BITS},\n///\n/// a malicious prover can \"hide\" an extra `MOD` inside the choice of\n/// `overflow_modulus`, `bf` and `cf`, so that the circuit is satisfied by a\n/// witness\n///\n/// Consequently, this function is only *conditionally* sound: we rely on the\n/// out-of-circuit implementation of `__add_with_flags` to provide the honest\n/// `(borrow_flags, carry_flags, overflow_modulus)` witness. Under that\n/// assumption, the constrained `result` matches `lhs + rhs (mod MOD)`.\n///\n/// ## Completeness\n///\n/// For inputs in the range `0 <= lhs, rhs < MOD` and honest flags from\n/// `__add_with_flags`, the constraints are complete: every valid `BigNum` sum\n/// `lhs + rhs (mod MOD)` admits a satisfying assignment.\n///\n/// Inputs with `lhs` or `rhs` in `[MOD, 2^{MOD_BITS})` are still representable\n/// as limb arrays and may admit satisfying witnesses, but then the operation\n/// no longer corresponds to a unique, well-defined addition in the field\n/// `Z / MOD Z`. Such uses are outside the intended semantics of this function.\npub(crate) fn add(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in unconstrained runtime\n unsafe {\n __add(params.modulus, lhs, rhs)\n }\n } else {\n // Safety: compute borrow/carry flags out-of-circuit\n let (result, carry_flags, borrow_flags, overflow_modulus): ([u128; N], [bool; N - 1], [bool; N - 1], bool) =\n unsafe { __add_with_flags(params.modulus, lhs, rhs) };\n validate_in_range::(result);\n\n let mut subtrahend: [u128; N] = if overflow_modulus {\n params.modulus\n } else {\n [0; N]\n };\n\n let result_limb: Field = (lhs[0] as Field) + (rhs[0] as Field)\n - (result[0] as Field)\n - (subtrahend[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) + (rhs[i] as Field)\n - (result[i] as Field)\n - (subtrahend[i] as Field)\n - (borrow_flags[i - 1] as Field)\n + (carry_flags[i - 1] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[i] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n }\n let result_limb: Field = (lhs[N - 1] as Field) + (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n - (subtrahend[N - 1] as Field)\n - (borrow_flags[N - 2] as Field)\n + (carry_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Subtract two `BigNum` values\n///\n/// Computes `result = lhs - rhs` using limb-wise subtraction with borrow flags,\n/// and an optional addition of `MOD` using carry flags. The function then\n/// constrains:\n/// - all `result` limbs to be a valid `BigNum` value, and\n/// - the subtraction/addition relation with the carry/borrow flags and the\n/// `underflow_modulus` bit.\n///\n/// ## Assumptions\n/// - All limbs of `lhs`, `rhs` and `MOD` are valid `BigNum` limbs\n/// (120-bit for non-top limbs, `TOP_LIMB_BITS` for the top limb).\n/// - Semantically, we intend to use this only with `0 <= lhs, rhs < MOD`,\n/// even though the limb/range constraints allow values up to `< 2^{MOD_BITS}`.\n///\n/// ## Soundness (intended relation)\n/// This function constrains the following equations:\n///\n/// result[0] = lhs[0] - rhs[0]\n/// + add[0]\n/// + bf[0] * 2^{120}\n/// - cf[0] < 2^{120}\n///\n/// result[i] = lhs[i] - rhs[i]\n/// + add[i]\n/// + bf[i] * 2^{120} - bf[i - 1]\n/// - cf[i] * 2^{120} + cf[i - 1] < 2^{120},\n/// for i = 1..N-2\n///\n/// result[N - 1] = lhs[N - 1] - rhs[N - 1]\n/// + add[N - 1]\n/// - bf[N - 2]\n/// + cf[N - 2] < 2^{TOP_LIMB_BITS}\n///\n/// where:\n/// - `bf[i]` are the borrow flags of the subtraction,\n/// - `cf[i]` are the carry flags of the optional addition, and\n/// - `add` is either the zero vector or `MOD`, depending on the\n/// `underflow_modulus` flag:\n/// * `underflow_modulus = 0` => `add = 0`\n/// * `underflow_modulus = 1` => `add = MOD`\n///\n/// If `lhs`, `rhs` and `MOD` are valid `BigNum` limbs and the witness for\n/// `(bf, cf, underflow_modulus)` is the honest one produced by `__sub_with_flags`,\n/// these constraints enforce:\n/// - a valid limb-wise borrow chain for `lhs - rhs`, and\n/// - a valid limb-wise addition chain for either `lhs - rhs` or\n/// `lhs - rhs + MOD`, with no underflow in any limb.\n///\n/// Under these assumptions the constrained result equals:\n///\n/// result = lhs - rhs (mod MOD)\n///\n/// in the intended arithmetic.\n///\n/// ## Limitations / extra satisfying witnesses\n///\n/// The constraint system itself does **not** uniquely determine the carry/borrow\n/// flags nor the `underflow_modulus` bit:\n///\n/// - For each limb `i`, `bf[i]` and `cf[i]` only appear in the combination\n/// `bf[i] * 2^{120} - cf[i] * 2^{120}`. This means that both\n///\n/// (bf[i], cf[i]) = (0, 0) and (bf[i], cf[i]) = (1, 1)\n///\n/// give the same contribution to the equation. As a result, there are multiple\n/// valid flag assignments for the *same* `lhs`, `rhs`, `add` and `result`.\n///\n/// - More importantly, when `lhs < rhs`, the true field result is\n///\n/// lhs - rhs + MOD,\n///\n/// and as long as\n///\n/// lhs - rhs + MOD < 2^{MOD_BITS},\n///\n/// a malicious prover can:\n/// * set `underflow_modulus` inconsistently with the true underflow, and\n/// * adjust the `(bf, cf)` flags accordingly,\n///\n/// such that all equations above still hold and all `result` limbs remain\n/// within range. In other words, the circuit can be satisfied by a witness\n/// that does **not** correspond to the unique intended subtraction modulo\n/// `MOD` for some inputs with `lhs < rhs`.\n///\n/// Consequently, this function is only *conditionally* sound: we rely on the\n/// out-of-circuit implementation of `__sub_with_flags` to provide the honest\n/// `(borrow_flags, carry_flags, underflow_modulus)` witness. Under that\n/// assumption, the constrained `result` matches `lhs - rhs (mod MOD)`.\n///\n/// ## Completeness\n///\n/// For inputs in the range `0 <= lhs, rhs < MOD` and honest flags from\n/// `__sub_with_flags`, the constraints are complete: every valid `BigNum`\n/// difference `lhs - rhs (mod MOD)` admits a satisfying assignment.\n///\n/// Inputs with `lhs` or `rhs` in `[MOD, 2^{MOD_BITS})` are still representable\n/// as limb arrays and may admit satisfying witnesses, but then the operation\n/// no longer corresponds to a unique, well-defined subtraction in the field\n/// `Z / MOD Z`. Such uses are outside the intended semantics of this function.\npub(crate) fn sub(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n if std::runtime::is_unconstrained() {\n // Safety: no need to constrain in unconstrained runtime\n unsafe {\n __sub(params.modulus, lhs, rhs)\n }\n } else {\n // Safety: we constrain carry, borrow, underflow and result immediately\n let (result, carry_flags, borrow_flags, underflow_modulus): ([u128; N], [bool; N - 1], [bool; N - 1], bool) =\n unsafe { __sub_with_flags(params.modulus, lhs, rhs) };\n validate_in_range::(result);\n\n let mut addend: [u128; N] = if underflow_modulus {\n params.modulus\n } else {\n [0; N]\n };\n\n let result_limb: Field = (lhs[0] as Field) - (rhs[0] as Field) - (result[0] as Field)\n + (addend[0] as Field)\n + (borrow_flags[0] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[0] as Field) * (TWO_POW_120 as Field);\n assert(result_limb == 0);\n\n for i in 1..N - 1 {\n let result_limb: Field = (lhs[i] as Field) - (rhs[i] as Field) - (result[i] as Field)\n + (addend[i] as Field)\n + (borrow_flags[i] as Field) * (TWO_POW_120 as Field)\n - (carry_flags[i] as Field) * (TWO_POW_120 as Field)\n - (borrow_flags[i - 1] as Field)\n + (carry_flags[i - 1] as Field);\n assert(result_limb == 0);\n }\n let result_limb: Field = (lhs[N - 1] as Field)\n - (rhs[N - 1] as Field)\n - (result[N - 1] as Field)\n + (addend[N - 1] as Field)\n - (borrow_flags[N - 2] as Field)\n + (carry_flags[N - 2] as Field);\n assert(result_limb == 0);\n result\n }\n}\n\n/// Compute the `BigNum` multiplication\n///\n/// Computes `result = lhs * rhs (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__mul`.\n/// 2. Constraining the quadratic relation `lhs * rhs - result = 0` with\n/// `evaluate_quadratic_expression`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `lhs * rhs - result = 0`\n///\n/// ## Note\n/// When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `mul`\npub(crate) fn mul(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n // Safety: we constrain the multiplication result immediately after\n let result: [u128; N] = unsafe { __mul::(params, lhs, rhs) };\n if !std::runtime::is_unconstrained() {\n // lhs * rhs - result = 0\n evaluate_quadratic_expression(\n params,\n [[lhs]],\n [[false]],\n [[rhs]],\n [[false]],\n [result],\n [true],\n );\n }\n result\n}\n\n/// Compute the `BigNum` squaring\n///\n/// Computes `result = val * val (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__sqr`.\n/// 2. Constraining the quadratic relation `val * val - result = 0` with\n/// `evaluate_quadratic_expression`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `val * val - result = 0`\n///\n/// ## Note\n/// When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `sqr`\npub(crate) fn sqr(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n // Safety: we constrain the multiplication result immediately after\n let result: [u128; N] = unsafe { __sqr::<_, MOD_BITS>(params, val) };\n if !std::runtime::is_unconstrained() {\n // val * val - result = 0\n evaluate_quadratic_expression(\n params,\n [[val]],\n [[false]],\n [[val]],\n [[false]],\n [result],\n [true],\n );\n }\n result\n}\n\n/// Compute the `BigNum` division\n///\n/// Computes `result = lhs * rhs^{-1} (mod MOD)` by:\n/// 1. Computing `result` out of circuit via `__div`.\n/// 2. Constraining the quadratic relation `result * rhs - lhs = 0` with\n/// `evaluate_quadratic_expression`.\n/// 3. Enforcing `rhs != 0 (mod MOD)`.\n///\n/// ## Soundness\n/// Soundness reduces to `evaluate_quadratic_expression` for the relation\n/// `result * rhs - lhs = 0`, together with the non-zero check on `rhs` and the\n/// assumption that `MOD` has multiplicative inverses for all non-zero elements\n/// (`params.has_multiplicative_inverse = true`).\n///\n/// ## Note\n/// - This is **expensive** in witness time due to modular inversion.\n/// - When possible, prefer expressing your computation directly as a quadratic\n/// relation and calling `evaluate_quadratic_expression` instead of using `div`.\n/// - In the unconstrained runtime, the behavior of `__div` on zero divisors is\n/// not constrained by this function.\npub(crate) fn div(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n assert(\n params.has_multiplicative_inverse,\n \"BigNum has no multiplicative inverse. Use udiv for unsigned integer division\",\n );\n // Safety: We constrain the result of division immediately after\n let result: [u128; N] = unsafe { __div::<_, MOD_BITS>(params, lhs, rhs) };\n if !std::runtime::is_unconstrained() {\n // result * rhs - lhs = 0\n evaluate_quadratic_expression(\n params,\n [[result]],\n [[false]],\n [[rhs]],\n [[false]],\n [lhs],\n [true],\n );\n assert_is_not_zero(params, rhs);\n }\n result\n}\n\n/// Compute the `BigNum` integer division with remainder\n///\n/// Computes `quotient = floor(numerator / divisor)` and\n/// `remainder = numerator % divisor` by:\n/// 1. Computing `(quotient, remainder)` out of circuit via `__udiv_mod`.\n/// 2. Constraining the quadratic relation\n/// quotient * divisor + remainder - numerator = 0\n/// with `validate_udiv_mod_expression`.\n/// 3. Enforcing `remainder < divisor`.\n///\n/// ## Soundness\n/// Soundness reduces to `validate_udiv_mod_expression` for the relation\n/// quotient * divisor + remainder - numerator = 0,\n/// together with `remainder < divisor` check enforced via `validate_gt`.\n///\n/// Under these checks, any satisfying assignment corresponds to a valid\n/// integer division `numerator = quotient * divisor + remainder` with\n/// `0 <= remainder < divisor`\n///\n/// ## Note\n/// Enforcing `divisor != 0` is not necessary. `remainder < divisor`\n/// Already enforces this.\npub(crate) fn udiv_mod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> ([u128; N], [u128; N]) {\n // Safety: We constrain the result of __udiv_mod immediately after\n let (quotient, remainder): ([u128; N], [u128; N]) = unsafe { __udiv_mod(numerator, divisor) };\n if !std::runtime::is_unconstrained() {\n // quotient * divisor + remainder - numerator = 0\n validate_udiv_mod_expression::(numerator, divisor, quotient, remainder);\n // remainder < divisor\n validate_gt::(divisor, remainder);\n }\n (quotient, remainder)\n}\n\n/// Compute the `BigNum` integer division\n///\n/// Returns `floor(numerator / divisor)`.\n/// All constraints and soundness details are handled inside `udiv_mod`.\npub(crate) fn udiv(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n udiv_mod::(numerator, divisor).0\n}\n\n/// Compute the `BigNum` remainder\n///\n/// Returns `numerator % divisor`.\n/// All constraints and soundness details are handled inside `udiv_mod`.\npub(crate) fn umod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n udiv_mod::(numerator, divisor).1\n}", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/constrained_ops.nr" - }, - "121": { - "source": "use crate::utils::split_bits;\n\nuse crate::constants::{TWO_POW_120, TWO_POW_126, TWO_POW_246};\n\nuse crate::fns::constrained_ops::{validate_in_range, validate_quotient_in_range};\nuse crate::fns::unconstrained_helpers::__barrett_reduction;\nuse crate::fns::unconstrained_ops::__is_zero;\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ UNCONSTRAINED EXPRESSIONS ------------------------------\n\n/// Compute the result of a linear combination of (possibly negative) `BigNum` values (unconstrained)\n///\n/// ## Note\n/// 1. `modulus2` is structured such that all limbs will be greater than `0`, even when subtracting.\n/// To do this, when computing `p - x`, we ensure that each limb in `p` is greater than each limb in `x`.\n/// We know that, for a valid bignum element, the limbs in `x` will be < 2^{120}\n/// Therefore each of the limbs in `p` (except the most significant) will borrow 2^{120} from the more significant limb.\n/// Finally, to ensure we do not underflow in the most significant limb, we use `2p` instead of `p`\n///\n/// 2. Returns the `Field` values that are not normalized to be 120-bit\nunconstrained fn __add_linear_expression(\n params: BigNumParams,\n vals: [[u128; N]; M],\n flags: [bool; M],\n) -> ([Field; N]) {\n let mut sum: [Field; N] = [0; N];\n let modulus2: [u128; N] = params.double_modulus;\n for i in 0..M {\n if (flags[i]) {\n for j in 0..N {\n sum[j] = sum[j] + (modulus2[j] as Field) - (vals[i][j] as Field);\n }\n } else {\n for j in 0..N {\n sum[j] = sum[j] + (vals[i][j] as Field);\n }\n }\n }\n sum\n}\n\n/// Compute the limb products of a quadratic expression (unconstrained)\n///\n/// See `__compute_quadratic_expression_with_borrow_flags` for full description\n///\n/// ## Note\n/// Returns the `Field` values that are not normalized to be 120-bit\nunconstrained fn __compute_quadratic_expression_product(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> [Field; 2 * N] {\n let mut lhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n let mut rhs: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n\n for i in 0..NUM_PRODUCTS {\n lhs[i] = __add_linear_expression(params, lhs_terms[i], lhs_flags[i]);\n rhs[i] = __add_linear_expression(params, rhs_terms[i], rhs_flags[i]);\n }\n let add: [Field; N] = __add_linear_expression(params, linear_terms, linear_flags);\n\n let mut mulout: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n for k in 0..NUM_PRODUCTS {\n mulout[i + j] += lhs[k][i] * rhs[k][j];\n }\n }\n mulout[i] += add[i];\n }\n mulout\n}\n\n/// Compute the borrow flags for a limb-wise subtraction `lhs - rhs` (unconstrained).\n///\n/// This helper operates on `N`-limb values where each limb is interpreted as a\n/// 120-bit chunk (base `B = 2^{120}`), but where intermediate limbs may exceed\n/// `2^{120}` due to sums of products.\n///\n/// Conceptually, we want to model the integer subtraction\n///\n/// lhs - rhs\n///\n/// as a base-`B` subtraction with borrows, without allowing any intermediate\n/// values to go negative in the circuit field. We achieve this by:\n///\n/// 1. Working with widened 246-bit ranges per limb.\n/// 2. Encoding a borrow from limb `i+1` into limb `i` by:\n/// - adding `2^{246}` into limb `i`,\n/// - subtracting `2^{126}` (= 2^{246 - 120}) from limb `i+1` after\n/// scaling by `2^{-120}`.\n///\n/// The returned `borrow_flags[i]` indicate whether the canonical integer\n/// subtraction would borrow from limb `i+1` into limb `i`. These flags are\n/// later re-applied in-circuit via `apply_borrow_flags`, and the resulting\n/// limbs are checked by `validate_expression_is_zero`.\nunconstrained fn __compute_borrow_flags(\n mut lhs_limbs: [Field; N],\n rhs_limbs: [Field; N],\n) -> [bool; N - 1] {\n // compute borrow flags from mulout_p and mulout_n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let borrow_shift: Field = TWO_POW_246; // 2^{246}\n let borrow_carry: Field = TWO_POW_126; // 2^{126} = 2^{246 - 120}\n let downshift_120: Field = 1 / (TWO_POW_120 as Field);\n\n // determine whether we need to borrow from more significant limbs.\n // initial limb is \"simple\" comparison operation\n borrow_flags[0] = lhs_limbs[0].lt(rhs_limbs[0]);\n\n // we have N - 1 borrow flags. The number of limbs is N\n // and there is nothing to borrow against for the final limb.\n let mut hi_bits: Field =\n (lhs_limbs[0] - rhs_limbs[0] + ((borrow_flags[0] as Field) * borrow_shift)) * downshift_120;\n\n for i in 1..(N - 1) {\n // compute the contribution from limb `i-1` that gets added into limb `i`, and add into limb `i`\n lhs_limbs[i] += hi_bits;\n\n let subtrahend: Field = rhs_limbs[i] + (borrow_flags[i - 1] as Field) * borrow_carry;\n\n // determine whether negative limb values are greater than positive limb values\n borrow_flags[i] = lhs_limbs[i].lt(subtrahend);\n let minuend: Field = lhs_limbs[i] + (borrow_flags[i] as Field) * borrow_shift;\n\n hi_bits = (minuend - subtrahend) * downshift_120;\n }\n borrow_flags\n}\n\n/// Given a degree-2 `BigNum` expression that is equal to `0 mod MOD`, compute\n/// the quotient and the borrow flags (unconstrained).\n///\n/// The expression has the form:\n///\n/// sum_{k=0}^{NUM_PRODUCTS-1} (L_k * R_k) + sum_{i=0}^{ADD_N-1} A_i = quotient * MOD\n///\n/// where each `L_k`, `R_k`, `A_i` is an `N`-limb `BigNum` assembled from the\n/// `(terms, flags)` arrays.\n///\n/// This helper:\n/// 1. Evaluates the quadratic expression into `mulout_p` as a `2N`-limb\n/// non-normalized value.\n/// 2. Normalizes `mulout_p` into 120-bit limbs and applies Barrett\n/// reduction to obtain `(quotient, remainder)`.\n/// 3. Asserts that the integer remainder is zero (debugging aid; range\n/// checks enforce this later).\n/// 4. Reconstructs `mulout_n = quotient * MOD`.\n/// 5. Computes `borrow_flags` for the limb-wise subtraction\n/// `mulout_p - mulout_n`,\n/// using the 2^{246}/2^{126} encoding described in\n/// `evaluate_quadratic_expression`.\n///\n/// The returned `quotient` and `borrow_flags` are later constrained\n/// in-circuit by `compute_quadratic_expression_with_modulus` and\n/// `evaluate_quadratic_expression`.\nunconstrained fn __compute_quadratic_expression_with_borrow_flags(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([u128; N], [bool; 2 * N - 2]) {\n let mulout_p: [Field; 2 * N] = __compute_quadratic_expression_product(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n\n // `__normalize_limbs` will validate that we do not overflow 2N, normally we should not overflow 2N-1\n let mut relation_result: [u128; 2 * N] = split_bits::__normalize_limbs(mulout_p);\n let (quotient, remainder): ([u128; N], [u128; N]) =\n __barrett_reduction(relation_result, params.redc_param, MOD_BITS, params.modulus);\n\n // This is verified later by the range checks but left for debugging purposes\n assert(__is_zero(remainder));\n\n // We do not normalize `mulout_n` so we won't fill the `2 * N - 1`\n let mut mulout_n: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n mulout_n[i + j] += (quotient[i] as Field) * (params.modulus[j] as Field);\n }\n }\n\n let borrow_flags: [bool; 2 * N - 1] = __compute_borrow_flags(mulout_p, mulout_n);\n\n // We have to copy it because we know that borrow_flags[2 * N - 1] is always 0\n // But we also have to provide 2 * N limbs to `__barrett_reduction`.\n // And keep `__compute_borrow_flags` generic enough\n let mut borrow_flags_real: [bool; 2 * N - 2] = [false; 2 * N - 2];\n for i in 0..2 * N - 2 {\n borrow_flags_real[i] = borrow_flags[i];\n }\n\n (quotient, borrow_flags_real)\n}\n\n/// Computes the quotient/remainder of a quadratic expression (unconstrained)\n///\n/// See `__compute_quadratic_expression_with_borrow_flags` for full description\npub(crate) unconstrained fn __compute_quadratic_expression(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([u128; N], [u128; N]) {\n let mulout: [Field; 2 * N] = __compute_quadratic_expression_product(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n // __normalize_limbs will validate that we do not overflow 2N, normally we should not overflow 2N-1\n let mut relation_result: [u128; 2 * N] = split_bits::__normalize_limbs(mulout);\n\n let (quotient, remainder): ([u128; N], [u128; N]) =\n __barrett_reduction(relation_result, params.redc_param, MOD_BITS, params.modulus);\n\n (quotient, remainder)\n}\n\n// ------------------------------ CONSTRAINED EXPRESSIONS ------------------------------\n\n/// Constrained version of `__add_linear_expression`\n///\n/// Computes all the linear parts of an expression in-circuit\n///\n/// ## Note\n/// 1. Negative terms are implemented by adding `double_modulus`\n/// `double_modulus` is chosen so that all limbs except the top one\n/// are > 2^{120}, which prevents underflows in intermediate computations.\n///\n/// 2. For the most significant limb we slightly reduce the padding (to keep the\n/// overall value equal to `2 * MOD`), so in principle there is a narrow edge\n/// case where that limb could underflow if enough negative contributions are\n/// accumulated and the top limb of `MOD` is very small. In practice, the\n/// global `BigNum` range and operand-count assumptions in\n/// `evaluate_quadratic_expression` rule out such patterns.\nfn compute_linear_expressions(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> ([[Field; N]; NUM_PRODUCTS], [[Field; N]; NUM_PRODUCTS], [Field; N]) {\n // lhs linear terms\n let mut lhs_linear: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n // rhs linear terms\n let mut rhs_linear: [[Field; N]; NUM_PRODUCTS] = [[0; N]; NUM_PRODUCTS];\n // linear terms\n let mut lin_expr: [Field; N] = [0; N];\n\n for k in 0..NUM_PRODUCTS {\n for i in 0..N {\n for j in 0..LHS_N {\n // Note: if lhs_flags[k][j] - `is_negative` is not known at comptime this is very expensive\n if (lhs_flags[k][j]) {\n lhs_linear[k][i] -= lhs_terms[k][j][i] as Field;\n lhs_linear[k][i] += params.double_modulus[i] as Field;\n } else {\n lhs_linear[k][i] += lhs_terms[k][j][i] as Field;\n }\n }\n for j in 0..RHS_N {\n // Note: if rhs_flags[k][j] - `is_negative` is not known at comptime this is very expensive\n if (rhs_flags[k][j]) {\n rhs_linear[k][i] -= rhs_terms[k][j][i] as Field;\n rhs_linear[k][i] += params.double_modulus[i] as Field;\n } else {\n rhs_linear[k][i] += rhs_terms[k][j][i] as Field;\n }\n }\n }\n }\n\n for i in 0..N {\n for j in 0..ADD_N {\n // Note: if linear_flags[j] - `is_negative` is not known at comptime this is very expensive\n if (linear_flags[j]) {\n lin_expr[i] -= linear_terms[j][i] as Field;\n lin_expr[i] += params.double_modulus[i] as Field;\n } else {\n lin_expr[i] += linear_terms[j][i] as Field;\n }\n }\n }\n\n (lhs_linear, rhs_linear, lin_expr)\n}\n\n/// Constrained version of `__compute_quadratic_expression_product`\n///\n/// Computes the following expression in-circuit:\n/// \\sum (L_i * R_i) + \\sum (A_i) - QUOTIENT * MOD\n///\n/// Because of the subtraction of `QUOTIENT * MODULUS`, the resulting limbs may\n/// underflow and represent *negative* values. To account for this, we allow the\n/// prover to choose a sequence of borrow flags and interpret the limbs with\n/// additional terms:\n///\n/// - for each limb `i` we may add `2^{246}` (via a flag at position `i`);\n/// - for each limb `i` we may subtract `2^{126 = 246 - 120}` (via the flag\n/// at position `i - 1`).\n///\n/// This corresponds to borrowing `2^{126}` from limb `i + 1` and adding\n/// `2^{246}` into limb `i`. After this adjustment, an honest prover can ensure\n/// that every limb lies in `[0, 2^{246})` and that the adjusted limbs encode\n/// the correct integer value.\n///\n/// Additionally, we constrain the quotient limbs via `validate_quotient_in_range`:\n/// - limbs `0..N-2` of `quotient` are < 2^{120};\n/// - the top limb is < 2^{TOP_LIMB_BITS + 6}.\n/// Which validates `quotient < 2^{MOD_BITS + 6}`\n///\n/// ## TODO\n/// Apply static or runtime checks in this method to validate that the effective\n/// `twiddle_factor` does not exceed 6 under the chosen parameters.\nfn compute_quadratic_expression_with_modulus(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) -> [Field; 2 * N - 1] {\n // Safety: use an unconstrained function to compute the value of the quotient and borrow_flags out-of-circuit\n let (quotient, borrow_flags): ([u128; N], [bool; 2 * N - 2]) = unsafe {\n __compute_quadratic_expression_with_borrow_flags::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n )\n };\n\n // Constrain the `quotient < 2^{MOD_BITS + 6}`\n // By constraining limbs(0..N-2) to be < 2^120 and the the top limb < 2^{TOP_LIMB_BITS + 6}\n validate_quotient_in_range::(quotient);\n\n // Compute the linear sums that represent L_i, R_i, A\n let (lhs_linear, rhs_linear, lin_expr): ([[Field; N]; NUM_PRODUCTS], [[Field; N]; NUM_PRODUCTS], [Field; N]) = compute_linear_expressions::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n\n // We want to evaluate that L * R + A - Quotient * MOD = 0, evaluated over the integers\n // For this we need to be able to borrow values from more-significant limbs into less-significant limbs,\n // so that we can ensure that no limbs will underflow\n let mut expression_limbs: [Field; 2 * N - 1] = [0; 2 * N - 1];\n\n // Compute the product t0 * t1 + t4 - Quotient * MOD\n // TODO: this is super nasty as it requires a multiplication\n for i in 0..N {\n for j in 0..N {\n for k in 0..NUM_PRODUCTS {\n if k == 0 {\n let new_term: Field = lhs_linear[k][i] * rhs_linear[k][j]\n - (quotient[i] as Field) * (params.modulus[j] as Field);\n // width-4 optimization\n std::as_witness(new_term);\n expression_limbs[i + j] += new_term;\n } else {\n expression_limbs[i + j] += lhs_linear[k][i] * rhs_linear[k][j];\n }\n }\n // This is the fallback for pure linear expression\n if (NUM_PRODUCTS == 0) {\n expression_limbs[i + j] -= (quotient[i] as Field) * (params.modulus[j] as Field);\n }\n }\n expression_limbs[i] += lin_expr[i];\n }\n\n apply_borrow_flags(expression_limbs, borrow_flags)\n}\n\n/// Apply a precomputed borrow chain to a limb array.\n///\n/// Given:\n///\n/// - `expression_limbs`: an `N`-limb array of `Field` values representing a\n/// (possibly non-normalized) degree-2-style expression, and\n/// - `borrow_flags[i]` indicating that we \"borrow\" from limb `i+1` into limb `i`,\n///\n/// this function applies the same 2^{246}/2^{126} encoding used in\n/// `__compute_borrow_flags` to produce an adjusted limb array\n///\n/// This matches the behavior of `__compute_borrow_flags`, which conceptually:\n///\n/// 1. Adds `2^{246}` into a limb when a borrow is taken at that limb;\n/// 2. After scaling by `2^{-120}`, contributes `2^{126}` into the next limb.\n///\n/// The resulting `expression_limbs` can then be passed to\n/// `validate_expression_is_zero`, which:\n///\n/// - right-shifts by 120 bits per limb,\n/// - enforces a 126-bit bound,\n/// - and propagates carries forward, finally checking that the most\n/// significant limb is zero.\n///\n/// ## Assumptions\n///\n/// - `borrow_flags` was computed consistently with the original construction\n/// of `expression_limbs` (e.g. via `__compute_borrow_flags` on the\n/// corresponding unconstrained expression).\n/// - The caller has ensured that each adjusted limb remains < 2^{246} for\n/// honest witnesses (e.g. via `NUM_PRODUCTS < 64`).\n///\n/// ## Note\n///\n/// This function does not itself enforce any bit-size bounds; it only applies\n/// the borrow encoding. The actual range checks happen later in\n/// `validate_expression_is_zero`.\n///\n/// ## TODO\n/// define trade-offs regarding the value of borrow_shift\n/// (the larger the value, the greater the range check that is required on product_limbs)\n/// (126-bit range check is a sweet spot for the barretenberg backend as it decomposes into 9 14-bit range checks)\n/// (the barretenberg backend can evaluate these in 5.25 gates. 127 bits costs 6.5 gates)\nfn apply_borrow_flags(\n mut expression_limbs: [Field; N],\n borrow_flags: [bool; N - 1],\n) -> [Field; N] {\n let borrow_shift: Field = TWO_POW_246; // 2^{246}\n let borrow_carry: Field = TWO_POW_126; // 2^{246 - 120} = 2^{126}\n\n // Get the product_limbs into the form where each entry is a 246-bit value\n expression_limbs[0] += (borrow_flags[0] as Field) * borrow_shift;\n for i in 1..(N - 1) {\n expression_limbs[i] += (borrow_flags[i] as Field) * borrow_shift\n - (borrow_flags[i - 1] as Field) * borrow_carry;\n }\n expression_limbs[N - 1] -= (borrow_flags[N - 2] as Field) * borrow_carry;\n expression_limbs\n}\n\n/// Validate that `limbs` represent the integer value `0`\n///\n/// ## Assumptions\n/// - `limbs` is an array of `Field` values that was derived arithmetically as\n/// a degree-2 expression\n/// - each limb satisfies `limbs[i] < 2^{246}`, as ensured by\n/// `compute_quadratic_expression_with_modulus` under its parameter bounds.\n///\n/// ## Details\n/// Each element `i` in `limbs` overlaps in bit-range with element `i+1`, EXCEPT for the low 120 bits\n/// i.e. we need to do the following for each limb `i`:\n/// 1. validate the limb's low-120 bits equals zero\n/// 2. compute the limb \"carry\" by right-shifting by 2^{120}\n/// 3. propagate the \"carry\" into limb `i+1`\n/// We can efficiently do all of the above by multiplying the limb by 2^{-120} and constraining the result to be <2^{126}\n///\n/// If the low 120 bits are nonzero, there is no value in `[0, 2^{126})` that\n/// could have produced this limb after multiplying by `2^{120}`. Since\n/// multiplication by `2^{120}` is a bijection on the Field, any limb with\n/// non-zero low 120 bits must map outside the `[0, 2^{126})` range after\n/// scaling by `2^{-120}`.\n///\n/// The most significant limb has no limb to \"carry\" values into - the entire limb must equal zero\n///\n/// ## Note\n/// The constant 126 is not arbitrary. We use 120-bit limbs and allow up to 64\n/// products per limb, which contributes at most `log2(64) = 6` bits of headroom.\n/// After scaling by `2^{-120}`, honest witnesses fit in 126 bits. We could in\n/// principle go higher (up to roughly `CircuitModulusBits - 121`), but 126 is\n/// the minimal bound consistent with `NUM_PRODUCTS < 64` and is significantly\n/// cheaper than larger bounds for the barretenberg backend.\nfn validate_expression_is_zero(mut limbs: [Field; N]) {\n let hi_shift: Field = TWO_POW_120 as Field;\n let hi_downshift: Field = 1 / hi_shift;\n for i in 0..N - 1 {\n limbs[i] *= hi_downshift;\n std::as_witness(limbs[i]);\n limbs[i].assert_max_bit_size::<126>(); // N.B. is this sufficient? going beyond 126 costs us 1 gate per limb\n limbs[i + 1] += limbs[i];\n }\n assert(limbs[N - 1] == 0);\n}\n\n/// Constrain a degree-2 `BigNum` expression to be equal to 0 (mod `MOD`)\n///\n//\n/// This method is intended for relations where the remainder term of the\n/// degree-2 expression is exactly zero as an integer relation. In other words,\n/// we use it only when we expect:\n///\n/// \\sum (L_i * R_i) + \\sum (A_i) - QUOTIENT * MOD = 0\n///\n/// as integers, not just modulo the circuit field or `BigNum` field.\n///\n/// ## Details\n///\n/// The constrained expression, viewed over the integers, is:\n///\n/// \\sum_{i=0}^{NUM_PRODUCTS-1} (L_i * R_i)\n/// + \\sum_{i=0}^{ADD_N-1} (A_i)\n/// - QUOTIENT * MOD\n/// = 0\n///\n/// Each `L_i`, `R_i`, `A_i` is an `N`-limb `BigNum` assembled from the\n/// `(terms, flags)` arrays. For example, for `i = 0`:\n///\n/// L_0 = \\sum_{j=0}^{LHS_N-1} lhs[0][j] as a `BigNum`\n/// R_0 = \\sum_{j=0}^{RHS_N-1} rhs[0][j] as a `BigNum`\n///\n/// The intent is to capture a generic degree-2 expression within Noir's\n/// limitations (no efficient dynamically sized vectors).\n///\n/// The expensive parts of this algorithm are:\n/// 1. evaluating the limb products required to compute the `L_i * R_i` values;\n/// 2. applying range constraints to validate that the result encodes 0.\n///\n/// ## Note\n/// When the expression is evaluated over `N`-limb `BigNum` values, the product\n/// has up to `2N - 1` significant limbs. Each limb is a sum of at most\n/// `NUM_PRODUCTS` products of `linear` 120-bit limbs and `quadratic` 240-bit-ish limbs\n///\n/// Note that:\n/// * limb-wise multiplication is not uniform across indices. For example:\n///\n/// [x0, x1, x2] * [y0, y1, y2] =\n/// [\n/// x0*y0, // 1 term\n/// x0*y1 + x1*y0, // 2 terms\n/// x0*y2 + x1*y1 + x2*y0, // 3 terms\n/// x1*y2 + x2*y1, // 2 terms\n/// x2*y2 // 1 term\n/// ]\n/// The number of partial products per limb grows linearly from 1 to N,\n/// then decreases linearly back to 1.\n///\n/// * we also allow linear combinations inside the products, which further increases the bound\n/// on a `quadratic` limb\n///\n/// * finally, when `is_negative` flag is set, we effectively add 2 * MOD to each limb, where\n/// 2 * MOD limbs are structured in such a way that they all are > 2**120\n///\n/// We allow `NUM_PRODUCTS < 64` completeness-wise, but it certainly can overflow the 2^{240 + `twiddle_factor=6`} bound\n/// in edge cases. See completeness section for an example.\n///\n/// ## Assumptions\n///\n/// Each `BigNum` value used in this gadget is already range constrained:\n/// - limbs `0..N-2` satisfy `limb_i < 2^{120}`\n/// - limb `N-1` satisfies `limb_{N-1} < 2^{TOP_LIMB_BITS}`\n///\n/// ## Completeness\n/// If an honest prover supplies inputs that satisfy the assumptions above,\n/// it can always find a `quotient` and `borrow_flags` such that the integer\n/// relation holds and all constraints are satisfied.\n///\n/// The only possibility to break completeness is by providing too many inputs, for example:\n///\n/// (a0 + a1 + a2) * (b0 + b1 + b2) + ... (60 times), with each a_i having its limbs at maximum value of 2^{120} - 1\n/// The middle limb will contain a value that will definitely overflow the 2^{246} bound.\n///\n/// ## Soundness\n/// This function is conditionally sound: it enforces that the degree-2 relation\n/// holds modulo `MOD`, but it does not, by itself, enforce that any particular\n/// term (for example a result `z`) is a *canonical* representative in\n/// `[0, MOD)`.\n///\n/// In other words, if the surrounding relation is invariant under adding a\n/// multiple of `MOD` to one of its terms, then a dishonest prover can exploit\n/// this. For example, consider a multiplication relation:\n///\n/// x * y - z = 0 (mod MOD)\n///\n/// Internally we encode this as:\n///\n/// x * y + 2 * MOD - z - quotient * MOD = 0\n///\n/// which is equivalent to:\n///\n/// x * y - z = (quotient - 2) * MOD\n///\n/// Suppose the honest witness uses some `z` satisfying\n/// `0 <= z < MOD` and some `quotient`. If the `BigNum` encoding allows\n/// `z' = z + MOD` (i.e. `z' < 2^{MOD_BITS}` still holds), then a dishonest\n/// prover can instead provide:\n///\n/// z' = z + MOD\n/// quotient' = quotient - 1\n///\n/// and still satisfy:\n///\n/// x * y + 2 * MOD - z' - quotient' * MOD = 0\n///\n/// even though `z'` is no longer the canonical representative of `x * y mod MOD`.\n///\n/// The same consideration applies to almost every constrained `BigNum` relation:\n/// whenever a value participates *only* through a modular equality, and no\n/// separate range constraint is imposed on that value, the prover is free to\n/// shift it by an extra `MOD` as long as the resulting limb\n/// encoding still satisfies its bit-bounds. This is inherent in working with\n/// modular constraints; the responsibility for enforcing canonical\n/// representatives lies with the caller when it is required.\n///\n/// This is the same \"extra modulus\" phenomenon as in the `add`/`sub` functions:\n/// the constraints are sound for modular arithmetic, but any caller that\n/// requires canonical outputs in `[0, MOD)` must additionally enforce a\n/// range check (for example via `validate_in_field`) on the relevant terms.\npub(crate) fn evaluate_quadratic_expression(\n params: BigNumParams,\n lhs_terms: [[[u128; N]; LHS_N]; NUM_PRODUCTS],\n lhs_flags: [[bool; LHS_N]; NUM_PRODUCTS],\n rhs_terms: [[[u128; N]; RHS_N]; NUM_PRODUCTS],\n rhs_flags: [[bool; RHS_N]; NUM_PRODUCTS],\n linear_terms: [[u128; N]; ADD_N],\n linear_flags: [bool; ADD_N],\n) {\n assert(NUM_PRODUCTS < 64, f\"evaluate_quadratic_expression overflow in operands count\");\n // NUM_PRODUCTS < 64 is a light bound that tries to ensure each limb sum < 2^{246} so that the 126-bit bound is valid.\n\n lhs_terms.for_each(|lhs_limbs: [[u128; N]; LHS_N]| {\n lhs_limbs.for_each(|term: [u128; N]| validate_in_range::(term))\n });\n rhs_terms.for_each(|rhs_limbs: [[u128; N]; RHS_N]| {\n rhs_limbs.for_each(|term: [u128; N]| validate_in_range::(term))\n });\n linear_terms.for_each(|term: [u128; N]| validate_in_range::(term));\n\n let expression_limbs: [Field; 2 * N - 1] = compute_quadratic_expression_with_modulus::(\n params,\n lhs_terms,\n lhs_flags,\n rhs_terms,\n rhs_flags,\n linear_terms,\n linear_flags,\n );\n validate_expression_is_zero(expression_limbs);\n}\n\n// ------------------------------ UDIV MOD EXPRESSION ------------------------------\n\n/// Given a `udiv_mod` `BigNum` expression that is equal to `0` over integers, compute the borrow flags (unconstrained)\n///\n/// Mirror function of `__compute_quadratic_expression_with_borrow_flags` optimized to compute borrow flags of an expression:\n/// divisor * quotient + remainder - numerator = 0\n/// see `__compute_quadratic_expression_with_borrow_flags` for details\n///\n/// The main differences from it are:\n/// 1. `product_limbs` stores only the least-significant `N` limbs of\n/// `quotient * divisor + remainder`. This is sufficient to compute the\n/// borrow flags for the first `N` limbs of\n/// quotient * divisor + remainder - numerator.\n///\n/// For an honest `udiv_mod` relation we also have\n/// quotient * divisor <= numerator < B^N,\n/// so the true product fits into `N` limbs as an integer.\n/// 2. Instead of subtracting `quotient * MOD` we subtract `numerator`. This is due to the fact that\n/// we no longer work over `MOD`, and we can't really do subtractions as we did previously: `double_modulus - x`\n///\n/// ## Note\n/// We leave the borrow values at 2^{246}, even though we should never reach this bound with just 3 terms\n/// The cases where it can happen are: N >= 64 (middle limb will have 64 additions). And it is a pure completeness issue\n/// But the rest of the library will probably not work with that massive number anyway\nunconstrained fn __compute_udiv_mod_expression_with_borrow_flags(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) -> [bool; N - 1] {\n let mut product_limbs: [Field; N] = [0; N];\n let mut numerator_field: [Field; N] = [0; N];\n for i in 0..N {\n for j in 0..N - i {\n product_limbs[i + j] += (quotient[i] as Field) * (divisor[j] as Field);\n }\n product_limbs[i] += (remainder[i] as Field);\n\n numerator_field[i] = numerator[i] as Field;\n }\n\n __compute_borrow_flags(product_limbs, numerator_field)\n}\n\n/// Constrained version of `__compute_udiv_mod_expression_with_borrow_flags`\n///\n/// Computes the following expression in-circuit:\n/// quotient * divisor + remainder - numerator = 0\n///\n/// Mirror function of `compute_quadratic_expression_with_modulus`. See it for details.\n///\n/// ## Soundness note\n/// We compute the full convolution `quotient * divisor` into `2N - 1` limbs\n/// and then constrain all limbs with index `i >= N` to be zero. For `i >= N`\n/// the value `expression_limbs_full[i]` is a sum of products\n/// sum_{j+k=i} quotient[j] * divisor[k]\n/// with no contribution from `numerator` or `remainder`.\n///\n/// Every limb of `quotient` and `divisor` is range-constrained to be a 120-bit\n/// integer, so each product term is < 2^{240} and each coefficient of the\n/// convolution is strictly smaller than the field modulus. In this regime,\n/// the constraint `expression_limbs_full[i] == 0` in `Field` coincides with\n/// the same equality over the integers.\n///\n/// Vanishing of all high limbs `i >= N` is therefore an integer statement that\n/// the product has degree < N, i.e.\n/// quotient * divisor < 2^{120 * N},\n/// so `quotient * divisor` fits into `N` 120-bit limbs and does not overflow.\nfn compute_udiv_mod_expression(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) -> [Field; N] {\n // Safety: use an unconstrained function to compute the value of the quotient and borrow_flags out-of-circuit\n let borrow_flags: [bool; N - 1] = unsafe {\n __compute_udiv_mod_expression_with_borrow_flags::(\n numerator,\n divisor,\n quotient,\n remainder,\n )\n };\n\n let mut expression_limbs_full: [Field; 2 * N - 1] = [0; 2 * N - 1];\n for i in 0..N {\n for j in 0..N {\n expression_limbs_full[i + j] += (quotient[i] as Field) * (divisor[j] as Field);\n }\n expression_limbs_full[i] += (remainder[i] as Field) - (numerator[i] as Field);\n }\n\n let mut expression_limbs: [Field; N] = [0; N];\n for i in 0..N {\n expression_limbs[i] = expression_limbs_full[i];\n }\n for i in N..2 * N - 1 {\n assert(expression_limbs_full[i] == 0);\n }\n\n apply_borrow_flags(expression_limbs, borrow_flags)\n}\n\n/// Constrain a `udiv_mod` `BigNum` expression to be equal to 0\n///\n/// Mirror function of `evaluate_quadratic_expression`\n///\n/// ## Details\n///\n/// The constrained expression, viewed over the integers, is:\n///\n/// quotient * divisor + remainder - numerator = 0\n///\n/// ## Completeness\n/// If an honest prover supplies valid `BigNum` inputs that satisfy the equation,\n/// it can always find `borrow_flags` such that the integer\n/// relation holds and all constraints are satisfied.\n///\n/// The only possibility to break completeness is by providing a `BigNum` with `N >= 64`\n/// See `__compute_udiv_mod_expression_with_borrow_flags` for details\n///\n/// ## Soundness\n/// This function is conditionally sound: it enforces that the degree-2 relation\n/// holds over the integers, but it does not, by itself, enforce that\n/// this relation is unique for given `numerator` and `divisor`\n///\n/// For example, if the true relation is\n/// quotient * divisor + remainder - numerator = 0\n///\n/// then we can set quotient' = quotient - 1, remainder' = remainder + divisor\npub(crate) fn validate_udiv_mod_expression(\n numerator: [u128; N],\n divisor: [u128; N],\n quotient: [u128; N],\n remainder: [u128; N],\n) {\n validate_in_range::(numerator);\n validate_in_range::(divisor);\n validate_in_range::(quotient);\n validate_in_range::(remainder);\n\n let expression_limbs: [Field; N] =\n compute_udiv_mod_expression::(numerator, divisor, quotient, remainder);\n validate_expression_is_zero(expression_limbs);\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/expressions.nr" - }, - "124": { - "source": "// This file contains the unconstrained helpers that are mostly used by unconstrained ops\n\nuse crate::constants::TWO_POW_120;\n\nuse crate::fns::unconstrained_ops::{__add, __eq, __gte, __mul, __neg, __pow, __sqr};\n\nuse crate::utils::msb::get_msb;\nuse crate::utils::split_bits::{__normalize_limbs, __split_120_bits};\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ DERIVATION HELPER FUNCTIONS ------------------------------\n\n/// Construct a `1` BigNum value (unconstrained)\npub(crate) unconstrained fn __one() -> [u128; N] {\n let mut limbs: [u128; N] = [0; N];\n limbs[0] = 1;\n limbs\n}\n\n/// Construct a BigNum value from Field (unconstrained)\n///\n/// Split the native `Field` value into `N` 120-bit limbs\npub(crate) unconstrained fn __from_field(val: Field) -> [u128; N] {\n let mut x: Field = val;\n let mut result: [u128; N] = [0; N];\n\n if (N == 1) {\n let (first_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n }\n\n if (N == 2) {\n let (first_limb, x): (u128, Field) = __split_120_bits(x);\n let (second_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n result[1] = second_limb;\n }\n\n if (N > 2) {\n let (first_limb, x): (u128, Field) = __split_120_bits(x);\n let (second_limb, x): (u128, Field) = __split_120_bits(x);\n let (third_limb, _): (u128, Field) = __split_120_bits(x);\n result[0] = first_limb;\n result[1] = second_limb;\n result[2] = third_limb;\n }\n result\n}\n\n// ------------------------------ ARITHMETIC WITH FLAGS HELPER FUNCTIONS ------------------------------\n// These are the functions that compute modular operations results as well as borrow and carry flags for constraints\n\n/// Compute the `MOD - val` and the corresponding borrow flags (unconstrained)\n///\n/// Negate the value and compute the flags indicating whether we need\n/// to borrow a `bit` from the upper limb when subtracting the value from modulus\n///\n/// ## Note\n/// The `borrow_in` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __neg_with_flags(\n modulus: [u128; N],\n val: [u128; N],\n) -> ([u128; N], [bool; N - 1]) {\n let mut result: [u128; N] = [0; N];\n let mut borrow_in: u128 = 0;\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n for i in 0..N {\n let sub_term: u128 = val[i] + borrow_in;\n borrow_in = (sub_term > modulus[i]) as u128;\n result[i] = borrow_in * TWO_POW_120 + modulus[i] - sub_term;\n if (i < N - 1) {\n borrow_flags[i] = (borrow_in != 0);\n }\n }\n (result, borrow_flags)\n}\n\n/// Compute modular addition and the corresponding borrow and carry flags (unconstrained)\n///\n/// Given `x, y, MOD` compute x + y or x + y - MOD in case it overflows\n/// Additionally compute all the carries from addition (x + y)\n/// and borrows from subtraction (- MOD)\n///\n/// ## Note\n/// The `borrow` must be equal to `carry` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __add_with_flags(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [bool; N - 1], [bool; N - 1], bool) {\n let mask: u128 = TWO_POW_120 - 1;\n\n let add_res: [u128; N] = __helper_add(lhs, rhs);\n let overflow: bool = __gte(add_res, modulus);\n\n let mut subtrahend: [u128; N] = if overflow { modulus } else { [0; N] };\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let mut carry_flags: [bool; N - 1] = [false; N - 1];\n\n let mut carry: u128 = 0;\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = lhs[i] + rhs[i] + carry;\n carry = add_term >> 120;\n add_term &= mask;\n\n let sub_term: u128 = subtrahend[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n // Only set `borrow` and `carry` if they differ\n // And if it's not the last limb\n if (carry != borrow) & (i < N - 1) {\n carry_flags[i] = carry != 0;\n borrow_flags[i] = borrow != 0;\n }\n }\n (result, carry_flags, borrow_flags, overflow)\n}\n\n/// Compute modular subtraction and the corresponding borrow and carry flags (unconstrained)\n///\n/// Given `x, y, MOD` compute x - y or x - y + MOD in case it overflows\n/// Additionally compute all the carries from addition (x + MOD)\n/// and borrows from subtraction (- y)\n///\n/// ## Note\n/// The `borrow` must be equal to `carry` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __sub_with_flags(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [bool; N - 1], [bool; N - 1], bool) {\n let mask: u128 = TWO_POW_120 - 1;\n\n let underflow: bool = !__gte(lhs, rhs);\n\n let addend: [u128; N] = if underflow { modulus } else { [0; N] };\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n let mut carry_flags: [bool; N - 1] = [false; N - 1];\n\n let mut carry: u128 = 0;\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = lhs[i] + addend[i] + carry;\n carry = add_term >> 120;\n add_term &= mask;\n\n let sub_term: u128 = rhs[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n // Only set `borrow` and `carry` if they differ\n // And if it's not the last limb\n if (carry != borrow) & (i < N - 1) {\n carry_flags[i] = carry != 0;\n borrow_flags[i] = borrow != 0;\n }\n }\n (result, carry_flags, borrow_flags, underflow)\n}\n\n/// Validate that lhs - rhs does not underflow (unconstrained)\n///\n/// Same as `__validate_gte_with_flags`, but we don't compute the\n/// result of a subtraction\npub(crate) unconstrained fn __validate_in_field_compute_borrow_flags(\n params: BigNumParams,\n val: [u128; N],\n) -> [bool; N - 1] {\n let modulus: [u128; N] = params.modulus;\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n borrow_flags[0] = modulus[0] < val[0];\n for i in 1..N - 1 {\n borrow_flags[i] = modulus[i] < val[i] + (borrow_flags[i - 1] as u128);\n }\n borrow_flags\n}\n\n/// Validate that lhs - rhs does not underflow (unconstrained)\n///\n/// Compute underflow flag (lhs < rhs)\n/// then perform subtraction with borrow flags\n///\n/// ## Note\n/// The `borrow` must be equal to 0 at the end of the loop.\n/// And it can't be nonzero, since we swap the terms at the beginning\npub(crate) unconstrained fn __validate_gte_with_flags(\n lhs: [u128; N],\n rhs: [u128; N],\n) -> (bool, [u128; N], [bool; N - 1]) {\n let mut a: [u128; N] = lhs;\n let mut b: [u128; N] = rhs;\n\n let underflow: bool = !__gte(lhs, rhs);\n // swap a and b if there's an underflow\n let (a, b): ([u128; N], [u128; N]) = if underflow { (b, a) } else { (a, b) };\n\n let mut result: [u128; N] = [0; N];\n\n let mut borrow_flags: [bool; N - 1] = [false; N - 1];\n\n let mut borrow: u128 = 0;\n for i in 0..N {\n let mut add_term: u128 = a[i];\n\n let sub_term: u128 = b[i] + borrow;\n borrow = (sub_term > add_term) as u128;\n\n result[i] = borrow * TWO_POW_120 + add_term - sub_term;\n\n if (i < N - 1) {\n borrow_flags[i] = borrow != 0;\n }\n }\n (underflow, result, borrow_flags)\n}\n\n// ------------------------------ BARRETT REDUCTION ------------------------------\n\n/// `BARRETT_REDUCTION_OVERFLOW_BITS` defines how large an input to barrett reduction can be\n///\n/// maximum value = modulus^2 << BARRETT_REDUCTION_OVERFLOW_BITS\n/// see __barrett_reduction for more details\ncomptime global BARRETT_REDUCTION_OVERFLOW_BITS: u32 = 4;\n\n/// Optimized modular multiplication (unconstrained)\n///\n/// The trick is to approximate 1/p with m/2**r, because division by 2**r is much cheaper\n/// In our case m = redc_param = floor(2^{MOD_BITS * 2 + BARRET_REDUCTION_OVERFLOW_BITS} / p)\n/// r = MOD_BITS * 2 + BARRET_REDUCTION_OVERFLOW_BITS\n///\n/// When we apply the barrett reduction, the maximum value of the output will be <= p * (1 + x/2^{2k})\n/// where p = modulus,\n/// x = reduction input\n///\n/// If x > p * p, we need k to be larger than modulus_bits()\n/// We hardcode k = 4, which means that the maximum value of x is approx. 16 * p * p\n/// This should be larger than most values put into `evaluate_quadratic_expression`\n///\n/// ## TODO\n/// Detect cases where x might be too large at comptime\n///\n/// ## Note\n/// very niche edge case error that we need to be aware of:\n/// N must be large enough to cover the modulus *plus* BARRETT_REDUCTION_OVERFLOW_BITS\n/// i.e. a 359-bit prime needs (I think) 4 limbs to represent or we may overflow\n/// when calling __barrett_reduction\n///\n/// ## Note on final reduction\n///\n/// Assumptions:\n/// - k = ceil(log2 p), so p <= 2^k\n/// - s = 4, m = redc_param = floor(2^{2*k + s}/p)\n/// - x < 16 * p^2 (x < 2^{2 * k + s})\n///\n/// Let m' = 2^{2*k + s} / p, and write m = m' - \\epsilon, \\epsilon \\in [0, 1)\n//\n/// quo = floor(x * m / 2^{2 * k + s}) = floor(x * m' / 2^{2 * k + s} - x * \\epsilon / 2^{2 * k + s}) =\n/// floor(x / p - x * \\epsilon / 2^{2 * k + s})\n///\n/// Bounds:\n/// quo <= floor(x / p)\n///\n/// floor(a - b) >= floor(a) - ceil(b) (known identity) =>\n/// quo >= floor(x / p) - ceil(x * \\epsilon / 2^{2 * k + s})\n/// >= floor(x / p) - ceil(x / 2^{2 * k + s}) (epsilon < 1)\n///\n/// x / 2^{2 * k + s} < C * p^2 / 2^{2 * k + s} <= C * 2^{2 * k} / 2^{2 * k + s} = C / 2^s\n///\n/// When the assumption holds (C = 16), ceil(x / 2^{2 * k + s}) = 1, for x > 0\n/// Therefore quo = {floor(x/p), floor(x/p) - 1}\n///\n/// In first case: rem = x - quo * p = x - floor(x/p) * p < p\n/// In second case: rem = x - (floor(x/p) - 1) * p = (x - floor(x/p) * p) + p -> need 1 subtraction\n///\n/// ### Note\n/// We allow 64 products to be summed inside the `evaluate_quadratic_expression`\n/// In that case x / 2^{2 * k + s} < 64 / 2^4 = 4 => hence we need to subtract modulus at most 4 times\n/// We can leave it 2 for now as it is unlikely to reach beyond 32 * p^2\n///\n/// In the worst case though, we will have the input > 64 * p^2\n/// (for example (a1 + b1) * (c1 + d1) + ... 64 times)\n/// This is highly unlikely though.\n///\n/// ### TODO:\n/// Possibly change the `BARRETT_REDUCTION_OVERFLOW_BITS` to 6, so that we need only 1 reduction here\n/// However we will have to recompute all the fields `redc_param`s and fix paramgen\npub(crate) unconstrained fn __barrett_reduction(\n x: [u128; 2 * N],\n redc_param: [u128; N],\n k: u32,\n modulus: [u128; N],\n) -> ([u128; N], [u128; N]) {\n // TODO: switch to __helper_mul, once the compiler is smart enough to handle this\n let mut mulout_field: [Field; 3 * N] = [0; 3 * N];\n for i in 0..(2 * N) {\n for j in 0..N {\n mulout_field[i + j] += (x[i] as Field) * (redc_param[j] as Field);\n }\n }\n let mulout: [u128; 3 * N] = __normalize_limbs(mulout_field);\n\n let quotient: [u128; 3 * N] = __shr(mulout, (k + k + BARRETT_REDUCTION_OVERFLOW_BITS));\n\n // Remove a bunch of zeros from the end\n let mut smaller_quotient: [u128; N] = [0; N];\n for i in 0..N {\n smaller_quotient[i] = quotient[i] as u128;\n }\n\n // long_quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array\n let long_quotient_mul_modulus: [u128; 2 * N] = __helper_mul(smaller_quotient, modulus);\n let long_remainder: [u128; 2 * N] = __helper_sub(x, long_quotient_mul_modulus);\n\n // Remove a bunch of zeros from the end\n let mut remainder: [u128; N] = [0; N];\n for i in 0..N {\n remainder[i] = long_remainder[i];\n }\n\n for _ in 0..2 {\n if (__gte(remainder, modulus)) {\n remainder = __helper_sub(remainder, modulus);\n smaller_quotient = __increment(smaller_quotient);\n }\n }\n\n (smaller_quotient, remainder)\n}\n\n// ------------------------------ ARITHMETIC HELPER FUNCTIONS ------------------------------\n// These are the functions that operate on limbs as if they were just big integers\n\n/// Adds `1` to the BigNum value without modular reduction (unconstrained)\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __increment(val: [u128; N]) -> [u128; N] {\n let mask: u128 = TWO_POW_120 - 1;\n\n let mut result: [u128; N] = [0; N];\n let mut carry: u128 = 1;\n for i in 0..N {\n let add_term: u128 = val[i] + carry;\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n result\n}\n\n/// Adds two `BigNum` values without modular reduction (unconstrained).\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __helper_add(lhs: [u128; N], rhs: [u128; N]) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let mut carry: u128 = 0;\n let mask: u128 = TWO_POW_120 - 1;\n\n for i in 0..N {\n let add_term: u128 = lhs[i] + rhs[i] + carry;\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n result\n}\n\n/// Subtracts two `BigNum` values without modular reduction (unconstrained).\n///\n/// ## Note\n/// The `borrow` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __helper_sub(lhs: [u128; N], rhs: [u128; N]) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let mut borrow: u128 = 0;\n for i in 0..N {\n let subtrahend: u128 = rhs[i] + borrow;\n borrow = (subtrahend > lhs[i]) as u128;\n result[i] = (borrow << 120) + lhs[i] - subtrahend;\n }\n result\n}\n\n/// Multiplies two `BigNum` values without modular reduction (unconstrained).\n///\n/// Computes the full schoolbook product of two N-limb little-endian arrays\n///\n/// ## Note\n/// The mathematical product fits in `2 * N - 1` limbs, but we keep `2 * N`\n/// limbs intentionally as the extra high limb safely absorbs a possible single limb overflow\n/// for moduli close to `120 * N` bits.\npub(crate) unconstrained fn __helper_mul(\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; 2 * N] {\n let mut result: [Field; 2 * N] = [0; 2 * N];\n for i in 0..N {\n for j in 0..N {\n result[i + j] += (lhs[i] as Field) * (rhs[j] as Field);\n }\n }\n __normalize_limbs(result)\n}\n\n// ------------------------------ LOGIC HELPER FUNCTIONS ------------------------------\n// These are the functions that operate on limbs as if they were just big integers\n\n/// Left-shifts a `BigNum` value by `shift` bits (unconstrained).\n///\n/// Performs a bitwise left shift across limbs.\n///\n/// ## Note\n/// The most significant limb is truncated to 120 bits after the shift.\n///\n/// No bounds check is performed on `num_shifted_limbs`.\n/// However, we use it only in `__udiv_mod`, where it is not possible to reach\n/// `num_shifted_limbs` > `N`\npub(crate) unconstrained fn __shl(input: [u128; N], shift: u32) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let num_shifted_limbs: u32 = shift / 120;\n let limb_shift: u128 = (shift % 120) as u128;\n let remainder_shift: u128 = 120 - limb_shift;\n\n let mask: u128 = TWO_POW_120 - 1;\n let mut remainder: u128 = input[0] >> remainder_shift;\n\n result[num_shifted_limbs] = (input[0] << limb_shift) & mask;\n\n for i in 1..(N - num_shifted_limbs) {\n let value: u128 = input[i];\n let upshift: u128 = ((value << limb_shift) | remainder) & mask;\n result[i + num_shifted_limbs] = upshift;\n remainder = value >> remainder_shift;\n }\n result\n}\n\n/// Right-shifts a `BigNum` value by `shift` bits (unconstrained).\n///\n/// Performs a bitwise right shift across limbs.\n///\n/// # Note\n/// No bounds check is performed on `num_shifted_limbs`.\n/// However, we use it only in `__tonelli_shanks_sqrt`, where it is not possible to reach\n/// `num_shifted_limbs` > `N`\npub(crate) unconstrained fn __shr(input: [u128; N], shift: u32) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n\n let num_shifted_limbs: u32 = shift / 120;\n let limb_shift: u128 = (shift % 120) as u128;\n\n let remainder_shift: u128 = 120 - limb_shift;\n let low_mask: u128 = (1 as u128 << limb_shift) - 1;\n\n result[0] = input[num_shifted_limbs] >> limb_shift;\n for i in 1..(N - num_shifted_limbs) {\n let value: u128 = input[i + num_shifted_limbs];\n\n let carry: u128 = (value & low_mask) << remainder_shift;\n result[i - 1] |= carry;\n\n result[i] = value >> limb_shift;\n }\n result\n}\n\n/// Right-shifts a `BigNum` value by `1` bit (unconstrained)\n///\n/// # Note\n/// All the operations on limbs are executed in place\n/// to save opcodes\npub(crate) unconstrained fn __shr1(mut input: [u128; N]) -> [u128; N] {\n let value: u128 = input[N - 1];\n let mut remainder: u128 = (value & 1) << 119;\n input[N - 1] >>= 1;\n\n for i in 1..N {\n let value: u128 = input[N - 1 - i];\n input[N - 1 - i] = (value >> 1) | remainder;\n remainder = (value & 1) << 119;\n }\n input\n}\n\n/// Returns the index of the most significant set bit in a `BigNum` value (unconstrained).\npub(crate) unconstrained fn __get_msb(val: [u128; N]) -> u32 {\n let mut count: u32 = 0;\n for i in 0..N {\n let idx: u32 = N - 1 - i;\n let v: u128 = val[idx];\n if (v > 0) {\n count = 120 * idx + get_msb(v);\n break;\n }\n }\n count\n}\n\n/// Returns `true` if the bit at position `bit` is set in the `BigNum` (unconstrained).\n///\n/// ## Note\n/// No bounds check is performed on `bit`\npub(crate) fn __get_bit(input: [u128; N], bit: u32) -> bool {\n let segment_index: u32 = bit / 120;\n let uint_index: u128 = (bit % 120) as u128;\n\n let limb: u128 = input[segment_index];\n let value: u128 = (limb >> uint_index) & 1;\n value == 1\n}\n\n// ------------------------------ SQRT HELPER FUNCTIONS ------------------------------\n// These are the functions that are used during taking a square root\n\n/// Compute the maximal power of 2 that divides the group order (unconstrained)\n///\n/// Find the maximum value s such that `MOD = 2^s * q + 1`, where `q` is odd\n/// This is needed for our Tonelli-Shanks sqrt algorithm\npub(crate) unconstrained fn __primitive_root_log_size(\n params: BigNumParams,\n) -> u32 {\n let mut target: [u128; N] = __helper_sub(params.modulus, __one());\n let mut result: u32 = 0;\n while !__get_bit(target, result) {\n result += 1;\n }\n result\n}\n\n/// Find a quadratic non-residue `g` where `g` is the smallest such value (unconstrained)\n/// i.e. smallest `g` such that `g^{(p - 1)/2} = -1 (mod MOD)`\n/// or smallest `g`, such that `x^2 - g = 0 (mod MOD)` has no solutions\n///\n/// ## Note\n/// WARNING If the field is not prime, this function will enter an infinite loop!\npub(crate) unconstrained fn __quadratic_non_residue(\n params: BigNumParams,\n) -> [u128; N] {\n let one: [u128; N] = __one();\n let neg_one: [u128; N] = __neg(params.modulus, one);\n\n let p_minus_one_over_two: [u128; N] = __shr1(__helper_sub(params.modulus, __one()));\n\n // We start with 2\n let mut target: [u128; N] = __increment(one);\n let mut expd: [u128; N] = __pow(params, target, p_minus_one_over_two);\n while !__eq(expd, neg_one) {\n target = __increment(target);\n expd = __pow(params, target, p_minus_one_over_two);\n }\n target\n}\n\n/// Compute the smallest `i`, such that `t^{2^i} = 1, t^{2^{i-1}} = -1 (mod MOD)` (unconstrained)\n///\n/// ## Note\n/// Multiplicative order of t must divide 2^v2(MOD-1), otherwise you'll end up in an infinite loop!\npub(crate) unconstrained fn __tonelli_shanks_sqrt_find_i(\n params: BigNumParams,\n t: [u128; N],\n) -> u32 {\n let one: [u128; N] = __one();\n let mut c: [u128; N] = t;\n\n let mut i: u32 = 0;\n // Compute t^{2^k} until it hits 1 for the first time\n while !__eq(c, one) {\n c = __sqr::(params, c);\n i += 1;\n }\n i\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/unconstrained_helpers.nr" - }, - "125": { - "source": "// This file contains the unconstrained operations that are used directly by BigNum class\n\nuse crate::fns::constrained_ops::derive_from_seed;\n\nuse crate::fns::unconstrained_helpers::{\n __barrett_reduction, __get_bit, __get_msb, __helper_add, __helper_mul, __helper_sub,\n __increment, __one, __primitive_root_log_size, __quadratic_non_residue, __shl, __shr, __shr1,\n __tonelli_shanks_sqrt_find_i,\n};\n\nuse crate::constants::TWO_POW_120;\n\nuse crate::params::BigNumParams;\n\n// ------------------------------ DERIVATION FUNCTIONS ------------------------------\n\n/// Deterministically derives a `BigNum` from a seed value (unconstrained)\n///\n/// Takes a seed byte array and generates a `BigNum` in the range [0, modulus-1].\n///\n/// See more information in `constrained_ops.nr`: `derive_from_seed`\npub(crate) unconstrained fn __derive_from_seed(\n params: BigNumParams,\n seed: [u8; SeedBytes],\n) -> [u128; N] {\n derive_from_seed::(params, seed)\n}\n\n// ------------------------------ COMPARISON FUNCTIONS ------------------------------\n\n/// Compare two limb arrays for equality (unconstrained)\npub(crate) unconstrained fn __eq(lhs: [u128; N], rhs: [u128; N]) -> bool {\n lhs == rhs\n}\n\n/// Compare a limb array to a zero array (unconstrained)\npub(crate) unconstrained fn __is_zero(limbs: [u128; N]) -> bool {\n limbs == [0; N]\n}\n\n/// Compare two little-endian limb arrays for `lhs >= rhs` over integers (unconstrained)\n///\n/// Starts from the most significant limb (`N - 1`) and returns true\n/// if `lhs` is greater or equal to `rhs`\npub(crate) unconstrained fn __gte(lhs: [u128; N], rhs: [u128; N]) -> bool {\n let mut result: bool = true;\n for i in 0..N {\n let idx: u32 = N - 1 - i;\n if (lhs[idx] != rhs[idx]) {\n result = lhs[idx] > rhs[idx];\n break;\n }\n }\n result\n}\n\n// ------------------------------ ARITHMETIC FUNCTIONS ------------------------------\n\n/// Negates a `BigNum` value, returning `m - x` (unconstrained)\n///\n/// ## Note\n/// The input is assumed to be less than modulus\npub(crate) unconstrained fn __neg(modulus: [u128; N], limbs: [u128; N]) -> [u128; N] {\n __helper_sub(modulus, limbs)\n}\n\n/// Adds two `BigNum` values with modular reduction (unconstrained)\n///\n/// Sums the limbs one by one, keeping the carry.\n/// In case the result overflows the modulus, the modulus is subtracted once\n///\n/// ## Note\n/// The `carry` must be `0` at the end of the loop.\n/// No explicit assertion is made, as this condition is validated during evaluation.\npub(crate) unconstrained fn __add(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n let mut result: [u128; N] = [0; N];\n let mut carry: u128 = 0;\n let mask: u128 = TWO_POW_120 - 1;\n\n for i in 0..N {\n let add_term: u128 = (lhs[i] + rhs[i] + carry);\n carry = add_term >> 120;\n result[i] = add_term & mask;\n }\n\n // check if the result is greater than the modulus\n if __gte(result, modulus) {\n __helper_sub(result, modulus)\n } else {\n result\n }\n}\n\n/// Subtracts two `BigNum` values with modular reduction (unconstrained).\n///\n/// Computes `x + (m - y)` (mod m)\npub(crate) unconstrained fn __sub(\n modulus: [u128; N],\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n __add(modulus, lhs, __neg(modulus, rhs))\n}\n\n/// Multiply `x` and `y` and reduce via Barrett, returning (Q, R) (unconstrained).\n///\n/// For `BigNum` values `x` and `y` compute (`Q`, `R`) such that:\n/// x * y = R + Q * m, 0 <= R < m\n/// See `__barrett_reduction` for details.\npub(crate) unconstrained fn __mul_with_quotient(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> ([u128; N], [u128; N]) {\n let to_reduce: [u128; N * 2] = __helper_mul(lhs, rhs);\n let (q, r): ([u128; N], [u128; N]) =\n __barrett_reduction(to_reduce, params.redc_param, MOD_BITS, params.modulus);\n (q, r)\n}\n\n/// Multiplies two `BigNum` values with modular reduction (unconstrained).\npub(crate) unconstrained fn __mul(\n params: BigNumParams,\n lhs: [u128; N],\n rhs: [u128; N],\n) -> [u128; N] {\n __mul_with_quotient::(params, lhs, rhs).1\n}\n\n/// Squares a `BigNum` value with modular reduction (unconstrained).\npub(crate) unconstrained fn __sqr(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n __mul_with_quotient::(params, val, val).1\n}\n\n/// Modular exponentiation via square-and-multiply. LSB-first (unconstrained).\n///\n/// Computes `x^e mod m`\n///\n/// ## Note\n/// For the loop, we are using `MOD_BITS` instead of `__get_msb`\n/// because it is much much cheaper\npub(crate) unconstrained fn __pow(\n params: BigNumParams,\n val: [u128; N],\n exponent: [u128; N],\n) -> [u128; N] {\n let mut accumulator: [u128; N] = __one();\n let mut x: [u128; N] = val;\n let num_bits: u32 = MOD_BITS + 1;\n\n for i in 0..num_bits {\n if __get_bit(exponent, i) {\n accumulator = __mul::(params, accumulator, x);\n }\n x = __sqr::(params, x);\n }\n accumulator\n}\n\n/// Given a `BigNum` value `x` compute x^{-1} (mod m) (unconstrained)\n///\n/// x^{p-1} = 1 (mod p) (Fermat's little theorem)\n/// x^{p-2} = x^{-1} (mod p)\n///\n/// ## Note\n/// The input value must be nonzero and modulus has to be prime\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __invmod(\n params: BigNumParams,\n val: [u128; N],\n) -> [u128; N] {\n let one: [u128; N] = __one();\n let exp: [u128; N] = __helper_sub(params.modulus, __helper_add(one, one));\n __pow::(params, val, exp)\n}\n\n/// Divides two `BigNum` values with modular reduction (unconstrained).\n///\n/// Computes `x * y^{-1}` (mod m)\n///\n/// ## Note\n/// The divisor must be nonzero\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __div(\n params: BigNumParams,\n numerator: [u128; N],\n divisor: [u128; N],\n) -> [u128; N] {\n let inv_divisor: [u128; N] = __invmod::(params, divisor);\n __mul::(params, numerator, inv_divisor)\n}\n\n/// Given the `BigNum` inputs `x, y`, compute integer division x / y (unconstrained)\n///\n/// This function implements binary long division and outputs (`quotient`, `remainder`) such that:\n/// 1. floor(numerator / divisor) = quotient\n/// 2. numerator % divisor = remainder\n/// 3. divisor * quotient + remainder = numerator\n///\n/// ## Note\n/// The divisor must be nonzero\n/// No explicit assertion is made, as this condition is validated during evaluation\npub(crate) unconstrained fn __udiv_mod(\n numerator: [u128; N],\n divisor: [u128; N],\n) -> ([u128; N], [u128; N]) {\n let mut quotient: [u128; N] = [0; N];\n let mut remainder: [u128; N] = numerator;\n let b: [u128; N] = divisor;\n\n let numerator_msb: u32 = __get_msb(numerator);\n let divisor_msb: u32 = __get_msb(divisor);\n if divisor_msb > numerator_msb {\n ([0; N], numerator)\n } else {\n let mut bit_difference: u32 = __get_msb(remainder) - __get_msb(divisor);\n let mut divisor: [u128; N] = __shl(divisor, bit_difference);\n let mut accumulator: [u128; N] = __shl(__one(), bit_difference);\n\n // The same as divisor > remainder\n if (__gte(divisor, __increment(remainder))) {\n divisor = __shr1(divisor);\n accumulator = __shr1(accumulator);\n }\n\n for _ in 0..(N * 120) {\n if (__gte(remainder, b) == false) {\n break;\n }\n // we've shunted 'divisor' up to have the same bit length as our remainder.\n // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b\n if (__gte(remainder, divisor)) {\n remainder = __helper_sub(remainder, divisor);\n // we can use OR here instead of +, as\n // accumulator is always a nice power of two\n quotient = __helper_add(quotient, accumulator);\n }\n divisor = __shr1(divisor);\n accumulator = __shr1(accumulator);\n }\n\n (quotient, remainder)\n }\n}\n\n/// Batch modular inversion of `BigNum` values in an array (unconstrained)\n///\n/// Given values v[0..M), returns inv[0...M) with inv[i] = v[i]^{-1} (mod m)\n///\n/// We use the Montgomery trick:\n/// First we compute the partial products:\n/// T0 = 1\n/// T1 = v1,\n/// T2 = v1 * v2,\n/// ...\n/// T_{m - 1} = T_{m - 2} * v_{m - 1} = v1 * ... * v_{m - 1}\n///\n/// P = T_{m-1} * v_m = v1 * v2 * ... * v_m\n///\n/// Then we calculate a single inverse P^-1 = v1^-1 * v2^-1 * ... * v_m^-1\n/// Finally we compute\n/// v_m^-1 = (P^-1 * T_{m-1})\n/// v_{m - 1}^-1 = (P^-1 * v_m * T_{m - 2})\n/// ....\n/// v_2^-1 = (P^-1 * v_m * ... * v_3 * T_1)\n/// v_1^-1 = (P^-1 * v_m * ... * v_2 * T_0)\n///\n/// ## Note\n/// Zero elements are allowed and are left unchanged in the resulting array\n///\n/// This interacts poorly with `neg(zero)`:\n/// Calling `neg` on `zero` yields `modulus` rather than `0`.\n/// A value in this form will **not** satisfy\n/// the `__is_zero` check and will lead to incorrect results.\n///\n/// This edge case should be rare, but it's worth keeping in mind when\n/// composing operations or debugging unexpected behavior\npub(crate) unconstrained fn batch_invert(\n params: BigNumParams,\n vals: [[u128; N]; M],\n) -> [[u128; N]; M] {\n let mut accumulator: [u128; N] = __one();\n let mut temporaries: [[u128; N]; M] = [[0; N]; M];\n\n for i in 0..M {\n temporaries[i] = accumulator;\n if (!__is_zero(vals[i])) {\n accumulator = __mul::(params, accumulator, vals[i]);\n }\n }\n\n let mut result: [[u128; N]; M] = [[0; N]; M];\n accumulator = __invmod::(params, accumulator);\n for i in 0..M {\n let idx: u32 = M - 1 - i;\n if (!__is_zero(vals[idx])) {\n let T0: [u128; N] = __mul::(params, accumulator, temporaries[idx]);\n accumulator = __mul::(params, accumulator, vals[idx]);\n result[idx] = T0;\n }\n }\n result\n}\n\n/// Batch modular inversion of `BigNum` values in a slice (unconstrained)\n///\n/// See `batch_invert` for details\npub(crate) unconstrained fn batch_invert_slice(\n params: BigNumParams,\n vals: [[u128; N]],\n) -> [[u128; N]] {\n let mut accumulator: [u128; N] = __one();\n let mut temporaries: [[u128; N]] = &[];\n\n let M: u32 = vals.len();\n\n for i in 0..M {\n temporaries = temporaries.push_back(accumulator);\n if (!__is_zero(vals[i])) {\n accumulator = __mul::(params, accumulator, vals[i]);\n }\n }\n\n let mut result: [[u128; N]] = [];\n accumulator = __invmod::(params, accumulator);\n for i in 0..M {\n let idx: u32 = M - 1 - i;\n if (!__is_zero(vals[idx])) {\n let T0: [u128; N] = __mul::(params, accumulator, temporaries[idx]);\n accumulator = __mul::(params, accumulator, vals[idx]);\n result = result.push_front(T0);\n } else {\n result = result.push_front([0; N]);\n }\n }\n\n result\n}\n\n/// Compute a modular square root in a prime field (unconstrained)\npub(crate) unconstrained fn __sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n assert(\n params.has_multiplicative_inverse,\n \"BigNum::__sqrt: Must be a field to take square roots\",\n );\n\n if (__is_zero(input)) {\n Option::some(input)\n } else if (params.modulus[0] % 4 == 3) {\n __easy_sqrt(params, input)\n } else {\n __tonelli_shanks_sqrt(params, input)\n }\n}\n\n/// Compute a modular square root using the Tonelli-Shanks algorithm (unconstrained)\n///\n/// Solves `x^2 = a (mod MOD)` for odd prime MOD\n///\n/// ## Algorithm\n///\n/// Here p = MOD\n///\n/// Tonelli-Shanks setup\n///\n/// Write `p - 1 = 2^s * Q`, `Q` - odd\n/// Define:\n/// `R = a^{(Q+1)/2}`\n/// `t = a^Q`\n///\n/// so that `R^2 = a^{Q + 1} = a * a^Q = a * t`\n/// If t = 1, we are done\n///\n/// By Euler's criterion, `a` is a quadratic reside iff `a^{(p - 1)/2} = 1`\n/// Since `t = a^Q` and `(p - 1) / 2 = Q * 2^{s-1}` we have:\n/// `t^{2^{s-1}} = a^{Q * 2^{s-1}} = a^{(p-1)/2} = 1`, assuming `a` is a q.r.\n///\n/// To proceed with computing our square root, we want to transfer `t` into a smaller subgroup,\n/// specifically, the `2^(s-2)`'th roots of unity or lower.\n///\n/// We do this by finding some value `b`, such that\n/// `(t * b^2)^{2^{s-2}} = 1` and `R' = R * b`\n/// Finding such a `b` is trivial, because from Euler's criterion, we know that,\n/// for any quadratic non-residue `z`, `z^{(p - 1) / 2} = -1`\n/// i.e. `z^{Q * 2^{s-1}} = -1`\n/// => `z^Q` is a `2^{s-1}`'th root of `-1`\n/// => `z^{2 * Q}` is a `2^{s-2}`'th root of `-1`\n///\n/// Since `t^{2^{s-1}} = 1`, we know that for some `i`, `i <= s - 2: t^{2^{i-1}} = -1`\n/// => `t * z^{2 * Q}` is a `2^{s - 2}`'th root of unity.\n/// We can iteratively transform `t` into ever smaller subgroups, until `t = 1`.\n/// At each iteration, we need to find a new value for `b`, which we can obtain\n/// by repeatedly squaring `z^Q`\n///\n/// ## Note\n/// Only use for prime fields! Function may infinite loop if used for non-prime fields\n///\n/// The input is assumed to be a nonzero value\npub(crate) unconstrained fn __tonelli_shanks_sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n let mut result: Option<[u128; N]> = Option::none();\n\n let one: [u128; N] = __one();\n let s: u32 = __primitive_root_log_size::(params); // p - 1 = 2^s * Q, where Q is odd\n let Q: [u128; N] = __shr(__helper_sub(params.modulus, one), s);\n let Q_minus_one_over_two: [u128; N] = __shr1(__helper_sub(Q, one)); // (Q - 1) / 2\n\n let z: [u128; N] = __quadratic_non_residue::(params);\n\n // Initialize:\n // b = a^{(Q - 1)/2}\n // R = a * b = a^{(Q + 1) / 2} => R^2 = a * a^Q\n // t = R * b = a^Q\n let mut b: [u128; N] = __pow::<_, MOD_BITS>(params, input, Q_minus_one_over_two);\n let mut r: [u128; N] = __mul::<_, MOD_BITS>(params, input, b);\n let mut t: [u128; N] = __mul::<_, MOD_BITS>(params, r, b);\n\n let mut check: [u128; N] = t;\n // Assure t^{2^{s - 1}} = a^{(p -1)/2} = 1, otherwise we have met a non-residue\n for _ in 0..s - 1 {\n check = __sqr::(params, check);\n }\n if (__eq(check, one)) {\n let mut m: u32 = s;\n let mut c: [u128; N] = __pow::(params, z, Q); // z^Q - proper 2^{M}'th root of unity\n\n // Tonelli-Shanks main loop\n\n // At the beginning of each iteration we have:\n // M - current exponent such that t lies in the subgroup of order 2^m\n // t - element, whose order divides 2^m\n // c - the proper 2^M'th root of unity\n // R - accumulator with R^2 = a * t\n\n // If t == 1, we are done and R is a square root\n //\n // Otherwise\n // 1. We compute 1 <= i < M, such that t^{2^i} = 1, t^{2^{i - 1}} = -1\n // 2. Set b = c^{2^{M - i - 1}}, so it becomes a proper 2^(i+1)'th root of unity\n // Then b^2 has order 2^i which matches the order of t\n //\n // 3. Update the state values:\n // R <- R * b\n // t <- t * b^2\n // c <- b^2 = c^{2^{M - i}}\n // M <- i\n // reduces the order of t from 2^i to at most 2^{i - 1} and preserves R^2 = a * t\n //\n // The loop runs at most s times because M strictly decreases\n for _ in 0..s {\n if (__eq(t, one)) {\n result = Option::some(r);\n break;\n }\n let i: u32 = __tonelli_shanks_sqrt_find_i::(params, t);\n let mut j: u32 = m - i - 1;\n b = c;\n for _ in 0..j {\n b = __sqr(params, b);\n }\n\n let b2: [u128; N] = __sqr::(params, b);\n c = b2;\n t = __mul::(params, t, b2);\n r = __mul::(params, r, b);\n m = i;\n }\n }\n result\n}\n\n/// Compute a modular square root for MOD = 3 (mod 4) (unconstrained)\n///\n/// In case MOD = 3 (mod 4), the square root can be computed using the formula:\n/// `R = a^{(MOD + 1) / 4} (mod MOD)`\n///\n/// Then R^2 = a^{(MOD + 1)/ 4 * 2} = a^{(MOD + 1) / 2} = a^{(MOD - 1) / 2 + 1} = a\n///\n/// ## Note\n/// The input is assumed to be a nonzero value\n///\n/// This is much cheaper than `__tonelli_shanks_sqrt`\npub(crate) unconstrained fn __easy_sqrt(\n params: BigNumParams,\n input: [u128; N],\n) -> std::option::Option<[u128; N]> {\n let mut result: Option<[u128; N]> = Option::none();\n\n let one: [u128; N] = __one();\n let p_minus_one_over_two: [u128; N] = __shr1(__helper_sub(params.modulus, one));\n let mut check: [u128; N] = __pow(params, input, p_minus_one_over_two);\n if (__eq(check, one)) {\n // a = (MOD - 1) / 2\n // b = (a + 1) / 2 = ((MOD - 1) / 2 + 1) / 2 = (MOD + 1) / 4\n let p_plus_one_over_four: [u128; N] = __shr1(__increment(p_minus_one_over_two));\n result = Option::some(__pow(params, input, p_plus_one_over_four));\n }\n result\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/fns/unconstrained_ops.nr" - }, - "134": { - "source": "use std::ops::WrappingMul;\n\nglobal MUL_DE_BRUIJN_BIT: [u32; 128] = [\n 1, 14, 2, 15, 26, 20, 3, 16, 68, 80, 27, 21, 56, 50, 4, 17, 65, 96, 69, 81, 105, 99, 28, 22, 86,\n 90, 57, 51, 72, 42, 5, 126, 18, 66, 48, 94, 97, 84, 70, 124, 82, 122, 106, 100, 114, 108, 29,\n 23, 77, 102, 87, 91, 119, 116, 58, 52, 61, 110, 73, 37, 43, 31, 6, 127, 13, 25, 19, 67, 79, 55,\n 49, 64, 95, 104, 98, 85, 89, 71, 41, 125, 47, 93, 83, 123, 121, 113, 107, 76, 101, 118, 115, 60,\n 109, 36, 30, 12, 24, 78, 54, 63, 103, 88, 40, 46, 92, 120, 112, 75, 117, 59, 35, 11, 53, 62, 39,\n 45, 111, 74, 34, 10, 38, 44, 33, 9, 32, 8, 7, 128,\n];\n\n/// Get the most significant bit position of a `val` (unconstrained)\n///\n/// Bit hack that uses De Bruijn sequence to calculate msb position in log(N)\n/// See [IntegerLog2DeBruijn](https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn)\npub(crate) unconstrained fn get_msb(x: u128) -> u32 {\n let result: u32 = if x == 0 {\n 0\n } else {\n let mut v: u128 = x;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v |= v >> 32;\n v |= v >> 64;\n let index: u128 = (v.wrapping_mul(0x1FC10C2FBCF471B913B14CD2595D6D5)) >> 121;\n MUL_DE_BRUIJN_BIT[index as u32]\n };\n result\n}\n\nmod tests {\n use crate::constants::{TWO_POW_120, TWO_POW_60};\n use crate::fns::unconstrained_helpers::__get_msb;\n use super::get_msb as get_msb128;\n use std::ops::WrappingMul;\n\n fn assert_msb_equal(x: u64) {\n // Safety: test code\n let msb64 = unsafe { get_msb64(x) };\n // Safety: test code\n let msb128 = unsafe { get_msb128(x as u128) };\n assert_eq(msb64, msb128);\n }\n\n #[test]\n /// Check that the msb functions are equivalent with de bruijn sequence for 64 bits and 128 bits\n fn test_get_msb() {\n // Test case 1: MSB at position 7\n let x: u64 = 0x80; // binary: 10000000\n assert_msb_equal(x);\n\n // Test case 2: MSB at position 0\n let x: u64 = 0x1; // binary: 00000001\n assert_msb_equal(x);\n\n // Test case 3: MSB at position 63\n let x: u64 = 0x8000000000000000; // binary: 1000...0000 (63 zeros)\n assert_msb_equal(x);\n\n // Test case 4: Zero input\n let x: u64 = 0x0;\n assert_msb_equal(x);\n\n // Test case 5: All bits set\n let x: u64 = 0xFFFFFFFFFFFFFFFF;\n assert_msb_equal(x);\n }\n\n /// Multiple entires in the `MUL_DE_BRUIJN_BIT` list do not map to a valid output of `v * 0x6c04f118e9966f6b`.\n /// This is a dummy value to fill the gaps in the map.\n global n1: u32 = 0xffffffff;\n\n global MUL_DE_BRUIJN_BIT_64: [u32; 128] = [\n 0, // change to 1 if you want bitSize(0) = 1\n 48, n1, n1, 31, n1, 15, 51, n1, 63, 5, n1, n1, n1, 19, n1, 23, 28, n1, n1, n1, 40, 36, 46,\n n1, 13, n1, n1, n1, 34, n1, 58, n1, 60, 2, 43, 55, n1, n1, n1, 50, 62, 4, n1, 18, 27, n1,\n 39, 45, n1, n1, 33, 57, n1, 1, 54, n1, 49, n1, 17, n1, n1, 32, n1, 53, n1, 16, n1, n1, 52,\n n1, n1, n1, 64, 6, 7, 8, n1, 9, n1, n1, n1, 20, 10, n1, n1, 24, n1, 29, n1, n1, 21, n1, 11,\n n1, n1, 41, n1, 25, 37, n1, 47, n1, 30, 14, n1, n1, n1, n1, 22, n1, n1, 35, 12, n1, n1, n1,\n 59, 42, n1, n1, 61, 3, 26, 38, 44, n1, 56,\n ];\n\n pub(crate) unconstrained fn get_msb64(x: u64) -> u32 {\n let mut v: u64 = x;\n v |= v >> 1;\n v |= v >> 2;\n v |= v >> 4;\n v |= v >> 8;\n v |= v >> 16;\n v |= v >> 32;\n let index: u64 = (v.wrapping_mul(0x6c04f118e9966f6b)) >> 57;\n (index as Field).assert_max_bit_size::<32>();\n MUL_DE_BRUIJN_BIT_64[index as u32]\n }\n\n unconstrained fn __get_msb64(val: [u128; N]) -> u32 {\n let mut count: u32 = 0;\n for i in 0..N {\n let v: u128 = val[((N) - 1 - i)];\n let v_low: u64 = v as u64 % TWO_POW_60 as u64;\n let v_high: u64 = ((v - v_low as u128) / TWO_POW_60) as u64;\n if (v_high > 0) {\n count = 60 * ((2 * N) - 1 - (i * 2)) + get_msb64(v_high);\n break;\n }\n if (v_low > 0) {\n count = 60 * ((2 * N) - 1 - (i * 2 + 1)) + get_msb64(v_low);\n break;\n }\n }\n count\n }\n\n #[test]\n // Check that the msb functions are equivalent with De Bruijn sequence for 64 bits and 128 bits\n unconstrained fn test_get_msb_equivalence() {\n // Test single limb (64-bit number)\n let x: Field = 0x8000000000000000;\n let arr: [u128; 4] = [0, 0, x as u128, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test multiple limbs (120-bit number)\n let x: Field = 0x800000000000000000000000000000; // 120 bits number, 2^119\n let arr: [u128; 4] = [0, 0, x as u128, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test zero\n let arr: [u128; 4] = [0, 0, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test all bits set (120 bits)\n let x: Field = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // 120 bits, 2^120 - 1\n let arr: [u128; 4] = [0, x as u128, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n\n // Test systematic bit positions\n for i in 0..120 {\n let x: u128 = 1;\n let shifted: u128 = x << i;\n let arr: [u128; 4] = [0, shifted, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n }\n\n // Test random-like patterns (multiple bits set)\n let patterns: [Field; 7] = [\n 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, // alternating bits\n 0x555555555555555555555555555555, // alternating bits (opposite)\n 0x1234567890ABCDEF1234567890ABCD, // some pattern\n 0xFEDCBA0987654321FEDCBA09876543, // some pattern\n 0x800000000000000000000000000001, // highest and lowest bits\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, // all bits except lowest\n 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFF, // all bits except highest\n ];\n for i in 0..patterns.len() {\n let arr: [u128; 4] = [0, patterns[i] as u128, 0, 0];\n let msb1: u32 = __get_msb64(arr);\n let msb2: u32 = __get_msb(arr);\n assert_eq(msb1, msb2);\n }\n\n // Test with MSB in different array positions (120 bits)\n let x: Field = 0x800000000000000000000000000000; // 120 bits\n let arr1: [u128; 4] = [x as u128, 0, 0, 0];\n let arr2: [u128; 4] = [0, x as u128, 0, 0];\n let arr3: [u128; 4] = [0, 0, x as u128, 0];\n let arr4: [u128; 4] = [0, 0, 0, x as u128];\n let msb1_1: u32 = __get_msb64(arr1);\n let msb2_1: u32 = __get_msb(arr1);\n assert_eq(msb1_1, msb2_1);\n\n let msb1_2: u32 = __get_msb64(arr2);\n let msb2_2: u32 = __get_msb(arr2);\n assert_eq(msb1_2, msb2_2);\n\n let msb1_3: u32 = __get_msb64(arr3);\n let msb2_3: u32 = __get_msb(arr3);\n assert_eq(msb1_3, msb2_3);\n\n let msb1_4: u32 = __get_msb64(arr4);\n let msb2_4: u32 = __get_msb(arr4);\n assert_eq(msb1_4, msb2_4);\n }\n\n #[test]\n unconstrained fn fuzz_get_msb(seed: [u128; 5]) {\n let mut seed_copy: [u128; 5] = seed;\n for i in 0..5 {\n seed_copy[i] = seed_copy[i] & (TWO_POW_120 - 1);\n }\n let msb1: u32 = __get_msb64(seed_copy);\n let msb2: u32 = __get_msb(seed_copy);\n assert_eq(msb1, msb2);\n }\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/utils/msb.nr" - }, - "135": { - "source": "use crate::constants::TWO_POW_120;\n\n/// Split the Field value into two 120-bit limbs (unconstrained)\n///\n/// Here we're taking advantage of truncating 120 bit limbs from the input field\n/// and then subtracting them from the input such that the field division is equivalent\n/// to integer division.\n///\n/// We return the lower 120-bit limb as a `u128` value,\n/// and the upper limbs as a `Field`, to avoid unnecessary conversions\n/// and potential overflows\npub(crate) unconstrained fn __split_120_bits(mut x: Field) -> (u128, Field) {\n let low: u128 = (x as u128) % TWO_POW_120;\n let high: Field = ((x - low as Field) / TWO_POW_120 as Field);\n (low, high)\n}\n\n/// Normalize an array of Field values into 120-bit limbs (unconstrained)\n///\n/// Each Field element is split into two parts modulo 2^{120}\n/// The overflow from the lower limbs is carried into the higher limbs\npub(crate) unconstrained fn __normalize_limbs(input: [Field; N]) -> [u128; N] {\n let mut normalized: [u128; N] = [0; N];\n let mut next: Field = input[0];\n for i in 0..(N - 1) {\n let (lo, hi): (u128, Field) = __split_120_bits(next);\n normalized[i] = lo;\n next = input[i + 1] + hi;\n }\n let (lo, hi): (u128, Field) = __split_120_bits(next);\n normalized[N - 1] = lo;\n\n // non-zero final carry <=> normalized value overflows the array length\n assert(hi == 0);\n\n normalized\n}\n", - "path": "/home/ace/nargo/github.com/gnosisguild/noir-bignum/v0.0.3/src/utils/split_bits.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_bn.vk deleted file mode 100644 index 08f48fd083b6b6c83bcd5e870c96cd4108f5f0a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg`9Bkk1Hf@(wlTvn=iD}$^DDXUA=f;v9EEb#_f>Oct{lsgBUg^Ob0df`p_(CGucOJ|i2hl930gAWUJwBsWd?#%x;+4n=|cg73_FC$e)LNKY- zIclkU^04u(MReaE^0__c!zEq z;<`NlirX%`$mx_LEl$xem92*3R}ygCDN?%~^Sx3eEUr4ud(xSuajSJE+tM2iR+p^P zHq*nW+kO>N6>!E%eYsC5%outCjt@$H{2$Jrr0goKd}r5P za>vbvk-CrPD!mP8@H>Rx!e0F0W=R9_N$|i)&4TI*|EQnKMqScqvj-HrIz@4n<2pOY8E1F)JM0#pHnM1fU=0zy( z_%qMyxZWQx?+BR=?Il@r!~nf*&8}!Ns7pMpqrWQrc)Zw@*Z-7XUcHL^6Txd4J!V2Al*=;v4!!`K@gbfaSTLmu69!42Y3A`+F|$K0(dhza^ZX< zxk|O~ zCqvH%(i|T)QI3tbM`SoLL!OXRwE7})MHgzTJ;C^Ha7~l_=qeo=nxTwu8&Vp+X zjELa1`&C#Z)5EP4)X<|kglT?JL~wB^Y?06EL8N+86e^7)q#H=nlM*Z9YJnL(kQj-X z1=AI>8JRSBW_Fkrk2^a;xc!McdhJz5`me!Y+qM^h#T~lG!8l@GsYy8@#AE(kG zoXDH`|MJTi!r}yBJ1aJNF(ai0zR11ytmB!vXuog&)`jFXHR*B?iMs9wAfzPJZ)Dd6 zC0p$Ji;lDsPz+LVmHpz4ZY=8Jh0bUpO+v6nv&vIEXwNalDdd&1=AJHoPAF!=eOtgy zDFWOi%Sml+d5S?551PpVyN-~^R)#vg*&X6~gR8<|vZ{)kb}kA8aK54xP-kczbq1WQ zKxG*Jj!+Pq4beI7A@x98E-@N9zFa4pUR8@}SOA8^kBiHVR-pj!Jta4a>G7klig7=Fa>FH*)N- z4utF?!G%ovG|&iSAjr+4gqxEs8HnpjTVwSr_#{|az6s0H85uBwM##N~kTe4BUKED= z=I4_%3NYX7-Hn7(W`}Iq!gXE$?N9&W>`Leqw|QC3CNsO^=CJVz*iKIv>f8greeX>K pUqbSRf$YAgnR`8jQ>|%vi+7ROaIe@*Qp1JEo_`4XI5_!f(Lb|$Eq(w1 diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json deleted file mode 100644 index c2117b26be..0000000000 --- a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "1413289141083555426", - "abi": { - "parameters": [ - { - "name": "decryption_shares", - "type": { - "kind": "array", - "length": 3, - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - } - } - }, - "visibility": "public" - }, - { "name": "party_ids", "type": { "kind": "array", "length": 3, "type": { "kind": "field" } }, "visibility": "public" }, - { - "name": "message", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - }, - "visibility": "public" - }, - { - "name": "u_global", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "crt_quotients", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 80, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - } - ], - "return_type": null, - "error_types": { - "991688543994151927": { "error_kind": "string", "string": "Division verification failed: result * rhs ≠ lhs (mod m)" }, - "6347439466827421235": { "error_kind": "string", "string": "CRT reconstruction verification failed" }, - "15764276373176857197": { "error_kind": "string", "string": "Stack too deep" } - } - }, - "bytecode": "H4sIAAAAAAAA/9z9f7hNVf82/O+dvbf9+4eiKEIRilAUIRQhFEUoilAUoQihKEJRhFCEEEIIoQihCEVRFKEoilCE0PcZ3WMf39Vc65prn+d8v437ecYfd8dxNZnjHHOMc70+81rrumNj/s+Is//s1LpD5+/qx8Tc/Mx///OLYsJHrP1n4Zgcjdg9sTm+NuIoHP2SjH/O74kNnetVuf7PP682/zRhLoqRCWP+whxeG3EU/h9/r/c/CJ1rMRumeC57ZfY/zb/o5/nPzEX9/8dfVtj+s2zbht32lptUcsndtRb379+sZYkbfqnTa2mXEbftPfHaUft35PTaa3wW5B/PCJ3nNRHmmcszzyjjPw/DM88HPPOMLZaLy48M7zpHmz8ypxI+c8p4Y/6wQpsf3H7He8vq9uv3zpTQdS5h90hcyH8WNhHPvKPNpZjPXLx/NvR+JXMFuKH5w9EW2Pv3lMz5g4wtBTwMNoO5R7TG8f49pcDNiM6ruJ1XtLX1Hihkva4FMoRu3mttSUg2ePGcFdbRmNgr/4l0TeH/Pe3/jNC5Xmc3fmlvg5cWaOvSwIMoQ7Z1GYG2Lg609XW5uPw+mcIeKHpQriM/FdB1CvWSz5yePxpb+F/n5HT+CF0i+Y+h0t6QY1E4hh+Fo18SZsDr7cKXlTZgWQcGLGfDlPc2SLkIBiwv0CrlgZ11A9kqNwi0SlmgVcrl4vIjAzUgMqcbSQPeqGDAcqQBK7AGNDesQBiwAmDAisoGNBkqEgasqGzA8nZeqAGR9bqJNOBNCgYs78CAN9uNX8nb4JUE2roS8CAqk21dWaCtywNtfXMuLr9PpsAGvDngQYx2ufHS1bmg5/+vA68H1grhi4QDzf32OXTgLXaTVpF2YBUHDqxqw1TztkjVCA6sJtAs1YCddSvZLLcKNEsVoFmq5uLyIwN1IDKn6qQDqys4sCrpwBqsA80NaxAOrAE4sKayA02GmoQDayo7sJqdF+pAZL1uIx14m4IDqzlw4O1249fyNngtgbauBTyI2mRb1xZo62pAW9+ei8vvkymwA29XdqDxUlnCgbcAa4XwJS7m/79Xg2Zj2YTeZ0/shbFm6Gm/I9uYZgRBs/mL9jhEcx37pOtKo7muAzTXs2Hu9FZuvQhovlOghu8EjmF9sobrC9RwXaCG6+Xi8iMDRTMypwYkmhsooLkeieaGLJrNDRsSaG4IoPkuZTSbDHcRaL5LGc132nmhaEbW624SzXcroPlOB2huZDd+Y2+DNxZo68bAg7iHbOt7BNr6TqCtG+Xi8vtkCozmRspoNl66g0BzHWCtEL5IfolS6V1j6Agz4L12gzaRNmATBwZsasPc522QphEMeJ9Aq9wH7KpmZKs0E2iVJkCrNM3F5UcGakBkTs1JAzZXMGBT0oAtWAOaG7YgDNgCMOD9ygY0Ge4nDHi/sgHvs/NCDYis1wOkAR9QMOB9DgzY0m78Vt4GbyXQ1q2AB/Eg2dYPCrT1fUBbt8zF5ffJFNiALclPBXSdquQs+7/+uxdYJ5Yu6KdaXaU5+ZkUPTPG24VjcpZnbyy3bjGeOfmMML8+ZDdNa2m/tnbg1zY2zMPe9msTwa8PCzTiw8AObEs2YluBRmwNNGKbXFx+ZKAnHZlTO9Kv7RT82ob0a3vWr+aG7Qm/tgf8+oiyX02GRwi/PqLs14ftvFC/Iuv1KOnXRxX8+rADv3awG7+jt8E7CrR1R+BBPEa29WMCbf0w0NYdcnH5fTIF9msH8lMhDrwPa6to1n0IWFOEOZFcyXgSuOe/X5JonQs+/DFKfAsdYRZ93B6UTtIW7eTAop1tmCe8TdY5gkWfEGi3J4Bd24Vsty4C7dYJaLfOubj8yEAtisypK2nRrgoW7UxatBtrUXPDboRFuwH19qSyRU2GJwmLPqls0SfsvFCLIuv1FGnRpxQs+oQDi3a3G7+Ht8F7CLR1D+BBPE229dMCbf0E0Nbdc3H5fTIFtmj3gAcx2uX/y1fR5tWzjm5BZDsxV87/3L/2fRx4hgCrYpG8kl+kvYNUwf8lxAwdYV+k7ZntZDOCfJHW/EWdckGT+Z+jcPRLwuDfy967tzT8ezuA/zM2TB/vx8YzEeDfR+CjpA9wZPuSHyV9BT5KegMfJc/k4vIjA4U/Mqd+JPz7KcD/GRL+z7LwNzd8loD/s8DnyXPK8DcZniPg/5wy/PvYeaHwR9arPwn//grw7+MA/gPsxn/e2+DPC7T188CDeIFs6xcE2roP0NYDcnH5fTIFhv8AZfgbL/XMhX+RthewVghfJL9Iy6I5Juf3CTPgQLtBB0kbcJADA75owwz2NsiLEQw4WKBVBgO7agjZKkMEWmUQ0Cov5uLyIwM1IDKnoaQBhyoY8EXSgC+xBjQ3fIkw4EuAAV9WNqDJ8DJhwJeVDTjYzgs1ILJew0gDDlMw4GAHBhxuN/4r3gZ/RaCtXwEexKtkW78q0NaDgbYenovL75MpsAGHk58K6DrdkbPs//pvILBOLF3QT7XeSnP6f+P/IsKF+hJuaPuMyDavGUFe5Jq/yOX/nOxI+6Rfk0b8aw4QP8qGGe39CBgVAfGjBT4WRgPHcAz5sTBG4GPhNeBjYVQuLj8y0LpD5vQ6ifjXFRA/ikT8WBbx5oZjCcSPBRA/ThnxJsM4AvHjlBE/2s4LRTyyXuNJxI9XQPxoB4h/w278N70N/qZAW78JPIgJZFtPEGjr0UBbv5GLy++TKTDi3wh4EKNdbrw0gniROxJYK5Yv6J4E/pcXIFJJfHPZrPP/V7+5PNEeyrek3fuWA/dOsmEme1tzUgT3ThZo0snASZpCNukUgSZ9C2jSSbm4/MhA3YvM6W3SvW8ruHcS6d6prHvNDacS7p0K1Ns0ZfeaDNMI905Tdu9kOy/Uvch6TSfdO13BvZMduPcdu/FneBt8hkBbzwAexEyyrWcKtPVkoK3fycXl98kU2L3vKB/EbI/lyvmf+9e9E4G1Avji7BvCI8hP3/9LKBc6wl4sz8r2qBlBXiybv+itXNBk/ucoHP2SMGC/a+89WxrYsx0Ae44NM9dbz3MiAHuuQGXPBY7se2RlvydQ2bOByp6Ti8uPDBTYyJzmkcCepwDsOSSw57PANjecTwB7PvB5skAZ2CbDAgLYC5Q/1+faeaHARtbrfRLY7ysAe64DYC+0G3+Rt8EXCbT1IuBBLCbberFAW88F2nphLi6/T6bAwF4Y8CBGu9x4aRbxYvldYK0Qvkh+Q5hFc0zO7xNmwA/sBl0ibcAlDgy41IZZ5m2QpREMuEygVZYBu+pDslU+FGiVJUCrLM3F5UcGakBkTh+RBvxIwYBLSQMuZw1obricMOBywIArlA1oMqwgDLhC2YDL7LxQAyLr9TFpwI8VDLjMgQFX2o2/ytvgqwTaehXwIFaTbb1aoK2XAW29MheX3ydTYAOuJD8V0HUakbPs//rvA2CdWLqgn2qzleaEmDTafWfl7L7/ujLSvygck7M/GzrXT+xGWCNt0jUOTLrWhlnnbbS1EUy6TqDl1gG76lOy5T4VaLk1QMutzcXlRwZ6epE5fUaa9DMFk64lTbqeNam54XrCpOsBk25QNqnJsIEw6QZlk66z80JNiqzX56RJP1cw6ToHJt1oN/4mb4NvEmjrTcCD2Ey29WaBtl4HtPXGXFx+n0yBTbpRyKSIl6KZ9BNgnXJIl38t9f/GX4iZL6bm8NqIo3D0S8L+i/wvsn1pRpD/It/8Rftiocn8z1E4+iVhYP7SPukt0mDe4gDMW22Yr7x1uzUCmL8SqOCvgGP4NVnBXwtU8Baggrfm4vIjAwUzMqdtJJi3KYB5Kwnm7SyYzQ23E2DeDoD5G2UwmwzfEGD+RhnMX9l5oWBG1utbEszfKoD5Kwdg3mE3/k5vg+8UaOudwIP4jmzr7wTa+iugrXfk4vL7ZAoM5h0BD2K0y42XvsiF/xf5XwJrxfJF8xdiyJxc/f+ZdqEwHprre3vAdkkbdpcDw+62YX7wNuDuCIb9QaAVfwBOxR6yFfcItOIuoBV35+LyIwM1LDKnvaRh9yoYdjdp2H2sYc0N9xGG3QdU6Y/KhjUZfiQM+6OyYX+w80INi6zXT6Rhf1Iw7A8ODLvfbvwD3gY/INDWB4AH8TPZ1j8LtPUPQFvvz8Xl98kU2LD7yU8Fzf8/00JtFc263wNrijBH6n95ALjnv7l35YIPf4wS30JHmEV/sQfloLRFDzqw6CEb5ldvkx2KYNFfBdrtV2DX/ka2228C7XYQaLdDubj8yEAtiszpMGnRwwoWPURa9AhrUXPDI4RFjwD19ruyRU2G3wmL/q5s0V/tvFCLIut1lLToUQWL/urAosfsxj/ubfDjAm19HHgQf5Bt/YdAW/8KtPWxXFx+n0yBLXoMPIgXymPo+9dfgLVFuCP5pYUvyE/g/0s4FzrCvrTwZ7ZJzQjypQXzFx3MBU3mf47C0S8JQ/YJe++T0sg+6QDZf9kwp7wV/VcEZJ8SqO1TwDE8Tdb2aYHaPgnU9l+5uPzIQJGNzOkMiewzCsj+i0T23yyyzQ3/JpD9N/CZdVYZ2SbDWQLZZ5WRfcrOC0U2sl7nSGSfU0D2KQfIPm83/j/eBv9HoK3/QTZuHNfW5s8FbetTQFufz8Xl98kUGNnnAx7EaJcbL/1JoPkEsFYIXyT/1wdYNMfk/D5hBoy1AS4y/5RskIviLrwBc9kwcaH/p0ys/RdeA8bFBW+VuLicXxtPtkq8QKtcFJfzVskVx+VHBmpAZE4JcZwBE+LkDZgrjjNg7rgANzR/GDVg7pw/yNhE4GGwGcw9UAMmgpsRnVecnRdqQGS9koAMoZs3KU7egHE5KyxRAybbjZ/ibfAUgbZOAR5EKtnWqQJtHQe0dXIcl98nU2ADJpOfCug6fZEz0/3rv1hgnS66QJ9qJ3PpzEnSpHtiL4BJz1b/j0nTbIB0aZOmOzBphg2T6W20jAgmzRRouUxgp2eRLZcl0HLpQMtlxHH5kYGeXmROeUiT5lEwaQZp0otZk5obXkyY9GLApJcom9RkuIQw6SXKJs2080JNiqxXXtKkeRVMmplTwuT6WMyk+ezGv9Tb4JcKtPWlwIO4jGzrywTaOhNo63xxXH6fTGEPFD0o+S6QSUO95GvSXCv/dU5O54/QJZL/GCpd0P8vVz0GzG9DFJA2YAEHBrzchrnC2yCXRzDgFQKtcgWwswqSrVJQoFUKAK1yeRyXHxmoAZE5FSINWEjBgJeTBrySNaC54ZWEAa8EDFhY2YD/LhphwMLKBrzCzgs1ILJeRUgDFlEw4BUODFjUbvyrvA1+lUBbXwU8iKvJtr5aoK2vANq6aByX3ydTYAMWDXgQo11uvJQeB/530/+PA/MDa4XwRcKB5n4X9H9YyePAYjZEcWkHFnfgwGtsmBLeFrkmggNLCDRLCWBnlSSbpaRAsxQHmuWaOC4/MlAHInMqRTqwlIIDryEdeC3rQHPDawkHXgs48DplB5oM1xEOvE7ZgSXsvFAHIutVmnRgaQUHlnDgwDJ241/vbfDrBdr6euBBlCXbuqxAW5cA2rpMHJffJ1NgB5ZRdqDxUgHCgcWAtUL4ErpXg2Zj2YTeZ0/shbFm6Gkvl21MM4Kg2fxFexyiubwNcYM0mm9wgOYbbZgK3sq9MQKaKwjUcAXgGFYka7iiQA3fANTwjXFcfmSgaEbmdBOJ5psU0HwjieabWTSbG95MoPlmAM2VlNFsMlQi0FxJGc0V7LxQNCPrVZlEc2UFNFdwgOZb7Mav4m3wKgJtXQV4EFXJtq4q0NYVgLa+JY7L75MpMJpvUUaz8VI5As3lgbVC+BLJgWw2pXeNoSPMgNVsgFulDXirAwNWt2FqeBukegQD1hBolRrArqpJtkpNgVa5FWiV6nFcfmSgBkTmdBtpwNsUDFidNODtrAHNDW8nDHg7YMBaygY0GWoRBqylbMAadl6oAZH1qk0asLaCAWs4MOAdduPX8TZ4HYG2rgM8iLpkW9cVaOsaQFvfEcfl98kU2IB3kJ8Kgv91YJj/qgHrdOsF+lS7QWlOfiZFz4zxduGYnOXZG8utW4xnTj4jzK/1bNg7pf16pwO/1rdhGnjbr34EvzYQaMQGwA5sSDZiQ4FGvBNoxPpxXH5koCcdmdNdpF/vUvBrfdKvd7N+NTe8m/Dr3YBfGyn71WRoRPi1kbJfG9h5oX5F1qsx6dfGCn5t4MCv99iNf6+3we8VaOt7gQfRhGzrJgJt3QBo63viuPw+mQL79R7yUyEOvA9rq2jWrQesKcKcSK5kPAnc898vSdwZBx/+GCW+hY4wiza1C3SftEXvc2DRZjZMc2+TNYtg0eYC7dYc2LUtyHZrIdBu9wHt1iyOy48M1KLInO4nLXq/gkWbkRZ9gLWoueEDhEUfAOqtpbJFTYaWhEVbKlu0uZ0XalFkvVqRFm2lYNHmDiz6oN34D3kb/CGBtn4IeBCtybZuLdDWzYG2fjCOy++TKbBFHwx4EKNd/r98FW1efevoFkS2E3Pl/M/9a9+mwDMEWBWL5A09b9HWIdp9y5Eq+L+EmKEj7Iu0bbKdbEaQL9Kav+i+OGgy/3MUjn5JGPwftvduKw3/tg7g386Gae/92GgXAf7tBT5K2gNH9hHyo+QRgY+StsBHSbs4Lj8yUPgjc3qUhP+jCvBvR8K/Awt/c8MOBPw7AJ8nHZXhbzJ0JODfURn+7e28UPgj6/UYCf/HFODf3gH8H7cbv5O3wTsJtHUn4EF0Jtu6s0Bbtwfa+vE4Lr9PpsDwf1wZ/sZLbeLwL9I+DKwVwpdIDmSzsWiOyfl9wgz4hA3QRdqAXRwYsKsN083bIF0jGLCbQKt0A3bVk2SrPCnQKl2AVukax+VHBmpAZE5PkQZ8SsGAXUkDdmcNaG7YnTBgd8CAPZQNaDL0IAzYQ9mA3ey8UAMi6/U0acCnFQzYzYEBe9qN38vb4L0E2roX8CB6k23dW6CtuwFt3TOOy++TKbABe5KfCug6lctZ9n/99wSwTl0u0KdaW6U5hZ6dsJuCc7xQ/4sIF+pLuKHt80y2ec0I8iLX/EUu/+dk+9gQfaUR39cB4vvZMM96PwL6RUD8swIfC88Cx/A58mPhOYGPhb7Ax0K/OC4/MtC6Q+bUn0R8fwXE9yMRP4BFvLnhAALxAwDEP6+MeJPheQLxzysj/lk7LxTxyHq9QCL+BQXEP+sA8QPtxh/kbfBBAm09CHgQL5Jt/aJAWz8LtPXAOC6/T6bAiB8Y8CBGu9x46RniRW4fYK36Cn2yRbsP8L+8AJEqkk3RuZl1/v/qN5cH2wUaIu3eIQ7cO9SGecnbmkMjuPclgSZ9CThJL5NN+rJAkw4BmnRoHJcfGah7kTkNI907TMG9Q0n3Dmfda244nHDvcKDeXlF2r8nwCuHeV5Td+5KdF+peZL1eJd37qoJ7X3Lg3hF244/0NvhIgbYeCTyI18i2fk2grV8C2npEHJffJ1Ng945QPojZHkO/ITwYWCuAL86+IfzMBXqxrES50BH2YnlUtkfNCPJi2fxFQ+KgyfzPUTj6JWHAHm3vPUYa2GMcAPt1G2ast55fjwDssQKVPRY4suPIyh4nUNljgMp+PY7LjwwU2MicxpPAHq8A7NdJYL/BAtvc8A0C2G8AnydvKgPbZHiTAPabyp/rY+28UGAj6zWBBPYEBWCPdQDsiXbjv+Vt8LcE2vot4EFMItt6kkBbjwXaemIcl98nU2BgTwx4EKNdbrw0inixPBpYK4QvkRzIZmPRHJPz+4QZcLINMEXagFMcGPBtG2aqt0HejmDAqQKtMhXYVdPIVpkm0CpTgFZ5O47LjwzUgMicppMGnK5gwLdJA77DGtDc8B3CgO8ABpyhbECTYQZhwBnKBpxq54UaEFmvmaQBZyoYcKoDA86yG/9db4O/K9DW7wIPYjbZ1rMF2noq0Naz4rj8PpkCG3AW+amArtMzOcv+r/8mA+s05QJ9qo1RmhNi0mj3HZWz+/7rykj/onBMzv5s6Fzn2ABzpU0614FJ37Nh5nkb7b0IJp0n0HLzgF01n2y5+QItNxdouffiuPzIQE8vMqcFpEkXKJj0PdKk77MmNTd8nzDp+4BJFyqb1GRYSJh0obJJ59l5oSZF1msRadJFCiad58Cki+3G/8Db4B8ItPUHwINYQrb1EoG2nge09eI4Lr9PpsAmXSxkUsRL0Uw6B1inHNLlX0uF7lPvQA/chfqFmPliag6vjTgKR78k7L/IX5rtSzOC/Bf55i/aFwtN5n+OwtEvCQPzMhviQ2kwf+gAzB/ZMMu9dftRBDAvF6jg5cAxXEFW8AqBCv4QqOCP4rj8yEDBjMzpYxLMHyuA+SMSzCtZMJsbriTAvBIA8yplMJsMqwgwr1IG83I7LxTMyHqtJsG8WgHMyx2A+RO78dd4G3yNQFuvAR7EWrKt1wq09XKgrT+J4/L7ZAoM5k8CHsRolxsvLY3D/4v8ZcBafSj0ySb5CzFkTpFsys5xTyz2bHJ4bcRROPolYYZdZ8N+Km3YTx0Y9jMbZr23AT+LYNj1Aq24HjgVG8hW3CDQip8CrfhZHJcfGahhkTl9Thr2cwXDfkYadiNrWHPDjYRhNwJVuknZsCbDJsKwm5QNu97OCzUssl6bScNuVjDsegeG/cJu/C+9Df6lQFt/CTyILWRbbxFo6/VAW38Rx+X3yRTYsF+Qnwpx4H1YW0Wz7jpgTRHmRHIl8788ANzz39yfxsGHP0aJb6EjzKJb7QJ9JW3RrxxY9GsbZpu3yb6OYNFtAu22Ddi128l22y7Qbl8B7fZ1HJcfGahFkTl9Q1r0GwWLfk1a9FvWouaG3xIW/Raotx3KFjUZdhAW3aFs0W12XqhFkfXaSVp0p4JFtzmw6Hd243/vbfDvBdr6e+BB7CLbepdAW28D2vq7OC6/T6bAFv0OPIgXymPo+9etwNoi3And22GT9cwxWral5Cfw/yWcCx1hX1rYnW1SM4J8acH8RV/FQZP5n6Nw9EvCkP2DvfceaWTvcYDsvTbMPm9F742A7H0Ctb0POIY/krX9o0Bt7wFqe28clx8ZKLKROf1EIvsnBWTvJZG9n0W2ueF+Atn7gc+sA8rINhkOEMg+oIzsfXZeKLKR9fqZRPbPCsje5wDZv9iNf9Db4AcF2vog8CAOkW19SKCt9wFt/Uscl98nU2Bk/xLwIEa73HhpN4HmH4C1QvgSyYFsNhbNMTm/T5gBf7UBfpM24G8ODHjYhjnibZDDEQx4RKBVjgC76neyVX4XaJXfgFY5HMflRwZqQGROR0kDHlUw4GHSgMdYA5obHiMMeAww4HFlA5oMxwkDHlc24BE7L9SAyHr9QRrwDwUDHnFgwD/txj/hbfATAm19AngQJ8m2PinQ1keAtv4zjsvvkymwAf8kPxXQdVqas+z/+u9XYJ1+u0CfanuU5hTJpOjhN/9Pz5A3wYVj+FE4+iUZ/5zf8x+X/mVDnJJ26SkHLj1tw5zxttrpCC49I9B0Z4Cd9TfZdH8LNN0poOlOx3H5kYGeYGROZ0mXnlVw6WnSpedYl5obniNceg5w6Xlll5oM5wmXnld26Rk7L9SlyHr9Q7r0HwWXnskpY2KvFHNpTLy9KD7mvwHNfxC0rc3fkdNrL4rn2vqi+OBtfQZo65h4Lr9PprAHih6UmPhgBzEnlxszQe8mYwv/a52cZkD4EsmB/5lsjHM2hY4wA+ayhy7O/FOyQeLiVcL4Nki8DZPgbRDzL7wGTBBolQTgBOYmWyW3QKvExee8VeLjufzIQA2IzCkxnjNgYry8AePjOQMmxQe4ofnDqAGTcv4gY5OBh8FmMPdADZgc8KMnJ5s9OR43ILJeKUCG0M2bEi9vwASSDDH+9/Ft8FS78dO8DZ4m0NZpwINIJ9s6XaCtE4C2To3n8vtkCmzAVPJTQfDNRpj/cgHrhNBF4j3gpP/n/1nj8D1ghj10mdIGzHRgwCwbJo+3QbIiGDCPQKvkAXbWxWSrXCzQKplAq2TFc/mRgRoQmdMlpAEvUTBgFmnAvKwBzQ3zEgbMCxgwn7IBTYZ8hAHzKRswj50XakBkvS4lDXipggHzODDgZXbj5/c2eH6Bts4PPIgCZFsXEGjrPEBbXxbP5ffJFNiAlwU8iNEunxTzf8yEvgfMANYK4Yvfe0D0kw7wpxaxQkeYFy+3B/QKaS9e4cCLBW2YQt62KRjBi4UEGqgQsAOvJBvoSoEGugJooILxXH5koKcImVNh0ouFFbxYkPRiEdaL5oZFCC8WAWqqqLIXTYaihBeLKnuxkJ0X6kVkva4ivXiVghcLOfDi1XbjF/M2eDGBti4GPIjiZFsXF2jrQkBbXx3P5ffJFNiLV5OfCnGe+0QZtK2iufJyYE0R5ki8X6z+//yBPx2+X7zGHtAS0l4s4cCLJW2YUt62KRnBi6UEGqgUsLOuJRvoWoEGKgE0UMl4Lj8yUC8ic7qO9OJ1Cl4sSXqxNOtFc8PShBdLA9VbRtmLJkMZwotllL1Yys4L9SKyXteTXrxewYulHHixrN345bwNXk6grcsBD6I82dblBdq6FNDWZeO5/D6ZAnuxbMCDGO3ybDOh7xevAdYK4Yvk+0XAn1rECh1hXrzBHtAbpb14owMvVrBhKnrbpkIEL1YUaKCKwA68iWygmwQa6EaggSrEc/mRgZ4iZE43k168WcGLFUgvVmK9aG5YifBiJaCmKit70WSoTHixsrIXK9p5oV5E1usW0ou3KHixogMvVrEbv6q3wasKtHVV4EFUI9u6mkBbVwTauko8l98nU2AvVrlA7xdZW0Vz5Q3AmiLMkXi/aK53+TvmW+0BrS7txeoOvFjDhqnpbZsaEbxYU6CBagI76zaygW4TaKDqQAPViOfyIwP1IjKn20kv3q7gxRqkF2uxXjQ3rEV4sRZQvbWVvWgy1Ca8WFvZizXtvFAvIut1B+nFOxS8WNOBF+vYjV/X2+B1Bdq6LvAg6pFtXU+grWsCbV0nnsvvkymwF+sEPIjRLs82E/p+8VZgrRC+SP6OWYlNoSPMgHfaQ1df2oD1HRiwgQ3T0NsgDSIYsKFAqzQEdtVdZKvcJdAq9YFWaRDP5UcGakBkTneTBrxbwYANSAM2Yg1obtiIMGAjwICNlQ1oMjQmDNhY2YAN7bxQAyLrdQ9pwHsUDNjQgQHvtRu/ibfBmwi0dRPgQTQl27qpQFs3BNr63nguv0+mwAa8l/xUEHyzEea/O4F1Qugi8R5wcozb3zHfZw9dM2kDNnNgwOY2TAtvgzSPYMAWAq3SAthZ95Otcr9AqzQDWqV5PJcfGagBkTk9QBrwAQUDNicN2JI1oLlhS8KALQEDtlI2oMnQijBgK2UDtrDzQg2IrNeDpAEfVDBgCwcGfMhu/NbeBm8t0NatgQfRhmzrNgJt3QJo64fiufw+mQIb8KGABzHa5dlmQt8D3gesFcIXye8ZAv7UIlboCPPiw/aAtpX2YlsHXmxnw7T3tk27CF5sL9BA7YEd+AjZQI8INFBboIHaxXP5kYGeImROj5JefFTBi+1IL3ZgvWhu2IHwYgegpjoqe9Fk6Eh4saOyF9vbeaFeRNbrMdKLjyl4sb0DLz5uN34nb4N3EmjrTsCD6Ey2dWeBtm4PtPXj8Vx+n0yBvfg4+amAfs+QtVU0Vz4MrCnCHIn3izVi3f6O+Ql7QLtIe7GLAy92tWG6edumawQvdhNooG7AznqSbKAnBRqoC9BAXeO5/MhAvYjM6SnSi08peLEr6cXurBfNDbsTXuwOVG8PZS+aDD0IL/ZQ9mI3Oy/Ui8h6PU168WkFL3Zz4MWeduP38jZ4L4G27gU8iN5kW/cWaOtuQFv3jOfy+2QK7MWeAQ9itMuzzYS+X3wCWCuEL5LvFwF/ahErdIR58Rl7QPtIe7GPAy/2tWH6edumbwQv9hNooH7ADnyWbKBnBRqoD9BAfeO5/MhATxEyp+dILz6n4MW+pBf7s140N+xPeLE/UFMDlL1oMgwgvDhA2Yv97LxQLyLr9TzpxecVvNjPgRdfsBt/oLfBBwq09UDgQQwi23qQQFv3A9r6hXguv0+mwF584QK9X2RtFc2VzwBrijBH4v2i+bMuf8f8oj2gg6W9ONiBF4fYMEO9bTMkgheHCjTQUGBnvUQ20EsCDTQYaKAh8Vx+ZKBeROb0MunFlxW8OIT04jDWi+aGwwgvDgOqd7iyF02G4YQXhyt7caidF+pFZL1eIb34ioIXhzrw4qt244/wNvgIgbYeATyIkWRbjxRo66FAW78az+X3yRTYi68GPIjRLs82E/p+8UVgrRC+SP6OWYlNoSPMgK/ZQzdK2oCjHBhwtA0zxtsgoyMYcIxAq4wBdtXrZKu8LtAqo4BWGR3P5UcGakBkTmNJA45VMOBo0oDjWAOaG44jDDgOMOB4ZQOaDOMJA45XNuAYOy/UgMh6vUEa8A0FA45xYMA37caf4G3wCQJtPQF4EBPJtp4o0NZjgLZ+M57L75MpsAHfJD8VBN9shPnvNWCdELpIvAecEuP2d8xv2UM3SdqAkxwYcLINM8XbIJMjGHCKQKtMAXbW22SrvC3QKpOAVpkcz+VHBmpAZE5TSQNOVTDgZNKA01gDmhtOIww4DTDgdGUDmgzTCQNOVzbgFDsv1IDIer1DGvAdBQNOcWDAGXbjz/Q2+EyBtp4JPIhZZFvPEmjrKUBbz4jn8vtkCmzAGQEPYrTLs82Evgd8C1grhC+S3zME/KlFrNAR5sV37QGdLe3F2Q68OMeGmettmzkRvDhXoIHmAjvwPbKB3hNooNlAA82J5/IjAz1FyJzmkV6cp+DFOaQX57NeNDecT3hxPlBTC5S9aDIsILy4QNmLc+28UC8i6/U+6cX3Fbw414EXF9qNv8jb4IsE2noR8CAWk229WKCt5wJtvTCey++TKbAXF5KfCuj3DFlbRXPlu8CaIsyReL9YM9bt75g/sAd0ibQXlzjw4lIbZpm3bZZG8OIygQZaBuysD8kG+lCggZYADbQ0nsuPDNSLyJw+Ir34kYIXl5JeXM560dxwOeHF5UD1rlD2osmwgvDiCmUvLrPzQr2IrNfHpBc/VvDiMgdeXGk3/ipvg68SaOtVwINYTbb1aoG2Xga09cp4Lr9PpsBeXBnwIEa7PNtM6PvFD4C1Qvgi+X4R8KcWsUJHmBc/sQd0jbQX1zjw4lobZp23bdZG8OI6gQZaB+zAT8kG+lSggdYADbQ2nsuPDPQUIXP6jPTiZwpeXEt6cT3rRXPD9YQX1wM1tUHZiybDBsKLG5S9uM7OC/Uisl6fk178XMGL6xx4caPd+Ju8Db5JoK03AQ9iM9nWmwXaeh3Q1hvjufw+mQJ7ceMFer/I2iqaKz8B1hRhjsT7RbOXXP6O+Qt7QL+U9uKXDry4xYbZ6m2bLRG8uFWggbYCO+srsoG+EmigL4EG2hLP5UcG6kVkTl+TXvxawYtbSC9uY71obriN8OI2oHq3K3vRZNhOeHG7she32nmhXkTW6xvSi98oeHGrAy9+azf+Dm+D7xBo6x3Ag9hJtvVOgbbeCrT1t/Fcfp9Mgb34bcCDGO3ybDOh7xe/ANYK4Yvk75iV2BQ6wgz4nT1030sb8HsHBtxlw+z2NsiuCAbcLdAqu4Fd9QPZKj8ItMr3QKvsiufyIwM1IDKnPaQB9ygYcBdpwL2sAc0N9xIG3AsYcJ+yAU2GfYQB9ykbcLedF2pAZL1+JA34o4IBdzsw4E924+/3Nvh+gbbeDzyIA2RbHxBo691AW/8Uz+X3yRTYgD+RnwqCbzbC/PcdsE4IXSTeA74d4/Z3zD/bQ/eLtAF/cWDAgzbMIW+DHIxgwEMCrXII2Fm/kq3yq0Cr/AK0ysF4Lj8yUAMic/qNNOBvCgY8SBrwMGtAc8PDhAEPAwY8omxAk+EIYcAjygY8ZOeFGhBZr99JA/6uYMBDDgx41G78Y94GPybQ1seAB3GcbOvjAm19CGjro/Fcfp9MgQ14NOBBjHZ5tpnQ94A/A2uF8EXye4aAP7WIFTrCvPiHPaB/SnvxTwdePGHDnPS2zYkIXjwp0EAngR34F9lAfwk00J9AA52I5/IjAz1FyJxOkV48peDFE6QXT7NeNDc8TXjxNFBTZ5S9aDKcIbx4RtmLJ+28UC8i6/U36cW/Fbx40oEXz9qNf87b4OcE2voc8CDOk219XqCtTwJtfTaey++TKbAXz5KfCuj3DFlbRXPlH8CaIsyReL94W6zb3zH/k/3JlBAj2zbmL8zhtRFH4f/193rGfxY/wf5nCTH/bRvzL7xeNBcFbaCLEnJ+ba4EroFyJQRvoJiEnDdQbAKXHxmoF5E5xSVwXoxLkPdibALnxfiEADc0fxj1YnzOH2RsAvAw2AzmHqgXE8DNiM7rIjsv1IvIeuUGMoRu3twJ8l68KGeFJerFRLvxk7wNniTQ1knAg0gm2zpZoK0vAto6MYHL75MpsBcTAx7EaJdnmwl9v/gP8n/oAhkk3y8C/tQiVugI82KKPaCp0l5MdeDFNBsm3ds2aRG8mC7QQOnAac0gGyhDoIFSgQZKS+DyIwM9RcicMkkvZip4MY30YhbrRXPDLMKLWYAX8yh70WTIQ3gxj7IX0+28UC8i63Ux6cWLFbyY7sCLl9iNn9fb4HkF2jov8CDykW2dT6Ct04G2viSBy++TKbAXLyE/FdD3i6ytorkyBVhThDkS7xfN3+Hyd8yX2gN6mbQXL3Pgxfw2TAFv2+SP4MUCAg1UANhZl5MNdLlAA10GNFD+BC4/MlAvInO6gvTiFQpezE96sSDrRXPDgoQXCwJeLKTsRZOhEOHFQspeLGDnhXoRWa8rSS9eqeDFAg68WNhu/CLeBi8i0NZFgAdRlGzrogJtXQBo68IJXH6fTIG9WDjgQYx2ebaZ0PeLlwJrhfBF8nfMSmwKHWEGvMoeuqulDXi1AwMWs2GKexukWAQDFhdoleLArrqGbJVrBFrlaqBViiVw+ZGBGhCZUwnSgCUUDFiMNGBJ1oDmhiUJA5YEDFhK2YAmQynCgKWUDVjczgs1ILJe15IGvFbBgMUdGPA6u/FLexu8tEBblwYeRBmyrcsItHVxoK2vS+Dy+2QKbMDryE8FwTcbYf67ClgnhC4S7wGnxrj9HfP19tCVlTZgWQcGLGfDlPc2SLkIBiwv0CrlgZ11A9kqNwi0SlmgVcolcPmRgRoQmdONpAFvVDBgOdKAFVgDmhtWIAxYATBgRWUDmgwVCQNWVDZgeTsv1IDIet1EGvAmBQOWd2DAm+3Gr+Rt8EoCbV0JeBCVybauLNDW5YG2vjmBy++TKbABbw54EKNdnm0m9D3g9cBaIXyR/J4h4E8tYoWOMC/eYg9oFWkvVnHgxao2TDVv21SN4MVqAg1UDdiBt5INdKtAA1UBGqhqApcfGegpQuZUnfRidQUvViW9WIP1orlhDcKLNYCaqqnsRZOhJuHFmsperGbnhXoRWa/bSC/epuDFag68eLvd+LW8DV5LoK1rAQ+iNtnWtQXauhrQ1rcncPl9MgX24u3kpwL6PUPWVtFceQuwpghzJN4v3h7r9nfMd9gDWkfai3UceLGuDVPP2zZ1I3ixnkAD1QN21p1kA90p0EB1gAaqm8DlRwbqRWRO9Ukv1lfwYl3Siw1YL5obNiC82ACo3obKXjQZGhJebKjsxXp2XqgXkfW6i/TiXQperOfAi3fbjd/I2+CNBNq6EfAgGpNt3VigresBbX13ApffJ1NgL94d8CBGuzzbTOj7xTuAtUL4Ivl+EfCnFrFCR5gX77EH9F5pL97rwItNbJim3rZpEsGLTQUaqCmwA+8jG+g+gQa6F2igJglcfmSgpwiZUzPSi80UvNiE9GJz1ovmhs0JLzYHaqqFshdNhhaEF1soe7GpnRfqRWS97ie9eL+CF5s68OIDduO39DZ4S4G2bgk8iFZkW7cSaOumQFs/kMDl98kU2IsPXKD3i6ytornyHmBNEeZIvF80/zOFLn/H/KA9oA9Je/EhB15sbcO08bZN6whebCPQQG2AnfUw2UAPCzTQQ0ADtU7g8iMD9SIyp7akF9sqeLE16cV2rBfNDdsRXmwHVG97ZS+aDO0JL7ZX9mIbOy/Ui8h6PUJ68REFL7Zx4MVH7cbv4G3wDgJt3QF4EB3Jtu4o0NZtgLZ+NIHL75MpsBcfDXgQo12ebSb0/eKDwFohfJH8HbMSm0JHmAEfs4fucWkDPu7AgJ1smM7eBukUwYCdBVqlM7CrniBb5QmBVnkcaJVOCVx+ZKAGRObUhTRgFwUDdiIN2JU1oLlhV8KAXQEDdlM2oMnQjTBgN2UDdrbzQg2IrNeTpAGfVDBgZwcGfMpu/O7eBu8u0NbdgQfRg2zrHgJt3Rlo66cSuPw+mQIb8CnyU0HwzUaY/x4D1gmhi8R7wGkxbn/H/LQ9dD2lDdjTgQF72TC9vQ3SK4IBewu0Sm9gZz1DtsozAq3SE2iVXglcfmSgBkTm1Ic0YB8FA/YiDdiXNaC5YV/CgH0BA/ZTNuC/h5UwYD9lA/a280INiKzXs6QBn1UwYG8HBnzObvz+3gbvL9DW/YEHMYBs6wECbd0baOvnErj8PpkCG/C5gAcx2uXZZkLfAz4NrBXCF8nvGQL+1CJW6Ajz4vP2gL4g7cUXHHhxoA0zyNs2AyN4cZBAAw0CduCLZAO9KNBALwANNDCBy48M9BQhcxpMenGwghcHkl4cwnrR3HAI4cUhQE0NVfaiyTCU8OJQZS8OsvNCvYis10ukF19S8OIgB1582W78Yd4GHybQ1sOABzGcbOvhAm09CGjrlxO4/D6ZAnvxZfJTAf2eIWuraK58HlhThDkS7xdrxbr9HfMr9oC+Ku3FVx14cYQNM9LbNiMieHGkQAONBHbWa2QDvSbQQK8CDTQigcuPDNSLyJxGkV4cpeDFEaQXR7NeNDccTXhxNFC9Y5S9aDKMIbw4RtmLI+28UC8i6/U66cXXFbw40oEXx9qNP87b4OME2noc8CDGk209XqCtRwJtPTaBy++TKbAXxwY8iNEuzzYT+n7xFWCtEL5Ivl8E/KlFrNAR5sU37AF9U9qLbzrw4gQbZqK3bSZE8OJEgQaaCOzAt8gGekuggd4EGmhCApcfGegpQuY0ifTiJAUvTiC9OJn1ornhZMKLk4GamqLsRZNhCuHFKcpenGjnhXoRWa+3SS++reDFiQ68ONVu/GneBp8m0NbTgAcxnWzr6QJtPRFo66kJXH6fTIG9OPUCvV9kbRXNlW8Aa4owR+L9ojkXLn/H/I49oDOkvTjDgRdn2jCzvG0zM4IXZwk00CxgZ71LNtC7Ag00A2igmQlcfmSgXkTmNJv04mwFL84kvTiH9aK54RzCi3OA6p2r7EWTYS7hxbnKXpxl54V6EVmv90gvvqfgxVkOvDjPbvz53gafL9DW84EHsYBs6wUCbT0LaOt5CVx+n0yBvTgv4EGMdnm2mdD3i+8Aa4XwRfJ3zEpsCh1hBnzfHrqF0gZc6MCAi2yYxd4GWRTBgIsFWmUxsKs+IFvlA4FWWQi0yqIELj8yUAMic1pCGnCJggEXkQZcyhrQ3HApYcClgAGXKRvQZFhGGHCZsgEX23mhBkTW60PSgB8qGHCxAwN+ZDf+cm+DLxdo6+XAg1hBtvUKgbZeDLT1Rwlcfp9MgQ34EfmpIPhmI8x/7wPrhNBF4j3g9Bi3v2P+2B66ldIGXOnAgKtsmNXeBlkVwYCrBVplNbCzPiFb5ROBVlkJtMqqBC4/MlADInNaQxpwjYIBV5EGXMsa0NxwLWHAtYAB1ykb0GRYRxhwnbIBV9t5oQZE1utT0oCfKhhwtQMDfmY3/npvg68XaOv1wIPYQLb1BoG2Xg209WcJXH6fTIEN+FnAgxjt8mwzoe8BPwbWCuGL5PcMAX9qESt0hHnxc3tAN0p7caMDL26yYTZ722ZTBC9uFmigzcAO/IJsoC8EGmgj0ECbErj8yEBPETKnL0kvfqngxU2kF7ewXjQ33EJ4cQtQU1uVvWgybCW8uFXZi5vtvFAvIuv1FenFrxS8uNmBF7+2G3+bt8G3CbT1NuBBbCfbertAW28G2vrrBC6/T6bAXvya/FRAv2fI2iqaKz8H1hRhjsT7xdqxbn/H/I09oN9Ke/FbB17cYcPs9LbNjghe3CnQQDuBnfUd2UDfCTTQt0AD7Ujg8iMD9SIyp+9JL36v4MUdpBd3sV40N9xFeHEXUL27lb1oMuwmvLhb2Ys77bxQLyLr9QPpxR8UvLjTgRf32I2/19vgewXaei/wIPaRbb1PoK13Am29J4HL75MpsBf3BDyI0S7PNhP6fvEbYK0Qvki+XwT8qUWs0BHmxR/tAf1J2os/OfDifhvmgLdt9kfw4gGBBjoA7MCfyQb6WaCBfgIaaH8Clx8Z6ClC5vQL6cVfFLy4n/TiQdaL5oYHCS8eBGrqkLIXTYZDhBcPKXvxgJ0X6kVkvX4lvfirghcPOPDib3bjH/Y2+GGBtj4MPIgjZFsfEWjrA0Bb/5bA5ffJFNiLv12g94usraK58kdgTRHmSLxfzB3j9nfMv9sDelTai0cdePGYDXPc2zbHInjxuEADHQd21h9kA/0h0EBHgQY6lsDlRwbqRWROf5Je/FPBi8dIL55gvWhueILw4gmgek8qe9FkOEl48aSyF4/beaFeRNbrL9KLfyl48bgDL56yG/+0t8FPC7T1aeBBnCHb+oxAWx8H2vpUApffJ1NgL54KeBCjXZ5tJvT94u/AWiF8kfwdsxKbQkeYAf+2h+6stAHPOjDgORvmvLdBzkUw4HmBVjkP7Kp/yFb5R6BVzgKtci6By48M1IDInGJycwY0f07agOdIA/5bc+wNzR9GDRibO+cP46LcugY0Gcw9UANelBvbjOi8ztt5oQZE1isXkCF085o/J23A8w4MGGc3fnzumP8GjM8dvK3jgQeRkJtr64Tcwdv6PNDWcbm5/D6ZAhswDjyI2UPwzUaY//4GPkHOBvQfetDeiXH7O+bc9tAlmn9KNkhibpUwvg2SZMMkexskKXe4AZMFWiUZOIEpZKukCLRKYu6ct0pSbi4/MlADInNKJQ2YqmDApNycAdNYA5obphEGTAMMmK5sQJMhnTBgurIBk+28UAMi65VBGjBDwYDJJBli/O/j2+CZduNneRs8S6Cts4AHkYds6zwCbZ0MtHVmbi6/T6bABswMeBCjXZ5tJvQ9YG5grRC+SH7PEPCnFrFCR5gXL7YH9BJpL17iwIt5bZh83rbJG8GL+QQaKB+wAy8lG+hSgQa6BGigvLm5/MhATxEyp8tIL16m4MW8pBfzs140N8xPeDE/4MUCyl40GQoQXiyg7MV8dl6oF5H1upz04uUKXsznwItX2I1f0NvgBQXauiDwIAqRbV1IoK3zAW19RW4uv0+mwF68gvxUQL9nyNoqmisvBtYUYY7E+8U7Yt3+jvlKe0ALS3uxsAMvFrFhinrbpkgELxYVaKCiwM66imygqwQaqDDQQEVyc/mRgXoRmdPVpBevVvBiEdKLxVgvmhsWI7xYDPBicWUvmgzFCS8WV/ZiUTsv1IvIel1DevEaBS8WdeDFEnbjl/Q2eEmBti4JPIhSZFuXEmjrokBbl8jN5ffJFNiLJQIexGiXZ5sJfb94JbBWCF8k3y8C/tQiVugI8+K19oBeJ+3F6xx4sbQNU8bbNqUjeLGMQAOVAXbg9WQDXS/QQNcBDVQ6N5cfGegpQuZUlvRiWQUvlia9WI71orlhOcKL5YCaKq/sRZOhPOHF8speLGPnhXoRWa8bSC/eoODFMg68eKPd+BW8DV5BoK0rAA+iItnWFQXaugzQ1jfm5vL7ZArsxRsv0PtF1lbRXHktsKYIcyTeLybGuP0d8032gN4s7cWbHXixkg1T2ds2lSJ4sbJAA1UGdtYtZAPdItBANwMNVCk3lx8ZqBeROVUhvVhFwYuVSC9WZb1obliV8GJVoHqrKXvRZKhGeLGashcr23mhXkTW61bSi7cqeLGyAy9Wtxu/hrfBawi0dQ3gQdQk27qmQFtXBtq6em4uv0+mwF6sHvAgRrs820zo+8WbgLVC+CL5O2YlNoWOMAPeZg/d7dIGvN2BAWvZMLW9DVIrggFrC7RKbWBX3UG2yh0CrXI70Cq1cnP5kYEaEJlTHdKAdRQMWIs0YF3WgOaGdQkD1gUMWE/ZgCZDPcKA9ZQNWNvOCzUgsl53kga8U8GAtR0YsL7d+A28Dd5AoK0bAA+iIdnWDQXaujbQ1vVzc/l9MgU2YH3yU0HwzUaY/24D1gmhi8R7wBkxbn/HfJc9dHdLG/BuBwZsZMM09jZIowgGbCzQKo2BnXUP2Sr3CLTK3UCrNMrN5UcGakBkTveSBrxXwYCNSAM2YQ1obtiEMGATwIBNlQ1oMjQlDNhU2YCN7bxQAyLrdR9pwPsUDNjYgQGb2Y3f3NvgzQXaujnwIFqQbd1CoK0bA23dLDeX3ydTYAM2C3gQo12ebSb0PeBdwFohfJH8niHgTy1ihY4wL95vD+gD0l58wIEXW9owrbxt0zKCF1sJNFArYAc+SDbQgwIN9ADQQC1zc/mRgZ4iZE4PkV58SMGLLUkvtma9aG7YmvBia6Cm2ih70WRoQ3ixjbIXW9l5oV5E1uth0osPK3ixlQMvtrUbv523wdsJtHU74EG0J9u6vUBbtwLaum1uLr9PpsBebEt+KqDfM2RtFc2V9wNrijBH4v1inVi3v2N+xB7QR6W9+KgDL3awYTp626ZDBC92FGigjsDOeoxsoMcEGuhRoIE65ObyIwP1IjKnx0kvPq7gxQ6kFzuxXjQ37ER4sRNQvZ2VvWgydCa82FnZix3tvFAvIuv1BOnFJxS82NGBF7vYjd/V2+BdBdq6K/AgupFt3U2grTsCbd0lN5ffJ1NgL3YJeBCjXZ5tJvT94iPAWiF8kXy/CPhTi1ihI8yLT9oD+pS0F59y4MXuNkwPb9t0j+DFHgIN1APYgU+TDfS0QAM9BTRQ99xcfmSgpwiZU0/Siz0VvNid9GIv1ovmhr0IL/YCaqq3shdNht6EF3sre7GHnRfqRWS9niG9+IyCF3s48GIfu/H7ehu8r0Bb9wUeRD+yrfsJtHUPoK375Oby+2QK7MU+F+j9ImuraK58ElhThDkS7xeTYtz+jvlZe0Cfk/bicw682N+GGeBtm/4RvDhAoIEGADvrebKBnhdooOeABuqfm8uPDNSLyJxeIL34goIX+5NeHMh60dxwIOHFgUD1DlL2oskwiPDiIGUvDrDzQr2IrNeLpBdfVPDiAAdeHGw3/hBvgw8RaOshwIMYSrb1UIG2HgC09eDcXH6fTIG9ODjgQYx2ebaZ0PeLzwJrhfBF8nfMSmwKHWEGfMkeupelDfiyAwMOs2GGextkWAQDDhdoleHArnqFbJVXBFrlZaBVhuXm8iMDNSAyp1dJA76qYMBhpAFHsAY0NxxBGHAEYMCRygY0GUYSBhypbMDhdl6oAZH1eo004GsKBhzuwICj7MYf7W3w0QJtPRp4EGPIth4j0NbDgbYelZvL75MpsAFHkZ8Kgm82wvz3ErBOCF0k3gPOjHH7O+bX7aEbK23AsQ4MOM6GGe9tkHERDDheoFXGAzvrDbJV3hBolbFAq4zLzeVHBmpAZE5vkgZ8U8GA40gDTmANaG44gTDgBMCAE5UNaDJMJAw4UdmA4+28UAMi6/UWacC3FAw43oEBJ9mNP9nb4JMF2noy8CCmkG09RaCtxwNtPSk3l98nU2ADTgp4EKNdnm0m9D3g68BaIXyR/J4h4E8tYoWOMC++bQ/oVGkvTnXgxWk2zHRv20yL4MXpAg00HdiB75AN9I5AA00FGmhabi4/MtBThMxpBunFGQpenEZ6cSbrRXPDmYQXZwI1NUvZiybDLMKLs5S9ON3OC/Uisl7vkl58V8GL0x14cbbd+HO8DT5HoK3nAA9iLtnWcwXaejrQ1rNzc/l9MgX24mzyUwH9niFrq2iufBtYU4Q5Eu8X68a6/R3ze/aAzpP24jwHXpxvwyzwts38CF5cINBAC4Cd9T7ZQO8LNNA8oIHm5+byIwP1IjKnhaQXFyp4cT7pxUWsF80NFxFeXARU72JlL5oMiwkvLlb24gI7L9SLyHp9QHrxAwUvLnDgxSV24y/1NvhSgbZeCjyIZWRbLxNo6wVAWy/JzeX3yRTYi0sCHsRol2ebCX2/+B6wVghfJN8vAv7UIlboCPPih/aAfiTtxY8ceHG5DbPC2zbLI3hxhUADrQB24MdkA30s0EAfAQ20PDeXHxnoKULmtJL04koFLy4nvbiK9aK54SrCi6uAmlqt7EWTYTXhxdXKXlxh54V6EVmvT0gvfqLgxRUOvLjGbvy13gZfK9DWa4EHsY5s63UCbb0CaOs1ubn8PpkCe3HNBXq/yNoqmis/BNYUYY7E+8XkGLe/Y/7UHtDPpL34mQMvrrdhNnjbZn0EL24QaKANwM76nGygzwUa6DOggdbn5vIjA/UiMqeNpBc3KnhxPenFTawXzQ03EV7cBFTvZmUvmgybCS9uVvbiBjsv1IvIen1BevELBS9ucODFL+3G3+Jt8C0Cbb0FeBBbybbeKtDWG4C2/jI3l987JL34ZcCDGO3ybDOh7xc/BdYK4Yvk75iV2BQ6wgz4lT10X0sb8GsHBtxmw2z3Nsi2CAbcLtAq24Fd9Q3ZKt8ItMrXQKtsy83lRwZqQGRO35IG/FbBgNtIA+5gDWhuuIMw4A7AgDuVDWgy7CQMuFPZgNvtvFADIuv1HWnA7xQMuN2BAb+3G3+Xt8F3CbT1LuBB7CbberdAW28H2vr73Fx+n0yBDfg9+akg+GYjzH9fAeuE0EXiPeCsGLe/Y/7BHro90gbc48CAe22Yfd4G2RvBgPsEWmUfsLN+JFvlR4FW2QO0yt7cXH5koAZE5vQTacCfFAy4lzTgftaA5ob7CQPuBwx4QNmAJsMBwoAHlA24z84LNSCyXj+TBvxZwYD7HBjwF7vxD3ob/KBAWx8EHsQhsq0PCbT1PqCtf8nN5ffJFNiAvwQ8iNEuzzYT+h7wB2CtEL5Ifs8Q8KcWsUJHmBd/tQf0N2kv/ubAi4dtmCPetjkcwYtHBBroCLADfycb6HeBBvoNaKDDubn8yEBPETKno6QXjyp48TDpxWOsF80NjxFePAbU1HFlL5oMxwkvHlf24hE7L9SLyHr9QXrxDwUvHnHgxT/txj/hbfATAm19AngQJ8m2PinQ1keAtv4zN5ffJ1NgL/5Jfiqg3zNkbRXNlb8Ca4owR+L9Yr1Yt79j/sse0FPSXjzlwIunbZgz3rY5HcGLZwQa6Ayws/4mG+hvgQY6BTTQ6dxcfmSgXkTmdJb04lkFL54mvXiO9aK54TnCi+eA6j2v7EWT4TzhxfPKXjxj54V6EVmvf0gv/qPgxTMOvBiTaC9KjPlvQPMfBG1r83fk9NqLErm2vigxeFufAdo6JpHL75MpsBdjEoMdxGiXZ5sJfb/4F3AQEb5Ivl8E/KlFrNAR5sVc9oDGmX9Ktk1cokoY37aJt2ESvG1j/oXXiwkCDZQAnNbcZAPlFmiguMScN1B8IpcfGegpQuaUmMh5MTFR3ovxiZwXkxID3ND8YdSLSTl/kLHJwMNgM5h7oF5MDvgxlZPNnpyIexFZrxQgQ+jmTUmU92ICyYsY//v4Nniq3fhp3gZPE2jrNOBBpJNtnS7Q1glAW6cmcvl9MgX2Yir5qYC+X2RtFc2VuYA1RZgj8X4xJcbt75gz7AHNlPZipgMvZtkwebxtkxXBi3kEGigPsLMuJhvoYoEGygQaKCuRy48M1IvInC4hvXiJghezSC/mZb1obpiX8GJewIv5lL1oMuQjvJhP2Yt57LxQLyLrdSnpxUsVvJjHgRcvsxs/v7fB8wu0dX7gQRQg27qAQFvnAdr6skQuv0+mwF68LOBBjHZ5tpnQ94sZwFohfJH8HbMSm0JHmAEvt4fuCmkDXuHAgAVtmELeBikYwYCFBFqlELCrriRb5UqBVrkCaJWCiVx+ZKAGROZUmDRgYQUDFiQNWIQ1oLlhEcKARQADFlU2oMlQlDBgUWUDFrLzQg2IrNdVpAGvUjBgIQcGvNpu/GLeBi8m0NbFgAdRnGzr4gJtXQho66sTufw+mQIb8GryU0HwzUaY/y4H1gmhi8R7wHdj3P6O+Rp76EpIG7CEAwOWtGFKeRukZAQDlhJolVLAzrqWbJVrBVqlBNAqJRO5/MhADYjM6TrSgNcpGLAkacDSrAHNDUsTBiwNGLCMsgFNhjKEAcsoG7CUnRdqQGS9ricNeL2CAUs5MGBZu/HLeRu8nEBblwMeRHmyrcsLtHUpoK3LJnL5fTIFNmDZgAcx2uXZZkLfA14DrBXCF8nvGQL+1CJW6Ajz4g32gN4o7cUbHXixgg1T0ds2FSJ4saJAA1UEduBNZAPdJNBANwINVCGRy48M9BQhc7qZ9OLNCl6sQHqxEutFc8NKhBcrATVVWdmLJkNlwouVlb1Y0c4L9SKyXreQXrxFwYsVHXixit34Vb0NXlWgrasCD6Ia2dbVBNq6ItDWVRK5/D6ZAnuxCvmpgH7PkLVVNFfeAKwpwhyJ94t3xrr9HfOt9oBWl/ZidQderGHD1PS2TY0IXqwp0EA1gZ11G9lAtwk0UHWggWokcvmRgXoRmdPtpBdvV/BiDdKLtVgvmhvWIrxYC6je2speNBlqE16srezFmnZeqBeR9bqD9OIdCl6s6cCLdezGr+tt8LoCbV0XeBD1yLauJ9DWNYG2rpPI5ffJFNiLdQIexGiXZ5sJfb94K7BWCF8k3y8C/tQiVugI8+Kd9oDWl/ZifQdebGDDNPS2TYMIXmwo0EANgR14F9lAdwk0UH2ggRokcvmRgZ4iZE53k168W8GLDUgvNmK9aG7YiPBiI6CmGit70WRoTHixsbIXG9p5oV5E1use0ov3KHixoQMv3ms3fhNvgzcRaOsmwINoSrZ1U4G2bgi09b2JXH6fTIG9eO8Fer/I2iqaK+8E1hRhjsT7xdQYt79jvs8e0GbSXmzmwIvNbZgW3rZpHsGLLQQaqAWws+4nG+h+gQZqBjRQ80QuPzJQLyJzeoD04gMKXmxOerEl60Vzw5aEF1sC1dtK2YsmQyvCi62UvdjCzgv1IrJeD5JefFDBiy0cePEhu/Fbexu8tUBbtwYeRBuyrdsItHULoK0fSuTy+2QK7MWHAh7EaJdnmwl9v3gfsFYIXyR/x6zEptARZsCH7aFrK23Atg4M2M6Gae9tkHYRDNheoFXaA7vqEbJVHhFolbZAq7RL5PIjAzUgMqdHSQM+qmDAdqQBO7AGNDfsQBiwA2DAjsoGNBk6EgbsqGzA9nZeqAGR9XqMNOBjCgZs78CAj9uN38nb4J0E2roT8CA6k23dWaCt2wNt/Xgil98nU2ADPk5+Kgi+2Qjz38PAOiF0kXgPODvG7e+Yn7CHrou0Abs4MGBXG6abt0G6RjBgN4FW6QbsrCfJVnlSoFW6AK3SNZHLjwzUgMicniIN+JSCAbuSBuzOGtDcsDthwO6AAXsk6hrQZOhBGLCHsgG72XmhBkTW62nSgE8rGLCbAwP2tBu/l7fBewm0dS/gQfQm27q3QFt3A9q6ZyKX3ydTYAP2DHgQo12ebSb0PeATwFohfJH8niHgTy1ihY4wLz5jD2gfaS/2ceDFvjZMP2/b9I3gxX4CDdQP2IHPkg30rEAD9QEaqG8ilx8Z6ClC5vQc6cXnFLzYl/Rif9aL5ob9CS/2B2pqgLIXTYYBhBcHKHuxn50X6kVkvZ4nvfi8ghf7OfDiC3bjD/Q2+ECBth4IPIhBZFsPEmjrfkBbv5DI5ffJFNiLL5CfCuj3DFlbRXPlM8CaIsyReL9YP9bt75hftAd0sLQXBzvw4hAbZqi3bYZE8OJQgQYaCuysl8gGekmggQYDDTQkkcuPDNSLyJxeJr34soIXh5BeHMZ60dxwGOHFYUD1Dlf2oskwnPDicGUvDrXzQr2IrNcrpBdfUfDiUAdefNVu/BHeBh8h0NYjgAcxkmzrkQJtPRRo61cTufw+mQJ78dWABzHa5dlmQt8vvgisFcIXyfeLgD+1iBU6wrz4mj2go6S9OMqBF0fbMGO8bTM6ghfHCDTQGGAHvk420OsCDTQKaKDRiVx+ZKCnCJnTWNKLYxW8OJr04jjWi+aG4wgvjgNqaryyF02G8YQXxyt7cYydF+pFZL3eIL34hoIXxzjw4pt240/wNvgEgbaeADyIiWRbTxRo6zFAW7+ZyOX3yRTYi29eoPeLrK2iufI1YE0R5ki8X0yLcfs75rfsAZ0k7cVJDrw42YaZ4m2byRG8OEWggaYAO+ttsoHeFmigSUADTU7k8iMD9SIyp6mkF6cqeHEy6cVprBfNDacRXpwGVO90ZS+aDNMJL05X9uIUOy/Ui8h6vUN68R0FL05x4MUZduPP9Db4TIG2ngk8iFlkW88SaOspQFvPSOTy+2QK7MUZAQ9itMuzzYS+X3wLWCuEL5K/Y1ZiU+gIM+C79tDNljbgbAcGnGPDzPU2yJwIBpwr0CpzgV31Htkq7wm0ymygVeYkcvmRgRoQmdM80oDzFAw4hzTgfNaA5obzCQPOBwy4QNmAJsMCwoALlA04184LNSCyXu+TBnxfwYBzHRhwod34i7wNvkigrRcBD2Ix2daLBdp6LtDWCxO5/D6ZAhtwIfmpIPhmI8x/7wLrhNBF4j3gnBi3v2P+wB66JdIGXOLAgEttmGXeBlkawYDLBFplGbCzPiRb5UOBVlkCtMrSRC4/MlADInP6iDTgRwoGXEoacDlrQHPD5YQBlwMGXKFsQJNhBWHAFcoGXGbnhRoQWa+PSQN+rGDAZQ4MuNJu/FXeBl8l0NargAexmmzr1QJtvQxo65WJXH6fTIENuDLgQYx2ebaZ0PeAHwBrhfBF8nuGgD+1iBU6wrz4iT2ga6S9uMaBF9faMOu8bbM2ghfXCTTQOmAHfko20KcCDbQGaKC1iVx+ZKCnCJnTZ6QXP1Pw4lrSi+tZL5obrie8uB6oqQ3KXjQZNhBe3KDsxXV2XqgXkfX6nPTi5wpeXOfAixvtxt/kbfBNAm29CXgQm8m23izQ1uuAtt6YyOX3yRTYixvJTwX0e4asraK58hNgTRHmSLxfbBDr9nfMX9gD+qW0F7904MUtNsxWb9tsieDFrQINtBXYWV+RDfSVQAN9CTTQlkQuPzJQLyJz+pr04tcKXtxCenEb60Vzw22EF7cB1btd2Ysmw3bCi9uVvbjVzgv1IrJe35Be/EbBi1sdePFbu/F3eBt8h0Bb7wAexE6yrXcKtPVWoK2/TeTy+2QK7MVvAx7EaJdnmwl9v/gFsFYIXyTfLwL+1CJW6Ajz4nf2gH4v7cXvHXhxlw2z29s2uyJ4cbdAA+0GduAPZAP9INBA3wMNtCuRy48M9BQhc9pDenGPghd3kV7cy3rR3HAv4cW9QE3tU/aiybCP8OI+ZS/utvNCvYis14+kF39U8OJuB178yW78/d4G3y/Q1vuBB3GAbOsDAm29G2jrnxK5/D6ZAnvxpwv0fpG1VTRXfgesKcIcifeL6TFuf8f8sz2gv0h78RcHXjxowxzyts3BCF48JNBAh4Cd9SvZQL8KNNAvQAMdTOTyIwP1IjKn30gv/qbgxYOkFw+zXjQ3PEx48TBQvUeUvWgyHCG8eETZi4fsvFAvIuv1O+nF3xW8eMiBF4/ajX/M2+DHBNr6GPAgjpNtfVygrQ8BbX00kcvvkymwF48GPIjRLs82E/p+8WdgrRC+SP6OWYlNoSPMgH/YQ/entAH/dGDAEzbMSW+DnIhgwJMCrXIS2FV/ka3yl0Cr/Am0yolELj8yUAMiczpFGvCUggFPkAY8zRrQ3PA0YcDTgAHPKBvQZDhDGPCMsgFP2nmhBkTW62/SgH8rGPCkAwOetRv/nLfBzwm09TngQZwn2/q8QFufBNr6bCKX3ydTYAOeJT8VBN9shPnvD2CdELpIvAecG+P2d8z/ZH/aJMXINoj5C3N4bcRR+H/9vZ7xn8VPsv9ZUsx/G8T8C68BzUVBW+WipJxfmyuJa5VcScFbJSYp560Sm8TlRwZqQGROcUmcAeOS5A0Ym8QZMD4pwA3NH0YNGJ/zBxmbADwMNoO5B2rABHAzovO6yM4LNSCyXrmBDKGbN3eSvAEvyllhiRow0W78JG+DJwm0dRLwIJLJtk4WaOuLgLZOTOLy+2QKbMDEgAcx2uXZZkLfA/6D/B+vQAbJ7xkC/tQiVugI82KKPaCp0l5MdeDFNBsm3ds2aRG8mC7QQOnAac0gGyhDoIFSgQZKS+LyIwM9RcicMkkvZip4MY30YhbrRXPDLMKLWYAX8yh70WTIQ3gxj7IX0+28UC8i63Ux6cWLFbyY7sCLl9iNn9fb4HkF2jov8CDykW2dT6Ct04G2viSJy++TKbAXLyE/FdDvGbK2iubKFGBNEeZIvF9sGOv2d8yX2gN6mbQXL3Pgxfw2TAFv2+SP4MUCAg1UANhZl5MNdLlAA10GNFD+JC4/MlAvInO6gvTiFQpezE96sSDrRXPDgoQXCwJeLKTsRZOhEOHFQspeLGDnhXoRWa8rSS9eqeDFAg68WNhu/CLeBi8i0NZFgAdRlGzrogJtXQBo68JJXH6fTIG9WDjgQYx2ebaZ0PeLlwJrhfBF8v0i4E8tYoWOMC9eZQ/o1dJevNqBF4vZMMW9bVMsgheLCzRQcWAHXkM20DUCDXQ10EDFkrj8yEBPETKnEqQXSyh4sRjpxZKsF80NSxJeLAnUVCllL5oMpQgvllL2YnE7L9SLyHpdS3rxWgUvFnfgxevsxi/tbfDSAm1dGngQZci2LiPQ1sWBtr4uicvvkymwF6+7QO8XWVtFc+VVwJoizJF4v5gR4/Z3zNfbA1pW2otlHXixnA1T3ts25SJ4sbxAA5UHdtYNZAPdINBAZYEGKpfE5UcG6kVkTjeSXrxRwYvlSC9WYL1obliB8GIFoHorKnvRZKhIeLGishfL23mhXkTW6ybSizcpeLG8Ay/ebDd+JW+DVxJo60rAg6hMtnVlgbYuD7T1zUlcfp9Mgb14c8CDGO3ybDOh7xevB9YK4Yvk75iV2BQ6wgx4iz10VaQNWMWBAavaMNW8DVI1ggGrCbRKNWBX3Uq2yq0CrVIFaJWqSVx+ZKAGROZUnTRgdQUDViUNWIM1oLlhDcKANQAD1lQ2oMlQkzBgTWUDVrPzQg2IrNdtpAFvUzBgNQcGvN1u/FreBq8l0Na1gAdRm2zr2gJtXQ1o69uTuPw+mQIb8HbyU0HwzUaY/24B1gmhi8R7wPdi3P6O+Q576OpIG7COAwPWtWHqeRukbgQD1hNolXrAzrqTbJU7BVqlDtAqdZO4/MhADYjMqT5pwPoKBqxLGrABa0BzwwaEARsABmyobECToSFhwIbKBqxn54UaEFmvu0gD3qVgwHoODHi33fiNvA3eSKCtGwEPojHZ1o0F2roe0NZ3J3H5fTIFNuDdAQ9itMuzzYS+B7wDWCuEL5LfMwT8qUWs0BHmxXvsAb1X2ov3OvBiExumqbdtmkTwYlOBBmoK7MD7yAa6T6CB7gUaqEkSlx8Z6ClC5tSM9GIzBS82Ib3YnPWiuWFzwovNgZpqoexFk6EF4cUWyl5saueFehFZr/tJL96v4MWmDrz4gN34Lb0N3lKgrVsCD6IV2datBNq6KdDWDyRx+X0yBfbiA+SnAvo9Q9ZW0Vx5D7CmCHMk3i/eFev2d8wP2gP6kLQXH3LgxdY2TBtv27SO4MU2Ag3UBthZD5MN9LBAAz0ENFDrJC4/MlAvInNqS3qxrYIXW5NebMd60dywHeHFdkD1tlf2osnQnvBie2UvtrHzQr2IrNcjpBcfUfBiGwdefNRu/A7eBu8g0NYdgAfRkWzrjgJt3QZo60eTuPw+mQJ78dGABzHa5dlmQt8vPgisFcIXyfeLgD+1iBU6wrz4mD2gj0t78XEHXuxkw3T2tk2nCF7sLNBAnYEd+ATZQE8INNDjQAN1SuLyIwM9RcicupBe7KLgxU6kF7uyXjQ37Ep4sStQU92UvWgydCO82E3Zi53tvFAvIuv1JOnFJxW82NmBF5+yG7+7t8G7C7R1d+BB9CDbuodAW3cG2vqpJC6/T6bAXnzqAr1fZG0VzZWPAWuKMEfi/WJmjNvfMT9tD2hPaS/2dODFXjZMb2/b9Irgxd4CDdQb2FnPkA30jEAD9QQaqFcSlx8ZqBeROfUhvdhHwYu9SC/2Zb1obtiX8GJfoHr7KXvx38NKeLGfshd723mhXkTW61nSi88qeLG3Ay8+Zzd+f2+D9xdo6/7AgxhAtvUAgbbuDbT1c0lcfp9Mgb34XMCDGO3ybDOh7xefBtYK4Yvk75iV2BQ6wgz4vD10L0gb8AUHBhxowwzyNsjACAYcJNAqg4Bd9SLZKi8KtMoLQKsMTOLyIwM1IDKnwaQBBysYcCBpwCGsAc0NhxAGHAIYcKiyAU2GoYQBhyobcJCdF2pAZL1eIg34koIBBzkw4Mt24w/zNvgwgbYeBjyI4WRbDxdo60FAW7+cxOX3yRTYgC+TnwqCbzbC/Pc8sE4IXSTeA86Lcfs75lfsoXtV2oCvOjDgCBtmpLdBRkQw4EiBVhkJ7KzXyFZ5TaBVXgVaZUQSlx8ZqAGROY0iDThKwYAjSAOOZg1objiaMOBowIBjlA1oMowhDDhG2YAj7bxQAyLr9TppwNcVDDjSgQHH2o0/ztvg4wTaehzwIMaTbT1eoK1HAm09NonL75MpsAHHBjyI0S7PNhP6HvAVYK0Qvkh+zxDwpxaxQkeYF9+wB/RNaS++6cCLE2yYid62mRDBixMFGmgisAPfIhvoLYEGehNooAlJXH5koKcImdMk0ouTFLw4gfTiZNaL5oaTCS9OBmpqirIXTYYphBenKHtxop0X6kVkvd4mvfi2ghcnOvDiVLvxp3kbfJpAW08DHsR0sq2nC7T1RKCtpyZx+X0yBfbiVPJTAf2eIWuraK58A1hThDkS7xfvjnX7O+Z37AGdIe3FGQ68ONOGmeVtm5kRvDhLoIFmATvrXbKB3hVooBlAA81M4vIjA/UiMqfZpBdnK3hxJunFOawXzQ3nEF6cA1TvXGUvmgxzCS/OVfbiLDsv1IvIer1HevE9BS/OcuDFeXbjz/c2+HyBtp4PPIgFZFsvEGjrWUBbz0vi8vtkCuzFeQEPYrTLs82Evl98B1grhC+S7xcBf2oRK3SEefF9e0AXSntxoQMvLrJhFnvbZlEELy4WaKDFwA78gGygDwQaaCHQQIuSuPzIQE8RMqclpBeXKHhxEenFpawXzQ2XEl5cCtTUMmUvmgzLCC8uU/biYjsv1IvIen1IevFDBS8uduDFj+zGX+5t8OUCbb0ceBAryLZeIdDWi4G2/iiJy++TKbAXP7pA7xdZW0Vz5fvAmiLMkXi/mBXj9nfMH9sDulLaiysdeHGVDbPa2zarInhxtUADrQZ21idkA30i0EArgQZalcTlRwbqRWROa0gvrlHw4irSi2tZL5obriW8uBao3nXKXjQZ1hFeXKfsxdV2XqgXkfX6lPTipwpeXO3Ai5/Zjb/e2+DrBdp6PfAgNpBtvUGgrVcDbf1ZEpffJ1NgL34W8CBGuzzbTOj7xY+BtUL4Ivk7ZiU2hY4wA35uD91GaQNudGDATTbMZm+DbIpgwM0CrbIZ2FVfkK3yhUCrbARaZVMSlx8ZqAGROX1JGvBLBQNuIg24hTWgueEWwoBbAANuVTagybCVMOBWZQNutvNCDYis11ekAb9SMOBmBwb82m78bd4G3ybQ1tuAB7GdbOvtAm29GWjrr5O4/D6ZAhvwa/JTQfDNRpj/PgfWCaGLxHvA+TFuf8f8jT1030ob8FsHBtxhw+z0NsiOCAbcKdAqO4Gd9R3ZKt8JtMq3QKvsSOLyIwM1IDKn70kDfq9gwB2kAXexBjQ33EUYcBdgwN3KBjQZdhMG3K1swJ12XqgBkfX6gTTgDwoG3OnAgHvsxt/rbfC9Am29F3gQ+8i23ifQ1juBtt6TxOX3yRTYgHsCHsRol2ebCX0P+A2wVghfJL9nCPhTi1ihI8yLP9oD+pO0F39y4MX9NswBb9vsj+DFAwINdADYgT+TDfSzQAP9BDTQ/iQuPzLQU4TM6RfSi78oeHE/6cWDrBfNDQ8SXjwI1NQhZS+aDIcILx5S9uIBOy/Ui8h6/Up68VcFLx5w4MXf7MY/7G3wwwJtfRh4EEfItj4i0NYHgLb+LYnL75MpsBd/Iz8V0O8ZsraK5sofgTVFmCPxfrFRrNvfMf9uD+hRaS8edeDFYzbMcW/bHIvgxeMCDXQc2Fl/kA30h0ADHQUa6FgSlx8ZqBeROf1JevFPBS8eI714gvWiueEJwosngOo9qexFk+Ek4cWTyl48bueFehFZr79IL/6l4MXjDrx4ym78094GPy3Q1qeBB3GGbOszAm19HGjrU0lcfp9Mgb14KuBBjHZ5tpnQ94u/A2uF8EXy/SLgTy1ihY4wL/5tD+hZaS+edeDFczbMeW/bnIvgxfMCDXQe2IH/kA30j0ADnQUa6FwSlx8Z6ClC5hSTzHnR/DlpL54jvRibHOCG5g+jXoxNzvnDuChZ14smg7kH6sWLkrHNiM7rvJ0X6kVkvXIBGUI3r/lz0l4878CLcXbjxyfH/DdgfHLwto4HHkRCMtfWCcnB2/o80NZxyVx+n0yBvRgHHsTsgb5fZG0VzZV/A582ZwO6Ej2UeWLc/o45tz2gieafkm2TmKwSxrdtkmyYZG/bJCWHezFZoIGSgdOaQjZQikADJSbnvIGSkrn8yEC9iMwplfRiqoIXk5I5L6axXjQ3TCO8mAZ4MV3ZiyZDOuHFdGUvJtt5oV5E1iuD9GKGgheTSV7E+N/Ht8Ez7cbP8jZ4lkBbZwEPIg/Z1nkE2joZaOvMZC6/T6bAXswMeBCjXZ5tJvT9Ym5grRC+SP6OWYlNoSPMgBfbQ3eJtAEvcWDAvDZMPm+D5I1gwHwCrZIP2FWXkq1yqUCrXAK0St5kLj8yUAMic7qMNOBlCgbMSxowP2tAc8P8hAHzAwYsoGxAk6EAYcACygbMZ+eFGhBZr8tJA16uYMB8Dgx4hd34Bb0NXlCgrQsCD6IQ2daFBNo6H9DWVyRz+X0yBTbgFeSnguCbjTD/XQysE0IXifeAC2Lc/o75SnvoCksbsLADAxaxYYp6G6RIBAMWFWiVosDOuopslasEWqUw0CpFkrn8yEANiMzpatKAVysYsAhpwGKsAc0NixEGLAYYsLiyAU2G4oQBiysbsKidF2pAZL2uIQ14jYIBizowYAm78Ut6G7ykQFuXBB5EKbKtSwm0dVGgrUskc/l9MgU2YImABzHa5dlmQt8DXgmsFcIXye8ZAv7UIlboCPPitfaAXiftxesceLG0DVPG2zalI3ixjEADlQF24PVkA10v0EDXAQ1UOpnLjwz0FCFzKkt6sayCF0uTXizHetHcsBzhxXJATZVX9qLJUJ7wYnllL5ax80K9iKzXDaQXb1DwYhkHXrzRbvwK3gavINDWFYAHUZFs64oCbV0GaOsbk7n8PpkCe/FG8lMB/Z4ha6torrwWWFOEORLvFxvHuv0d8032gN4s7cWbHXixkg1T2ds2lSJ4sbJAA1UGdtYtZAPdItBANwMNVCmZy48M1IvInKqQXqyi4MVKpBersl40N6xKeLEqUL3VlL1oMlQjvFhN2YuV7bxQLyLrdSvpxVsVvFjZgRer241fw9vgNQTaugbwIGqSbV1ToK0rA21dPZnL75MpsBerBzyI0S7PNhP6fvEmYK0Qvki+XwT8qUWs0BHmxdvsAb1d2ou3O/BiLRumtrdtakXwYm2BBqoN7MA7yAa6Q6CBbgcaqFYylx8Z6ClC5lSH9GIdBS/WIr1Yl/WiuWFdwot1gZqqp+xFk6Ee4cV6yl6sbeeFehFZrztJL96p4MXaDrxY3278Bt4GbyDQ1g2AB9GQbOuGAm1dG2jr+slcfp9Mgb1Y/wK9X2RtFc2VtwFrijBH4v3ixTFuf8d8lz2gd0t78W4HXmxkwzT2tk2jCF5sLNBAjYGddQ/ZQPcINNDdQAM1SubyIwP1IjKne0kv3qvgxUakF5uwXjQ3bEJ4sQlQvU2VvWgyNCW82FTZi43tvFAvIut1H+nF+xS82NiBF5vZjd/c2+DNBdq6OfAgWpBt3UKgrRsDbd0smcvvkymwF5sFPIjRLs82E/p+8S5grRC+SP6OWYlNoSPMgPfbQ/eAtAEfcGDAljZMK2+DtIxgwFYCrdIK2FUPkq3yoECrPAC0SstkLj8yUAMic3qINOBDCgZsSRqwNWtAc8PWhAFbAwZso2xAk6ENYcA2ygZsZeeFGhBZr4dJAz6sYMBWDgzY1m78dt4GbyfQ1u2AB9GebOv2Am3dCmjrtslcfp9MgQ3YlvxUEHyzEea/+4F1Qugi8R7w/Ri3v2N+xB66R6UN+KgDA3awYTp6G6RDBAN2FGiVjsDOeoxslccEWuVRoFU6JHP5kYEaEJnT46QBH1cwYAfSgJ1YA5obdiIM2AkwYGdlA5oMnQkDdlY2YEc7L9SAyHo9QRrwCQUDdnRgwC5243f1NnhXgbbuCjyIbmRbdxNo645AW3dJ5vL7ZApswC4BD2K0y7PNhL4HfARYK4Qvkt8zBPypRazQEebFJ+0BfUrai0858GJ3G6aHt226R/BiD4EG6gHswKfJBnpaoIGeAhqoezKXHxnoKULm1JP0Yk8FL3YnvdiL9aK5YS/Ci72Amuqt7EWToTfhxd7KXuxh54V6EVmvZ0gvPqPgxR4OvNjHbvy+3gbvK9DWfYEH0Y9s634Cbd0DaOs+yVx+n0yBvdiH/FRAv2fI2iqaK58E1hRhjsT7xXti3f6O+Vl7QJ+T9uJzDrzY34YZ4G2b/hG8OECggQYAO+t5soGeF2ig54AG6p/M5UcG6kVkTi+QXnxBwYv9SS8OZL1objiQ8OJAoHoHKXvRZBhEeHGQshcH2HmhXkTW60XSiy8qeHGAAy8Otht/iLfBhwi09RDgQQwl23qoQFsPANp6cDKX3ydTYC8ODngQo12ebSb0/eKzwFohfJF8vwj4U4tYoSPMiy/ZA/qytBdfduDFYTbMcG/bDIvgxeECDTQc2IGvkA30ikADvQw00LBkLj8y0FOEzOlV0ouvKnhxGOnFEawXzQ1HEF4cAdTUSGUvmgwjCS+OVPbicDsv1IvIer1GevE1BS8Od+DFUXbjj/Y2+GiBth4NPIgxZFuPEWjr4UBbj0rm8vtkCuzFURfo/SJrq2iufAlYU4Q5Eu8XL4lx+zvm1+0BHSvtxbEOvDjOhhnvbZtxEbw4XqCBxgM76w2ygd4QaKCxQAONS+byIwP1IjKnN0kvvqngxXGkFyewXjQ3nEB4cQJQvROVvWgyTCS8OFHZi+PtvFAvIuv1FunFtxS8ON6BFyfZjT/Z2+CTBdp6MvAgppBtPUWgrccDbT0pmcvvkymwFycFPIjRLs82E/p+8XVgrRC+SP6OWYlNoSPMgG/bQzdV2oBTHRhwmg0z3dsg0yIYcLpAq0wHdtU7ZKu8I9AqU4FWmZbM5UcGakBkTjNIA85QMOA00oAzWQOaG84kDDgTMOAsZQOaDLMIA85SNuB0Oy/UgMh6vUsa8F0FA053YMDZduPP8Tb4HIG2ngM8iLlkW88VaOvpQFvPTuby+2QKbMDZ5KeC4JuNMP+9DawTQheJ94ALY9z+jvk9e+jmSRtwngMDzrdhFngbZH4EAy4QaJUFwM56n2yV9wVaZR7QKvOTufzIQA2IzGkhacCFCgacTxpwEWtAc8NFhAEXAQZcrGxAk2ExYcDFygZcYOeFGhBZrw9IA36gYMAFDgy4xG78pd4GXyrQ1kuBB7GMbOtlAm29AGjrJclcfp9MgQ24JOBBjHZ5tpnQ94DvAWuF8EXye4aAP7WIFTrCvPihPaAfSXvxIwdeXG7DrPC2zfIIXlwh0EArgB34MdlAHws00EdAAy1P5vIjAz1FyJxWkl5cqeDF5aQXV7FeNDdcRXhxFVBTq5W9aDKsJry4WtmLK+y8UC8i6/UJ6cVPFLy4woEX19iNv9bb4GsF2not8CDWkW29TqCtVwBtvSaZy++TKbAX15CfCuj3DFlbRXPlh8CaIsyReL94b6zb3zF/ag/oZ9Je/MyBF9fbMBu8bbM+ghc3CDTQBmBnfU420OcCDfQZ0EDrk7n8yEC9iMxpI+nFjQpeXE96cRPrRXPDTYQXNwHVu1nZiybDZsKLm5W9uMHOC/Uisl5fkF78QsGLGxx48Uu78bd4G3yLQFtvAR7EVrKttwq09Qagrb9M5vL7ZArsxS8DHsRol2ebCX2/+CmwVghfJN8vAv7UIlboCPPiV/aAfi3txa8deHGbDbPd2zbbInhxu0ADbQd24DdkA30j0EBfAw20LZnLjwz0FCFz+pb04rcKXtxGenEH60Vzwx2EF3cANbVT2Ysmw07CizuVvbjdzgv1IrJe35Fe/E7Bi9sdePF7u/F3eRt8l0Bb7wIexG6yrXcLtPV2oK2/T+by+2QK7MXvL9D7RdZW0Vz5FbCmCHMk3i/mjXH7O+Yf7AHdI+3FPQ68uNeG2edtm70RvLhPoIH2ATvrR7KBfhRooD1AA+1N5vIjA/UiMqefSC/+pODFvaQX97NeNDfcT3hxP1C9B5S9aDIcILx4QNmL++y8UC8i6/Uz6cWfFby4z4EXf7Eb/6C3wQ8KtPVB4EEcItv6kEBb7wPa+pdkLr9PpsBe/CXgQYx2ebaZ0PeLPwBrhfBF8nfMSmwKHWEG/NUeut+kDfibAwMetmGOeBvkcAQDHhFolSPArvqdbJXfBVrlN6BVDidz+ZGBGhCZ01HSgEcVDHiYNOAx1oDmhscIAx4DDHhc2YAmw3HCgMeVDXjEzgs1ILJef5AG/EPBgEccGPBPu/FPeBv8hEBbnwAexEmyrU8KtPURoK3/TOby+2QKbMA/yU8FwTcbYf77FVgnhC4S7wEXxbj9HfNf9tCdkjbgKQcGPG3DnPE2yOkIBjwj0CpngJ31N9kqfwu0yimgVU4nc/mRgRoQmdNZ0oBnFQx4mjTgOdaA5obnCAOeAwx4XtmAJsN5woDnlQ14xs4LNSCyXv+QBvxHwYBnHBgwJsVelBLz34DmPwja1ubvyOm1F6VwbX1RSvC2PgO0dUwKl98nU2ADxqQEO4jRLs82E/oe8C/gICJ8kfyeIeBPLWKFjjAv5rIHNM78U7Jt4lJUwvi2TbwNk+BtG/MvvF5MEGigBOC05iYbKLdAA8Wl5LyB4lO4/MhATxEyp8QUzouJKfJejE/hvJiUEuCG5g+jXkzK+YOMTQYeBpvB3AP1YnLAj6mcbPbkFNyLyHqlABlCN29KirwXE0hexPjfx7fBU+3GT/M2eJpAW6cBDyKdbOt0gbZOANo6NYXL75MpsBdTyU8F9HuGrK2iuTIXsKYIcyTeLzaJdfs75gx7QDOlvZjpwItZNkweb9tkRfBiHoEGygPsrIvJBrpYoIEygQbKSuHyIwP1IjKnS0gvXqLgxSzSi3lZL5ob5iW8mBfwYj5lL5oM+Qgv5lP2Yh47L9SLyHpdSnrxUgUv5nHgxcvsxs/vbfD8Am2dH3gQBci2LiDQ1nmAtr4shcvvkymwFy8LeBCjXZ5tJvT9YgawVghfJN8vAv7UIlboCPPi5faAXiHtxSsceLGgDVPI2zYFI3ixkEADFQJ24JVkA10p0EBXAA1UMIXLjwz0FCFzKkx6sbCCFwuSXizCetHcsAjhxSJATRVV9qLJUJTwYlFlLxay80K9iKzXVaQXr1LwYiEHXrzabvxi3gYvJtDWxYAHUZxs6+ICbV0IaOurU7j8PpkCe/HqC/R+kbVVNFdeDqwpwhyJ94v5Ytz+jvkae0BLSHuxhAMvlrRhSnnbpmQEL5YSaKBSwM66lmygawUaqATQQCVTuPzIQL2IzOk60ovXKXixJOnF0qwXzQ1LE14sDVRvGWUvmgxlCC+WUfZiKTsv1IvIel1PevF6BS+WcuDFsnbjl/M2eDmBti4HPIjyZFuXF2jrUkBbl03h8vtkCuzFsgEPYrTLs82Evl+8BlgrhC+Sv2NWYlPoCDPgDfbQ3ShtwBsdGLCCDVPR2yAVIhiwokCrVAR21U1kq9wk0Co3Aq1SIYXLjwzUgMicbiYNeLOCASuQBqzEGtDcsBJhwEqAASsrG9BkqEwYsLKyASvaeaEGRNbrFtKAtygYsKIDA1axG7+qt8GrCrR1VeBBVCPbuppAW1cE2rpKCpffJ1NgA1YhPxUE32yE+e8GYJ0Quki8B1wc4/Z3zLfaQ1dd2oDVHRiwhg1T09sgNSIYsKZAq9QEdtZtZKvcJtAq1YFWqZHC5UcGakBkTreTBrxdwYA1SAPWYg1obliLMGAtwIC1lQ1oMtQmDFhb2YA17bxQAyLrdQdpwDsUDFjTgQHr2I1f19vgdQXaui7wIOqRbV1PoK1rAm1dJ4XL75MpsAHrBDyI0S7PNhP6HvBWYK0Qvkh+zxDwpxaxQkeYF++0B7S+tBfrO/BiAxumobdtGkTwYkOBBmoI7MC7yAa6S6CB6gMN1CCFy48M9BQhc7qb9OLdCl5sQHqxEetFc8NGhBcbATXVWNmLJkNjwouNlb3Y0M4L9SKyXveQXrxHwYsNHXjxXrvxm3gbvIlAWzcBHkRTsq2bCrR1Q6Ct703h8vtkCuzFe8lPBfR7hqytornyTmBNEeZIvF9sGuv2d8z32QPaTNqLzRx4sbkN08LbNs0jeLGFQAO1AHbW/WQD3S/QQM2ABmqewuVHBupFZE4PkF58QMGLzUkvtmS9aG7YkvBiS6B6Wyl70WRoRXixlbIXW9h5oV5E1utB0osPKnixhQMvPmQ3fmtvg7cWaOvWwINoQ7Z1G4G2bgG09UMpXH6fTIG9+FDAgxjt8mwzoe8X7wPWCuGL5PtFwJ9axAodYV582B7QttJebOvAi+1smPbetmkXwYvtBRqoPbADHyEb6BGBBmoLNFC7FC4/MtBThMzpUdKLjyp4sR3pxQ6sF80NOxBe7ADUVEdlL5oMHQkvdlT2Yns7L9SLyHo9RnrxMQUvtnfgxcftxu/kbfBOAm3dCXgQncm27izQ1u2Btn48hcvvkymwFx+/QO8XWVtFc+XDwJoizJF4v3hpjNvfMT9hD2gXaS92ceDFrjZMN2/bdI3gxW4CDdQN2FlPkg30pEADdQEaqGsKlx8ZqBeROT1FevEpBS92Jb3YnfWiuWF3wovdgertoexFk6EH4cUeyl7sZueFehFZr6dJLz6t4MVuDrzY0278Xt4G7yXQ1r2AB9GbbOveAm3dDWjrnilcfp9Mgb3YM+BBjHZ5tpnQ94tPAGuF8EXyd8xKbAodYQZ8xh66PtIG7OPAgH1tmH7eBukbwYD9BFqlH7CrniVb5VmBVukDtErfFC4/MlADInN6jjTgcwoG7EsasD9rQHPD/oQB+wMGHKBsQJNhAGHAAcoG7GfnhRoQWa/nSQM+r2DAfg4M+ILd+AO9DT5QoK0HAg9iENnWgwTauh/Q1i+kcPl9MgU24Avkp4Lgm40w/z0DrBNCF4n3gB/EuP0d84v20A2WNuBgBwYcYsMM9TbIkAgGHCrQKkOBnfUS2SovCbTKYKBVhqRw+ZGBGhCZ08ukAV9WMOAQ0oDDWAOaGw4jDDgMMOBwZQOaDMMJAw5XNuBQOy/UgMh6vUIa8BUFAw51YMBX7cYf4W3wEQJtPQJ4ECPJth4p0NZDgbZ+NYXL75MpsAFfDXgQo12ebSb0PeCLwFohfJH8niHgTy1ihY4wL75mD+goaS+OcuDF0TbMGG/bjI7gxTECDTQG2IGvkw30ukADjQIaaHQKlx8Z6ClC5jSW9OJYBS+OJr04jvWiueE4wovjgJoar+xFk2E84cXxyl4cY+eFehFZrzdIL76h4MUxDrz4pt34E7wNPkGgrScAD2Ii2dYTBdp6DNDWb6Zw+X0yBfbim+SnAvo9Q9ZW0Vz5GrCmCHMk3i/eF+v2d8xv2QM6SdqLkxx4cbINM8XbNpMjeHGKQANNAXbW22QDvS3QQJOABpqcwuVHBupFZE5TSS9OVfDiZNKL01gvmhtOI7w4Daje6cpeNBmmE16cruzFKXZeqBeR9XqH9OI7Cl6c4sCLM+zGn+lt8JkCbT0TeBCzyLaeJdDWU4C2npHC5ffJFNiLMwIexGiXZ5sJfb/4FrBWCF8k3y8C/tQiVugI8+K79oDOlvbibAdenGPDzPW2zZwIXpwr0EBzgR34HtlA7wk00GyggeakcPmRgZ4iZE7zSC/OU/DiHNKL81kvmhvOJ7w4H6ipBcpeNBkWEF5coOzFuXZeqBeR9Xqf9OL7Cl6c68CLC+3GX+Rt8EUCbb0IeBCLybZeLNDWc4G2XpjC5ffJFNiLCy/Q+0XWVtFc+S6wpghzJN4vXhbj9nfMH9gDukTai0sceHGpDbPM2zZLI3hxmUADLQN21odkA30o0EBLgAZamsLlRwbqRWROH5Fe/EjBi0tJLy5nvWhuuJzw4nKgelcoe9FkWEF4cYWyF5fZeaFeRNbrY9KLHyt4cZkDL660G3+Vt8FXCbT1KuBBrCbberVAWy8D2nplCpffJ1NgL64MeBCjXZ5tJvT94gfAWiF8kfwdsxKbQkeYAT+xh26NtAHXODDgWhtmnbdB1kYw4DqBVlkH7KpPyVb5VKBV1gCtsjaFy48M1IDInD4jDfiZggHXkgZczxrQ3HA9YcD1gAE3KBvQZNhAGHCDsgHX2XmhBkTW63PSgJ8rGHCdAwNutBt/k7fBNwm09SbgQWwm23qzQFuvA9p6YwqX3ydTYANuJD8VBN9shPnvE2CdELpIvAdcEuP2d8xf2EP3pbQBv3RgwC02zFZvg2yJYMCtAq2yFdhZX5Gt8pVAq3wJtMqWFC4/MlADInP6mjTg1woG3EIacBtrQHPDbYQBtwEG3K5sQJNhO2HA7coG3GrnhRoQWa9vSAN+o2DArQ4M+K3d+Du8Db5DoK13AA9iJ9nWOwXaeivQ1t+mcPl9MgU24LcBD2K0y7PNhL4H/AJYK4Qvkt8zBPypRazQEebF7+wB/V7ai9878OIuG2a3t212RfDiboEG2g3swB/IBvpBoIG+BxpoVwqXHxnoKULmtIf04h4FL+4ivbiX9aK54V7Ci3uBmtqn7EWTYR/hxX3KXtxt54V6EVmvH0kv/qjgxd0OvPiT3fj7vQ2+X6Ct9wMP4gDZ1gcE2no30NY/pXD5fTIF9uJP5KcC+j1D1lbRXPkdsKYIcyTeLzaLdfs75p/tAf1F2ou/OPDiQRvmkLdtDkbw4iGBBjoE7KxfyQb6VaCBfgEa6GAKlx8ZqBeROf1GevE3BS8eJL14mPWiueFhwouHgeo9ouxFk+EI4cUjyl48ZOeFehFZr99JL/6u4MVDDrx41G78Y94GPybQ1seAB3GcbOvjAm19CGjroylcfp9Mgb14NOBBjHZ5tpnQ94s/A2uF8EXy/SLgTy1ihY4wL/5hD+if0l7804EXT9gwJ71tcyKCF08KNNBJYAf+RTbQXwIN9CfQQCdSuPzIQE8RMqdTpBdPKXjxBOnF06wXzQ1PE148DdTUGWUvmgxnCC+eUfbiSTsv1IvIev1NevFvBS+edODFs3bjn/M2+DmBtj4HPIjzZFufF2jrk0Bbn03h8vtkCuzFsxfo/SJrq2iu/ANYU4Q5Eu8X88e4/R3zP9mfTKkxsm1j/sIcXhtxFP5ff69n/GfxU+1/lhrz37Yx/8LrRXNR0Aa6KDXn1+ZK5RooV2rwBopJzXkDxaZy+ZGBehGZU1wq58W4VHkvxqZyXoxPDXBD84dRL8bn/EHGJgAPg81g7oF6MQHcjOi8LrLzQr2IrFduIEPo5s2dKu/Fi3JWWKJeTLQbP8nb4EkCbZ0EPIhksq2TBdr6IqCtE1O5/D6ZAnsxMeBBjHZ5tpnQ94v/IP+HLpBB8nfMSmwKHWEGTLGHLlXagKkODJhmw6R7GyQtggHTBVolHTiBGWSrZAi0SirQKmmpXH5koAZE5pRJGjBTwYBppAGzWAOaG2YRBswCDJhH2YAmQx7CgHmUDZhu54UaEFmvi0kDXqxgwHQHBrzEbvy83gbPK9DWeYEHkY9s63wCbZ0OtPUlqVx+n0yBDXgJ+akg+GYjzH8pwDohdJF4D7g0xu3vmC+1h+4yaQNe5sCA+W2YAt4GyR/BgAUEWqUAsLMuJ1vlcoFWuQxolfypXH5koAZE5nQFacArFAyYnzRgQdaA5oYFCQMWBAxYSNmAJkMhwoCFlA1YwM4LNSCyXleSBrxSwYAFHBiwsN34RbwNXkSgrYsAD6Io2dZFBdq6ANDWhVO5/D6ZAhuwcMCDGO3ybDOh7wEvBdYK4Yvk9wwBf2oRK3SEefEqe0Cvlvbi1Q68WMyGKe5tm2IRvFhcoIGKAzvwGrKBrhFooKuBBiqWyuVHBnqKkDmVIL1YQsGLxUgvlmS9aG5YkvBiSaCmSil70WQoRXixlLIXi9t5oV5E1uta0ovXKnixuAMvXmc3fmlvg5cWaOvSwIMoQ7Z1GYG2Lg609XWpXH6fTIG9eB35qYB+z5C1VTRXXgWsKcIcifeLzWPd/o75entAy0p7sawDL5azYcp726ZcBC+WF2ig8sDOuoFsoBsEGqgs0EDlUrn8yEC9iMzpRtKLNyp4sRzpxQqsF80NKxBerABUb0VlL5oMFQkvVlT2Ynk7L9SLyHrdRHrxJgUvlnfgxZvtxq/kbfBKAm1dCXgQlcm2rizQ1uWBtr45lcvvkymwF28OeBCjXZ5tJvT94vXAWiF8kXy/CPhTi1ihI8yLt9gDWkXai1UceLGqDVPN2zZVI3ixmkADVQN24K1kA90q0EBVgAaqmsrlRwZ6ipA5VSe9WF3Bi1VJL9ZgvWhuWIPwYg2gpmoqe9FkqEl4saayF6vZeaFeRNbrNtKLtyl4sZoDL95uN34tb4PXEmjrWsCDqE22dW2Btq4GtPXtqVx+n0yBvXj7BXq/yNoqmitvAdYUYY7E+8UCMW5/x3yHPaB1pL1Yx4EX69ow9bxtUzeCF+sJNFA9YGfdSTbQnQINVAdooLqpXH5koF5E5lSf9GJ9BS/WJb3YgPWiuWEDwosNgOptqOxFk6Eh4cWGyl6sZ+eFehFZr7tIL96l4MV6Drx4t934jbwN3kigrRsBD6Ix2daNBdq6HtDWd6dy+X0yBfbi3QEPYrTLs82Evl+8A1grhC+Sv2NWYlPoCDPgPfbQ3SttwHsdGLCJDdPU2yBNIhiwqUCrNAV21X1kq9wn0Cr3Aq3SJJXLjwzUgMicmpEGbKZgwCakAZuzBjQ3bE4YsDlgwBbKBjQZWhAGbKFswKZ2XqgBkfW6nzTg/QoGbOrAgA/Yjd/S2+AtBdq6JfAgWpFt3UqgrZsCbf1AKpffJ1NgAz5AfioIvtkI8989wDohdJF4D7gsxu3vmB+0h+4haQM+5MCArW2YNt4GaR3BgG0EWqUNsLMeJlvlYYFWeQholdapXH5koAZE5tSWNGBbBQO2Jg3YjjWguWE7woDtAAO2VzagydCeMGB7ZQO2sfNCDYis1yOkAR9RMGAbBwZ81G78Dt4G7yDQ1h2AB9GRbOuOAm3dBmjrR1O5/D6ZAhvw0YAHMdrl2WZC3wM+CKwVwhfJ7xkC/tQiVugI8+Jj9oA+Lu3Fxx14sZMN09nbNp0ieLGzQAN1BnbgE2QDPSHQQI8DDdQplcuPDPQUIXPqQnqxi4IXO5Fe7Mp60dywK+HFrkBNdVP2osnQjfBiN2UvdrbzQr2IrNeTpBefVPBiZwdefMpu/O7eBu8u0NbdgQfRg2zrHgJt3Rlo66dSufw+mQJ78SnyUwH9niFrq2iufAxYU4Q5Eu8XW8S6/R3z0/aA9pT2Yk8HXuxlw/T2tk2vCF7sLdBAvYGd9QzZQM8INFBPoIF6pXL5kYF6EZlTH9KLfRS82Iv0Yl/Wi+aGfQkv9gWqt5+yF/89rIQX+yl7sbedF+pFZL2eJb34rIIXezvw4nN24/f3Nnh/gbbuDzyIAWRbDxBo695AWz+XyuX3yRTYi88FPIjRLs82E/p+8WlgrRC+SL5fBPypRazQEebF5+0BfUHaiy848OJAG2aQt20GRvDiIIEGGgTswBfJBnpRoIFeABpoYCqXHxnoKULmNJj04mAFLw4kvTiE9aK54RDCi0OAmhqq7EWTYSjhxaHKXhxk54V6EVmvl0gvvqTgxUEOvPiy3fjDvA0+TKCthwEPYjjZ1sMF2noQ0NYvp3L5fTIF9uLLF+j9ImuraK58HlhThDkS7xcvj3H7O+ZX7AF9VdqLrzrw4ggbZqS3bUZE8OJIgQYaCeys18gGek2ggV4FGmhEKpcfGagXkTmNIr04SsGLI0gvjma9aG44mvDiaKB6xyh70WQYQ3hxjLIXR9p5oV5E1ut10ouvK3hxpAMvjrUbf5y3wccJtPU44EGMJ9t6vEBbjwTaemwql98nU2Avjg14EKNdnm0m9P3iK8BaIXyR/B2zEptCR5gB37CH7k1pA77pwIATbJiJ3gaZEMGAEwVaZSKwq94iW+UtgVZ5E2iVCalcfmSgBkTmNIk04CQFA04gDTiZNaC54WTCgJMBA05RNqDJMIUw4BRlA06080INiKzX26QB31Yw4EQHBpxqN/40b4NPE2jracCDmE629XSBtp4ItPXUVC6/T6bABpxKfioIvtkI898bwDohdJF4D/hhjNvfMb9jD90MaQPOcGDAmTbMLG+DzIxgwFkCrTIL2Fnvkq3yrkCrzABaZWYqlx8ZqAGROc0mDThbwYAzSQPOYQ1objiHMOAcwIBzlQ1oMswlDDhX2YCz7LxQAyLr9R5pwPcUDDjLgQHn2Y0/39vg8wXaej7wIBaQbb1AoK1nAW09L5XL75MpsAHnBTyI0S7PNhP6HvAdYK0Qvkh+zxDwpxaxQkeYF9+3B3ShtBcXOvDiIhtmsbdtFkXw4mKBBloM7MAPyAb6QKCBFgINtCiVy48M9BQhc1pCenGJghcXkV5cynrR3HAp4cWlQE0tU/aiybCM8OIyZS8utvNCvYis14ekFz9U8OJiB178yG785d4GXy7Q1suBB7GCbOsVAm29GGjrj1K5/D6ZAnvxI/JTAf2eIWuraK58H1hThDkS7xfvj3X7O+aP7QFdKe3FlQ68uMqGWe1tm1URvLhaoIFWAzvrE7KBPhFooJVAA61K5fIjA/UiMqc1pBfXKHhxFenFtawXzQ3XEl5cC1TvOmUvmgzrCC+uU/biajsv1IvIen1KevFTBS+uduDFz+zGX+9t8PUCbb0eeBAbyLbeINDWq4G2/iyVy++TKbAXPwt4EKNdnm0m9P3ix8BaIXyRfL8I+FOLWKEjzIuf2wO6UdqLGx14cZMNs9nbNpsieHGzQANtBnbgF2QDfSHQQBuBBtqUyuVHBnqKkDl9SXrxSwUvbiK9uIX1ornhFsKLW4Ca2qrsRZNhK+HFrcpe3GznhXoRWa+vSC9+peDFzQ68+LXd+Nu8Db5NoK23AQ9iO9nW2wXaejPQ1l+ncvl9MgX24tcX6P0ia6torvwcWFOEORLvF6+Icfs75m/sAf1W2ovfOvDiDhtmp7dtdkTw4k6BBtoJ7KzvyAb6TqCBvgUaaEcqlx8ZqBeROX1PevF7BS/uIL24i/WiueEuwou7gOrdrexFk2E34cXdyl7caeeFehFZrx9IL/6g4MWdDry4x278vd4G3yvQ1nuBB7GPbOt9Am29E2jrPalcfp9Mgb24J+BBjHZ5tpnQ94vfAGuF8EXyd8xKbAodYQb80R66n6QN+JMDA+63YQ54G2R/BAMeEGiVA8Cu+plslZ8FWuUnoFX2p3L5kYEaEJnTL6QBf1Ew4H7SgAdZA5obHiQMeBAw4CFlA5oMhwgDHlI24AE7L9SAyHr9ShrwVwUDHnBgwN/sxj/sbfDDAm19GHgQR8i2PiLQ1geAtv4tlcvvkymwAX8jPxUE32yE+e9HYJ0Quki8B/woxu3vmH+3h+6otAGPOjDgMRvmuLdBjkUw4HGBVjkO7Kw/yFb5Q6BVjgKtciyVy48M1IDInP4kDfinggGPkQY8wRrQ3PAEYcATgAFPKhvQZDhJGPCksgGP23mhBkTW6y/SgH8pGPC4AwOeshv/tLfBTwu09WngQZwh2/qMQFsfB9r6VCqX3ydTYAOeCngQo12ebSb0PeDvwFohfJH8niHgTy1ihY4wL/5tD+hZaS+edeDFczbMeW/bnIvgxfMCDXQe2IH/kA30j0ADnQUa6Fwqlx8Z6ClC5hSTxnnR/DlpL54jvRibFuCG5g+jXoxNy/nDuChN14smg7kH6sWL0rDNiM7rvJ0X6kVkvXIBGUI3r/lz0l4878CLcXbjx6fF/DdgfFrwto4HHkRCGtfWCWnB2/o80NZxaVx+n0yBvRgHHsTsgX7PkLVVNFf+DXzanA3oSvRQPhDr9nfMue0BTTT/lGybxDSVML5tk2TDJHvbJikt3IvJAg2UDJzWFLKBUgQaKDEt5w2UlMblRwbqRWROqaQXUxW8mJTGeTGN9aK5YRrhxTTAi+nKXjQZ0gkvpit7MdnOC/Uisl4ZpBczFLyYTPIixv8+vg2eaTd+lrfBswTaOgt4EHnIts4j0NbJQFtnpnH5fTIF9mJmwIMY7fJsM6HvF3MDa4XwRfL9IuBPLWKFjjAvXmwP6CXSXrzEgRfz2jD5vG2TN4IX8wk0UD5gB15KNtClAg10CdBAedO4/MhATxEyp8tIL16m4MW8pBfzs140N8xPeDE/4MUCyl40GQoQXiyg7MV8dl6oF5H1upz04uUKXsznwItX2I1f0NvgBQXauiDwIAqRbV1IoK3zAW19RRqX3ydTYC9ecYHeL7K2iubKi4E1RZgj8X6xYIzb3zFfaQ9oYWkvFnbgxSI2TFFv2xSJ4MWiAg1UFNhZV5ENdJVAAxUGGqhIGpcfGagXkTldTXrxagUvFiG9WIz1orlhMcKLxQAvFlf2oslQnPBicWUvFrXzQr2IrNc1pBevUfBiUQdeLGE3fklvg5cUaOuSwIMoRbZ1KYG2Lgq0dYk0Lr9PpsBeLBHwIEa7PNtM6PvFK4G1Qvgi+TtmJTaFjjADXmsP3XXSBrzOgQFL2zBlvA1SOoIBywi0ShlgV11Ptsr1Aq1yHdAqpdO4/MhADYjMqSxpwLIKBixNGrAca0Bzw3KEAcsBBiyvbECToTxhwPLKBixj54UaEFmvG0gD3qBgwDIODHij3fgVvA1eQaCtKwAPoiLZ1hUF2roM0NY3pnH5fTIFNuCN5KeC4JuNMP9dC6wTQheJ94DLY9z+jvkme+huljbgzQ4MWMmGqextkEoRDFhZoFUqAzvrFrJVbhFolZuBVqmUxuVHBmpAZE5VSANWUTBgJdKAVVkDmhtWJQxYFTBgNWUDmgzVCANWUzZgZTsv1IDIet1KGvBWBQNWdmDA6nbj1/A2eA2Btq4BPIiaZFvXFGjrykBbV0/j8vtkCmzA6gEPYrTLs82Evge8CVgrhC+S3zME/KlFrNAR5sXb7AG9XdqLtzvwYi0bpra3bWpF8GJtgQaqDezAO8gGukOggW4HGqhWGpcfGegpQuZUh/RiHQUv1iK9WJf1orlhXcKLdYGaqqfsRZOhHuHFesperG3nhXoRWa87SS/eqeDF2g68WN9u/AbeBm8g0NYNgAfRkGzrhgJtXRto6/ppXH6fTIG9WJ/8VEC/Z8jaKporbwPWFGGOxPtF8zHh8nfMd9kDere0F+924MVGNkxjb9s0iuDFxgIN1BjYWfeQDXSPQAPdDTRQozQuPzJQLyJzupf04r0KXmxEerEJ60VzwyaEF5sA1dtU2YsmQ1PCi02VvdjYzgv1IrJe95FevE/Bi40deLGZ3fjNvQ3eXKCtmwMPogXZ1i0E2rox0NbN0rj8PpkCe7FZwIMY7fJsM6HvF+8C1grhi+T7RcCfWsQKHWFevN8e0AekvfiAAy+2tGFaedumZQQvthJooFbADnyQbKAHBRroAaCBWqZx+ZGBniJkTg+RXnxIwYstSS+2Zr1obtia8GJroKbaKHvRZGhDeLGNshdb2XmhXkTW62HSiw8reLGVAy+2tRu/nbfB2wm0dTvgQbQn27q9QFu3Atq6bRqX3ydTYC+2vUDvF1lbRXPl/cCaIsyReL9YKMbt75gfsQf0UWkvPurAix1smI7etukQwYsdBRqoI7CzHiMb6DGBBnoUaKAOaVx+ZKBeROb0OOnFxxW82IH0YifWi+aGnQgvdgKqt7OyF02GzoQXOyt7saOdF+pFZL2eIL34hIIXOzrwYhe78bt6G7yrQFt3BR5EN7Ktuwm0dUegrbukcfl9MgX2YpeABzHa5dlmQt8vPgKsFcIXyd8xK7EpdIQZ8El76J6SNuBTDgzY3Ybp4W2Q7hEM2EOgVXoAu+ppslWeFmiVp4BW6Z7G5UcGakBkTj1JA/ZUMGB30oC9WAOaG/YiDNgLMGBvZQOaDL0JA/ZWNmAPOy/UgMh6PUMa8BkFA/ZwYMA+duP39TZ4X4G27gs8iH5kW/cTaOseQFv3SePy+2QKbMA+5KeC4JuNMP89CawTQheJ94ArYtz+jvlZe+iekzbgcw4M2N+GGeBtkP4RDDhAoFUGADvrebJVnhdoleeAVumfxuVHBmpAZE4vkAZ8QcGA/UkDDmQNaG44kDDgQMCAg5QNaDIMIgw4SNmAA+y8UAMi6/UiacAXFQw4wIEBB9uNP8Tb4EME2noI8CCGkm09VKCtBwBtPTiNy++TKbABBwc8iNEuzzYT+h7wWWCtEL5Ifs8Q8KcWsUJHmBdfsgf0ZWkvvuzAi8NsmOHethkWwYvDBRpoOLADXyEb6BWBBnoZaKBhaVx+ZKCnCJnTq6QXX1Xw4jDSiyNYL5objiC8OAKoqZHKXjQZRhJeHKnsxeF2XqgXkfV6jfTiawpeHO7Ai6Psxh/tbfDRAm09GngQY8i2HiPQ1sOBth6VxuX3yRTYi6PITwX0e4asraK58iVgTRHmSLxfbBXr9nfMr9sDOlbai2MdeHGcDTPe2zbjInhxvEADjQd21htkA70h0EBjgQYal8blRwbqRWROb5JefFPBi+NIL05gvWhuOIHw4gSgeicqe9FkmEh4caKyF8fbeaFeRNbrLdKLbyl4cbwDL06yG3+yt8EnC7T1ZOBBTCHbeopAW48H2npSGpffJ1NgL04KeBCjXZ5tJvT94uvAWiF8kXy/CPhTi1ihI8yLb9sDOlXai1MdeHGaDTPd2zbTInhxukADTQd24DtkA70j0EBTgQaalsblRwZ6ipA5zSC9OEPBi9NIL85kvWhuOJPw4kygpmYpe9FkmEV4cZayF6fbeaFeRNbrXdKL7yp4cboDL862G3+Ot8HnCLT1HOBBzCXbeq5AW08H2np2GpffJ1NgL86+QO8XWVtFc+XbwJoizJF4v3hljNvfMb9nD+g8aS/Oc+DF+TbMAm/bzI/gxQUCDbQA2Fnvkw30vkADzQMaaH4alx8ZqBeROS0kvbhQwYvzSS8uYr1obriI8OIioHoXK3vRZFhMeHGxshcX2HmhXkTW6wPSix8oeHGBAy8usRt/qbfBlwq09VLgQSwj23qZQFsvANp6SRqX3ydTYC8uCXgQo12ebSb0/eJ7wFohfJH8HbMSm0JHmAE/tIfuI2kDfuTAgMttmBXeBlkewYArBFplBbCrPiZb5WOBVvkIaJXlaVx+ZKAGROa0kjTgSgUDLicNuIo1oLnhKsKAqwADrlY2oMmwmjDgamUDrrDzQg2IrNcnpAE/UTDgCgcGXGM3/lpvg68VaOu1wINYR7b1OoG2XgG09Zo0Lr9PpsAGXEN+Kgi+2Qjz34fAOiF0kXgP+HGM298xf2oP3WfSBvzMgQHX2zAbvA2yPoIBNwi0ygZgZ31OtsrnAq3yGdAq69O4/MhADYjMaSNpwI0KBlxPGnATa0Bzw02EATcBBtysbECTYTNhwM3KBtxg54UaEFmvL0gDfqFgwA0ODPil3fhbvA2+RaCttwAPYivZ1lsF2noD0NZfpnH5fTIFNuCXAQ9itMuzzYS+B/wUWCuEL5LfMwT8qUWs0BHmxa/sAf1a2otfO/DiNhtmu7dttkXw4naBBtoO7MBvyAb6RqCBvgYaaFsalx8Z6ClC5vQt6cVvFby4jfTiDtaL5oY7CC/uAGpqp7IXTYadhBd3Kntxu50X6kVkvb4jvfidghe3O/Di93bj7/I2+C6Btt4FPIjdZFvvFmjr7UBbf5/G5ffJFNiL35OfCuj3DFlbRXPlV8CaIsyReL/4YKzb3zH/YA/oHmkv7nHgxb02zD5v2+yN4MV9Ag20D9hZP5IN9KNAA+0BGmhvGpcfGagXkTn9RHrxJwUv7iW9uJ/1ornhfsKL+4HqPaDsRZPhAOHFA8pe3GfnhXoRWa+fSS/+rODFfQ68+Ivd+Ae9DX5QoK0PAg/iENnWhwTaeh/Q1r+kcfl9MgX24i8BD2K0y7PNhL5f/AFYK4Qvku8XAX9qESt0hHnxV3tAf5P24m8OvHjYhjnibZvDEbx4RKCBjgA78HeygX4XaKDfgAY6nMblRwZ6ipA5HSW9eFTBi4dJLx5jvWhueIzw4jGgpo4re9FkOE548biyF4/YeaFeRNbrD9KLfyh48YgDL/5pN/4Jb4OfEGjrE8CDOEm29UmBtj4CtPWfaVx+n0yBvfjnBXq/yNoqmit/BdYUYY7E+0VzncvfMf9lD+gpaS+ecuDF0zbMGW/bnI7gxTMCDXQG2Fl/kw30t0ADnQIa6HQalx8ZqBeROZ0lvXhWwYunSS+eY71obniO8OI5oHrPK3vRZDhPePG8shfP2HmhXkTW6x/Si/8oePGMAy/GpNuL0mP+G9D8B0Hb2vwdOb32onSurS9KD97WZ4C2jknn8vtkCuzFmPRgBzHa5eY65nfMfwEHEeGL5O+YldgUOsIMmMseujjzT8kGiUtXCePbIPE2TIK3Qcy/8BowQaBVEoATmJtsldwCrRKXnvNWiU/n8iMDNSAyp8R0zoCJ6fIGjE/nDJiUHuCG5g+jBkzK+YOMTQYeBpvB3AM1YHLAj56cbPbkdNyAyHqlABlCN29KurwBE0gyxPjfx7fBU+3GT/M2eJpAW6cBDyKdbOt0gbZOANo6NZ3L75MpsAFTyU8FwTcbYf7LBawTQheJ94ArY9z+jjnDHrpMaQNmOjBglg2Tx9sgWREMmEegVfIAO+tislUuFmiVTKBVstK5/MhADYjM6RLSgJcoGDCLNGBe1oDmhnkJA+YFDJhP2YAmQz7CgPmUDZjHzgs1ILJel5IGvFTBgHkcGPAyu/Hzexs8v0Bb5wceRAGyrQsItHUeoK0vS+fy+2QKbMDLAh7EaJevjOF+x5wBrBXCF8nvGQL+1CJW6Ajz4uX2gF4h7cUrHHixoA1TyNs2BSN4sZBAAxUCduCVZANdKdBAVwANVDCdy48M9BQhcypMerGwghcLkl4swnrR3LAI4cUiQE0VVfaiyVCU8GJRZS8WsvNCvYis11WkF69S8GIhB1682m78Yt4GLybQ1sWAB1GcbOviAm1dCGjrq9O5/D6ZAnvxavJTAf2eIWuraK68HFhThDkS7xcfinX7O+Zr7AEtIe3FEg68WNKGKeVtm5IRvFhKoIFKATvrWrKBrhVooBJAA5VM5/IjA/UiMqfrSC9ep+DFkqQXS7NeNDcsTXixNFC9ZZS9aDKUIbxYRtmLpey8UC8i63U96cXrFbxYyoEXy9qNX87b4OUE2roc8CDKk21dXqCtSwFtXTady++TKbAXywY8iNEuzzYT+n7xGmCtEL5Ivl8E/KlFrNAR5sUb7AG9UdqLNzrwYgUbpqK3bSpE8GJFgQaqCOzAm8gGukmggW4EGqhCOpcfGegpQuZ0M+nFmxW8WIH0YiXWi+aGlQgvVgJqqrKyF02GyoQXKyt7saKdF+pFZL1uIb14i4IXKzrwYhW78at6G7yqQFtXBR5ENbKtqwm0dUWgraukc/l9MgX2YpUL9H6RtVU0V94ArCnCHIn3i0Vi3P6O+VZ7QKtLe7G6Ay/WsGFqetumRgQv1hRooJrAzrqNbKDbBBqoOtBANdK5/MhAvYjM6XbSi7creLEG6cVarBfNDWsRXqwFVG9tZS+aDLUJL9ZW9mJNOy/Ui8h63UF68Q4FL9Z04MU6duPX9TZ4XYG2rgs8iHpkW9cTaOuaQFvXSefy+2QK7MU6AQ9itMuzzYS+X7wVWCuEL5K/Y1ZiU+gIM+Cd9tDVlzZgfQcGbGDDNPQ2SIMIBmwo0CoNgV11F9kqdwm0Sn2gVRqkc/mRgRoQmdPdpAHvVjBgA9KAjVgDmhs2IgzYCDBgY2UDmgyNCQM2VjZgQzsv1IDIet1DGvAeBQM2dGDAe+3Gb+Jt8CYCbd0EeBBNybZuKtDWDYG2vjedy++TKbAB7yU/FQTfbIT5705gnRC6SLwHXBXj9nfM99lD10zagM0cGLC5DdPC2yDNIxiwhUCrtAB21v1kq9wv0CrNgFZpns7lRwZqQGROD5AGfEDBgM1JA7ZkDWhu2JIwYEvAgK2UDWgytCIM2ErZgC3svFADIuv1IGnABxUM2MKBAR+yG7+1t8FbC7R1a+BBtCHbuo1AW7cA2vqhdC6/T6bABnwo4EGMdnm2mdD3gPcBa4XwRfJ7hoA/tYgVOsK8+LA9oG2lvdjWgRfb2TDtvW3TLoIX2ws0UHtgBz5CNtAjAg3UFmigdulcfmSgpwiZ06OkFx9V8GI70osdWC+aG3YgvNgBqKmOyl40GToSXuyo7MX2dl6oF5H1eoz04mMKXmzvwIuP243fydvgnQTauhPwIDqTbd1ZoK3bA239eDqX3ydTYC8+Tn4qoN8zZG0VzZUPA2uKMEfi/WLrWLe/Y37CHtAu0l7s4sCLXW2Ybt626RrBi90EGqgbsLOeJBvoSYEG6gI0UNd0Lj8yUC8ic3qK9OJTCl7sSnqxO+tFc8PuhBe7A9XbQ9mLJkMPwos9lL3Yzc4L9SKyXk+TXnxawYvdHHixp934vbwN3kugrXsBD6I32da9Bdq6G9DWPdO5/D6ZAnuxZ8CDGO3ybDOh7xefANYK4Yvk+0XAn1rECh1hXnzGHtA+0l7s48CLfW2Yft626RvBi/0EGqgfsAOfJRvoWYEG6gM0UN90Lj8y0FOEzOk50ovPKXixL+nF/qwXzQ37E17sD9TUAGUvmgwDCC8OUPZiPzsv1IvIej1PevF5BS/2c+DFF+zGH+ht8IECbT0QeBCDyLYeJNDW/YC2fiGdy++TKbAXX7hA7xdZW0Vz5TPAmiLMkXi/WDTG7e+YX7QHdLC0Fwc78OIQG2aot22GRPDiUIEGGgrsrJfIBnpJoIEGAw00JJ3LjwzUi8icXia9+LKCF4eQXhzGetHccBjhxWFA9Q5X9qLJMJzw4nBlLw6180K9iKzXK6QXX1Hw4lAHXnzVbvwR3gYfIdDWI4AHMZJs65ECbT0UaOtX07n8PpkCe/HVgAcx2uXZZkLfL74IrBXCF8nfMSuxKXSEGfA1e+hGSRtwlAMDjrZhxngbZHQEA44RaJUxwK56nWyV1wVaZRTQKqPTufzIQA2IzGksacCxCgYcTRpwHGtAc8NxhAHHAQYcr2xAk2E8YcDxygYcY+eFGhBZrzdIA76hYMAxDgz4pt34E7wNPkGgrScAD2Ii2dYTBdp6DNDWb6Zz+X0yBTbgm+SnguCbjTD/vQasE0IXifeAq2Pc/o75LXvoJkkbcJIDA062YaZ4G2RyBANOEWiVKcDOeptslbcFWmUS0CqT07n8yEANiMxpKmnAqQoGnEwacBprQHPDaYQBpwEGnK5sQJNhOmHA6coGnGLnhRoQWa93SAO+o2DAKQ4MOMNu/JneBp8p0NYzgQcxi2zrWQJtPQVo6xnpXH6fTIENOCPgQYx2ebaZ0PeAbwFrhfBF8nuGgD+1iBU6wrz4rj2gs6W9ONuBF+fYMHO9bTMnghfnCjTQXGAHvkc20HsCDTQbaKA56Vx+ZKCnCJnTPNKL8xS8OIf04nzWi+aG8wkvzgdqaoGyF02GBYQXFyh7ca6dF+pFZL3eJ734voIX5zrw4kK78Rd5G3yRQFsvAh7EYrKtFwu09VygrRemc/l9MgX24kLyUwH9niFrq2iufBdYU4Q5Eu8X28S6/R3zB/aALpH24hIHXlxqwyzzts3SCF5cJtBAy4Cd9SHZQB8KNNASoIGWpnP5kYF6EZnTR6QXP1Lw4lLSi8tZL5obLie8uByo3hXKXjQZVhBeXKHsxWV2XqgXkfX6mPTixwpeXObAiyvtxl/lbfBVAm29CngQq8m2Xi3Q1suAtl6ZzuX3yRTYiysDHsRol2ebCX2/+AGwVghfJN8vAv7UIlboCPPiJ/aArpH24hoHXlxrw6zzts3aCF5cJ9BA64Ad+CnZQJ8KNNAaoIHWpnP5kYGeImROn5Fe/EzBi2tJL65nvWhuuJ7w4nqgpjYoe9Fk2EB4cYOyF9fZeaFeRNbrc9KLnyt4cZ0DL260G3+Tt8E3CbT1JuBBbCbberNAW68D2npjOpffJ1NgL268QO8XWVtFc+UnwJoizJF4v3hVjNvfMX9hD+iX0l780oEXt9gwW71tsyWCF7cKNNBWYGd9RTbQVwIN9CXQQFvSufzIQL2IzOlr0otfK3hxC+nFbawXzQ23EV7cBlTvdmUvmgzbCS9uV/biVjsv1IvIen1DevEbBS9udeDFb+3G3+Ft8B0Cbb0DeBA7ybbeKdDWW4G2/jady++TKbAXvw14EKNdnm0m9P3iF8BaIXyR/B2zEptCR5gBv7OH7ntpA37vwIC7bJjd3gbZFcGAuwVaZTewq34gW+UHgVb5HmiVXelcfmSgBkTmtIc04B4FA+4iDbiXNaC54V7CgHsBA+5TNqDJsI8w4D5lA+6280INiKzXj6QBf1Qw4G4HBvzJbvz93gbfL9DW+4EHcYBs6wMCbb0baOuf0rn8PpkCG/An8lNB8M1GmP++A9YJoYvEe8BPYtz+jvlne+h+kTbgLw4MeNCGOeRtkIMRDHhIoFUOATvrV7JVfhVolV+AVjmYzuVHBmpAZE6/kQb8TcGAB0kDHmYNaG54mDDgYcCAR5QNaDIcIQx4RNmAh+y8UAMi6/U7acDfFQx4yIEBj9qNf8zb4McE2voY8CCOk219XKCtDwFtfTSdy++TKbABjwY8iNEuzzYT+h7wZ2CtEL5Ifs8Q8KcWsUJHmBf/sAf0T2kv/unAiydsmJPetjkRwYsnBRroJLAD/yIb6C+BBvoTaKAT6Vx+ZKCnCJnTKdKLpxS8eIL04mnWi+aGpwkvngZq6oyyF02GM4QXzyh78aSdF+pFZL3+Jr34t4IXTzrw4lm78c95G/ycQFufAx7EebKtzwu09Umgrc+mc/l9MgX24lnyUwH9niFrq2iu/ANYU4Q5Eu8XH451+zvmf7I/mTJiZNvG/IU5vDbiKPy//l7P+M/iZ9j/LCPmv21j/oXXi+aioA10UUbOr82VwTVQrozgDRSTkfMGis3g8iMD9SIyp7gMzotxGfJejM3gvBifEeCG5g+jXozP+YOMTQAeBpvB3AP1YgK4GdF5XWTnhXoRWa/cQIbQzZs7Q96LF+WssES9mGg3fpK3wZME2joJeBDJZFsnC7T1RUBbJ2Zw+X0yBfZiYsCDGO3ybDOh7xf/Qf4PXSCD5PtFwJ9axAodYV5MsQc0VdqLqQ68mGbDpHvbJi2CF9MFGigdOK0ZZANlCDRQKtBAaRlcfmSgpwiZUybpxUwFL6aRXsxivWhumEV4MQvwYh5lL5oMeQgv5lH2YrqdF+pFZL0uJr14sYIX0x148RK78fN6GzyvQFvnBR5EPrKt8wm0dTrQ1pdkcPl9MgX24iXkpwL6fpG1VTRXpgBrijBH4v3i1TFuf8d8qT2gl0l78TIHXsxvwxTwtk3+CF4sINBABYCddTnZQJcLNNBlQAPlz+DyIwP1IjKnK0gvXqHgxfykFwuyXjQ3LEh4sSDgxULKXjQZChFeLKTsxQJ2XqgXkfW6kvTilQpeLODAi4Xtxi/ibfAiAm1dBHgQRcm2LirQ1gWAti6cweX3yRTYi4UDHsRol2ebCX2/eCmwVghfJH/HrMSm0BFmwKvsobta2oBXOzBgMRumuLdBikUwYHGBVikO7KpryFa5RqBVrgZapVgGlx8ZqAGROZUgDVhCwYDFSAOWZA1obliSMGBJwICllA1oMpQiDFhK2YDF7bxQAyLrdS1pwGsVDFjcgQGvsxu/tLfBSwu0dWngQZQh27qMQFsXB9r6ugwuv0+mwAa8jvxUEHyzEea/q4B1Qugi8R5wTYzb3zFfbw9dWWkDlnVgwHI2THlvg5SLYMDyAq1SHthZN5CtcoNAq5QFWqVcBpcfGagBkTndSBrwRgUDliMNWIE1oLlhBcKAFQADVlQ2oMlQkTBgRWUDlrfzQg2IrNdNpAFvUjBgeQcGvNlu/EreBq8k0NaVgAdRmWzrygJtXR5o65szuPw+mQIb8OaABzHa5dlmQt8DXg+sFcIXye8ZAv7UIlboCPPiLfaAVpH2YhUHXqxqw1Tztk3VCF6sJtBA1YAdeCvZQLcKNFAVoIGqZnD5kYGeImRO1UkvVlfwYlXSizVYL5ob1iC8WAOoqZrKXjQZahJerKnsxWp2XqgXkfW6jfTibQperObAi7fbjV/L2+C1BNq6FvAgapNtXVugrasBbX17BpffJ1NgL95Ofiqg3zNkbRXNlbcAa4owR+L9YttYt79jvsMe0DrSXqzjwIt1bZh63rapG8GL9QQaqB6ws+4kG+hOgQaqAzRQ3QwuPzJQLyJzqk96sb6CF+uSXmzAetHcsAHhxQZA9TZU9qLJ0JDwYkNlL9az80K9iKzXXaQX71LwYj0HXrzbbvxG3gZvJNDWjYAH0Zhs68YCbV0PaOu7M7j8PpkCe/HugAcx2uXZZkLfL94BrBXCF8n3i4A/tYgVOsK8eI89oPdKe/FeB15sYsM09bZNkwhebCrQQE2BHXgf2UD3CTTQvUADNcng8iMDPUXInJqRXmym4MUmpBebs140N2xOeLE5UFMtlL1oMrQgvNhC2YtN7bxQLyLrdT/pxfsVvNjUgRcfsBu/pbfBWwq0dUvgQbQi27qVQFs3Bdr6gQwuv0+mwF584AK9X2RtFc2V9wBrijBH4v1isRi3v2N+0B7Qh6S9+JADL7a2Ydp426Z1BC+2EWigNsDOephsoIcFGughoIFaZ3D5kYF6EZlTW9KLbRW82Jr0YjvWi+aG7QgvtgOqt72yF02G9oQX2yt7sY2dF+pFZL0eIb34iIIX2zjw4qN243fwNngHgbbuADyIjmRbdxRo6zZAWz+aweX3yRTYi48GPIjRLs82E/p+8UFgrRC+SP6OWYlNoSPMgI/ZQ/e4tAEfd2DATjZMZ2+DdIpgwM4CrdIZ2FVPkK3yhECrPA60SqcMLj8yUAMic+pCGrCLggE7kQbsyhrQ3LArYcCugAG7KRvQZOhGGLCbsgE723mhBkTW60nSgE8qGLCzAwM+ZTd+d2+Ddxdo6+7Ag+hBtnUPgbbuDLT1Uxlcfp9MgQ34FPmpIPhmI8x/jwHrhNBF4j3g2hi3v2N+2h66ntIG7OnAgL1smN7eBukVwYC9BVqlN7CzniFb5RmBVukJtEqvDC4/MlADInPqQxqwj4IBe5EG7Msa0NywL2HAvoAB+ykb8N/DShiwn7IBe9t5oQZE1utZ0oDPKhiwtwMDPmc3fn9vg/cXaOv+wIMYQLb1AIG27g209XMZXH6fTIEN+FzAgxjt8mwzoe8BnwbWCuGL5PcMAX9qESt0hHnxeXtAX5D24gsOvDjQhhnkbZuBEbw4SKCBBgE78EWygV4UaKAXgAYamMHlRwZ6ipA5DSa9OFjBiwNJLw5hvWhuOITw4hCgpoYqe9FkGEp4caiyFwfZeaFeRNbrJdKLLyl4cZADL75sN/4wb4MPE2jrYcCDGE629XCBth4EtPXLGVx+n0yBvfgy+amAfs+QtVU0Vz4PrCnCHIn3i+1i3f6O+RV7QF+V9uKrDrw4woYZ6W2bERG8OFKggUYCO+s1soFeE2igV4EGGpHB5UcG6kVkTqNIL45S8OII0oujWS+aG44mvDgaqN4xyl40GcYQXhyj7MWRdl6oF5H1ep304usKXhzpwItj7cYf523wcQJtPQ54EOPJth4v0NYjgbYem8Hl98kU2ItjAx7EaJdnmwl9v/gKsFYIXyTfLwL+1CJW6Ajz4hv2gL4p7cU3HXhxgg0z0ds2EyJ4caJAA00EduBbZAO9JdBAbwINNCGDy48M9BQhc5pEenGSghcnkF6czHrR3HAy4cXJQE1NUfaiyTCF8OIUZS9OtPNCvYis19ukF99W8OJEB16cajf+NG+DTxNo62nAg5hOtvV0gbaeCLT11Awuv0+mwF6ceoHeL7K2iubKN4A1RZgj8X6xeIzb3zG/Yw/oDGkvznDgxZk2zCxv28yM4MVZAg00C9hZ75IN9K5AA80AGmhmBpcfGagXkTnNJr04W8GLM0kvzmG9aG44h/DiHKB65yp70WSYS3hxrrIXZ9l5oV5E1us90ovvKXhxlgMvzrMbf763wecLtPV84EEsINt6gUBbzwLael4Gl98nU2Avzgt4EKNdnm0m9P3iO8BaIXyR/B2zEptCR5gB37eHbqG0ARc6MOAiG2axt0EWRTDgYoFWWQzsqg/IVvlAoFUWAq2yKIPLjwzUgMiclpAGXKJgwEWkAZeyBjQ3XEoYcClgwGXKBjQZlhEGXKZswMV2XqgBkfX6kDTghwoGXOzAgB/Zjb/c2+DLBdp6OfAgVpBtvUKgrRcDbf1RBpffJ1NgA35EfioIvtkI89/7wDohdJF4D7guxu3vmD+2h26ltAFXOjDgKhtmtbdBVkUw4GqBVlkN7KxPyFb5RKBVVgKtsiqDy48M1IDInNaQBlyjYMBVpAHXsgY0N1xLGHAtYMB1ygY0GdYRBlynbMDVdl6oAZH1+pQ04KcKBlztwICf2Y2/3tvg6wXaej3wIDaQbb1BoK1XA239WQaX3ydTYAN+FvAgRrs820zoe8CPgbVC+CL5PUPAn1rECh1hXvzcHtCN0l7c6MCLm2yYzd622RTBi5sFGmgzsAO/IBvoC4EG2gg00KYMLj8y0FOEzOlL0otfKnhxE+nFLawXzQ23EF7cAtTUVmUvmgxbCS9uVfbiZjsv1IvIen1FevErBS9uduDFr+3G3+Zt8G0Cbb0NeBDbybbeLtDWm4G2/jqDy++TKbAXvyY/FdDvGbK2iubKz4E1RZgj8X6xfazb3zF/Yw/ot9Je/NaBF3fYMDu9bbMjghd3CjTQTmBnfUc20HcCDfQt0EA7Mrj8yEC9iMzpe9KL3yt4cQfpxV2sF80NdxFe3AVU725lL5oMuwkv7lb24k47L9SLyHr9QHrxBwUv7nTgxT124+/1NvhegbbeCzyIfWRb7xNo651AW+/J4PL7ZArsxT0BD2K0y7PNhL5f/AZYK4Qvku8XAX9qESt0hHnxR3tAf5L24k8OvLjfhjngbZv9Ebx4QKCBDgA78GeygX4WaKCfgAban8HlRwZ6ipA5/UJ68RcFL+4nvXiQ9aK54UHCiweBmjqk7EWT4RDhxUPKXjxg54V6EVmvX0kv/qrgxQMOvPib3fiHvQ1+WKCtDwMP4gjZ1kcE2voA0Na/ZXD5fTIF9uJvF+j9ImuraK78EVhThDkS7xeviXH7O+bf7QE9Ku3Fow68eMyGOe5tm2MRvHhcoIGOAzvrD7KB/hBooKNAAx3L4PIjA/UiMqc/SS/+qeDFY6QXT7BeNDc8QXjxBFC9J5W9aDKcJLx4UtmLx+28UC8i6/UX6cW/FLx43IEXT9mNf9rb4KcF2vo08CDOkG19RqCtjwNtfSqDy++TKbAXTwU8iNEuzzYT+n7xd2CtEL5I/o5ZiU2hI8yAf9tDd1bagGcdGPCcDXPe2yDnIhjwvECrnAd21T9kq/wj0CpngVY5l8HlRwZqQGROMZmcAc2fkzbgOdKAsZkBbmj+MGrA2MycP4yLMnUNaDKYe6AGvCgT24zovM7beaEGRNYrF5AhdPOaPydtwPMODBhnN358Zsx/A8ZnBm/reOBBJGRybZ2QGbytzwNtHZfJ5ffJFNiAceBBzB6CbzbC/Pc38AlyNqD/0IP2aYzb3zHntocu0fxTskESM1XC+DZIkg2T7G2QpMxwAyYLtEoycAJTyFZJEWiVxMyct0pSJpcfGagBkTmlkgZMVTBgUiZnwDTWgOaGaYQB0wADpisb0GRIJwyYrmzAZDsv1IDIemWQBsxQMGAySYYY//v4Nnim3fhZ3gbPEmjrLOBB5CHbOo9AWycDbZ2ZyeX3yRTYgJkBD2K0y7PNhL4HzA2sFcIXye8ZAv7UIlboCPPixfaAXiLtxUsceDGvDZPP2zZ5I3gxn0AD5QN24KVkA10q0ECXAA2UN5PLjwz0FCFzuoz04mUKXsxLejF/ZoAb5ie8mB/wYgFlL5oMBQgvFlD2Yj47L9SLyHpdTnrxcgUv5nPgxSvsxi/obfCCAm1t/o6cXlsok2tr8+eCtrXPp0pYW1+RyeX3yRTYi1dkcp8K6PcMWVtFc+XFwJoizJF4v/hIrNvfMV+Zaf+s+adk2xTOVAnj2zZFbJiimTH/bRvzL7xeLJoZvIGKAjvrKrKBrhJooMJAAxXJ5PIjA/UiMqerMzkvXp0p78UimZwXi2UGuKH5w6gXi+X8QcYWBx4Gm8HcA/VicXAzovMqaueFehFZr2uADKGb95pMeS8WJXkR438f3wYvYTd+SW+DlxRo65LAgyhFtnUpgbYuCrR1iUwuv0+mwF4sEfAgRrs820zo+8UrgbVC+CL5fhHwpxaxQkeYF6+1B/Q6aS9e58CLpW2YMt62KR3Bi2UEGqgMsAOvJxvoeoEGug5ooNKZXH5koKcImVNZ0otlFbxYmvRiucwANyxHeLEcUFPllb1oMpQnvFhe2Ytl7LxQLyLrdQPpxRsUvFjGgRdvtBu/grfBKwi0dQXgQVQk27qiQFuXAdr6xkwuv0+mwF68kfxUQN8vsraK5sprgTVFmCPxfrFEjNvfMd9kD+jN0l682YEXK9kwlb1tUymCFysLNFBlYGfdQjbQLQINdDPQQJUyufzIQL2IzKkK6cUqCl6sRHqxamaAG1YlvFgVqN5qyl40GaoRXqym7MXKdl6oF5H1upX04q0KXqzswIvV7cav4W3wGgJtXQN4EDXJtq4p0NaVgbaunsnl98kU2IvVAx7EaJdnmwl9v3gTsFYIXyR/x6zEptARZsDb7KG7XdqAtzswYC0bpra3QWpFMGBtgVapDeyqO8hWuUOgVW4HWqVWJpcfGagBkTnVIQ1YR8GAtUgD1s0McMO6hAHrAgasp2xAk6EeYcB6ygasbeeFGhBZrztJA96pYMDaDgxY3278Bt4GbyDQ1g2AB9GQbOuGAm1dG2jr+plcfp9MgQ1Yn/xUEHyzEea/24B1Qugi8R7wsxi3v2O+yx66u6UNeLcDAzayYRp7G6RRBAM2FmiVxsDOuodslXsEWuVuoFUaZXL5kYEaEJnTvaQB71UwYCPSgE0yA9ywCWHAJoABmyob0GRoShiwqbIBG9t5oQZE1us+0oD3KRiwsQMDNrMbv7m3wZsLtHVz4EG0INu6hUBbNwbaulkml98nU2ADNgt4EKNdnm0m9D3gXcBaIXyR/J4h4E8tYoWOMC/ebw/oA9JefMCBF1vaMK28bdMyghdbCTRQK2AHPkg20IMCDfQA0EAtM7n8yEBPETKnh0gvPqTgxZakF1tnBrhha8KLrYGaaqPsRZOhDeHFNspebGXnhXoRWa+HSS8+rODFVg682NZu/HbeBm8n0NbtgAfRnmzr9gJt3Qpo67aZXH6fTIG92Jb8VEC/Z8jaKpor7wfWFGGOxPvFR2Pd/o75EXtAH5X24qMOvNjBhunobZsOEbzYUaCBOgI76zGygR4TaKBHgQbqkMnlRwbqRWROj5NefFzBix1IL3bKDHDDToQXOwHV21nZiyZDZ8KLnZW92NHOC/Uisl5PkF58QsGLHR14sYvd+F29Dd5VoK27Ag+iG9nW3QTauiPQ1l0yufw+mQJ7sUvAgxjt8mwzoe8XHwHWCuGL5PtFwJ9axAodYV580h7Qp6S9+JQDL3a3YXp426Z7BC/2EGigHsAOfJpsoKcFGugpoIG6Z3L5kYGeImROPUkv9lTwYnfSi70yA9ywF+HFXkBN9Vb2osnQm/Bib2Uv9rDzQr2IrNczpBefUfBiDwde7GM3fl9vg/cVaOu+wIPoR7Z1P4G27gG0dZ9MLr9PpsBe7EN+KqDvF1lbRXPlk8CaIsyReL9YMsbt75iftQf0OWkvPufAi/1tmAHetukfwYsDBBpoALCznicb6HmBBnoOaKD+mVx+ZKBeROb0AunFFxS82J/04sDMADccSHhxIFC9g5S9aDIMIrw4SNmLA+y8UC8i6/Ui6cUXFbw4wIEXB9uNP8Tb4EME2noI8CCGkm09VKCtBwBtPTiTy++TKbAXBwc8iNEuzzYT+n7xWWCtEL5I/o5ZiU2hI8yAL9lD97K0AV92YMBhNsxwb4MMi2DA4QKtMhzYVa+QrfKKQKu8DLTKsEwuPzJQAyJzepU04KsKBhxGGnBEZoAbjiAMOAIw4EhlA5oMIwkDjlQ24HA7L9SAyHq9RhrwNQUDDndgwFF244/2NvhogbYeDTyIMWRbjxFo6+FAW4/K5PL7ZApswFHkp4Lgm40w/70ErBNCF4n3gOtj3P6O+XV76MZKG3CsAwOOs2HGextkXAQDjhdolfHAznqDbJU3BFplLNAq4zK5/MhADYjM6U3SgG8qGHAcacAJmQFuOIEw4ATAgBOVDWgyTCQMOFHZgOPtvFADIuv1FmnAtxQMON6BASfZjT/Z2+CTBdp6MvAgppBtPUWgrccDbT0pk8vvkymwAScFPIjRLs82E/oe8HVgrRC+SH7PEPCnFrFCR5gX37YHdKq0F6c68OI0G2a6t22mRfDidIEGmg7swHfIBnpHoIGmAg00LZPLjwz0FCFzmkF6cYaCF6eRXpyZGeCGMwkvzgRqapayF02GWYQXZyl7cbqdF+pFZL3eJb34roIXpzvw4my78ed4G3yOQFvPAR7EXLKt5wq09XSgrWdncvl9MgX24mzyUwH9niFrq2iufBtYU4Q5Eu8XO8S6/R3ze/aAzpP24jwHXpxvwyzwts38CF5cINBAC4Cd9T7ZQO8LNNA8oIHmZ3L5kYF6EZnTQtKLCxW8OJ/04qLMADdcRHhxEVC9i5W9aDIsJry4WNmLC+y8UC8i6/UB6cUPFLy4wIEXl9iNv9Tb4EsF2nop8CCWkW29TKCtFwBtvSSTy++TKbAXlwQ8iNEuzzYT+n7xPWCtEL5Ivl8E/KlFrNAR5sUP7QH9SNqLHznw4nIbZoW3bZZH8OIKgQZaAezAj8kG+liggT4CGmh5JpcfGegpQua0kvTiSgUvLie9uCozwA1XEV5cBdTUamUvmgyrCS+uVvbiCjsv1IvIen1CevETBS+ucODFNXbjr/U2+FqBtl4LPIh1ZFuvE2jrFUBbr8nk8vtkCuzFNeSnAvp+kbVVNFd+CKwpwhyJ94ulYtz+jvlTe0A/k/biZw68uN6G2eBtm/URvLhBoIE2ADvrc7KBPhdooM+ABlqfyeVHBupFZE4bSS9uVPDietKLmzID3HAT4cVNQPVuVvaiybCZ8OJmZS9usPNCvYis1xekF79Q8OIGB1780m78Ld4G3yLQ1luAB7GVbOutAm29AWjrLzO5/D6ZAnvxy4AHMdrl2WZC3y9+CqwVwhfJ3zErsSl0hBnwK3vovpY24NcODLjNhtnubZBtEQy4XaBVtgO76huyVb4RaJWvgVbZlsnlRwZqQGRO35IG/FbBgNtIA+7IDHDDHYQBdwAG3KlsQJNhJ2HAncoG3G7nhRoQWa/vSAN+p2DA7Q4M+L3d+Lu8Db5LoK13AQ9iN9nWuwXaejvQ1t9ncvl9MgU24Pfkp4Lgm40w/30FrBNCF4n3gBti3P6O+Qd76PZIG3CPAwPutWH2eRtkbwQD7hNolX3AzvqRbJUfBVplD9AqezO5/MhADYjM6SfSgD8pGHAvacD9mQFuuJ8w4H7AgAeUDWgyHCAMeEDZgPvsvFADIuv1M2nAnxUMuM+BAX+xG/+gt8EPCrT1QeBBHCLb+pBAW+8D2vqXTC6/T6bABvwl4EGMdnm2mdD3gD8Aa4XwRfJ7hoA/tYgVOsK8+Ks9oL9Je/E3B148bMMc8bbN4QhePCLQQEeAHfg72UC/CzTQb0ADHc7k8iMDPUXInI6SXjyq4MXDpBePZQa44THCi8eAmjqu7EWT4TjhxePKXjxi54V6EVmvP0gv/qHgxSMOvPin3fgnvA1+QqCtTwAP4iTZ1icF2voI0NZ/ZnL5fTIF9uKf5KcC+j1D1lbRXPkrsKYIcyTeL3aMdfs75r/sAT0l7cVTDrx42oY5422b0xG8eEaggc4AO+tvsoH+FmigU0ADnc7k8iMD9SIyp7OkF88qePE06cVzmQFueI7w4jmges8re9FkOE948byyF8/YeaFeRNbrH9KL/yh48YwDL8Zk2YuyYv4b0PwHQdva/B05vfaiLK6tL8oK3tZngLaOyeLy+2QK7MWYrGAHMdrl2WZC3y/+BRxEhC+S7xcBf2oRK3SEeTGXPaBx5p+SbROXpRLGt23ibZgEb9uYf+H1YoJAAyUApzU32UC5BRooLivnDRSfxeVHBnqKkDklZnFeTMyS92J8FufFpKwANzR/GPViUs4fZGwy8DDYDOYeqBeTA35M5WSzJ2fhXkTWKwXIELp5U7LkvZhA8iLG/z6+DZ5qN36at8HTBNo6DXgQ6WRbpwu0dQLQ1qlZXH6fTIG9mEp+KqDvF1lbRXNlLmBNEeZIvF+8Nsbt75gz7AHNlPZipgMvZtkwebxtkxXBi3kEGigPsLMuJhvoYoEGygQaKCuLy48M1IvInC4hvXiJghezSC/mZb1obpiX8GJewIv5lL1oMuQjvJhP2Yt57LxQLyLrdSnpxUsVvJjHgRcvsxs/v7fB8wu0dX7gQRQg27qAQFvnAdr6siwuv0+mwF68LOBBjHZ5tpnQ94sZwFohfJH8HbMSm0JHmAEvt4fuCmkDXuHAgAVtmELeBikYwYCFBFqlELCrriRb5UqBVrkCaJWCWVx+ZKAGROZUmDRgYQUDFiQNWIQ1oLlhEcKARQADFlU2oMlQlDBgUWUDFrLzQg2IrNdVpAGvUjBgIQcGvNpu/GLeBi8m0NbFgAdRnGzr4gJtXQho66uzuPw+mQIb8GryU0HwzUaY/y4H1gmhi8R7wM9j3P6O+Rp76EpIG7CEAwOWtGFKeRukZAQDlhJolVLAzrqWbJVrBVqlBNAqJbO4/MhADYjM6TrSgNcpGLAkacDSrAHNDUsTBiwNGLCMsgFNhjKEAcsoG7CUnRdqQGS9ricNeL2CAUs5MGBZu/HLeRu8nEBblwMeRHmyrcsLtHUpoK3LZnH5fTIFNmDZgAcx2uXZZkLfA14DrBXCF8nvGQL+1CJW6Ajz4g32gN4o7cUbHXixgg1T0ds2FSJ4saJAA1UEduBNZAPdJNBANwINVCGLy48M9BQhc7qZ9OLNCl6sQHqxEutFc8NKhBcrATVVWdmLJkNlwouVlb1Y0c4L9SKyXreQXrxFwYsVHXixit34Vb0NXlWgrasCD6Ia2dbVBNq6ItDWVbK4/D6ZAnuxCvmpgH7PkLVVNFfeAKwpwhyJ94uPxbr9HfOt9oBWl/ZidQderGHD1PS2TY0IXqwp0EA1gZ11G9lAtwk0UHWggWpkcfmRgXoRmdPtpBdvV/BiDdKLtVgvmhvWIrxYC6je2speNBlqE16srezFmnZeqBeR9bqD9OIdCl6s6cCLdezGr+tt8LoCbV0XeBD1yLauJ9DWNYG2rpPF5ffJFNiLdQIexGiXZ5sJfb94K7BWCF8k3y8C/tQiVugI8+Kd9oDWl/ZifQdebGDDNPS2TYMIXmwo0EANgR14F9lAdwk0UH2ggRpkcfmRgZ4iZE53k168W8GLDUgvNmK9aG7YiPBiI6CmGit70WRoTHixsbIXG9p5oV5E1use0ov3KHixoQMv3ms3fhNvgzcRaOsmwINoSrZ1U4G2bgi09b1ZXH6fTIG9eO8Fer/I2iqaK+8E1hRhjsT7xeti3P6O+T57QJtJe7GZAy82t2FaeNumeQQvthBooBbAzrqfbKD7BRqoGdBAzbO4/MhAvYjM6QHSiw8oeLE56cWWrBfNDVsSXmwJVG8rZS+aDK0IL7ZS9mILOy/Ui8h6PUh68UEFL7Zw4MWH7MZv7W3w1gJt3Rp4EG3Itm4j0NYtgLZ+KIvL75MpsBcfCngQo12ebSb0/eJ9wFohfJH8HbMSm0JHmAEftoeurbQB2zowYDsbpr23QdpFMGB7gVZpD+yqR8hWeUSgVdoCrdIui8uPDNSAyJweJQ34qIIB25EG7MAa0NywA2HADoABOyob0GToSBiwo7IB29t5oQZE1usx0oCPKRiwvQMDPm43fidvg3cSaOtOwIPoTLZ1Z4G2bg+09eNZXH6fTIEN+Dj5qSD4ZiPMfw8D64TQReI94MYYt79jfsIeui7SBuziwIBdbZhu3gbpGsGA3QRapRuws54kW+VJgVbpArRK1ywuPzJQAyJzeoo04FMKBuxKGrA7a0Bzw+6EAbsDBuyhbECToQdhwB7KBuxm54UaEFmvp0kDPq1gwG4ODNjTbvxe3gbvJdDWvYAH0Zts694Cbd0NaOueWVx+n0yBDdgz4EGMdnm2mdD3gE8Aa4XwRfJ7hoA/tYgVOsK8+Iw9oH2kvdjHgRf72jD9vG3TN4IX+wk0UD9gBz5LNtCzAg3UB2igvllcfmSgpwiZ03OkF59T8GJf0ov9WS+aG/YnvNgfqKkByl40GQYQXhyg7MV+dl6oF5H1ep704vMKXuznwIsv2I0/0NvgAwXaeiDwIAaRbT1IoK37AW39QhaX3ydTYC++QH4qoN8zZG0VzZXPAGuKMEfi/eLjsW5/x/yiPaCDpb042IEXh9gwQ71tMySCF4cKNNBQYGe9RDbQSwINNBhooCFZXH5koF5E5vQy6cWXFbw4hPTiMNaL5obDCC8OA6p3uLIXTYbhhBeHK3txqJ0X6kVkvV4hvfiKgheHOvDiq3bjj/A2+AiBth4BPIiRZFuPFGjroUBbv5rF5ffJFNiLrwY8iNEuzzYT+n7xRWCtEL5Ivl8E/KlFrNAR5sXX7AEdJe3FUQ68ONqGGeNtm9ERvDhGoIHGADvwdbKBXhdooFFAA43O4vIjAz1FyJzGkl4cq+DF0aQXx7FeNDccR3hxHFBT45W9aDKMJ7w4XtmLY+y8UC8i6/UG6cU3FLw4xoEX37Qbf4K3wScItPUE4EFMJNt6okBbjwHa+s0sLr9PpsBefPMCvV9kbRXNla8Ba4owR+L9YukYt79jfsse0EnSXpzkwIuTbZgp3raZHMGLUwQaaAqws94mG+htgQaaBDTQ5CwuPzJQLyJzmkp6caqCFyeTXpzGetHccBrhxWlA9U5X9qLJMJ3w4nRlL06x80K9iKzXO6QX31Hw4hQHXpxhN/5Mb4PPFGjrmcCDmEW29SyBtp4CtPWMLC6/T6bAXpwR8CBGuzzbTOj7xbeAtUL4Ivk7ZiU2hY4wA75rD91saQPOdmDAOTbMXG+DzIlgwLkCrTIX2FXvka3ynkCrzAZaZU4Wlx8ZqAGROc0jDThPwYBzSAPOZw1objifMOB8wIALlA1oMiwgDLhA2YBz7bxQAyLr9T5pwPcVDDjXgQEX2o2/yNvgiwTaehHwIBaTbb1YoK3nAm29MIvL75MpsAEXkp8Kgm82wvz3LrBOCF0k3gNuinH7O+YP7KFbIm3AJQ4MuNSGWeZtkKURDLhMoFWWATvrQ7JVPhRolSVAqyzN4vIjAzUgMqePSAN+pGDApaQBl7MGNDdcThhwOWDAFcoGNBlWEAZcoWzAZXZeqAGR9fqYNODHCgZc5sCAK+3GX+Vt8FUCbb0KeBCrybZeLdDWy4C2XpnF5ffJFNiAKwMexGiXZ5sJfQ/4AbBWCF8kv2cI+FOLWKEjzIuf2AO6RtqLaxx4ca0Ns87bNmsjeHGdQAOtA3bgp2QDfSrQQGuABlqbxeVHBnqKkDl9RnrxMwUvriW9uJ71ornhesKL64Ga2qDsRZNhA+HFDcpeXGfnhXoRWa/PSS9+ruDFdQ68uNFu/E3eBt8k0NabgAexmWzrzQJtvQ5o641ZXH6fTIG9uJH8VEC/Z8jaKporPwHWFGGOxPvFTrFuf8f8hT2gX0p78UsHXtxiw2z1ts2WCF7cKtBAW4Gd9RXZQF8JNNCXQANtyeLyIwP1IjKnr0kvfq3gxS2kF7exXjQ33EZ4cRtQvduVvWgybCe8uF3Zi1vtvFAvIuv1DenFbxS8uNWBF7+1G3+Ht8F3CLT1DuBB7CTbeqdAW28F2vrbLC6/T6bAXvw24EGMdnm2mdD3i18Aa4XwRfL9IuBPLWKFjjAvfmcP6PfSXvzegRd32TC7vW2zK4IXdws00G5gB/5ANtAPAg30PdBAu7K4/MhATxEypz2kF/coeHEX6cW9rBfNDfcSXtwL1NQ+ZS+aDPsIL+5T9uJuOy/Ui8h6/Uh68UcFL+524MWf7Mbf723w/QJtvR94EAfItj4g0Na7gbb+KYvL75MpsBd/ukDvF1lbRXPld8CaIsyReL9YJsbt75h/tgf0F2kv/uLAiwdtmEPetjkYwYuHBBroELCzfiUb6FeBBvoFaKCDWVx+ZKBeROb0G+nF3xS8eJD04mHWi+aGhwkvHgaq94iyF02GI4QXjyh78ZCdF+pFZL1+J734u4IXDznw4lG78Y95G/yYQFsfAx7EcbKtjwu09SGgrY9mcfl9MgX24tGABzHa5dlmQt8v/gysFcIXyd8xK7EpdIQZ8A976P6UNuCfDgx4woY56W2QExEMeFKgVU4Cu+ovslX+EmiVP4FWOZHF5UcGakBkTqdIA55SMOAJ0oCnWQOaG54mDHgaMOAZZQOaDGcIA55RNuBJOy/UgMh6/U0a8G8FA550YMCzduOf8zb4OYG2Pgc8iPNkW58XaOuTQFufzeLy+2QKbMD/H/F2H25T1b4Pf+1eFEXZ7+97UhRFURRFKIqiKIoiFEVRFEVRFEVRFEUoiqIoiqIIRVEURVEURVEURRF6fuPb2MezzLXuudZ5zusyxh+349Dc5jjHHONcn3seex0gPxUE32zE+O8PYJ0Quki8B1wZcfs95n+LP21SI7INYv7BJK+NO7z/9e/6xmGLn2r/LjVyeIOY/+A3oLkobKsclZr8tUencq1ydGr4VomkJt8qKalcfmSgBkTmdEwqZ8BjUuUNmJLKGfDY1BA3ND+MGvDY5B9kSgngYbAZzD1QA5YANyM6r6PsvFADIut1HJAhevMelypvwKOSKyxRAx5vN35Jf4OXFGjrksCDKEW2dSmBtj4KaOvjU7n8AZlCG/D4kAcx0eXFZkLfA/6L/J9XIIPk7xkC/tQiVvSI8eIJ9oCeKO3FEx14sbQNU8bfNqXjeLGMQAOVAU7rSWQDnSTQQCcCDVQ6lcuPDPQUIXM6mfTiyQpeLE16sSzrRXPDsoQXywJeTFX2osmQSngxVdmLZey8UC8i65VGejFNwYtlHHgx3W78DH+DZwi0dQbwIDLJts4UaOsyQFunp3L5AzKF9mI6+amA/p4ha6tErjwBWFOEORLvF7unuP0ec5Y9oNnSXsx24MUcGybX3zY5cbyYK9BAucDOyiMbKE+ggbKBBspJ5fIjA/UiMqd80ov5Cl7MIb1YwHrR3LCA8GIB4MVCZS+aDIWEFwuVvZhr54V6EVmvItKLRQpezHXgRc9u/HL+Bi8n0NblgAdRnmzr8gJtnQu0tZfK5Q/IFNqLXsiDmOjyYjOh7xezgLVC+CL5fhHwpxaxokeMF0+xB/RUaS+e6sCLFWyYiv62qRDHixUFGqgisANPIxvoNIEGOhVooAqpXH5koKcImdPppBdPV/BiBdKLlVgvmhtWIrxYCaipyspeNBkqE16srOzFinZeqBeR9TqD9OIZCl6s6MCLZ9qNX8Xf4FUE2roK8CCqkm1dVaCtKwJtfWYqlz8gU2gvnnmE3i+ytkrkylOANUWYI/F+8ayI2+8xn2UP6NnSXjzbgRer2TDV/W1TLY4Xqws0UHVgZ51DNtA5Ag10NtBA1VK5/MhAvYjM6VzSi+cqeLEa6cUarBfNDWsQXqwBVG9NZS+aDDUJL9ZU9mJ1Oy/Ui8h6nUd68TwFL1Z34MXz7cav5W/wWgJtXQt4ELXJtq4t0NbVgbY+P5XLH5AptBfPD3kQE11ebCb0/eJZwFohfJH8HrMSm6JHjAEvsIfuQmkDXujAgHVsmLr+BqkTx4B1BVqlLrCrLiJb5SKBVrkQaJU6qVx+ZKAGROZUjzRgPQUD1iENWJ81oLlhfcKA9QEDNlA2oMnQgDBgA2UD1rXzQg2IrNfFpAEvVjBgXQcGvMRu/Ib+Bm8o0NYNgQfRiGzrRgJtXRdo60tSufwBmUIb8BLyU0HwzUaM/y4A1gmhi8R7wM8ibr/HfKk9dJdJG/AyBwZsbMM08TdI4zgGbCLQKk2AnXU52SqXC7TKZUCrNE7l8iMDNSAypytIA16hYMDGpAGbsgY0N2xKGLApYMBmygY0GZoRBmymbMAmdl6oAZH1upI04JUKBmziwIBX2Y3f3N/gzQXaujnwIFqQbd1CoK2bAG19VSqXPyBTaANeFfIgJrq82Ezoe8BLgbVC+CL5e4aAP7WIFT1ivHi1PaDXSHvxGgdebGnDtPK3Tcs4Xmwl0ECtgB14LdlA1wo00DVAA7VM5fIjAz1FyJyuI714nYIXW5JebM160dywNeHF1kBNtVH2osnQhvBiG2UvtrLzQr2IrNf1pBevV/BiKwdevMFu/Lb+Bm8r0NZtgQfRjmzrdgJt3Qpo6xtSufwBmUJ78QbyUwH9PUPWVolceTWwpghzJN4v3pHi9nvMN9oD2l7ai+0deLGDDdPR3zYd4nixo0ADdQR21k1kA90k0EDtgQbqkMrlRwbqRWRON5NevFnBix1IL3ZivWhu2InwYiegejsre9Fk6Ex4sbOyFzvaeaFeRNbrFtKLtyh4saMDL95qN34Xf4N3EWjrLsCD6Eq2dVeBtu4ItPWtqVz+gEyhvXhryIOY6PJiM6HvF28E1grhi+T7RcCfWsSKHjFevM0e0NulvXi7Ay92s2G6+9umWxwvdhdooO7ADryDbKA7BBrodqCBuqVy+ZGBniJkTneSXrxTwYvdSC/2YL1obtiD8GIPoKZ6KnvRZOhJeLGnshe723mhXkTW6y7Si3cpeLG7Ay/ebTd+L3+D9xJo617Ag+hNtnVvgbbuDrT13alc/oBMob149xF6v8jaKpErbwPWFGGOxPvFsyNuv8d8jz2g90p78V4HXuxjw/T1t02fOF7sK9BAfYGddR/ZQPcJNNC9QAP1SeXyIwP1IjKn+0kv3q/gxT6kF/uxXjQ37Ed4sR9Qvf2Vvfh/h5XwYn9lL/a180K9iKzXA6QXH1DwYl8HXnzQbvwB/gYfINDWA4AHMZBs64ECbd0XaOsHU7n8AZlCe/HBkAcx0eXFZkLfL94DrBXCF8nvMSuxKXrEGPAhe+geljbgww4MOMiGGexvkEFxDDhYoFUGA7vqEbJVHhFolYeBVhmUyuVHBmpAZE6PkgZ8VMGAg0gDDmENaG44hDDgEMCAQ5UNaDIMJQw4VNmAg+28UAMi6/UYacDHFAw42IEBH7cbf5i/wYcJtPUw4EEMJ9t6uEBbDwba+vFULn9AptAGfJz8VBB8sxHjv4eAdULoIvEe8POI2+8xP2EP3ZPSBnzSgQFH2DAj/Q0yIo4BRwq0ykhgZz1FtspTAq3yJNAqI1K5/MhADYjM6WnSgE8rGHAEacBRrAHNDUcRBhwFGHC0sgFNhtGEAUcrG3CknRdqQGS9niEN+IyCAUc6MOCzduOP8Tf4GIG2HgM8iLFkW48VaOuRQFs/m8rlD8gU2oDPhjyIiS4vNhP6HvAJYK0Qvkj+niHgTy1iRY8YLz5nD+g4aS+Oc+DF8TbMBH/bjI/jxQkCDTQB2IHPkw30vEADjQMaaHwqlx8Z6ClC5vQC6cUXFLw4nvTiRNaL5oYTCS9OBGpqkrIXTYZJhBcnKXtxgp0X6kVkvV4kvfiighcnOPDiS3bjT/Y3+GSBtp4MPIgpZFtPEWjrCUBbv5TK5Q/IFNqLL5GfCujvGbK2SuTK54A1RZgj8X7xzhS332N+2R7QV6S9+IoDL061Yab522ZqHC9OE2igacDOepVsoFcFGugVoIGmpnL5kYF6EZnTa6QXX1Pw4lTSi9NZL5obTie8OB2o3hnKXjQZZhBenKHsxWl2XqgXkfV6nfTi6wpenObAi2/YjT/T3+AzBdp6JvAgZpFtPUugracBbf1GKpc/IFNoL74R8iAmurzYTOj7xZeBtUL4Ivl+EfCnFrGiR4wX37QH9C1pL77lwIuzbZg5/raZHceLcwQaaA6wA98mG+htgQZ6C2ig2alcfmSgpwiZ0zukF99R8OJs0otzWS+aG84lvDgXqKl5yl40GeYRXpyn7MU5dl6oF5H1epf04rsKXpzjwIvv2Y0/39/g8wXaej7wIBaQbb1AoK3nAG39XiqXPyBTaC++d4TeL7K2SuTKN4E1RZgj8X6xWsTt95jftwd0obQXFzrw4iIbZrG/bRbF8eJigQZaDOysD8gG+kCggRYCDbQolcuPDNSLyJw+JL34oYIXF5FeXMJ60dxwCeHFJUD1LlX2osmwlPDiUmUvLrbzQr2IrNdHpBc/UvDiYgde/Nhu/GX+Bl8m0NbLgAexnGzr5QJtvRho649TufwBmUJ78eOQBzHR5cVmQt8vvg+sFcIXye8xK7EpesQY8BN76D6VNuCnDgy4woZZ6W+QFXEMuFKgVVYCu+ozslU+E2iVT4FWWZHK5UcGakBkTp+TBvxcwYArSAOuYg1obriKMOAqwICrlQ1oMqwmDLha2YAr7bxQAyLr9QVpwC8UDLjSgQG/tBt/jb/B1wi09RrgQawl23qtQFuvBNr6y1Quf0Cm0Ab8kvxUEHyzEeO/T4B1Qugi8R5wVcTt95i/sofua2kDfu3AgOtsmPX+BlkXx4DrBVplPbCzviFb5RuBVvkaaJV1qVx+ZKAGROb0LWnAbxUMuI404AbWgOaGGwgDbgAMuFHZgCbDRsKAG5UNuN7OCzUgsl7fkQb8TsGA6x0Y8Hu78Tf5G3yTQFtvAh7EZrKtNwu09Xqgrb9P5fIHZAptwO9DHsRElxebCX0P+BWwVghfJH/PEPCnFrGiR4wXf7AH9EdpL/7owItbbJit/rbZEseLWwUaaCuwA38iG+gngQb6EWigLalcfmSgpwiZ08+kF39W8OIW0ovbWC+aG24jvLgNqKntyl40GbYTXtyu7MWtdl6oF5H1+oX04i8KXtzqwIu/2o2/w9/gOwTaegfwIHaSbb1ToK23Am39ayqXPyBTaC/+Sn4qoL9nyNoqkSt/ANYUYY7E+8UeKW6/x/ybPaC/S3vxdwde3GXD7Pa3za44Xtwt0EC7gZ31B9lAfwg00O9AA+1K5fIjA/UiMqc/SS/+qeDFXaQX97BeNDfcQ3hxD1C9e5W9aDLsJby4V9mLu+28UC8i6/UX6cW/FLy424EX/7Ybf5+/wfcJtPU+4EHsJ9t6v0Bb7wba+u9ULn9AptBe/DvkQUx0ebGZ0PeLvwFrhfBF8v0i4E8tYkWPGC/+Yw/oAWkvHnDgxYM2zCF/2xyM48VDAg10CNiB/5IN9K9AAx0AGuhgKpcfGegpQuYUSeO8aH5O2osHSS+mpIW4oflh1Ispack/jKPSdL1oMph7oF48Kg3bjOi8Dtl5oV5E1utoIEP05jU/J+3FQw68eIzd+MemRQ4PeGxa+LY+FngQJdK4ti6RFr6tDwFtfUwalz8gU2gvHgMexOKBvl9kbZXIlf8AnzYHQroSPZTVI26/x3ycPaDHmz8l2+b4NJUwgW1T0oYp5W+bkmmxXiwl0EClgNN6AtlAJwg00PFpyTdQyTQuPzJQLyJzOpH04okKXiyZxnmxNOtFc8PShBdLA14so+xFk6EM4cUyyl4sZeeFehFZr5NIL56k4MVSJC8iwfcJbPCT7cYv62/wsgJtXRZ4EKlkW6cKtHUpoK1PTuPyB2QK7cWTQx7ERJcXmwl9v3gcsFYIXyS/x6zEpugRY8A0e+jSpQ2Y7sCAGTZMpr9BMuIYMFOgVTKBXZVFtkqWQKukA62SkcblRwZqQGRO2aQBsxUMmEEaMIc1oLlhDmHAHMCAucoGNBlyCQPmKhsw084LNSCyXnmkAfMUDJjpwID5duMX+Bu8QKCtC4AHUUi2daFAW2cCbZ2fxuUPyBTagPnkp4Lgm40Y/6UB64TQReI94OqI2+8xF9lD50kb0HNgwHI2THl/g5SLY8DyAq1SHthZp5CtcopAq3hAq5RL4/IjAzUgMqdTSQOeqmDAcqQBK7AGNDesQBiwAmDAisoGNBkqEgasqGzA8nZeqAGR9TqNNOBpCgYs78CAp9uNX8nf4JUE2roS8CAqk21dWaCtywNtfXoalz8gU2gDnh7yICa6vNhM6HvAImCtEL5I/p4h4E8tYkWPGC+eYQ/omdJePNOBF6vYMFX9bVMljherCjRQVWAHnkU20FkCDXQm0EBV0rj8yEBPETKns0kvnq3gxSqkF6uxXjQ3rEZ4sRpQU9WVvWgyVCe8WF3Zi1XtvFAvIut1DunFcxS8WNWBF8+1G7+Gv8FrCLR1DeBB1CTbuqZAW1cF2vrcNC5/QKbQXjyX/FRAf8+QtVUiV54BrCnCHIn3iz1T3H6P+Tx7QM+X9uL5DrxYy4ap7W+bWnG8WFuggWoDO+sCsoEuEGig84EGqpXG5UcG6kVkTheSXrxQwYu1SC/WYb1obliH8GIdoHrrKnvRZKhLeLGushdr23mhXkTW6yLSixcpeLG2Ay/Wsxu/vr/B6wu0dX3gQTQg27qBQFvXBtq6XhqXPyBTaC/WC3kQE11ebCb0/eJ5wFohfJF8vwj4U4tY0SPGixfbA3qJtBcvceDFhjZMI3/bNIzjxUYCDdQI2IGXkg10qUADXQI0UMM0Lj8y0FOEzOky0ouXKXixIenFxqwXzQ0bE15sDNRUE2UvmgxNCC82UfZiIzsv1IvIel1OevFyBS82cuDFK+zGb+pv8KYCbd0UeBDNyLZuJtDWjYC2viKNyx+QKbQXrzhC7xdZWyVy5cXAmiLMkXi/eE7E7feYr7QH9CppL17lwIvNbZgW/rZpHseLLQQaqAWws64mG+hqgQa6Cmig5mlcfmSgXkTmdA3pxWsUvNic9GJL1ovmhi0JL7YEqreVshdNhlaEF1spe7GFnRfqRWS9riW9eK2CF1s48OJ1duO39jd4a4G2bg08iDZkW7cRaOsWQFtfl8blD8gU2ovXhTyIiS4vNhP6fvFKYK0Qvkh+j1mJTdEjxoDX20N3g7QBb3BgwLY2TDt/g7SNY8B2Aq3SDthVN5KtcqNAq9wAtErbNC4/MlADInNqTxqwvYIB25IG7MAa0NywA2HADoABOyob0GToSBiwo7IB29l5oQZE1usm0oA3KRiwnQMD3mw3fid/g3cSaOtOwIPoTLZ1Z4G2bge09c1pXP6ATKENeDP5qSD4ZiPGf9cD64TQReI94BcRt99jvsUeululDXirAwN2sWG6+hukSxwDdhVola7AzrqNbJXbBFrlVqBVuqRx+ZGBGhCZ0+2kAW9XMGAX0oDdWAOaG3YjDNgNMGB3ZQOaDN0JA3ZXNmBXOy/UgMh63UEa8A4FA3Z1YMA77cbv4W/wHgJt3QN4ED3Jtu4p0NZdgba+M43LH5AptAHvDHkQE11ebCb0PeAtwFohfJH8PUPAn1rEih4xXrzLHtC7pb14twMv9rJhevvbplccL/YWaKDewA68h2ygewQa6G6ggXqlcfmRgZ4iZE73kl68V8GLvUgv9mG9aG7Yh/BiH6Cm+ip70WToS3ixr7IXe9t5oV5E1us+0ov3KXixtwMv3m83fj9/g/cTaOt+wIPoT7Z1f4G27g209f1pXP6ATKG9eD/5qYD+niFrq0SuvAtYU4Q5Eu8X70px+z3mB+wBfVDaiw868OIAG2agv20GxPHiQIEGGgjsrIfIBnpIoIEeBBpoQBqXHxmoF5E5PUx68WEFLw4gvTiI9aK54SDCi4OA6h2s7EWTYTDhxcHKXhxo54V6EVmvR0gvPqLgxYEOvPio3fhD/A0+RKCthwAPYijZ1kMF2nog0NaPpnH5AzKF9uKjIQ9iosuLzYS+X3wAWCuEL5LvFwF/ahEresR48TF7QB+X9uLjDrw4zIYZ7m+bYXG8OFyggYYDO/AJsoGeEGigx4EGGpbG5UcGeoqQOT1JevFJBS8OI704gvWiueEIwosjgJoaqexFk2Ek4cWRyl4cbueFehFZr6dILz6l4MXhDrz4tN34o/wNPkqgrUcBD2I02dajBdp6ONDWT6dx+QMyhfbi00fo/SJrq0SufAxYU4Q5Eu8Xz424/R7zM/aAPivtxWcdeHGMDTPW3zZj4nhxrEADjQV21nNkAz0n0EDPAg00Jo3LjwzUi8icxpFeHKfgxTGkF8ezXjQ3HE94cTxQvROUvWgyTCC8OEHZi2PtvFAvIuv1POnF5xW8ONaBF1+wG3+iv8EnCrT1ROBBTCLbepJAW48F2vqFNC5/QKbQXnwh5EFMdHmxmdD3i88Aa4XwRfJ7zEpsih4xBnzRHrqXpA34kgMDTrZhpvgbZHIcA04RaJUpwK56mWyVlwVa5SWgVSancfmRgRoQmdMrpAFfUTDgZNKAU1kDmhtOJQw4FTDgNGUDmgzTCANOUzbgFDsv1IDIer1KGvBVBQNOcWDA1+zGn+5v8OkCbT0deBAzyLaeIdDWU4C2fi2Nyx+QKbQBXyM/FQTfbMT470VgnRC6SLwH/DLi9nvMr9tD94a0Ad9wYMCZNswsf4PMjGPAWQKtMgvYWW+SrfKmQKu8AbTKzDQuPzJQAyJzeos04FsKBpxJGnA2a0Bzw9mEAWcDBpyjbECTYQ5hwDnKBpxl54UaEFmvt0kDvq1gwFkODPiO3fhz/Q0+V6Ct5wIPYh7Z1vME2noW0NbvpHH5AzKFNuA7IQ9iosuLzYS+B3wdWCuEL5K/Zwj4U4tY0SPGi+/aA/qetBffc+DF+TbMAn/bzI/jxQUCDbQA2IHvkw30vkADvQc00Pw0Lj8y0FOEzGkh6cWFCl6cT3pxEetFc8NFhBcXATW1WNmLJsNiwouLlb24wM4L9SKyXh+QXvxAwYsLHHjxQ7vxl/gbfIlAWy8BHsRSsq2XCrT1AqCtP0zj8gdkCu3FD8lPBfT3DFlbJXLlu8CaIsyReL94d4rb7zF/ZA/ox9Je/NiBF5fZMMv9bbMsjheXCzTQcmBnfUI20CcCDfQx0EDL0rj8yEC9iMzpU9KLnyp4cRnpxRWsF80NVxBeXAFU70plL5oMKwkvrlT24nI7L9SLyHp9RnrxMwUvLnfgxc/txl/lb/BVAm29CngQq8m2Xi3Q1suBtv48jcsfkCm0Fz8PeRATXV5sJvT94kfAWiF8kXy/CPhTi1jRI8aLX9gD+qW0F7904MU1Nsxaf9usiePFtQINtBbYgV+RDfSVQAN9CTTQmjQuPzLQU4TM6WvSi18reHEN6cV1rBfNDdcRXlwH1NR6ZS+aDOsJL65X9uJaOy/Ui8h6fUN68RsFL6514MVv7cbf4G/wDQJtvQF4EBvJtt4o0NZrgbb+No3LH5AptBe/PULvF1lbJXLlF8CaIsyReL9YI+L2e8zf2QP6vbQXv3fgxU02zGZ/22yK48XNAg20GdhZP5AN9INAA30PNNCmNC4/MlAvInP6kfTijwpe3ER6cQvrRXPDLYQXtwDVu1XZiybDVsKLW5W9uNnOC/Uisl4/kV78ScGLmx148We78bf5G3ybQFtvAx7EdrKttwu09WagrX9O4/IHZArtxZ9DHsRElxebCX2/+B2wVghfJL/HrMSm6BFjwF/softV2oC/OjDgDhtmp79BdsQx4E6BVtkJ7KrfyFb5TaBVfgVaZUcalx8ZqAGROf1OGvB3BQPuIA24izWgueEuwoC7AAPuVjagybCbMOBuZQPutPNCDYis1x+kAf9QMOBOBwb80278Pf4G3yPQ1nuAB7GXbOu9Am29E2jrP9O4/AGZQhvwT/JTQfDNRoz/fgHWCaGLxHvANRG332P+yx66v6UN+LcDA+6zYfb7G2RfHAPuF2iV/cDO+odslX8EWuVvoFX2pXH5kYEaEJnTAdKABxQMuI804EHWgOaGBwkDHgQMeEjZgCbDIcKAh5QNuN/OCzUgsl7/kgb8V8GA+x0YMJJuL0qPHB7Q/EXYtjb/RrLXHpXOtfVR6eHbej/Q1pF0Ln9AptAGjKSHO4iJLi82E/oe8C/gICJ8kfw9Q8CfWsSKHjFePNoe0GPMn5Jtc0y6SpjAtjnWhinhbxvzH/xeLCHQQCWA03oc2UDHCTTQMenJN9Cx6Vx+ZKCnCJnT8emcF49Pl/fisemcF0umh7ih+WHUiyWTf5AppYCHwWYw90C9WCrkx1Qym71UOu5FZL1OADJEb94T0uW9WILkRST4PoENfqLd+KX9DV5aoK1LAw+iDNnWZQTaugTQ1iemc/kDMoX24onkpwL6e4asrRK58mhgTRHmSLxf7JXi9nvMJ9kDerK0F0924MWyNkyqv23KxvFiqkADpQI7K41soDSBBjoZaKCy6Vx+ZKBeROaUTnoxXcGLZUkvZrBeNDfMILyYAXgxU9mLJkMm4cVMZS+m2nmhXkTWK4v0YpaCF1MdeDHbbvwcf4PnCLR1DvAgcsm2zhVo61SgrbPTufwBmUJ7MTvkQUx0ebGZ0PeLJwFrhfBF8v0i4E8tYkWPGC/m2QOaL+3FfAdeLLBhCv1tUxDHi4UCDVQI7MAisoGKBBooH2iggnQuPzLQU4TMySO96Cl4sYD0YjnWi+aG5QgvlgNqqryyF02G8oQXyyt7sdDOC/Uisl6nkF48RcGLhQ68eKrd+BX8DV5BoK0rAA+iItnWFQXauhBo61PTufwBmUJ78dQj9H6RtVUiV+YBa4owR+L9Ys2I2+8xn2YP6OnSXjzdgRcr2TCV/W1TKY4XKws0UGVgZ51BNtAZAg10OtBAldK5/MhAvYjM6UzSi2cqeLES6cUqrBfNDasQXqwCVG9VZS+aDFUJL1ZV9mJlOy/Ui8h6nUV68SwFL1Z24MWz7cav5m/wagJtXQ14ENXJtq4u0NaVgbY+O53LH5AptBfPDnkQE11ebCb0/eJpwFohfJH8HrMSm6JHjAHPsYfuXGkDnuvAgDVsmJr+BqkRx4A1BVqlJrCrziNb5TyBVjkXaJUa6Vx+ZKAGROZ0PmnA8xUMWIM0YC3WgOaGtQgD1gIMWFvZgCZDbcKAtZUNWNPOCzUgsl4XkAa8QMGANR0Y8EK78ev4G7yOQFvXAR5EXbKt6wq0dU2grS9M5/IHZAptwAvJTwXBNxsx/jsHWCeELhLvAddG3H6P+SJ76OpJG7CeAwPWt2Ea+BukfhwDNhBolQbAzrqYbJWLBVqlHtAq9dO5/MhADYjM6RLSgJcoGLA+acCGrAHNDRsSBmwIGLCRsgFNhkaEARspG7CBnRdqQGS9LiUNeKmCARs4MOBlduM39jd4Y4G2bgw8iCZkWzcRaOsGQFtfls7lD8gU2oCXhTyIiS4vNhP6HvAiYK0Qvkj+niHgTy1iRY8YL15uD+gV0l68woEXm9owzfxt0zSOF5sJNFAzYAdeSTbQlQINdAXQQE3TufzIQE8RMqerSC9epeDFpqQXm7NeNDdsTnixOVBTLZS9aDK0ILzYQtmLzey8UC8i63U16cWrFbzYzIEXr7Ebv6W/wVsKtHVL4EG0Itu6lUBbNwPa+pp0Ln9AptBevIb8VEB/z5C1VSJXXg6sKcIcifeLvVPcfo/5WntAr5P24nUOvNjahmnjb5vWcbzYRqCB2gA763qyga4XaKDrgAZqnc7lRwbqRWRON5BevEHBi61JL7ZlvWhu2JbwYlugetspe9FkaEd4sZ2yF9vYeaFeRNbrRtKLNyp4sY0DL7a3G7+Dv8E7CLR1B+BBdCTbuqNAW7cB2rp9Opc/IFNoL7YPeRATXV5sJvT94rXAWiF8kXy/CPhTi1jRI8aLN9kDerO0F2924MVONkxnf9t0iuPFzgIN1BnYgbeQDXSLQAPdDDRQp3QuPzLQU4TM6VbSi7cqeLET6cUurBfNDbsQXuwC1FRXZS+aDF0JL3ZV9mJnOy/Ui8h63UZ68TYFL3Z24MXb7cbv5m/wbgJt3Q14EN3Jtu4u0Nadgba+PZ3LH5AptBdvP0LvF1lbJXLlTcCaIsyReL94XsTt95jvsAf0Tmkv3unAiz1smJ7+tukRx4s9BRqoJ7Cz7iIb6C6BBroTaKAe6Vx+ZKBeROZ0N+nFuxW82IP0Yi/Wi+aGvQgv9gKqt7eyF02G3oQXeyt7saedF+pFZL3uIb14j4IXezrw4r124/fxN3gfgbbuAzyIvmRb9xVo655AW9+bzuUPyBTai/eGPIiJLi82E/p+8Q5grRC+SH6PWYlN0SPGgPfZQ3e/tAHvd2DAfjZMf3+D9ItjwP4CrdIf2FUPkK3ygECr3A+0Sr90Lj8yUAMic3qQNOCDCgbsRxpwAGtAc8MBhAEHAAYcqGxAk2EgYcCBygbsb+eFGhBZr4dIAz6kYMD+Dgz4sN34g/wNPkigrQcBD2Iw2daDBdq6P9DWD6dz+QMyhTbgw+SnguCbjRj/3QesE0IXifeAX0Xcfo/5EXvoHpU24KMODDjEhhnqb5AhcQw4VKBVhgI76zGyVR4TaJVHgVYZks7lRwZqQGROj5MGfFzBgENIAw5jDWhuOIww4DDAgMOVDWgyDCcMOFzZgEPtvFADIuv1BGnAJxQMONSBAZ+0G3+Ev8FHCLT1COBBjCTbeqRAWw8F2vrJdC5/QKbQBnwy5EFMdHmxmdD3gI8Aa4XwRfL3DAF/ahEresR48Sl7QJ+W9uLTDrw4yoYZ7W+bUXG8OFqggUYDO/AZsoGeEWigp4EGGpXO5UcGeoqQOT1LevFZBS+OIr04hvWiueEYwotjgJoaq+xFk2Es4cWxyl4cbeeFehFZr+dILz6n4MXRDrw4zm788f4GHy/Q1uOBBzGBbOsJAm09Gmjrcelc/oBMob04jvxUQH/PkLVVIlc+BawpwhyJ94v3pLj9HvPz9oC+IO3FFxx4caINM8nfNhPjeHGSQANNAnbWi2QDvSjQQC8ADTQxncuPDNSLyJxeIr34koIXJ5JenMx60dxwMuHFyUD1TlH2oskwhfDiFGUvTrLzQr2IrNfLpBdfVvDiJAdefMVu/Kn+Bp8q0NZTgQcxjWzraQJtPQlo61fSufwBmUJ78ZWQBzHR5cVmQt8vPg+sFcIXyfeLgD+1iBU9Yrz4qj2gr0l78TUHXpxuw8zwt830OF6cIdBAM4Ad+DrZQK8LNNBrQANNT+fyIwM9Rcic3iC9+IaCF6eTXpzJetHccCbhxZlATc1S9qLJMIvw4ixlL86w80K9iKzXm6QX31Tw4gwHXnzLbvzZ/gafLdDWs4EHMYds6zkCbT0DaOu30rn8AZlCe/GtI/R+kbVVIle+CqwpwhyJ94vnR9x+j/lte0DfkfbiOw68ONeGmedvm7lxvDhPoIHmATvrXbKB3hVooHeABpqbzuVHBupFZE7vkV58T8GLc0kvzme9aG44n/DifKB6Fyh70WRYQHhxgbIX59l5oV5E1ut90ovvK3hxngMvLrQbf5G/wRcJtPUi4EEsJtt6sUBbzwPaemE6lz8gU2gvLgx5EBNdXmwm9P3i28BaIXyR/B6zEpuiR4wBP7CH7kNpA37owIBLbJil/gZZEseASwVaZSmwqz4iW+UjgVb5EGiVJelcfmSgBkTm9DFpwI8VDLiENOAy1oDmhssIAy4DDLhc2YAmw3LCgMuVDbjUzgs1ILJen5AG/ETBgEsdGPBTu/FX+Bt8hUBbrwAexEqyrVcKtPVSoK0/TefyB2QKbcBPyU8FwTcbMf77AFgnhC4S7wG/jrj9HvNn9tB9Lm3Azx0YcJUNs9rfIKviGHC1QKusBnbWF2SrfCHQKp8DrbIqncuPDNSAyJy+JA34pYIBV5EGXMMa0NxwDWHANYAB1yob0GRYSxhwrbIBV9t5oQZE1usr0oBfKRhwtQMDfm03/jp/g68TaOt1wINYT7b1eoG2Xg209dfpXP6ATKEN+HXIg5jo8mIzoe8BPwPWCuGL5O8ZAv7UIlb0iPHiN/aAfivtxW8deHGDDbPR3zYb4nhxo0ADbQR24HdkA30n0EDfAg20IZ3Ljwz0FCFz+p704vcKXtxAenET60Vzw02EFzcBNbVZ2Ysmw2bCi5uVvbjRzgv1IrJeP5Be/EHBixsdePFHu/G3+Bt8i0BbbwEexFayrbcKtPVGoK1/TOfyB2QK7cUfyU8F9PcMWVslcuU3wJoizJF4v3hvitvvMf9kD+jP0l782YEXt9kw2/1tsy2OF7cLNNB2YGf9QjbQLwIN9DPQQNvSufzIQL2IzOlX0ou/KnhxG+nFHawXzQ13EF7cAVTvTmUvmgw7CS/uVPbidjsv1IvIev1GevE3BS9ud+DF3+3G3+Vv8F0Cbb0LeBC7ybbeLdDW24G2/j2dyx+QKbQXfw95EBNdXmwm9P3iT8BaIXyRfL8I+FOLWNEjxot/2AP6p7QX/3TgxT02zF5/2+yJ48W9Ag20F9iBf5EN9JdAA/0JNNCedC4/MtBThMzpb9KLfyt4cQ/pxX2sF80N9xFe3AfU1H5lL5oM+wkv7lf24l47L9SLyHr9Q3rxHwUv7nXgxQN24x/0N/hBgbY+CDyIQ2RbHxJo671AWx9I5/IHZArtxQNH6P0ia6tErvwDWFOEORLvF2tF3H6P+d/iT6aMiGzbmH8wyWvjDu9//bu+cdjiZ9i/y4gc3jbmP/i9aC4K20BHZSR/7dEZXAMdnRG+gSIZyTdQSgaXHxmoF5E5HZPBefGYDHkvpmRwXjw2I8QNzQ+jXjw2+QeZUgJ4GGwGcw/UiyXAzYjO6yg7L9SLyHodB2SI3rzHZch78ajkCkvUi8fbjV/S3+AlBdq6JPAgSpFtXUqgrY8C2vr4DC5/QKbQXjw+5EFMdHmxmdD3i/8i/0cXyCD5PWYlNkWPGAOeYA/didIGPNGBAUvbMGX8DVI6jgHLCLRKGeAEnkS2ykkCrXIi0CqlM7j8yEANiMzpZNKAJysYsDRpwLKsAc0NyxIGLAsYMFXZgCZDKmHAVGUDlrHzQg2IrFcaacA0BQOWcWDAdLvxM/wNniHQ1hnAg8gk2zpToK3LAG2dnsHlD8gU2oDp5KeC4JuNGP+dAKwTQheJ94DrIm6/x5xlD122tAGzHRgwx4bJ9TdIThwD5gq0Si6ws/LIVskTaJVsoFVyMrj8yEANiMwpnzRgvoIBc0gDFrAGNDcsIAxYABiwUNmAJkMhYcBCZQPm2nmhBkTWq4g0YJGCAXMdGNCzG7+cv8HLCbR1OeBBlCfburxAW+cCbe1lcPkDMoU2oBfyICa6vNhM6HvALGCtEL5I/p4h4E8tYkWPGC+eYg/oqdJePNWBFyvYMBX9bVMhjhcrCjRQRWAHnkY20GkCDXQq0EAVMrj8yEBPETKn00kvnq7gxQqkFyuxXjQ3rER4sRJQU5WVvWgyVCa8WFnZixXtvFAvIut1BunFMxS8WNGBF8+0G7+Kv8GrCLR1FeBBVCXbuqpAW1cE2vrMDC5/QKbQXjyT/FRAf8+QtVUiV54CrCnCHIn3i31S3H6P+Sx7QM+W9uLZDrxYzYap7m+banG8WF2ggaoDO+scsoHOEWigs4EGqpbB5UcG6kVkTueSXjxXwYvVSC/WYL1obliD8GINoHprKnvRZKhJeLGmsher23mhXkTW6zzSi+cpeLG6Ay+ebzd+LX+D1xJo61rAg6hNtnVtgbauDrT1+Rlc/oBMob14fsiDmOjyYjOh7xfPAtYK4Yvk+0XAn1rEih4xXrzAHtALpb14oQMv1rFh6vrbpk4cL9YVaKC6wA68iGygiwQa6EKggepkcPmRgZ4iZE71SC/WU/BiHdKL9VkvmhvWJ7xYH6ipBspeNBkaEF5soOzFunZeqBeR9bqY9OLFCl6s68CLl9iN39Df4A0F2roh8CAakW3dSKCt6wJtfUkGlz8gU2gvXnKE3i+ytkrkyguANUWYI/F+sXbE7feYL7UH9DJpL17mwIuNbZgm/rZpHMeLTQQaqAmwsy4nG+hygQa6DGigxhlcfmSgXkTmdAXpxSsUvNiY9GJT1ovmhk0JLzYFqreZshdNhmaEF5spe7GJnRfqRWS9riS9eKWCF5s48OJVduM39zd4c4G2bg48iBZkW7cQaOsmQFtflcHlD8gU2otXhTyIiS4vNhP6fvFSYK0Qvkh+j1mJTdEjxoBX20N3jbQBr3FgwJY2TCt/g7SMY8BWAq3SCthV15Ktcq1Aq1wDtErLDC4/MlADInO6jjTgdQoGbEkasDVrQHPD1oQBWwMGbKNsQJOhDWHANsoGbGXnhRoQWa/rSQNer2DAVg4MeIPd+G39Dd5WoK3bAg+iHdnW7QTauhXQ1jdkcPkDMoU24A3kp4Lgm40Y/10NrBNCF4n3gOsjbr/HfKM9dO2lDdjegQE72DAd/Q3SIY4BOwq0SkdgZ91EtspNAq3SHmiVDhlcfmSgBkTmdDNpwJsVDNiBNGAn1oDmhp0IA3YCDNhZ2YAmQ2fCgJ2VDdjRzgs1ILJet5AGvEXBgB0dGPBWu/G7+Bu8i0BbdwEeRFeyrbsKtHVHoK1vzeDyB2QKbcBbQx7ERJcXmwl9D3gjsFYIXyR/zxDwpxaxokeMF2+zB/R2aS/e7sCL3WyY7v626RbHi90FGqg7sAPvIBvoDoEGuh1ooG4ZXH5koKcImdOdpBfvVPBiN9KLPVgvmhv2ILzYA6ipnspeNBl6El7sqezF7nZeqBeR9bqL9OJdCl7s7sCLd9uN38vf4L0E2roX8CB6k23dW6CtuwNtfXcGlz8gU2gv3k1+KqC/Z8jaKpErbwPWFGGOxPvFviluv8d8jz2g90p78V4HXuxjw/T1t02fOF7sK9BAfYGddR/ZQPcJNNC9QAP1yeDyIwP1IjKn+0kv3q/gxT6kF/uxXjQ37Ed4sR9Qvf2Vvfh/h5XwYn9lL/a180K9iKzXA6QXH1DwYl8HXnzQbvwB/gYfINDWA4AHMZBs64ECbd0XaOsHM7j8AZlCe/HBkAcx0eXFZkLfL94DrBXCF8n3i4A/tYgVPWK8+JA9oA9Le/FhB14cZMMM9rfNoDheHCzQQIOBHfgI2UCPCDTQw0ADDcrg8iMDPUXInB4lvfioghcHkV4cwnrR3HAI4cUhQE0NVfaiyTCU8OJQZS8OtvNCvYis12OkFx9T8OJgB1583G78Yf4GHybQ1sOABzGcbOvhAm09GGjrxzO4/AGZQnvx8SP0fpG1VSJXPgSsKcIcifeLF0Tcfo/5CXtAn5T24pMOvDjChhnpb5sRcbw4UqCBRgI76ymygZ4SaKAngQYakcHlRwbqRWROT5NefFrBiyNIL45ivWhuOIrw4iigekcre9FkGE14cbSyF0faeaFeRNbrGdKLzyh4caQDLz5rN/4Yf4OPEWjrMcCDGEu29ViBth4JtPWzGVz+gEyhvfhsyIOY6PJiM6HvF58A1grhi+T3mJXYFD1iDPicPXTjpA04zoEBx9swE/wNMj6OAScItMoEYFc9T7bK8wKtMg5olfEZXH5koAZE5vQCacAXFAw4njTgRNaA5oYTCQNOBAw4SdmAJsMkwoCTlA04wc4LNSCyXi+SBnxRwYATHBjwJbvxJ/sbfLJAW08GHsQUsq2nCLT1BKCtX8rg8gdkCm3Al8hPBcE3GzH+ew5YJ4QuEu8Bv4m4/R7zy/bQvSJtwFccGHCqDTPN3yBT4xhwmkCrTAN21qtkq7wq0CqvAK0yNYPLjwzUgMicXiMN+JqCAaeSBpzOGtDccDphwOmAAWcoG9BkmEEYcIayAafZeaEGRNbrddKArysYcJoDA75hN/5Mf4PPFGjrmcCDmEW29SyBtp4GtPUbGVz+gEyhDfhGyIOY6PJiM6HvAV8G1grhi+TvGQL+1CJW9Ijx4pv2gL4l7cW3HHhxtg0zx982s+N4cY5AA80BduDbZAO9LdBAbwENNDuDy48M9BQhc3qH9OI7Cl6cTXpxLutFc8O5hBfnAjU1T9mLJsM8wovzlL04x84L9SKyXu+SXnxXwYtzHHjxPbvx5/sbfL5AW88HHsQCsq0XCLT1HKCt38vg8gdkCu3F98hPBfT3DFlbJXLlm8CaIsyReL94X4rb7zG/bw/oQmkvLnTgxUU2zGJ/2yyK48XFAg20GNhZH5AN9IFAAy0EGmhRBpcfGagXkTl9SHrxQwUvLiK9uIT1ornhEsKLS4DqXarsRZNhKeHFpcpeXGznhXoRWa+PSC9+pODFxQ68+LHd+Mv8Db5MoK2XAQ9iOdnWywXaejHQ1h9ncPkDMoX24schD2Kiy4vNhL5ffB9YK4Qvku8XAX9qESt6xHjxE3tAP5X24qcOvLjChlnpb5sVcby4UqCBVgI78DOygT4TaKBPgQZakcHlRwZ6ipA5fU568XMFL64gvbiK9aK54SrCi6uAmlqt7EWTYTXhxdXKXlxp54V6EVmvL0gvfqHgxZUOvPil3fhr/A2+RqCt1wAPYi3Z1msF2nol0NZfZnD5AzKF9uKXR+j9ImurRK78BFhThDkS7xcvjLj9HvNX9oB+Le3Frx14cZ0Ns97fNuvieHG9QAOtB3bWN2QDfSPQQF8DDbQug8uPDNSLyJy+Jb34rYIX15Fe3MB60dxwA+HFDUD1blT2osmwkfDiRmUvrrfzQr2IrNd3pBe/U/Diegde/N5u/E3+Bt8k0NabgAexmWzrzQJtvR5o6+8zuPwBmUJ78fuQBzHR5cVmQt8vfgWsFcIXye8xK7EpesQY8Ad76H6UNuCPDgy4xYbZ6m+QLXEMuFWgVbYCu+onslV+EmiVH4FW2ZLB5UcGakBkTj+TBvxZwYBbSANuYw1obriNMOA2wIDblQ1oMmwnDLhd2YBb7bxQAyLr9QtpwF8UDLjVgQF/tRt/h7/Bdwi09Q7gQewk23qnQFtvBdr61wwuf0Cm0Ab8lfxUEHyzEeO/H4B1Qugi8R7w24jb7zH/Zg/d79IG/N2BAXfZMLv9DbIrjgF3C7TKbmBn/UG2yh8CrfI70Cq7Mrj8yEANiMzpT9KAfyoYcBdpwD2sAc0N9xAG3AMYcK+yAU2GvYQB9yobcLedF2pAZL3+Ig34l4IBdzsw4N924+/zN/g+gbbeBzyI/WRb7xdo691AW/+dweUPyBTagH+HPIiJLi82E/oe8DdgrRC+SP6eIeBPLWJFjxgv/mMP6AFpLx5w4MWDNswhf9scjOPFQwINdAjYgf+SDfSvQAMdABroYAaXHxnoKULmFMnkvGh+TtqLB0kvpmSGuKH5YdSLKZnJP4yjMnW9aDKYe6BePCoT24zovA7ZeaFeRNbraCBD9OY1PyftxUMOvHiM3fjHZkYOD3hsZvi2PhZ4ECUyubYukRm+rQ8BbX1MJpc/IFNoLx4DHsTigf6eIWurRK78B/i0ORDSleihvD/F7feYj7MH9Hjzp2TbHJ+pEiawbUraMKX8bVMyM9aLpQQaqBRwWk8gG+gEgQY6PjP5BiqZyeVHBupFZE4nkl48UcGLJTM5L5ZmvWhuWJrwYmnAi2WUvWgylCG8WEbZi6XsvFAvIut1EunFkxS8WIrkRST4PoENfrLd+GX9DV5WoK3LAg8ilWzrVIG2LgW09cmZXP6ATKG9eHLIg5jo8mIzoe8XjwPWCuGL5PtFwJ9axIoeMV5Mswc0XdqL6Q68mGHDZPrbJiOOFzMFGigT2IFZZANlCTRQOtBAGZlcfmSgpwiZUzbpxWwFL2aQXsxhvWhumEN4MQfwYq6yF02GXMKLucpezLTzQr2IrFce6cU8BS9mOvBivt34Bf4GLxBo6wLgQRSSbV0o0NaZQFvnZ3L5AzKF9mL+EXq/yNoqkSvTgDVFmCPxfrFOxO33mIvsAfWkveg58GI5G6a8v23KxfFieYEGKg/srFPIBjpFoIE8oIHKZXL5kYF6EZnTqaQXT1XwYjnSixVYL5obViC8WAHwYkVlL5oMFQkvVlT2Ynk7L9SLyHqdRnrxNAUvlnfgxdPtxq/kb/BKAm1dCXgQlcm2rizQ1uWBtj49k8sfkCm0F08PeRATXV5sJvT9YhGwVghfJL/HrMSm6BFjwDPsoTtT2oBnOjBgFRumqr9BqsQxYFWBVqkK7KqzyFY5S6BVzgRapUomlx8ZqAGROZ1NGvBsBQNWIQ1YjTWguWE1woDVAANWVzagyVCdMGB1ZQNWtfNCDYis1zmkAc9RMGBVBwY81278Gv4GryHQ1jWAB1GTbOuaAm1dFWjrczO5/AGZQhvwXPJTQfDNRoz/zgDWCaGLxHvADRG332M+zx6686UNeL4DA9ayYWr7G6RWHAPWFmiV2sDOuoBslQsEWuV8oFVqZXL5kYEaEJnThaQBL1QwYC3SgHVYA5ob1iEMWAcwYF1lA5oMdQkD1lU2YG07L9SAyHpdRBrwIgUD1nZgwHp249f3N3h9gbauDzyIBmRbNxBo69pAW9fL5PIHZAptwHohD2Kiy4vNhL4HPA9YK4Qvkr9nCPhTi1jRI8aLF9sDeom0Fy9x4MWGNkwjf9s0jOPFRgIN1AjYgZeSDXSpQANdAjRQw0wuPzLQU4TM6TLSi5cpeLEh6cXGrBfNDRsTXmwM1FQTZS+aDE0ILzZR9mIjOy/Ui8h6XU568XIFLzZy4MUr7MZv6m/wpgJt3RR4EM3Itm4m0NaNgLa+IpPLH5AptBevID8V0N8zZG2VyJUXA2uKMEfi/WK/FLffY77SHtCrpL14lQMvNrdhWvjbpnkcL7YQaKAWwM66mmygqwUa6CqggZpncvmRgXoRmdM1pBevUfBic9KLLVkvmhu2JLzYEqjeVspeNBlaEV5spezFFnZeqBeR9bqW9OK1Cl5s4cCL19mN39rf4K0F2ro18CDakG3dRqCtWwBtfV0mlz8gU2gvXhfyICa6vNhM6PvFK4G1Qvgi+X4R8KcWsaJHjBevtwf0Bmkv3uDAi21tmHb+tmkbx4vtBBqoHbADbyQb6EaBBroBaKC2mVx+ZKCnCJlTe9KL7RW82Jb0YgfWi+aGHQgvdgBqqqOyF02GjoQXOyp7sZ2dF+pFZL1uIr14k4IX2znw4s1243fyN3gngbbuBDyIzmRbdxZo63ZAW9+cyeUPyBTaizcfofeLrK0SufJ6YE0R5ki8X6wbcfs95lvsAb1V2ou3OvBiFxumq79tusTxYleBBuoK7KzbyAa6TaCBbgUaqEsmlx8ZqBeROd1OevF2BS92Ib3YjfWiuWE3wovdgOrtruxFk6E74cXuyl7saueFehFZrztIL96h4MWuDrx4p934PfwN3kOgrXsAD6In2dY9Bdq6K9DWd2Zy+QMyhfbinSEPYqLLi82Evl+8BVgrhC+S32NWYlP0iDHgXfbQ3S1twLsdGLCXDdPb3yC94hiwt0Cr9AZ21T1kq9wj0Cp3A63SK5PLjwzUgMic7iUNeK+CAXuRBuzDGtDcsA9hwD6AAfsqG9Bk6EsYsK+yAXvbeaEGRNbrPtKA9ykYsLcDA95vN34/f4P3E2jrfsCD6E+2dX+Btu4NtPX9mVz+gEyhDXg/+akg+GYjxn93AeuE0EXiPeDGiNvvMT9gD92D0gZ80IEBB9gwA/0NMiCOAQcKtMpAYGc9RLbKQwKt8iDQKgMyufzIQA2IzOlh0oAPKxhwAGnAQawBzQ0HEQYcBBhwsLIBTYbBhAEHKxtwoJ0XakBkvR4hDfiIggEHOjDgo3bjD/E3+BCBth4CPIihZFsPFWjrgUBbP5rJ5Q/IFNqAj4Y8iIkuLzYT+h7wAWCtEL5I/p4h4E8tYkWPGC8+Zg/o49JefNyBF4fZMMP9bTMsjheHCzTQcGAHPkE20BMCDfQ40EDDMrn8yEBPETKnJ0kvPqngxWGkF0ewXjQ3HEF4cQRQUyOVvWgyjCS8OFLZi8PtvFAvIuv1FOnFpxS8ONyBF5+2G3+Uv8FHCbT1KOBBjCbberRAWw8H2vrpTC5/QKbQXnya/FRAf8+QtVUiVz4GrCnCHIn3i/1T3H6P+Rl7QJ+V9uKzDrw4xoYZ62+bMXG8OFaggcYCO+s5soGeE2igZ4EGGpPJ5UcG6kVkTuNIL45T8OIY0ovjWS+aG44nvDgeqN4Jyl40GSYQXpyg7MWxdl6oF5H1ep704vMKXhzrwIsv2I0/0d/gEwXaeiLwICaRbT1JoK3HAm39QiaXPyBTaC++EPIgJrq82Ezo+8VngLVC+CL5fhHwpxaxokeMF1+0B/QlaS++5MCLk22YKf62mRzHi1MEGmgKsANfJhvoZYEGeglooMmZXH5koKcImdMrpBdfUfDiZNKLU1kvmhtOJbw4FaipacpeNBmmEV6cpuzFKXZeqBeR9XqV9OKrCl6c4sCLr9mNP93f4NMF2no68CBmkG09Q6CtpwBt/Vomlz8gU2gvvnaE3i+ytkrkyheBNUWYI/F+8aKI2+8xv24P6BvSXnzDgRdn2jCz/G0zM44XZwk00CxgZ71JNtCbAg30BtBAMzO5/MhAvYjM6S3Si28peHEm6cXZrBfNDWcTXpwNVO8cZS+aDHMIL85R9uIsOy/Ui8h6vU168W0FL85y4MV37Maf62/wuQJtPRd4EPPItp4n0NazgLZ+J5PLH5AptBffCXkQE11ebCb0/eLrwFohfJH8HrMSm6JHjAHftYfuPWkDvufAgPNtmAX+Bpkfx4ALBFplAbCr3idb5X2BVnkPaJX5mVx+ZKAGROa0kDTgQgUDzicNuIg1oLnhIsKAiwADLlY2oMmwmDDgYmUDLrDzQg2IrNcHpAE/UDDgAgcG/NBu/CX+Bl8i0NZLgAexlGzrpQJtvQBo6w8zufwBmUIb8EPyU0HwzUaM/94F1gmhi8R7wO8ibr/H/JE9dB9LG/BjBwZcZsMs9zfIsjgGXC7QKsuBnfUJ2SqfCLTKx0CrLMvk8iMDNSAyp09JA36qYMBlpAFXsAY0N1xBGHAFYMCVygY0GVYSBlypbMDldl6oAZH1+ow04GcKBlzuwICf242/yt/gqwTaehXwIFaTbb1aoK2XA239eSaXPyBTaAN+HvIgJrq82Ezoe8CPgLVC+CL5e4aAP7WIFT1ivPiFPaBfSnvxSwdeXGPDrPW3zZo4Xlwr0EBrgR34FdlAXwk00JdAA63J5PIjAz1FyJy+Jr34tYIX15BeXMd60dxwHeHFdUBNrVf2osmwnvDiemUvrrXzQr2IrNc3pBe/UfDiWgde/NZu/A3+Bt8g0NYbgAexkWzrjQJtvRZo628zufwBmUJ78VvyUwH9PUPWVolc+QWwpghzJN4vPpDi9nvM39kD+r20F7934MVNNsxmf9tsiuPFzQINtBnYWT+QDfSDQAN9DzTQpkwuPzJQLyJz+pH04o8KXtxEenEL60Vzwy2EF7cA1btV2Ysmw1bCi1uVvbjZzgv1IrJeP5Fe/EnBi5sdePFnu/G3+Rt8m0BbbwMexHayrbcLtPVmoK1/zuTyB2QK7cWfQx7ERJcXmwl9v/gdsFYIXyTfLwL+1CJW9Ijx4i/2gP4q7cVfHXhxhw2z0982O+J4cadAA+0EduBvZAP9JtBAvwINtCOTy48M9BQhc/qd9OLvCl7cQXpxF+tFc8NdhBd3ATW1W9mLJsNuwou7lb24084L9SKyXn+QXvxDwYs7HXjxT7vx9/gbfI9AW+8BHsResq33CrT1TqCt/8zk8gdkCu3FP4/Q+0XWVolc+QuwpghzJN4v1ou4/R7zX/aA/i3txb8deHGfDbPf3zb74nhxv0AD7Qd21j9kA/0j0EB/Aw20L5PLjwzUi8icDpBePKDgxX2kFw+yXjQ3PEh48SBQvYeUvWgyHCK8eEjZi/vtvFAvIuv1L+nFfxW8uN+BFyNZ9qKsyOEBzV+EbWvzbyR77VFZXFsflRW+rfcDbR3J4vIHZArtxUhWuIOY6PJ6Ee57zH8BBxHhi+T3mJXYFD1iDHi0PXTHmD8lG+SYLJUwgQ1yrA1Twt8g5j/4DVhCoFVKACfwOLJVjhNolWOykm+VY7O4/MhADYjM6fgszoDHZ8kb8NgszoAls0Lc0PwwasCSyT/IlFLAw2AzmHugBiwV8qMnmc1eKgs3ILJeJwAZojfvCVnyBixBkiESfJ/ABj/RbvzS/gYvLdDWpYEHUYZs6zICbV0CaOsTs7j8AZlCG/BE8lNB8M1GjP+OBtYJoYvEe8DvI26/x3ySPXQnSxvwZAcGLGvDpPobpGwcA6YKtEoqsLPSyFZJE2iVk4FWKZvF5UcGakBkTumkAdMVDFiWNGAGa0BzwwzCgBmAATOVDWgyZBIGzFQ2YKqdF2pAZL2ySANmKRgw1YEBs+3Gz/E3eI5AW+cADyKXbOtcgbZOBdo6O4vLH5AptAGzQx7ERJd/H+G+x3wSsFYIXyR/zxDwpxaxokeMF/PsAc2X9mK+Ay8W2DCF/rYpiOPFQoEGKgR2YBHZQEUCDZQPNFBBFpcfGegpQubkkV70FLxYQHqxHOtFc8NyhBfLATVVXtmLJkN5wovllb1YaOeFehFZr1NIL56i4MVCB1481W78Cv4GryDQ1hWAB1GRbOuKAm1dCLT1qVlc/oBMob14KvmpgP6eIWurRK7MA9YUYY7E+8UHU9x+j/k0e0BPl/bi6Q68WMmGqexvm0pxvFhZoIEqAzvrDLKBzhBooNOBBqqUxeVHBupFZE5nkl48U8GLlUgvVmG9aG5YhfBiFaB6qyp70WSoSnixqrIXK9t5oV5E1uss0otnKXixsgMvnm03fjV/g1cTaOtqwIOoTrZ1dYG2rgy09dlZXP6ATKG9eHbIg5jo8mIzoe8XTwPWCuGL5PtFwJ9axIoeMV48xx7Qc6W9eK4DL9awYWr626ZGHC/WFGigmsAOPI9soPMEGuhcoIFqZHH5kYGeImRO55NePF/BizVIL9ZivWhuWIvwYi2gpmore9FkqE14sbayF2vaeaFeRNbrAtKLFyh4saYDL15oN34df4PXEWjrOsCDqEu2dV2Btq4JtPWFWVz+gEyhvXjhEXq/yNoqkSvPAdYUYY7E+8X6EbffY77IHtB60l6s58CL9W2YBv62qR/Hiw0EGqgBsLMuJhvoYoEGqgc0UP0sLj8yUC8ic7qE9OIlCl6sT3qxIetFc8OGhBcbAtXbSNmLJkMjwouNlL3YwM4L9SKyXpeSXrxUwYsNHHjxMrvxG/sbvLFAWzcGHkQTsq2bCLR1A6CtL8vi8gdkCu3Fy0IexESXF5sJfb94EbBWCF8kv8esxKboEWPAy+2hu0LagFc4MGBTG6aZv0GaxjFgM4FWaQbsqivJVrlSoFWuAFqlaRaXHxmoAZE5XUUa8CoFAzYlDdicNaC5YXPCgM0BA7ZQNqDJ0IIwYAtlAzaz80INiKzX1aQBr1YwYDMHBrzGbvyW/gZvKdDWLYEH0Yps61YCbd0MaOtrsrj8AZlCG/Aa8lNB8M1GjP8uB9YJoYvEe8BNEbffY77WHrrrpA14nQMDtrZh2vgbpHUcA7YRaJU2wM66nmyV6wVa5TqgVVpncfmRgRoQmdMNpAFvUDBga9KAbVkDmhu2JQzYFjBgO2UDmgztCAO2UzZgGzsv1IDIet1IGvBGBQO2cWDA9nbjd/A3eAeBtu4APIiOZFt3FGjrNkBbt8/i8gdkCm3A9iEPYqLLi82Evge8FlgrhC+Sv2cI+FOLWNEjxos32QN6s7QXb3bgxU42TGd/23SK48XOAg3UGdiBt5ANdItAA90MNFCnLC4/MtBThMzpVtKLtyp4sRPpxS6sF80NuxBe7ALUVFdlL5oMXQkvdlX2Ymc7L9SLyHrdRnrxNgUvdnbgxdvtxu/mb/BuAm3dDXgQ3cm27i7Q1p2Btr49i8sfkCm0F28nPxXQ3zNkbZXIlTcBa4owR+L94oAUt99jvsMe0DulvXinAy/2sGF6+tumRxwv9hRooJ7AzrqLbKC7BBroTqCBemRx+ZGBehGZ092kF+9W8GIP0ou9WC+aG/YivNgLqN7eyl40GXoTXuyt7MWedl6oF5H1uof04j0KXuzpwIv32o3fx9/gfQTaug/wIPqSbd1XoK17Am19bxaXPyBTaC/eG/IgJrq82Ezo+8U7gLVC+CL5fhHwpxaxokeMF++zB/R+aS/e78CL/WyY/v626RfHi/0FGqg/sAMfIBvoAYEGuh9ooH5ZXH5koKcImdODpBcfVPBiP9KLA1gvmhsOILw4AKipgcpeNBkGEl4cqOzF/nZeqBeR9XqI9OJDCl7s78CLD9uNP8jf4IME2noQ8CAGk209WKCt+wNt/XAWlz8gU2gvPnyE3i+ytkrkyvuANUWYI/F+sUHE7feYH7EH9FFpLz7qwItDbJih/rYZEseLQwUaaCiwsx4jG+gxgQZ6FGigIVlcfmSgXkTm9DjpxccVvDiE9OIw1ovmhsMILw4Dqne4shdNhuGEF4cre3GonRfqRWS9niC9+ISCF4c68OKTduOP8Df4CIG2HgE8iJFkW48UaOuhQFs/mcXlD8gU2otPhjyIiS4vNhP6fvERYK0Qvkh+j1mJTdEjxoBP2UP3tLQBn3ZgwFE2zGh/g4yKY8DRAq0yGthVz5Ct8oxAqzwNtMqoLC4/MlADInN6ljTgswoGHEUacAxrQHPDMYQBxwAGHKtsQJNhLGHAscoGHG3nhRoQWa/nSAM+p2DA0Q4MOM5u/PH+Bh8v0NbjgQcxgWzrCQJtPRpo63FZXP6ATKENOI78VBB8sxHjv6eAdULoIvEecHPE7feYn7eH7gVpA77gwIATbZhJ/gaZGMeAkwRaZRKws14kW+VFgVZ5AWiViVlcfmSgBkTm9BJpwJcUDDiRNOBk1oDmhpMJA04GDDhF2YAmwxTCgFOUDTjJzgs1ILJeL5MGfFnBgJMcGPAVu/Gn+ht8qkBbTwUexDSyracJtPUkoK1fyeLyB2QKbcBXQh7ERJcXmwl9D/g8sFYIXyR/zxDwpxaxokeMF1+1B/Q1aS++5sCL022YGf62mR7HizMEGmgGsANfJxvodYEGeg1ooOlZXH5koKcImdMbpBffUPDidNKLM1kvmhvOJLw4E6ipWcpeNBlmEV6cpezFGXZeqBeR9XqT9OKbCl6c4cCLb9mNP9vf4LMF2no28CDmkG09R6CtZwBt/VYWlz8gU2gvvkV+KqC/Z8jaKpErXwXWFGGOxPvFgSluv8f8tj2g70h78R0HXpxrw8zzt83cOF6cJ9BA84Cd9S7ZQO8KNNA7QAPNzeLyIwP1IjKn90gvvqfgxbmkF+ezXjQ3nE94cT5QvQuUvWgyLCC8uEDZi/PsvFAvIuv1PunF9xW8OM+BFxfajb/I3+CLBNp6EfAgFpNtvVigrecBbb0wi8sfkCm0FxeGPIiJLi82E/p+8W1grRC+SL5fBPypRazoEePFD+wB/VDaix868OISG2apv22WxPHiUoEGWgrswI/IBvpIoIE+BBpoSRaXHxnoKULm9DHpxY8VvLiE9OIy1ovmhssILy4Damq5shdNhuWEF5cre3GpnRfqRWS9PiG9+ImCF5c68OKnduOv8Df4CoG2XgE8iJVkW68UaOulQFt/msXlD8gU2oufHqH3i6ytErnyA2BNEeZIvF+8OOL2e8yf2QP6ubQXP3fgxVU2zGp/26yK48XVAg20GthZX5AN9IVAA30ONNCqLC4/MlAvInP6kvTilwpeXEV6cQ3rRXPDNYQX1wDVu1bZiybDWsKLa5W9uNrOC/Uisl5fkV78SsGLqx148Wu78df5G3ydQFuvAx7EerKt1wu09Wqgrb/O4vIHZArtxa9DHsRElxebCX2/+BmwVghfJL/HrMSm6BFjwG/softW2oDfOjDgBhtmo79BNsQx4EaBVtkI7KrvyFb5TqBVvgVaZUMWlx8ZqAGROX1PGvB7BQNuIA24iTWgueEmwoCbAANuVjagybCZMOBmZQNutPNCDYis1w+kAX9QMOBGBwb80W78Lf4G3yLQ1luAB7GVbOutAm29EWjrH7O4/AGZQhvwR/JTQfDNRoz/vgHWCaGLxHvAHyJuv8f8kz10P0sb8GcHBtxmw2z3N8i2OAbcLtAq24Gd9QvZKr8ItMrPQKtsy+LyIwM1IDKnX0kD/qpgwG2kAXewBjQ33EEYcAdgwJ3KBjQZdhIG3KlswO12XqgBkfX6jTTgbwoG3O7AgL/bjb/L3+C7BNp6F/AgdpNtvVugrbcDbf17Fpc/IFNoA/4e8iAmurzYTOh7wJ+AtUL4Ivl7hoA/tYgVPWK8+Ic9oH9Ke/FPB17cY8Ps9bfNnjhe3CvQQHuBHfgX2UB/CTTQn0AD7cni8iMDPUXInP4mvfi3ghf3kF7cx3rR3HAf4cV9QE3tV/aiybCf8OJ+ZS/utfNCvYis1z+kF/9R8OJeB148YDf+QX+DHxRo64PAgzhEtvUhgbbeC7T1gSwuf0Cm0F48QH4qoL9nyNoqkSv/ANYUYY7E+8WHUtx+j/nf4k+m7Ihs25h/MMlr4w7vf/27vnHY4mfbv8uOHN425j/4vWguCttAR2Unf+3R2VwDHZ0dvoEi2ck3UEo2lx8ZqBeROR2TzXnxmGx5L6Zkc148NjvEDc0Po148NvkHmVICeBhsBnMP1IslwM2IzusoOy/Ui8h6HQdkiN68x2XLe/Go5ApL1IvH241f0t/gJQXauiTwIEqRbV1KoK2PAtr6+Gwuf0Cm0F48PuRBTHR5sZnQ94v/Iv9HF8gg+X4R8KcWsaJHjBdPsAf0RGkvnujAi6VtmDL+tikdx4tlBBqoDHBaTyIb6CSBBjoRaKDS2Vx+ZKCnCJnTyaQXT1bwYmnSi2VZL5obliW8WBbwYqqyF02GVMKLqcpeLGPnhXoRWa800otpCl4s48CL6XbjZ/gbPEOgrTOAB5FJtnWmQFuXAdo6PZvLH5AptBfTyU8F9P0ia6tErjwBWFOEORLvFy+JuP0ec5Y9oNnSXsx24MUcGybX3zY5cbyYK9BAucDOyiMbKE+ggbKBBsrJ5vIjA/UiMqd80ov5Cl7MIb1YwHrR3LCA8GIB4MVCZS+aDIWEFwuVvZhr54V6EVmvItKLRQpezHXgRc9u/HL+Bi8n0NblgAdRnmzr8gJtnQu0tZfN5Q/IFNqLXsiDmOjyYjOh7xezgLVC+CL5PWYlNkWPGAOeYg/dqdIGPNWBASvYMBX9DVIhjgErCrRKRWBXnUa2ymkCrXIq0CoVsrn8yEANiMzpdNKApysYsAJpwEqsAc0NKxEGrAQYsLKyAU2GyoQBKysbsKKdF2pAZL3OIA14hoIBKzow4Jl241fxN3gVgbauAjyIqmRbVxVo64pAW5+ZzeUPyBTagGeSnwqCbzZi/HcKsE4IXSTeA/4Ycfs95rPsoTtb2oBnOzBgNRumur9BqsUxYHWBVqkO7KxzyFY5R6BVzgZapVo2lx8ZqAGROZ1LGvBcBQNWIw1YgzWguWENwoA1AAPWVDagyVCTMGBNZQNWt/NCDYis13mkAc9TMGB1BwY83278Wv4GryXQ1rWAB1GbbOvaAm1dHWjr87O5/AGZQhvw/JAHMdHlxWZC3wOeBawVwhfJ3zME/KlFrOgR48UL7AG9UNqLFzrwYh0bpq6/berE8WJdgQaqC+zAi8gGukiggS4EGqhONpcfGegpQuZUj/RiPQUv1iG9WJ/1orlhfcKL9YGaaqDsRZOhAeHFBsperGvnhXoRWa+LSS9erODFug68eInd+A39Dd5QoK0bAg+iEdnWjQTaui7Q1pdkc/kDMoX24iXkpwL6e4asrRK58gJgTRHmSLxffDjF7feYL7UH9DJpL17mwIuNbZgm/rZpHMeLTQQaqAmwsy4nG+hygQa6DGigxtlcfmSgXkTmdAXpxSsUvNiY9GJT1ovmhk0JLzYFqreZshdNhmaEF5spe7GJnRfqRWS9riS9eKWCF5s48OJVduM39zd4c4G2bg48iBZkW7cQaOsmQFtflc3lD8gU2otXhTyIiS4vNhP6fvFSYK0Qvki+XwT8qUWs6BHjxavtAb1G2ovXOPBiSxumlb9tWsbxYiuBBmoF7MBryQa6VqCBrgEaqGU2lx8Z6ClC5nQd6cXrFLzYkvRia9aL5oatCS+2BmqqjbIXTYY2hBfbKHuxlZ0X6kVkva4nvXi9ghdbOfDiDXbjt/U3eFuBtm4LPIh2ZFu3E2jrVkBb35DN5Q/IFNqLNxyh94usrRK58mpgTRHmSLxfbBhx+z3mG+0BbS/txfYOvNjBhunob5sOcbzYUaCBOgI76yaygW4SaKD2QAN1yObyIwP1IjKnm0kv3qzgxQ6kFzuxXjQ37ER4sRNQvZ2VvWgydCa82FnZix3tvFAvIut1C+nFWxS82NGBF2+1G7+Lv8G7CLR1F+BBdCXbuqtAW3cE2vrWbC5/QKbQXrw15EFMdHmxmdD3izcCa4XwRfJ7zEpsih4xBrzNHrrbpQ14uwMDdrNhuvsbpFscA3YXaJXuwK66g2yVOwRa5XagVbplc/mRgRoQmdOdpAHvVDBgN9KAPVgDmhv2IAzYAzBgT2UDmgw9CQP2VDZgdzsv1IDIet1FGvAuBQN2d2DAu+3G7+Vv8F4Cbd0LeBC9ybbuLdDW3YG2vjubyx+QKbQB7yY/FQTfbMT47zZgnRC6SLwH3BJx+z3me+yhu1fagPc6MGAfG6avv0H6xDFgX4FW6QvsrPvIVrlPoFXuBVqlTzaXHxmoAZE53U8a8H4FA/YhDdiPNaC5YT/CgP0AA/ZXNuD/HVbCgP2VDdjXzgs1ILJeD5AGfEDBgH0dGPBBu/EH+Bt8gEBbDwAexECyrQcKtHVfoK0fzObyB2QKbcAHQx7ERJcXmwl9D3gPsFYIXyR/zxDwpxaxokeMFx+yB/RhaS8+7MCLg2yYwf62GRTHi4MFGmgwsAMfIRvoEYEGehhooEHZXH5koKcImdOjpBcfVfDiINKLQ1gvmhsOIbw4BKipocpeNBmGEl4cquzFwXZeqBeR9XqM9OJjCl4c7MCLj9uNP8zf4MME2noY8CCGk209XKCtBwNt/Xg2lz8gU2gvPk5+KqC/Z8jaKpErHwLWFGGOxPvFQSluv8f8hD2gT0p78UkHXhxhw4z0t82IOF4cKdBAI4Gd9RTZQE8JNNCTQAONyObyIwP1IjKnp0kvPq3gxRGkF0exXjQ3HEV4cRRQvaOVvWgyjCa8OFrZiyPtvFAvIuv1DOnFZxS8ONKBF5+1G3+Mv8HHCLT1GOBBjCXbeqxAW48E2vrZbC5/QKbQXnw25EFMdHmxmdD3i08Aa4XwRfL9IuBPLWJFjxgvPmcP6DhpL45z4MXxNswEf9uMj+PFCQINNAHYgc+TDfS8QAONAxpofDaXHxnoKULm9ALpxRcUvDie9OJE1ovmhhMJL04EamqSshdNhkmEFycpe3GCnRfqRWS9XiS9+KKCFyc48OJLduNP9jf4ZIG2ngw8iClkW08RaOsJQFu/lM3lD8gU2osvHaH3i6ytErnyOWBNEeZIvF9sFHH7PeaX7QF9RdqLrzjw4lQbZpq/babG8eI0gQaaBuysV8kGelWggV4BGmhqNpcfGagXkTm9RnrxNQUvTiW9OJ31ornhdMKL04HqnaHsRZNhBuHFGcpenGbnhXoRWa/XSS++ruDFaQ68+Ibd+DP9DT5ToK1nAg9iFtnWswTaehrQ1m9kc/kDMoX24hshD2Kiy4vNhL5ffBlYK4Qvkt9jVmJT9Igx4Jv20L0lbcC3HBhwtg0zx98gs+MYcI5Aq8wBdtXbZKu8LdAqbwGtMjuby48M1IDInN4hDfiOggFnkwacyxrQ3HAuYcC5gAHnKRvQZJhHGHCesgHn2HmhBkTW613SgO8qGHCOAwO+Zzf+fH+Dzxdo6/nAg1hAtvUCgbaeA7T1e9lc/oBMoQ34HvmpIPhmI8Z/bwLrhNBF4j3g1ojb7zG/bw/dQmkDLnRgwEU2zGJ/gyyKY8DFAq2yGNhZH5Ct8oFAqywEWmVRNpcfGagBkTl9SBrwQwUDLiINuIQ1oLnhEsKASwADLlU2oMmwlDDgUmUDLrbzQg2IrNdHpAE/UjDgYgcG/Nhu/GX+Bl8m0NbLgAexnGzr5QJtvRho64+zufwBmUIb8OOQBzHR5cVmQt8Dvg+sFcIXyd8zBPypRazoEePFT+wB/VTai5868OIKG2alv21WxPHiSoEGWgnswM/IBvpMoIE+BRpoRTaXHxnoKULm9Dnpxc8VvLiC9OIq1ovmhqsIL64Camq1shdNhtWEF1cre3GlnRfqRWS9viC9+IWCF1c68OKXduOv8Tf4GoG2XgM8iLVkW68VaOuVQFt/mc3lD8gU2otfkp8K6O8ZsrZK5MpPgDVFmCPxfnFwitvvMX9lD+jX0l782oEX19kw6/1tsy6OF9cLNNB6YGd9QzbQNwIN9DXQQOuyufzIQL2IzOlb0ovfKnhxHenFDawXzQ03EF7cAFTvRmUvmgwbCS9uVPbiejsv1IvIen1HevE7BS+ud+DF7+3G3+Rv8E0Cbb0JeBCbybbeLNDW64G2/j6byx+QKbQXvw95EBNdXmwm9P3iV8BaIXyRfL8I+FOLWNEjxos/2AP6o7QXf3TgxS02zFZ/22yJ48WtAg20FdiBP5EN9JNAA/0INNCWbC4/MtBThMzpZ9KLPyt4cQvpxW2sF80NtxFe3AbU1HZlL5oM2wkvblf24lY7L9SLyHr9QnrxFwUvbnXgxV/txt/hb/AdAm29A3gQO8m23inQ1luBtv41m8sfkCm0F389Qu8XWVslcuUPwJoizJF4v3hpxO33mH+zB/R3aS/+7sCLu2yY3f622RXHi7sFGmg3sLP+IBvoD4EG+h1ooF3ZXH5koF5E5vQn6cU/Fby4i/TiHtaL5oZ7CC/uAap3r7IXTYa9hBf3Kntxt50X6kVkvf4ivfiXghd3O/Di33bj7/M3+D6Btt4HPIj9ZFvvF2jr3UBb/53N5Q/IFNqLf4c8iIkuLzYT+n7xN2CtEL5Ifo9ZiU3RI8aA/9hDd0DagAccGPCgDXPI3yAH4xjwkECrHAJ21b9kq/wr0CoHgFY5mM3lRwZqQGROkRzOgObnpA14kDRgSk6IG5ofRg2YkpP8wzgqR9eAJoO5B2rAo3KwzYjO65CdF2pAZL2OBjJEb17zc9IGPOTAgMfYjX9sTuTwgMfmhG/rY4EHUSKHa+sSOeHb+hDQ1sfkcPkDMoU24DHgQSwegm82Yvz3D/AJciCk/9CD9lPE7feYj7OH7njzp2SDHJ+jEiawQUraMKX8DVIyJ9aApQRapRRwAk8gW+UEgVY5Pif5VimZw+VHBmpAZE4nkgY8UcGAJXM4A5ZmDWhuWJowYGnAgGWUDWgylCEMWEbZgKXsvFADIut1EmnAkxQMWIokQyT4PoENfrLd+GX9DV5WoK3LAg8ilWzrVIG2LgW09ck5XP6ATKENeHLIg5jo8mIzoe8BjwPWCuGL5O8ZAv7UIlb0iPFimj2g6dJeTHfgxQwbJtPfNhlxvJgp0ECZwA7MIhsoS6CB0oEGysjh8iMDPUXInLJJL2YreDGD9GIO60VzwxzCizmAF3OVvWgy5BJezFX2YqadF+pFZL3ySC/mKXgx04EX8+3GL/A3eIFAWxcAD6KQbOtCgbbOBNo6P4fLH5AptBfzyU8F9PcMWVslcmUasKYIcyTeLz6S4vZ7zEX2gHrSXvQceLGcDVPe3zbl4nixvEADlQd21ilkA50i0EAe0EDlcrj8yEC9iMzpVNKLpyp4sRzpxQqsF80NKxBerAB4saKyF02GioQXKyp7sbydF+pFZL1OI714moIXyzvw4ul241fyN3glgbauBDyIymRbVxZo6/JAW5+ew+UPyBTai6eHPIiJLi82E/p+sQhYK4Qvku8XAX9qESt6xHjxDHtAz5T24pkOvFjFhqnqb5sqcbxYVaCBqgI78Cyygc4SaKAzgQaqksPlRwZ6ipA5nU168WwFL1YhvViN9aK5YTXCi9WAmqqu7EWToTrhxerKXqxq54V6EVmvc0gvnqPgxaoOvHiu3fg1/A1eQ6CtawAPoibZ1jUF2roq0Nbn5nD5AzKF9uK5R+j9ImurRK48A1hThDkS7xcvi7j9HvN59oCeL+3F8x14sZYNU9vfNrXieLG2QAPVBnbWBWQDXSDQQOcDDVQrh8uPDNSLyJwuJL14oYIXa5FerMN60dywDuHFOkD11lX2oslQl/BiXWUv1rbzQr2IrNdFpBcvUvBibQderGc3fn1/g9cXaOv6wINoQLZ1A4G2rg20db0cLn9AptBerBfyICa6vNhM6PvF84C1Qvgi+T1mJTZFjxgDXmwP3SXSBrzEgQEb2jCN/A3SMI4BGwm0SiNgV11KtsqlAq1yCdAqDXO4/MhADYjM6TLSgJcpGLAhacDGrAHNDRsTBmwMGLCJsgFNhiaEAZsoG7CRnRdqQGS9LicNeLmCARs5MOAVduM39Td4U4G2bgo8iGZkWzcTaOtGQFtfkcPlD8gU2oBXkJ8Kgm82Yvx3MbBOCF0k3gP+HHH7PeYr7aG7StqAVzkwYHMbpoW/QZrHMWALgVZpAeysq8lWuVqgVa4CWqV5DpcfGagBkTldQxrwGgUDNicN2JI1oLlhS8KALQEDtlI2oMnQijBgK2UDtrDzQg2IrNe1pAGvVTBgCwcGvM5u/Nb+Bm8t0NatgQfRhmzrNgJt3QJo6+tyuPwBmUIb8LqQBzHR5cVmQt8DXgmsFcIXyd8zBPypRazoEePF6+0BvUHaizc48GJbG6adv23axvFiO4EGagfswBvJBrpRoIFuABqobQ6XHxnoKULm1J70YnsFL7YlvdiB9aK5YQfCix2Amuqo7EWToSPhxY7KXmxn54V6EVmvm0gv3qTgxXYOvHiz3fid/A3eSaCtOwEPojPZ1p0F2rod0NY353D5AzKF9uLN5KcC+nuGrK0SufJ6YE0R5ki8X3w0xe33mG+xB/RWaS/e6sCLXWyYrv626RLHi10FGqgrsLNuIxvoNoEGuhVooC45XH5koF5E5nQ76cXbFbzYhfRiN9aL5obdCC92A6q3u7IXTYbuhBe7K3uxq50X6kVkve4gvXiHghe7OvDinXbj9/A3eA+Btu4BPIieZFv3FGjrrkBb35nD5Q/IFNqLd4Y8iIkuLzYT+n7xFmCtEL5Ivl8E/KlFrOgR48W77AG9W9qLdzvwYi8bpre/bXrF8WJvgQbqDezAe8gGukegge4GGqhXDpcfGegpQuZ0L+nFexW82Iv0Yh/Wi+aGfQgv9gFqqq+yF02GvoQX+yp7sbedF+pFZL3uI714n4IXezvw4v124/fzN3g/gbbuBzyI/mRb9xdo695AW9+fw+UPyBTai/cfofeLrK0SufIuYE0R5ki8X2wccfs95gfsAX1Q2osPOvDiABtmoL9tBsTx4kCBBhoI7KyHyAZ6SKCBHgQaaEAOlx8ZqBeROT1MevFhBS8OIL04iPWiueEgwouDgOodrOxFk2Ew4cXByl4caOeFehFZr0dILz6i4MWBDrz4qN34Q/wNPkSgrYcAD2Io2dZDBdp6INDWj+Zw+QMyhfbioyEPYqLLi82Evl98AFgrhC+S32NWYlP0iDHgY/bQPS5twMcdGHCYDTPc3yDD4hhwuECrDAd21RNkqzwh0CqPA60yLIfLjwzUgMicniQN+KSCAYeRBhzBGtDccARhwBGAAUcqG9BkGEkYcKSyAYfbeaEGRNbrKdKATykYcLgDAz5tN/4of4OPEmjrUcCDGE229WiBth4OtPXTOVz+gEyhDfg0+akg+GYjxn+PAeuE0EXiPeC2iNvvMT9jD92z0gZ81oEBx9gwY/0NMiaOAccKtMpYYGc9R7bKcwKt8izQKmNyuPzIQA2IzGkcacBxCgYcQxpwPGtAc8PxhAHHAwacoGxAk2ECYcAJygYca+eFGhBZr+dJAz6vYMCxDgz4gt34E/0NPlGgrScCD2IS2daTBNp6LNDWL+Rw+QMyhTbgCyEPYqLLi82Evgd8BlgrhC+Sv2cI+FOLWNEjxosv2gP6krQXX3Lgxck2zBR/20yO48UpAg00BdiBL5MN9LJAA70ENNDkHC4/MtBThMzpFdKLryh4cTLpxamsF80NpxJenArU1DRlL5oM0wgvTlP24hQ7L9SLyHq9SnrxVQUvTnHgxdfsxp/ub/DpAm09HXgQM8i2niHQ1lOAtn4th8sfkCm0F18jPxXQ3zNkbZXIlS8Ca4owR+L94pAUt99jft0e0DekvfiGAy/OtGFm+dtmZhwvzhJooFnAznqTbKA3BRroDaCBZuZw+ZGBehGZ01ukF99S8OJM0ouzWS+aG84mvDgbqN45yl40GeYQXpyj7MVZdl6oF5H1epv04tsKXpzlwIvv2I0/19/gcwXaei7wIOaRbT1PoK1nAW39Tg6XPyBTaC++E/IgJrq82Ezo+8XXgbVC+CL5fhHwpxaxokeMF9+1B/Q9aS++58CL822YBf62mR/HiwsEGmgBsAPfJxvofYEGeg9ooPk5XH5koKcImdNC0osLFbw4n/TiItaL5oaLCC8uAmpqsbIXTYbFhBcXK3txgZ0X6kVkvT4gvfiBghcXOPDih3bjL/E3+BKBtl4CPIilZFsvFWjrBUBbf5jD5Q/IFNqLHx6h94usrRK58l1gTRHmSLxfbBJx+z3mj+wB/Vjaix878OIyG2a5v22WxfHicoEGWg7srE/IBvpEoIE+BhpoWQ6XHxmoF5E5fUp68VMFLy4jvbiC9aK54QrCiyuA6l2p7EWTYSXhxZXKXlxu54V6EVmvz0gvfqbgxeUOvPi53fir/A2+SqCtVwEPYjXZ1qsF2no50Naf53D5AzKF9uLnIQ9iosuLzYS+X/wIWCuEL5LfY1ZiU/SIMeAX9tB9KW3ALx0YcI0Ns9bfIGviGHCtQKusBXbVV2SrfCXQKl8CrbImh8uPDNSAyJy+Jg34tYIB15AGXMca0NxwHWHAdYAB1ysb0GRYTxhwvbIB19p5oQZE1usb0oDfKBhwrQMDfms3/gZ/g28QaOsNwIPYSLb1RoG2Xgu09bc5XP6ATKEN+C35qSD4ZiPGf18A64TQReI94PaI2+8xf2cP3ffSBvzegQE32TCb/Q2yKY4BNwu0ymZgZ/1AtsoPAq3yPdAqm3K4/MhADYjM6UfSgD8qGHATacAtrAHNDbcQBtwCGHCrsgFNhq2EAbcqG3CznRdqQGS9fiIN+JOCATc7MODPduNv8zf4NoG23gY8iO1kW28XaOvNQFv/nMPlD8gU2oA/hzyIiS4vNhP6HvA7YK0Qvkj+niHgTy1iRY8YL/5iD+iv0l781YEXd9gwO/1tsyOOF3cKNNBOYAf+RjbQbwIN9CvQQDtyuPzIQE8RMqffSS/+ruDFHaQXd7FeNDfcRXhxF1BTu5W9aDLsJry4W9mLO+28UC8i6/UH6cU/FLy404EX/7Qbf4+/wfcItPUe4EHsJdt6r0Bb7wTa+s8cLn9AptBe/JP8VEB/z5C1VSJX/gKsKcIcifeLQ1Pcfo/5L3tA/5b24t8OvLjPhtnvb5t9cby4X6CB9gM76x+ygf4RaKC/gQbal8PlRwbqRWROB0gvHlDw4j7SiwdZL5obHiS8eBCo3kPKXjQZDhFePKTsxf12XqgXkfX6l/Tivwpe3O/Ai5Fce1Fu5PCA5i/CtrX5N5K99qhcrq2Pyg3f1vuBto7kcvkDMoX2YiQ33EFMdHmxmdD3i38BBxHhi+T7RcCfWsSKHjFePNoe0GPMn5Jtc0yuSpjAtjnWhinhbxvzH/xeLCHQQCWA03oc2UDHCTTQMbnJN9CxuVx+ZKCnCJnT8bmcF4/PlffisbmcF0vmhrih+WHUiyWTf5AppYCHwWYw90C9WCrkx1Qym71ULu5FZL1OADJEb94TcuW9WILkRST4PoENfqLd+KX9DV5aoK1LAw+iDNnWZQTaugTQ1ifmcvkDMoX24onkpwL6fpG1VSJXHg2sKcIcifeLl0fcfo/5JHtAT5b24skOvFjWhkn1t03ZOF5MFWigVGBnpZENlCbQQCcDDVQ2l8uPDNSLyJzSSS+mK3ixLOnFDNaL5oYZhBczAC9mKnvRZMgkvJip7MVUOy/Ui8h6ZZFezFLwYqoDL2bbjZ/jb/AcgbbOAR5ELtnWuQJtnQq0dXYulz8gU2gvZoc8iIkuLzYT+n7xJGCtEL5Ifo9ZiU3RI8aAefbQ5UsbMN+BAQtsmEJ/gxTEMWChQKsUAruqiGyVIoFWyQdapSCXy48M1IDInDzSgJ6CAQtIA5ZjDWhuWI4wYDnAgOWVDWgylCcMWF7ZgIV2XqgBkfU6hTTgKQoGLHRgwFPtxq/gb/AKAm1dAXgQFcm2rijQ1oVAW5+ay+UPyBTagKeSnwqCbzZi/JcHrBNCF4n3gL9E3H6P+TR76E6XNuDpDgxYyYap7G+QSnEMWFmgVSoDO+sMslXOEGiV04FWqZTL5UcGakBkTmeSBjxTwYCVSANWYQ1obliFMGAVwIBVlQ1oMlQlDFhV2YCV7bxQAyLrdRZpwLMUDFjZgQHPthu/mr/Bqwm0dTXgQVQn27q6QFtXBtr67Fwuf0Cm0AY8O+RBTHR5sZnQ94CnAWuF8EXy9wwBf2oRK3rEePEce0DPlfbiuQ68WMOGqelvmxpxvFhToIFqAjvwPLKBzhNooHOBBqqRy+VHBnqKkDmdT3rxfAUv1iC9WIv1orlhLcKLtYCaqq3sRZOhNuHF2sperGnnhXoRWa8LSC9eoODFmg68eKHd+HX8DV5HoK3rAA+iLtnWdQXauibQ1hfmcvkDMoX24oXkpwL6e4asrRK58hxgTRHmSLxffCzF7feYL7IHtJ60F+s58GJ9G6aBv23qx/FiA4EGagDsrIvJBrpYoIHqAQ1UP5fLjwzUi8icLiG9eImCF+uTXmzIetHcsCHhxYZA9TZS9qLJ0IjwYiNlLzaw80K9iKzXpaQXL1XwYgMHXrzMbvzG/gZvLNDWjYEH0YRs6yYCbd0AaOvLcrn8AZlCe/GykAcx0eXFZkLfL14ErBXCF8n3i4A/tYgVPWK8eLk9oFdIe/EKB15sasM087dN0zhebCbQQM2AHXgl2UBXCjTQFUADNc3l8iMDPUXInK4ivXiVghebkl5sznrR3LA54cXmQE21UPaiydCC8GILZS82s/NCvYis19WkF69W8GIzB168xm78lv4GbynQ1i2BB9GKbOtWAm3dDGjra3K5/AGZQnvxmiP0fpG1VSJXXg6sKcIcifeLV0Tcfo/5WntAr5P24nUOvNjahmnjb5vWcbzYRqCB2gA763qyga4XaKDrgAZqncvlRwbqRWRON5BevEHBi61JL7ZlvWhu2JbwYlugetspe9FkaEd4sZ2yF9vYeaFeRNbrRtKLNyp4sY0DL7a3G7+Dv8E7CLR1B+BBdCTbuqNAW7cB2rp9Lpc/IFNoL7YPeRATXV5sJvT94rXAWiF8kfwesxKbokeMAW+yh+5maQPe7MCAnWyYzv4G6RTHgJ0FWqUzsKtuIVvlFoFWuRlolU65XH5koAZE5nQracBbFQzYiTRgF9aA5oZdCAN2AQzYVdmAJkNXwoBdlQ3Y2c4LNSCyXreRBrxNwYCdHRjwdrvxu/kbvJtAW3cDHkR3sq27C7R1Z6Ctb8/l8gdkCm3A28lPBcE3GzH+uwlYJ4QuEu8Bf424/R7zHfbQ3SltwDsdGLCHDdPT3yA94hiwp0Cr9AR21l1kq9wl0Cp3Aq3SI5fLjwzUgMic7iYNeLeCAXuQBuzFGtDcsBdhwF6AAXsrG9Bk6E0YsLeyAXvaeaEGRNbrHtKA9ygYsKcDA95rN34ff4P3EWjrPsCD6Eu2dV+Btu4JtPW9uVz+gEyhDXhvyIOY6PJiM6HvAe8A1grhi+TvGQL+1CJW9Ijx4n32gN4v7cX7HXixnw3T3982/eJ4sb9AA/UHduADZAM9INBA9wMN1C+Xy48M9BQhc3qQ9OKDCl7sR3pxAOtFc8MBhBcHADU1UNmLJsNAwosDlb3Y384L9SKyXg+RXnxIwYv9HXjxYbvxB/kbfJBAWw8CHsRgsq0HC7R1f6CtH87l8gdkCu3Fh8lPBfT3DFlbJXLlfcCaIsyReL/4eIrb7zE/Yg/oo9JefNSBF4fYMEP9bTMkjheHCjTQUGBnPUY20GMCDfQo0EBDcrn8yEC9iMzpcdKLjyt4cQjpxWGsF80NhxFeHAZU73BlL5oMwwkvDlf24lA7L9SLyHo9QXrxCQUvDnXgxSftxh/hb/ARAm09AngQI8m2HinQ1kOBtn4yl8sfkCm0F58MeRATXV5sJvT94iPAWiF8kXy/CPhTi1jRI8aLT9kD+rS0F5924MVRNsxof9uMiuPF0QINNBrYgc+QDfSMQAM9DTTQqFwuPzLQU4TM6VnSi88qeHEU6cUxrBfNDccQXhwD1NRYZS+aDGMJL45V9uJoOy/Ui8h6PUd68TkFL4524MVxduOP9zf4eIG2Hg88iAlkW08QaOvRQFuPy+XyB2QK7cVxR+j9ImurRK58ClhThDkS7xebRtx+j/l5e0BfkPbiCw68ONGGmeRvm4lxvDhJoIEmATvrRbKBXhRooBeABpqYy+VHBupFZE4vkV58ScGLE0kvTma9aG44mfDiZKB6pyh70WSYQnhxirIXJ9l5oV5E1utl0osvK3hxkgMvvmI3/lR/g08VaOupwIOYRrb1NIG2ngS09Su5XP6ATKG9+ErIg5jo8mIzoe8XnwfWCuGL5PeYldgUPWIM+Ko9dK9JG/A1BwacbsPM8DfI9DgGnCHQKjOAXfU62SqvC7TKa0CrTM/l8iMDNSAypzdIA76hYMDppAFnsgY0N5xJGHAmYMBZygY0GWYRBpylbMAZdl6oAZH1epM04JsKBpzhwIBv2Y0/29/gswXaejbwIOaQbT1HoK1nAG39Vi6XPyBTaAO+RX4qCL7ZiPHfq8A6IXSReA+4I+L2e8xv20P3jrQB33FgwLk2zDx/g8yNY8B5Aq0yD9hZ75Kt8q5Aq7wDtMrcXC4/MlADInN6jzTgewoGnEsacD5rQHPD+YQB5wMGXKBsQJNhAWHABcoGnGfnhRoQWa/3SQO+r2DAeQ4MuNBu/EX+Bl8k0NaLgAexmGzrxQJtPQ9o64W5XP6ATKENuDDkQUx0ebGZ0PeAbwNrhfBF8vcMAX9qESt6xHjxA3tAP5T24ocOvLjEhlnqb5slcby4VKCBlgI78COygT4SaKAPgQZaksvlRwZ6ipA5fUx68WMFLy4hvbiM9aK54TLCi8uAmlqu7EWTYTnhxeXKXlxq54V6EVmvT0gvfqLgxaUOvPip3fgr/A2+QqCtVwAPYiXZ1isF2nop0Naf5nL5AzKF9uKn5KcC+nuGrK0SufIDYE0R5ki8XxyW4vZ7zJ/ZA/q5tBc/d+DFVTbMan/brIrjxdUCDbQa2FlfkA30hUADfQ400KpcLj8yUC8ic/qS9OKXCl5cRXpxDetFc8M1hBfXANW7VtmLJsNawotrlb242s4L9SKyXl+RXvxKwYurHXjxa7vx1/kbfJ1AW68DHsR6sq3XC7T1aqCtv87l8gdkCu3Fr0MexESXF5sJfb/4GbBWCF8k3y8C/tQiVvSI8eI39oB+K+3Fbx14cYMNs9HfNhvieHGjQANtBHbgd2QDfSfQQN8CDbQhl8uPDPQUIXP6nvTi9wpe3EB6cRPrRXPDTYQXNwE1tVnZiybDZsKLm5W9uNHOC/Uisl4/kF78QcGLGx148Ue78bf4G3yLQFtvAR7EVrKttwq09UagrX/M5fIHZArtxR+P0PtF1laJXPkNsKYIcyTeLzaLuP0e80/2gP4s7cWfHXhxmw2z3d822+J4cbtAA20HdtYvZAP9ItBAPwMNtC2Xy48M1IvInH4lvfirghe3kV7cwXrR3HAH4cUdQPXuVPaiybCT8OJOZS9ut/NCvYis12+kF39T8OJ2B1783W78Xf4G3yXQ1ruAB7GbbOvdAm29HWjr33O5/AGZQnvx95AHMdHlxWZC3y/+BKwVwhfJ7zErsSl6xBjwD3vo/pQ24J8ODLjHhtnrb5A9cQy4V6BV9gK76i+yVf4SaJU/gVbZk8vlRwZqQGROf5MG/FvBgHtIA+5jDWhuuI8w4D7AgPuVDWgy7CcMuF/ZgHvtvFADIuv1D2nAfxQMuNeBAQ/YjX/Q3+AHBdr6IPAgDpFtfUigrfcCbX0gl8sfkCm0AQ+QnwqCbzZi/PcHsE4IXSTeA+6MuP0e87/FnzZ5EdkGMf9gktfGHd7/+nd947DFz7N/lxc5vEHMf/Ab0FwUtlWOykv+2qPzuFY5Oi98q0Tykm+VlDwuPzJQAyJzOiaPM+AxefIGTMnjDHhsXogbmh9GDXhs8g8ypQTwMNgM5h6oAUuAmxGd11F2XqgBkfU6DsgQvXmPy5M34FHJFZaoAY+3G7+kv8FLCrR1SeBBlCLbupRAWx8FtPXxeVz+gEyhDXh8yIOY6PJiM6HvAf9F/s8rkEHy9wwBf2oRK3rEePEEe0BPlPbiiQ68WNqGKeNvm9JxvFhGoIHKAKf1JLKBThJooBOBBiqdx+VHBnqKkDmdTHrxZAUvlia9WJb1orlhWcKLZQEvpip70WRIJbyYquzFMnZeqBeR9UojvZim4MUyDryYbjd+hr/BMwTaOgN4EJlkW2cKtHUZoK3T87j8AZlCezGd/FRAf8+QtVUiV54ArCnCHIn3i8NT3H6POcse0GxpL2Y78GKODZPrb5ucOF7MFWigXGBn5ZENlCfQQNlAA+XkcfmRgXoRmVM+6cV8BS/mkF4sYL1oblhAeLEA8GKhshdNhkLCi4XKXsy180K9iKxXEenFIgUv5jrwomc3fjl/g5cTaOtywIMoT7Z1eYG2zgXa2svj8gdkCu1FL+RBTHR5sZnQ94tZwFohfJF8vwj4U4tY0SPGi6fYA3qqtBdPdeDFCjZMRX/bVIjjxYoCDVQR2IGnkQ10mkADnQo0UIU8Lj8y0FOEzOl00ounK3ixAunFSqwXzQ0rEV6sBNRUZWUvmgyVCS9WVvZiRTsv1IvIep1BevEMBS9WdODFM+3Gr+Jv8CoCbV0FeBBVybauKtDWFYG2PjOPyx+QKbQXzzxC7xdZWyVy5SnAmiLMkXi/eGXE7feYz7IH9GxpL57twIvVbJjq/rapFseL1QUaqDqws84hG+gcgQY6G2iganlcfmSgXkTmdC7pxXMVvFiN9GIN1ovmhjUIL9YAqremshdNhpqEF2sqe7G6nRfqRWS9ziO9eJ6CF6s78OL5duPX8jd4LYG2rgU8iNpkW9cWaOvqQFufn8flD8gU2ovnhzyIiS4vNhP6fvEsYK0Qvkh+j1mJTdEjxoAX2EN3obQBL3RgwDo2TF1/g9SJY8C6Aq1SF9hVF5GtcpFAq1wItEqdPC4/MlADInOqRxqwnoIB65AGrM8a0NywPmHA+oABGygb0GRoQBiwgbIB69p5oQZE1uti0oAXKxiwrgMDXmI3fkN/gzcUaOuGwINoRLZ1I4G2rgu09SV5XP6ATKENeAn5qSD4ZiPGfxcA64TQReI94G8Rt99jvtQeusukDXiZAwM2tmGa+BukcRwDNhFolSbAzrqcbJXLBVrlMqBVGudx+ZGBGhCZ0xWkAa9QMGBj0oBNWQOaGzYlDNgUMGAzZQOaDM0IAzZTNmATOy/UgMh6XUka8EoFAzZxYMCr7MZv7m/w5gJt3Rx4EC3Itm4h0NZNgLa+Ko/LH5AptAGvCnkQE11ebCb0PeClwFohfJH8PUPAn1rEih4xXrzaHtBrpL14jQMvtrRhWvnbpmUcL7YSaKBWwA68lmygawUa6BqggVrmcfmRgZ4iZE7XkV68TsGLLUkvtma9aG7YmvBia6Cm2ih70WRoQ3ixjbIXW9l5oV5E1ut60ovXK3ixlQMv3mA3flt/g7cVaOu2wINoR7Z1O4G2bgW09Q15XP6ATKG9eAP5qYD+niFrq0SuvBpYU4Q5Eu8Xn0hx+z3mG+0BbS/txfYOvNjBhunob5sOcbzYUaCBOgI76yaygW4SaKD2QAN1yOPyIwP1IjKnm0kv3qzgxQ6kFzuxXjQ37ER4sRNQvZ2VvWgydCa82FnZix3tvFAvIut1C+nFWxS82NGBF2+1G7+Lv8G7CLR1F+BBdCXbuqtAW3cE2vrWPC5/QKbQXrw15EFMdHmxmdD3izcCa4XwRfL9IuBPLWJFjxgv3mYP6O3SXrzdgRe72TDd/W3TLY4Xuws0UHdgB95BNtAdAg10O9BA3fK4/MhATxEypztJL96p4MVupBd7sF40N+xBeLEHUFM9lb1oMvQkvNhT2Yvd7bxQLyLrdRfpxbsUvNjdgRfvthu/l7/Bewm0dS/gQfQm27q3QFt3B9r67jwuf0Cm0F68+wi9X2RtlciVtwFrijBH4v3iVf/vfzoe8///hRfhh5f4kpP+PVDvMC/eYw/ovdJevNeBF/vYMH39bdMnjhf7CjRQX2Bn3Uc20H0CDXQv0EB98rj8yEC9iMzpftKL9yt4sQ/pxX6sF80N+xFe7AdUb39lL/7fYSW82F/Zi33tvFAvIuv1AOnFBxS82DdZXhz9vpgXH7Qbf4C/wQcItPUA4EEMJNt6oEBb9wXa+sE8Ln9AppgHih6UB0MexESXF5sJer949ML/s06yGRC+SH6PWYlN0SPGgA/ZQ/ewtAEfdmDAQTbMYH+DDIpjwMECrTIY2FWPkK3yiECrPAy0yqA8Lj8yUAMic3qUNOCjCgYcRBpwCGtAc8MhhAGHAAYcqmxAk2EoYcChygYcbOeFGhBZr8dIAz6mYMDBDgz4uN34w/wNPkygrYcBD2I42dbDBdp6MNDWj+dx+QMyhTbg4+SnguCbjRj/PQSsE0IXifeA5p4zHL4HfMIeuielDfikAwOOsGFG+htkRBwDjhRolZHAznqKbJWnBFrlSaBVRuRx+ZGBGhCZ09OkAZ9WMOAI0oCjWAOaG44iDDgKMOBoZQOaDKMJA45WNuBIOy/UgMh6PUMa8BkFA450YMBn7cYf42/wMQJtPQZ4EGPJth4r0NYjgbZ+No/LH5AptAGfDXkQE11ebCb0PeATwFohfJH8PUPAn1rEih4xXnzOHtBx0l4c58CL422YCf62GR/HixMEGmgCsAOfJxvoeYEGGgc00Pg8Lj8y0FOEzOkF0osvKHhxPOnFiawXzQ0nEl6cCNTUJGUvmgyTCC9OUvbiBDsv1IvIer1IevFFBS9OcODFl+zGn+xv8MkCbT0ZeBBTyLaeItDWE4C2fimPyx+QKbQXXyI/FdDfM2RtlciVzwFrijBH4v3ik//vBzY6fL/4sj2gr0h78RUHXpxqw0zzt83UOF6cJtBA04Cd9SrZQK8KNNArQANNzePyIwP1IjKn10gvvqbgxamkF6ezXjQ3nE54cTpQvTOUvWgyzCC8OEPZi9PsvFAvIuv1OunF1xW8OM2BF9+wG3+mv8FnCrT1TOBBzCLbepZAW08D2vqNPC5/QKbQXnwj5EFMdHmxmdD3iy8Da4XwRfL9IuBPLWJFjxgvvmkP6FvSXnzLgRdn2zBz/G0zO44X5wg00BxgB75NNtDbAg30FtBAs/O4/MhATxEyp3dIL76j4MXZpBfnsl40N5xLeHEuUFPzlL1oMswjvDhP2Ytz7LxQLyLr9S7pxXcVvDjHgRffsxt/vr/B5wu09XzgQSwg23qBQFvPAdr6vTwuf0Cm0F587wi9X2RtlciVbwJrijBH4v1i84jb7zG/bw/oQmkvLnTgxUU2zGJ/2yyK48XFAg20GNhZH5AN9IFAAy0EGmhRHpcfGagXkTl9SHrxQwUvLiK9uIT1ornhEsKLS4DqXarsRZNhKeHFpcpeXGznhXoRWa+PSC9+pODFxQ68+LHd+Mv8Db5MoK2XAQ9iOdnWywXaejHQ1h/ncfkDMoX24schD2Kiy4vNhL5ffB9YK4Qvkt9jVmJT9Igx4Cf20H0qbcBPHRhwhQ2z0t8gK+IYcKVAq6wEdtVnZKt8JtAqnwKtsiKPy48M1IDInD4nDfi5ggFXkAZcxRrQ3HAVYcBVgAFXKxvQZFhNGHC1sgFX2nmhBkTW6wvSgF8oGHClAwN+aTf+Gn+DrxFo6zXAg1hLtvVagbZeCbT1l3lc/oBMoQ34JfmpIPhmI8Z/nwDrhNBF4j3grojb7zF/ZQ/d19IG/NqBAdfZMOv9DbIujgHXC7TKemBnfUO2yjcCrfI10Crr8rj8yEANiMzpW9KA3yoYcB1pwA2sAc0NNxAG3AAYcKOyAU2GjYQBNyobcL2dF2pAZL2+Iw34nYIB1zsw4Pd242/yN/gmgbbeBDyIzWRbbxZo6/VAW3+fx+UPyBTagN+HPIiJLi82E/oe8CtgrRC+SP6eIeBPLWJFjxgv/mAP6I/SXvzRgRe32DBb/W2zJY4Xtwo00FZgB/5ENtBPAg30I9BAW/K4/MhATxEyp59JL/6s4MUtpBe3sV40N9xGeHEbUFPblb1oMmwnvLhd2Ytb7bxQLyLr9QvpxV8UvLjVgRd/tRt/h7/Bdwi09Q7gQewk23qnQFtvBdr61zwuf0Cm0F78lfxUQH/PkLVVIlf+AKwpwhyJ94sjUtx+j/k3e0B/l/bi7w68uMuG2e1vm11xvLhboIF2AzvrD7KB/hBooN+BBtqVx+VHBupFZE5/kl78U8GLu0gv7mG9aG64h/DiHqB69yp70WTYS3hxr7IXd9t5oV5E1usv0ot/KXhxtwMv/m03/j5/g+8TaOt9wIPYT7b1foG23g209d95XP6ATKG9+HfIg5jo8mIzoe8XfwPWCuGL5PtFwJ9axIoeMV78xx7QA9JePODAiwdtmEP+tjkYx4uHBBroELAD/yUb6F+BBjoANNDBPC4/MtBThMwpks950fyctBcPkl5MyQ9xQ/PDqBdT8pN/GEfl63rRZDD3QL14VD62GdF5HbLzQr2IrNfRQIbozWt+TtqLhxx48Ri78Y/Njxwe8Nj88G19LPAgSuRzbV0iP3xbHwLa+ph8Ln9AptBePAY8iMUDfb/I2iqRK/8BPm0OhHQleihbRNx+j/k4e0CPN39Kts3x+SphAtumpA1Tyt82JfNjvVhKoIFKAaf1BLKBThBooOPzk2+gkvlcfmSgXkTmdCLpxRMVvFgyn/NiadaL5oalCS+WBrxYRtmLJkMZwotllL1Yys4L9SKyXieRXjxJwYulSF5Egu8T2OAn241f1t/gZQXauizwIFLJtk4VaOtSQFufnM/lD8gU2osnhzyIiS4vNhP6fvE4YK0Qvkh+j1mJTdEjxoBp9tClSxsw3YEBM2yYTH+DZMQxYKZAq2QCuyqLbJUsgVZJB1olI5/LjwzUgMicskkDZisYMIM0YA5rQHPDHMKAOYABc5UNaDLkEgbMVTZgpp0XakBkvfJIA+YpGDDTgQHz7cYv8Dd4gUBbFwAPopBs60KBts4E2jo/n8sfkCm0AfPJTwXBNxsx/ksD1gmhi8R7wN0Rt99jLrKHzpM2oOfAgOVsmPL+BikXx4DlBVqlPLCzTiFb5RSBVvGAVimXz+VHBmpAZE6nkgY8VcGA5UgDVmANaG5YgTBgBcCAFZUNaDJUJAxYUdmA5e28UAMi63UaacDTFAxY3oEBT7cbv5K/wSsJtHUl4EFUJtu6skBblwfa+vR8Ln9AptAGPD3kQUx0ebGZ0PeARcBaIXyR/D1DwJ9axIoeMV48wx7QM6W9eKYDL1axYar626ZKHC9WFWigqsAOPItsoLMEGuhMoIGq5HP5kYGeImROZ5NePFvBi1VIL1ZjvWhuWI3wYjWgpqore9FkqE54sbqyF6vaeaFeRNbrHNKL5yh4saoDL55rN34Nf4PXEGjrGsCDqEm2dU2Btq4KtPW5+Vz+gEyhvXgu+amA/p4ha6tErjwDWFOEORLvF0emuP0e83n2gJ4v7cXzHXixlg1T2982teJ4sbZAA9UGdtYFZANdINBA5wMNVCufy48M1IvInC4kvXihghdrkV6sw3rR3LAO4cU6QPXWVfaiyVCX8GJdZS/WtvNCvYis10WkFy9S8GJtB16sZzd+fX+D1xdo6/rAg2hAtnUDgbauDbR1vXwuf0Cm0F6sF/IgJrq82Ezo+8XzgLVC+CL5fhHwpxaxokeMFy+2B/QSaS9e4sCLDW2YRv62aRjHi40EGqgRsAMvJRvoUoEGugRooIb5XH5koKcImdNlpBcvU/BiQ9KLjVkvmhs2JrzYGKipJspeNBmaEF5souzFRnZeqBeR9bqc9OLlCl5s5MCLV9iN39Tf4E0F2rop8CCakW3dTKCtGwFtfUU+lz8gU2gvXnGE3i+ytkrkyouBNUWYI/F+8eqI2+8xX2kP6FXSXrzKgReb2zAt/G3TPI4XWwg0UAtgZ11NNtDVAg10FdBAzfO5/MhAvYjM6RrSi9coeLE56cWWrBfNDVsSXmwJVG8rZS+aDK0IL7ZS9mILOy/Ui8h6XUt68VoFL7Zw4MXr7MZv7W/w1gJt3Rp4EG3Itm4j0NYtgLa+Lp/LH5AptBevC3kQE11ebCb0/eKVwFohfJH8HrMSm6JHjAGvt4fuBmkD3uDAgG1tmHb+Bmkbx4DtBFqlHbCrbiRb5UaBVrkBaJW2+Vx+ZKAGRObUnjRgewUDtiUN2IE1oLlhB8KAHQADdlQ2oMnQkTBgR2UDtrPzQg2IrNdNpAFvUjBgOwcGvNlu/E7+Bu8k0NadgAfRmWzrzgJt3Q5o65vzufwBmUIb8GbyU0HwzUaM/64H1gmhi8R7wD8ibr/HfIs9dLdKG/BWBwbsYsN09TdIlzgG7CrQKl2BnXUb2Sq3CbTKrUCrdMnn8iMDNSAyp9tJA96uYMAupAG7sQY0N+xGGLAbYMDuygY0GboTBuyubMCudl6oAZH1uoM04B0KBuzqwIB32o3fw9/gPQTaugfwIHqSbd1ToK27Am19Zz6XPyBTaAPeGfIgJrq82Ezoe8BbgLVC+CL5e4aAP7WIFT1ivHiXPaB3S3vxbgde7GXD9Pa3Ta84Xuwt0EC9gR14D9lA9wg00N1AA/XK5/IjAz1FyJzuJb14r4IXe5Fe7MN60dywD+HFPkBN9VX2osnQl/BiX2Uv9rbzQr2IrNd9pBfvU/BibwdevN9u/H7+Bu8n0Nb9gAfRn2zr/gJt3Rto6/vzufwBmUJ78X7yUwH9PUPWVolceRewpghzJN4vPpXi9nvMD9gD+qC0Fx904MUBNsxAf9sMiOPFgQINNBDYWQ+RDfSQQAM9CDTQgHwuPzJQLyJzepj04sMKXhxAenEQ60Vzw0GEFwcB1TtY2Ysmw2DCi4OVvTjQzgv1IrJej5BefETBiwMdePFRu/GH+Bt8iEBbDwEexFCyrYcKtPVAoK0fzefyB2QK7cVHQx7ERJcXmwl9v/gAsFYIXyTfLwL+1CJW9Ijx4mP2gD4u7cXHHXhxmA0z3N82w+J4cbhAAw0HduATZAM9IdBAjwMNNCyfy48M9BQhc3qS9OKTCl4cRnpxBOtFc8MRhBdHADU1UtmLJsNIwosjlb043M4L9SKyXk+RXnxKwYvDHXjxabvxR/kbfJRAW48CHsRosq1HC7T1cKCtn87n8gdkCu3Fp4/Q+0XWVolc+RiwpghzJN4vXhNx+z3mZ+wBfVbai8868OIYG2asv23GxPHiWIEGGgvsrOfIBnpOoIGeBRpoTD6XHxmoF5E5jSO9OE7Bi2NIL45nvWhuOJ7w4nigeicoe9FkmEB4cYKyF8faeaFeRNbredKLzyt4cawDL75gN/5Ef4NPFGjricCDmES29SSBth4LtPUL+Vz+gEyhvfhCyIOY6PJiM6HvF58B1grhi+T3mJXYFD1iDPiiPXQvSRvwJQcGnGzDTPE3yOQ4Bpwi0CpTgF31MtkqLwu0yktAq0zO5/IjAzUgMqdXSAO+omDAyaQBp7IGNDecShhwKmDAacoGNBmmEQacpmzAKXZeqAGR9XqVNOCrCgac4sCAr9mNP93f4NMF2no68CBmkG09Q6CtpwBt/Vo+lz8gU2gDvkZ+Kgi+2Yjx34vAOiF0kXgP+GfE7feYX7eH7g1pA77hwIAzbZhZ/gaZGceAswRaZRaws94kW+VNgVZ5A2iVmflcfmSgBkTm9BZpwLcUDDiTNOBs1oDmhrMJA84GDDhH2YAmwxzCgHOUDTjLzgs1ILJeb5MGfFvBgLMcGPAdu/Hn+ht8rkBbzwUexDyyrecJtPUsoK3fyefyB2QKbcB3Qh7ERJcXmwl9D/g6sFYIXyR/zxDwpxaxokeMF9+1B/Q9aS++58CL822YBf62mR/HiwsEGmgBsAPfJxvofYEGeg9ooPn5XH5koKcImdNC0osLFbw4n/TiItaL5oaLCC8uAmpqsbIXTYbFhBcXK3txgZ0X6kVkvT4gvfiBghcXOPDih3bjL/E3+BKBtl4CPIilZFsvFWjrBUBbf5jP5Q/IFNqLH5KfCujvGbK2SuTKd4E1RZgj8X7x6RS332P+yB7Qj6W9+LEDLy6zYZb722ZZHC8uF2ig5cDO+oRsoE8EGuhjoIGW5XP5kYF6EZnTp6QXP1Xw4jLSiytYL5obriC8uAKo3pXKXjQZVhJeXKnsxeV2XqgXkfX6jPTiZwpeXO7Ai5/bjb/K3+CrBNp6FfAgVpNtvVqgrZcDbf15Ppc/IFNoL34e8iAmurzYTOj7xY+AtUL4Ivl+EfCnFrGiR4wXv7AH9EtpL37pwItrbJi1/rZZE8eLawUaaC2wA78iG+grgQb6EmigNflcfmSgpwiZ09ekF79W8OIa0ovrWC+aG64jvLgOqKn1yl40GdYTXlyv7MW1dl6oF5H1+ob04jcKXlzrwIvf2o2/wd/gGwTaegPwIDaSbb1RoK3XAm39bT6XPyBTaC9+e4TeL7K2SuTKL4A1RZgj8X6xZcTt95i/swf0e2kvfu/Ai5tsmM3+ttkUx4ubBRpoM7CzfiAb6AeBBvoeaKBN+Vx+ZKBeROb0I+nFHxW8uIn04hbWi+aGWwgvbgGqd6uyF02GrYQXtyp7cbOdF+pFZL1+Ir34k4IXNzvw4s9242/zN/g2gbbeBjyI7WRbbxdo681AW/+cz+UPyBTaiz+HPIiJLi82E/p+8TtgrRC+SH6PWYlN0SPGgL/YQ/ertAF/dWDAHTbMTn+D7IhjwJ0CrbIT2FW/ka3ym0Cr/Aq0yo58Lj8yUAMic/qdNODvCgbcQRpwF2tAc8NdhAF3AQbcrWxAk2E3YcDdygbcaeeFGhBZrz9IA/6hYMCdDgz4p934e/wNvkegrfcAD2Iv2dZ7Bdp6J9DWf+Zz+QMyhTbgn+SnguCbjRj//QKsE0IXifeAeyJuv8f8lz10f0sb8G8HBtxnw+z3N8i+OAbcL9Aq+4Gd9Q/ZKv8ItMrfQKvsy+fyIwM1IDKnA6QBDygYcB9pwIOsAc0NDxIGPAgY8JCyAU2GQ4QBDykbcL+dF2pAZL3+JQ34r4IB9zswYKTAXlQQOTyg+YuwbW3+jWSvPaqAa+ujCsK39X6grSMFXP6ATKENGCkIdxATXV5sJvQ94F/AQUT4Ivl7hoA/tYgVPWK8eLQ9oMeYPyXb5pgClTCBbXOsDVPC3zbmP/i9WEKggUoAp/U4soGOE2igYwqSb6BjC7j8yEBPETKn4ws4Lx5fIO/FYws4L5YsCHFD88OoF0sm/yBTSgEPg81g7oF6sVTIj6lkNnupAtyLyHqdAGSI3rwnFMh7sQTJi0jwfQIb/ES78Uv7G7y0QFuXBh5EGbKtywi0dQmgrU8s4PIHZArtxRPJTwX09wxZWyVy5dHAmiLMkXi/OCrF7feYT7IH9GRpL57swItlbZhUf9uUjePFVIEGSgV2VhrZQGkCDXQy0EBlC7j8yEC9iMwpnfRiuoIXy5JezGC9aG6YQXgxA/BiprIXTYZMwouZyl5MtfNCvYisVxbpxSwFL6Y68GK23fg5/gbPEWjrHOBB5JJtnSvQ1qlAW2cXcPkDMoX2YnbIg5jo8mIzoe8XTwLWCuGL5PtFwJ9axIoeMV7Mswc0X9qL+Q68WGDDFPrbpiCOFwsFGqgQ2IFFZAMVCTRQPtBABQVcfmSgpwiZk0d60VPwYgHpxXKsF80NyxFeLAfUVHllL5oM5Qkvllf2YqGdF+pFZL1OIb14ioIXCx148VS78Sv4G9z8Rdi2Nv9GstdWLODaumJB+LYO+FSJaetTC7j8AZlCe/HUAu5TAX2/yNoqkSvzgDVFmCPxfrFVxO33mE8r+O/P082fkm1zeoFKmMC2qWTDVC6IHN425j/4vVhZoIEqAzvrDLKBzhBooNOBBqpUwOVHBupFZE5nFnBePLNA3ouVCjgvVikIcUPzw6gXqwDVWxV4GGwGcw/Ui1XBzYjOq7KdF+pFZL3OAjJEb96zCuS9WJnkRST4PoENfrbd+NX8DV5NoK2rAQ+iOtnW1QXaujLQ1mcXcPkDMoX24tkhD2Kiy4vNhL5fPA1YK4Qvkt9jVmJT9Igx4Dn20J0rbcBzHRiwhg1T098gNeIYsKZAq9QEdtV5ZKucJ9Aq5wKtUqOAy48M1IDInM4nDXi+ggFrkAasxRrQ3LAWYcBagAFrKxvQZKhNGLC2sgFr2nmhBkTW6wLSgBcoGLCmAwNeaDd+HX+D1xFo6zrAg6hLtnVdgbauCbT1hQVc/oBMoQ14IfmpIPhmI8Z/5wDrhNBF4j3g3ojb7zFfZA9dPWkD1nNgwPo2TAN/g9SPY8AGAq3SANhZF5OtcrFAq9QDWqV+AZcfGagBkTldQhrwEgUD1icN2JA1oLlhQ8KADQEDNlI2oMnQiDBgI2UDNrDzQg2IrNelpAEvVTBgAwcGvMxu/Mb+Bm8s0NaNgQfRhGzrJgJt3QBo68sKuPwBmUIb8LKQBzHR5cVmQt8DXgSsFcIXyd8zBPypRazoEePFy+0BvULai1c48GJTG6aZv22axvFiM4EGagbswCvJBrpSoIGuABqoaQGXHxnoKULmdBXpxasUvNiU9GJz1ovmhs0JLzYHaqqFshdNhhaEF1soe7GZnRfqRWS9ria9eLWCF5s58OI1duO39Dd4S4G2bgk8iFZkW7cSaOtmQFtfU8DlD8gU2ovXkJ8K6O8ZsrZK5MrLgTVFmCPxfnF0itvvMV9rD+h10l68zoEXW9swbfxt0zqOF9sINFAbYGddTzbQ9QINdB3QQK0LuPzIQL2IzOkG0os3KHixNenFtqwXzQ3bEl5sC1RvO2UvmgztCC+2U/ZiGzsv1IvIet1IevFGBS+2ceDF9nbjd/A3eAeBtu4APIiOZFt3FGjrNkBbty/g8gdkCu3F9iEPYqLLi82Evl+8FlgrhC+S7xcBf2oRK3rEePEme0BvlvbizQ682MmG6exvm05xvNhZoIE6AzvwFrKBbhFooJuBBupUwOVHBnqKkDndSnrxVgUvdiK92IX1orlhF8KLXYCa6qrsRZOhK+HFrspe7GznhXoRWa/bSC/epuDFzg68eLvd+N38Dd5NoK27AQ+iO9nW3QXaujPQ1rcXcPkDMoX24u1H6P0ia6tErrwJWFOEORLvF6+NuP0e8x32gN4p7cU7HXixhw3T0982PeJ4sadAA/UEdtZdZAPdJdBAdwIN1KOAy48M1IvInO4mvXi3ghd7kF7sxXrR3LAX4cVeQPX2VvaiydCb8GJvZS/2tPNCvYis1z2kF+9R8GJPB1681278Pv4G7yPQ1n2AB9GXbOu+Am3dE2jrewu4/AGZQnvx3pAHMdHlxWZC3y/eAawVwhfJ7zErsSl6xBjwPnvo7pc24P0ODNjPhunvb5B+cQzYX6BV+gO76gGyVR4QaJX7gVbpV8DlRwZqQGROD5IGfFDBgP1IAw5gDWhuOIAw4ADAgAOVDWgyDCQMOFDZgP3tvFADIuv1EGnAhxQM2N+BAR+2G3+Qv8EHCbT1IOBBDCbberBAW/cH2vrhAi5/QKbQBnyY/FQQfLMR47/7gHVC6CLxHvCviNvvMT9iD92j0gZ81IEBh9gwQ/0NMiSOAYcKtMpQYGc9RrbKYwKt8ijQKkMKuPzIQA2IzOlx0oCPKxhwCGnAYawBzQ2HEQYcBhhwuLIBTYbhhAGHKxtwqJ0XakBkvZ4gDfiEggGHOjDgk3bjj/A3+AiBth4BPIiRZFuPFGjroUBbP1nA5Q/IFNqAT4Y8iIkuLzYT+h7wEWCtEL5I/p4h4E8tYkWPGC8+ZQ/o09JefNqBF0fZMKP9bTMqjhdHCzTQaGAHPkM20DMCDfQ00ECjCrj8yEBPETKnZ0kvPqvgxVGkF8ewXjQ3HEN4cQxQU2OVvWgyjCW8OFbZi6PtvFAvIuv1HOnF5xS8ONqBF8fZjT/e3+DjBdp6PPAgJpBtPUGgrUcDbT2ugMsfkCm0F8eRnwro7xmytkrkyqeANUWYI/F+8ZkUt99jft4e0BekvfiCAy9OtGEm+dtmYhwvThJooEnAznqRbKAXBRroBaCBJhZw+ZGBehGZ00ukF19S8OJE0ouTWS+aG04mvDgZqN4pyl40GaYQXpyi7MVJdl6oF5H1epn04ssKXpzkwIuv2I0/1d/gUwXaeirwIKaRbT1NoK0nAW39SgGXPyBTaC++EvIgJrq82Ezo+8XngbVC+CL5fhHwpxaxokeMF1+1B/Q1aS++5sCL022YGf62mR7HizMEGmgGsANfJxvodYEGeg1ooOkFXH5koKcImdMbpBffUPDidNKLM1kvmhvOJLw4E6ipWcpeNBlmEV6cpezFGXZeqBeR9XqT9OKbCl6c4cCLb9mNP9vf4LMF2no28CDmkG09R6CtZwBt/VYBlz8gU2gvvnWE3i+ytkrkyleBNUWYI/F+8bqI2+8xv20P6DvSXnzHgRfn2jDz/G0zN44X5wk00DxgZ71LNtC7Ag30DtBAcwu4/MhAvYjM6T3Si+8peHEu6cX5rBfNDecTXpwPVO8CZS+aDAsILy5Q9uI8Oy/Ui8h6vU968X0FL85z4MWFduMv8jf4IoG2XgQ8iMVkWy8WaOt5QFsvLODyB2QK7cWFIQ9iosuLzYS+X3wbWCuEL5LfY1ZiU/SIMeAH9tB9KG3ADx0YcIkNs9TfIEviGHCpQKssBXbVR2SrfCTQKh8CrbKkgMuPDNSAyJw+Jg34sYIBl5AGXMYa0NxwGWHAZYABlysb0GRYThhwubIBl9p5oQZE1usT0oCfKBhwqQMDfmo3/gp/g68QaOsVwINYSbb1SoG2Xgq09acFXP6ATKEN+Cn5qSD4ZiPGfx8A64TQReI94N8Rt99j/sweus+lDfi5AwOusmFW+xtkVRwDrhZoldXAzvqCbJUvBFrlc6BVVhVw+ZGBGhCZ05ekAb9UMOAq0oBrWAOaG64hDLgGMOBaZQOaDGsJA65VNuBqOy/UgMh6fUUa8CsFA652YMCv7cZf52/wdQJtvQ54EOvJtl4v0Nargbb+uoDLH5AptAG/DnkQE11ebCb0PeBnwFohfJH8PUPAn1rEih4xXvzGHtBvpb34rQMvbrBhNvrbZkMcL24UaKCNwA78jmyg7wQa6FuggTYUcPmRgZ4iZE7fk178XsGLG0gvbmK9aG64ifDiJqCmNit70WTYTHhxs7IXN9p5oV5E1usH0os/KHhxowMv/mg3/hZ/g28RaOstwIPYSrb1VoG23gi09Y8FXP6ATKG9+CP5qYD+niFrq0Su/AZYU4Q5Eu8Xn01x+z3mn+wB/Vnaiz878OI2G2a7v222xfHidoEG2g7srF/IBvpFoIF+BhpoWwGXHxmoF5E5/Up68VcFL24jvbiD9aK54Q7CizuA6t2p7EWTYSfhxZ3KXtxu54V6EVmv30gv/qbgxe0OvPi73fi7/A2+S6CtdwEPYjfZ1rsF2no70Na/F3D5AzKF9uLvIQ9iosuLzYS+X/wJWCuEL5LvFwF/ahEresR48Q97QP+U9uKfDry4x4bZ62+bPXG8uFeggfYCO/AvsoH+EmigP4EG2lPA5UcGeoqQOf1NevFvBS/uIb24j/WiueE+wov7gJrar+xFk2E/4cX9yl7ca+eFehFZr39IL/6j4MW9Drx4wG78g/4GPyjQ1geBB3GIbOtDAm29F2jrAwVc/oBMob144Ai9X2RtlciVfwBrijBH4v1i64jb7zH/W/zJVBiRbRvzDyZ5bdzh/a9/1zcOW/xC+3eFkcPbxvwHvxfNRWEb6KjC5K89upBroKMLwzdQpDD5Bkop5PIjA/UiMqdjCjkvHlMo78WUQs6LxxaGuKH5YdSLxyb/IFNKAA+DzWDugXqxBLgZ0XkdZeeFehFZr+OADNGb97hCeS8elVxhiXrxeLvxS/obvKRAW5cEHkQpsq1LCbT1UUBbH1/I5Q/IFNqLx4c8iIkuLzYT+n7xX+T/6AIZJL/HrMSm6BFjwBPsoTtR2oAnOjBgaRumjL9BSscxYBmBVikDnMCTyFY5SaBVTgRapXQhlx8ZqAGROZ1MGvBkBQOWJg1YljWguWFZwoBlAQOmKhvQZEglDJiqbMAydl6oAZH1SiMNmKZgwDIODJhuN36Gv8EzBNo6A3gQmWRbZwq0dRmgrdMLufwBmUIbMJ38VBB8sxHjvxOAdULoIvEecF/E7feYs+yhy5Y2YLYDA+bYMLn+BsmJY8BcgVbJBXZWHtkqeQKtkg20Sk4hlx8ZqAGROeWTBsxXMGAOacAC1oDmhgWEAQsAAxYqG9BkKCQMWKhswFw7L9SAyHoVkQYsUjBgrgMDenbjl/M3eDmBti4HPIjyZFuXF2jrXKCtvUIuf0Cm0Ab0Qh7ERJcXmwl9D5gFrBXCF8nfMwT8qUWs6BHjxVPsAT1V2ounOvBiBRumor9tKsTxYkWBBqoI7MDTyAY6TaCBTgUaqEIhlx8Z6ClC5nQ66cXTFbxYgfRiJdaL5oaVCC9WAmqqsrIXTYbKhBcrK3uxop0X6kVkvc4gvXiGghcrOvDimXbjV/E3eBWBtq4CPIiqZFtXFWjrikBbn1nI5Q/IFNqLZ5KfCujvGbK2SuTKU4A1RZgj8X5xTIrb7zGfZQ/o2dJePNuBF6vZMNX9bVMtjherCzRQdWBnnUM20DkCDXQ20EDVCrn8yEC9iMzpXNKL5yp4sRrpxRqsF80NaxBerAFUb01lL5oMNQkv1lT2YnU7L9SLyHqdR3rxPAUvVnfgxfPtxq/lb/BaAm1dC3gQtcm2ri3Q1tWBtj6/kMsfkCm0F88PeRATXV5sJvT94lnAWiF8kXy/CPhTi1jRI8aLF9gDeqG0Fy904MU6Nkxdf9vUiePFugINVBfYgReRDXSRQANdCDRQnUIuPzLQU4TMqR7pxXoKXqxDerE+60Vzw/qEF+sDNdVA2YsmQwPCiw2UvVjXzgv1IrJeF5NevFjBi3UdePESu/Eb+hu8oUBbNwQeRCOyrRsJtHVdoK0vKeTyB2QK7cVLjtD7RdZWiVx5AbCmCHMk3i+2ibj9HvOl9oBeJu3Fyxx4sbEN08TfNo3jeLGJQAM1AXbW5WQDXS7QQJcBDdS4kMuPDNSLyJyuIL14hYIXG5NebMp60dywKeHFpkD1NlP2osnQjPBiM2UvNrHzQr2IrNeVpBevVPBiEwdevMpu/Ob+Bm8u0NbNgQfRgmzrFgJt3QRo66sKufwBmUJ78aqQBzHR5cVmQt8vXgqsFcIXye8xK7EpesQY8Gp76K6RNuA1DgzY0oZp5W+QlnEM2EqgVVoBu+paslWuFWiVa4BWaVnI5UcGakBkTteRBrxOwYAtSQO2Zg1obtiaMGBrwIBtlA1oMrQhDNhG2YCt7LxQAyLrdT1pwOsVDNjKgQFvsBu/rb/B2wq0dVvgQbQj27qdQFu3Atr6hkIuf0Cm0Aa8gfxUEHyzEeO/q4F1Qugi8R5wf8Tt95hvtIeuvbQB2zswYAcbpqO/QTrEMWBHgVbpCOysm8hWuUmgVdoDrdKhkMuPDNSAyJxuJg14s4IBO5AG7MQa0NywE2HAToABOysb0GToTBiws7IBO9p5oQZE1usW0oC3KBiwowMD3mo3fhd/g3cRaOsuwIPoSrZ1V4G27gi09a2FXP6ATKENeGvIg5jo8mIzoe8BbwTWCuGL5O8ZAv7UIlb0iPHibfaA3i7txdsdeLGbDdPd3zbd4nixu0ADdQd24B1kA90h0EC3Aw3UrZDLjwz0FCFzupP04p0KXuxGerEH60Vzwx6EF3sANdVT2YsmQ0/Ciz2Vvdjdzgv1IrJed5FevEvBi90dePFuu/F7+Ru8l0Bb9wIeRG+yrXsLtHV3oK3vLuTyB2QK7cW7yU8F9PcMWVslcuVtwJoizJF4vzg2xe33mO+xB/ReaS/e68CLfWyYvv626RPHi30FGqgvsLPuIxvoPoEGuhdooD6FXH5koF5E5nQ/6cX7FbzYh/RiP9aL5ob9CC/2A6q3v7IX/++wEl7sr+zFvnZeqBeR9XqA9OIDCl7s68CLD9qNP8Df4AME2noA8CAGkm09UKCt+wJt/WAhlz8gU2gvPhjyICa6vNhM6PvFe4C1Qvgi+X4R8KcWsaJHjBcfsgf0YWkvPuzAi4NsmMH+thkUx4uDBRpoMLADHyEb6BGBBnoYaKBBhVx+ZKCnCJnTo6QXH1Xw4iDSi0NYL5obDiG8OASoqaHKXjQZhhJeHKrsxcF2XqgXkfV6jPTiYwpeHOzAi4/bjT/M3+DDBNp6GPAghpNtPVygrQcDbf14IZc/IFNoLz5+hN4vsrZK5MqHgDVFmCPxfvH6iNvvMT9hD+iT0l580oEXR9gwI/1tMyKOF0cKNNBIYGc9RTbQUwIN9CTQQCMKufzIQL2IzOlp0otPK3hxBOnFUawXzQ1HEV4cBVTvaGUvmgyjCS+OVvbiSDsv1IvIej1DevEZBS+OdODFZ+3GH+Nv8DECbT0GeBBjybYeK9DWI4G2fraQyx+QKbQXnw15EBNdXmwm9P3iE8BaIXyR/B6zEpuiR4wBn7OHbpy0Acc5MOB4G2aCv0HGxzHgBIFWmQDsqufJVnleoFXGAa0yvpDLjwzUgMicXiAN+IKCAceTBpzIGtDccCJhwImAAScpG9BkmEQYcJKyASfYeaEGRNbrRdKALyoYcIIDA75kN/5kf4NPFmjrycCDmEK29RSBtp4AtPVLhVz+gEyhDfgS+akg+GYjxn/PAeuE0EXiPeA/EbffY37ZHrpXpA34igMDTrVhpvkbZGocA04TaJVpwM56lWyVVwVa5RWgVaYWcvmRgRoQmdNrpAFfUzDgVNKA01kDmhtOJww4HTDgDGUDmgwzCAPOUDbgNDsv1IDIer1OGvB1BQNOc2DAN+zGn+lv8JkCbT0TeBCzyLaeJdDW04C2fqOQyx+QKbQB3wh5EBNdXmwm9D3gy8BaIXyR/D1DwJ9axIoeMV580x7Qt6S9+JYDL862Yeb422Z2HC/OEWigOcAOfJtsoLcFGugtoIFmF3L5kYGeImRO75BefEfBi7NJL85lvWhuOJfw4lygpuYpe9FkmEd4cZ6yF+fYeaFeRNbrXdKL7yp4cY4DL75nN/58f4PPF2jr+cCDWEC29QKBtp4DtPV7hVz+gEyhvfge+amA/p4ha6tErnwTWFOEORLvF59Lcfs95vftAV0o7cWFDry4yIZZ7G+bRXG8uFiggRYDO+sDsoE+EGighUADLSrk8iMD9SIypw9JL36o4MVFpBeXsF40N1xCeHEJUL1Llb1oMiwlvLhU2YuL7bxQLyLr9RHpxY8UvLjYgRc/tht/mb/Blwm09TLgQSwn23q5QFsvBtr640Iuf0Cm0F78OORBTHR5sZnQ94vvA2uF8EXy/SLgTy1iRY8YL35iD+in0l781IEXV9gwK/1tsyKOF1cKNNBKYAd+RjbQZwIN9CnQQCsKufzIQE8RMqfPSS9+ruDFFaQXV7FeNDdcRXhxFVBTq5W9aDKsJry4WtmLK+28UC8i6/UF6cUvFLy40oEXv7Qbf42/wdcItPUa4EGsJdt6rUBbrwTa+stCLn9AptBe/PIIvV9kbZXIlZ8Aa4owR+L94g0Rt99j/soe0K+lvfi1Ay+us2HW+9tmXRwvrhdooPXAzvqGbKBvBBroa6CB1hVy+ZGBehGZ07ekF79V8OI60osbWC+aG24gvLgBqN6Nyl40GTYSXtyo7MX1dl6oF5H1+o704ncKXlzvwIvf242/yd/gmwTaehPwIDaTbb1ZoK3XA239fSGXPyBTaC9+H/IgJrq82Ezo+8WvgLVC+CL5PWYlNkWPGAP+YA/dj9IG/NGBAbfYMFv9DbIljgG3CrTKVmBX/US2yk8CrfIj0CpbCrn8yEANiMzpZ9KAPysYcAtpwG2sAc0NtxEG3AYYcLuyAU2G7YQBtysbcKudF2pAZL1+IQ34i4IBtzow4K924+/wN/gOgbbeATyInWRb7xRo661AW/9ayOUPyBTagL+SnwqCbzZi/PcDsE4IXSTeAx6IuP0e82/20P0ubcDfHRhwlw2z298gu+IYcLdAq+wGdtYfZKv8IdAqvwOtsquQy48M1IDInP4kDfinggF3kQbcwxrQ3HAPYcA9gAH3KhvQZNhLGHCvsgF323mhBkTW6y/SgH8pGHC3AwP+bTf+Pn+D7xNo633Ag9hPtvV+gbbeDbT134Vc/oBMoQ34d8iDmOjyYjOh7wF/A9YK4Yvk7xkC/tQiVvSI8eI/9oAekPbiAQdePGjDHPK3zcE4Xjwk0ECHgB34L9lA/wo00AGggQ4WcvmRgZ4iZE6RIs6L5uekvXiQ9GJKUYgbmh9GvZhSlPzDOKpI14smg7kH6sWjirDNiM7rkJ0X6kVkvY4GMkRvXvNz0l485MCLx9iNf2xR5PCAxxaFb+tjgQdRoohr6xJF4dv6ENDWxxRx+QMyhfbiMeBBLB7o7xmytkrkyn+AT5sDIV2JHspxKW6/x3ycPaDHmz8l2+b4IpUwgW1T0oYp5W+bkkWxXiwl0EClgNN6AtlAJwg00PFFyTdQySIuPzJQLyJzOpH04okKXixZxHmxNOtFc8PShBdLA14so+xFk6EM4cUyyl4sZeeFehFZr5NIL56k4MVSJC8iwfcJbPCT7cYv62/wsgJtXRZ4EKlkW6cKtHUpoK1PLuLyB2QK7cWTQx7ERJcXmwl9v3gcsFYIXyTfLwL+1CJW9IjxYpo9oOnSXkx34MUMGybT3zYZcbyYKdBAmcAOzCIbKEuggdKBBsoo4vIjAz1FyJyySS9mK3gxg/RiDutFc8Mcwos5gBdzlb1oMuQSXsxV9mKmnRfqRWS98kgv5il4MdOBF/Ptxi/wN3iBQFsXAA+ikGzrQoG2zgTaOr+Iyx+QKbQX84/Q+0XWVolcmQasKcIcifeLbSNuv8dcZA+oJ+1Fz4EXy9kw5f1tUy6OF8sLNFB5YGedQjbQKQIN5AENVK6Iy48M1IvInE4lvXiqghfLkV6swHrR3LAC4cUKgBcrKnvRZKhIeLGishfL23mhXkTW6zTSi6cpeLG8Ay+ebjd+JX+DVxJo60rAg6hMtnVlgbYuD7T16UVc/oBMob14esiDmOjyYjOh7xeLgLVC+CL5PWYlNkWPGAOeYQ/dmdIGPNOBAavYMFX9DVIljgGrCrRKVWBXnUW2ylkCrXIm0CpVirj8yEANiMzpbNKAZysYsAppwGqsAc0NqxEGrAYYsLqyAU2G6oQBqysbsKqdF2pAZL3OIQ14joIBqzow4Ll249fwN3gNgbauATyImmRb1xRo66pAW59bxOUPyBTagOeSnwqCbzZi/HcGsE4IXSTeAx6MuP0e83n20J0vbcDzHRiwlg1T298gteIYsLZAq9QGdtYFZKtcINAq5wOtUquIy48M1IDInC4kDXihggFrkQaswxrQ3LAOYcA6gAHrKhvQZKhLGLCusgFr23mhBkTW6yLSgBcpGLC2AwPWsxu/vr/B6wu0dX3gQTQg27qBQFvXBtq6XhGXPyBTaAPWC3kQE11ebCb0PeB5wFohfJH8PUPAn1rEih4xXrzYHtBLpL14iQMvNrRhGvnbpmEcLzYSaKBGwA68lGygSwUa6BKggRoWcfmRgZ4iZE6XkV68TMGLDUkvNma9aG7YmPBiY6Cmmih70WRoQnixibIXG9l5oV5E1uty0ouXK3ixkQMvXmE3flN/gzcVaOumwINoRrZ1M4G2bgS09RVFXP6ATKG9eAX5qYD+niFrq0SuvBhYU4Q5Eu8Xx6e4/R7zlfaAXiXtxasceLG5DdPC3zbN43ixhUADtQB21tVkA10t0EBXAQ3UvIjLjwzUi8icriG9eI2CF5uTXmzJetHcsCXhxZZA9bZS9qLJ0IrwYitlL7aw80K9iKzXtaQXr1XwYgsHXrzObvzW/gZvLdDWrYEH0YZs6zYCbd0CaOvrirj8AZlCe/G6kAcx0eXFZkLfL14JrBXCF8n3i4A/tYgVPWK8eL09oDdIe/EGB15sa8O087dN2zhebCfQQO2AHXgj2UA3CjTQDUADtS3i8iMDPUXInNqTXmyv4MW2pBc7sF40N+xAeLEDUFMdlb1oMnQkvNhR2Yvt7LxQLyLrdRPpxZsUvNjOgRdvthu/k7/BOwm0dSfgQXQm27qzQFu3A9r65iIuf0Cm0F68+Qi9X2RtlciV1wNrijBH4v1iu4jb7zHfYg/ordJevNWBF7vYMF39bdMljhe7CjRQV2Bn3UY20G0CDXQr0EBdirj8yEC9iMzpdtKLtyt4sQvpxW6sF80NuxFe7AZUb3dlL5oM3Qkvdlf2Ylc7L9SLyHrdQXrxDgUvdnXgxTvtxu/hb/AeAm3dA3gQPcm27inQ1l2Btr6ziMsfkCm0F+8MeRATXV5sJvT94i3AWiF8kfwesxKbokeMAe+yh+5uaQPe7cCAvWyY3v4G6RXHgL0FWqU3sKvuIVvlHoFWuRtolV5FXH5koAZE5nQvacB7FQzYizRgH9aA5oZ9CAP2AQzYV9mAJkNfwoB9lQ3Y284LNSCyXveRBrxPwYC9HRjwfrvx+/kbvJ9AW/cDHkR/sq37C7R1b6Ct7y/i8gdkCm3A+8lPBcE3GzH+uwtYJ4QuEu8BD0Xcfo/5AXvoHpQ24IMODDjAhhnob5ABcQw4UKBVBgI76yGyVR4SaJUHgVYZUMTlRwZqQGROD5MGfFjBgANIAw5iDWhuOIgw4CDAgIOVDWgyDCYMOFjZgAPtvFADIuv1CGnARxQMONCBAR+1G3+Iv8GHCLT1EOBBDCXbeqhAWw8E2vrRIi5/QKbQBnw05EFMdHmxmdD3gA8Aa4XwRfL3DAF/ahEresR48TF7QB+X9uLjDrw4zIYZ7m+bYXG8OFyggYYDO/AJsoGeEGigx4EGGlbE5UcGeoqQOT1JevFJBS8OI704gvWiueEIwosjgJoaqexFk2Ek4cWRyl4cbueFehFZr6dILz6l4MXhDrz4tN34o/wNPkqgrUcBD2I02dajBdp6ONDWTxdx+QMyhfbi0+SnAvp7hqytErnyMWBNEeZIvF+ckOL2e8zP2AP6rLQXn3XgxTE2zFh/24yJ48WxAg00FthZz5EN9JxAAz0LNNCYIi4/MlAvInMaR3pxnIIXx5BeHM960dxwPOHF8UD1TlD2oskwgfDiBGUvjrXzQr2IrNfzpBefV/DiWAdefMFu/In+Bp8o0NYTgQcxiWzrSQJtPRZo6xeKuPwBmUJ78YWQBzHR5cVmQt8vPgOsFcIXyfeLgD+1iBU9Yrz4oj2gL0l78SUHXpxsw0zxt83kOF6cItBAU4Ad+DLZQC8LNNBLQANNLuLyIwM9RcicXiG9+IqCFyeTXpzKetHccCrhxalATU1T9qLJMI3w4jRlL06x80K9iKzXq6QXX1Xw4hQHXnzNbvzp/gafLtDW04EHMYNs6xkCbT0FaOvXirj8AZlCe/G1I/R+kbVVIle+CKwpwhyJ94s3Rtx+j/l1e0DfkPbiGw68ONOGmeVvm5lxvDhLoIFmATvrTbKB3hRooDeABppZxOVHBupFZE5vkV58S8GLM0kvzma9aG44m/DibKB65yh70WSYQ3hxjrIXZ9l5oV5E1utt0otvK3hxlgMvvmM3/lx/g88VaOu5wIOYR7b1PIG2ngW09TtFXP6ATKG9+E7Ig5jo8hsj3PeYXwfWCuGL5PeYldgUPWIM+K49dO9JG/A9Bwacb8Ms8DfI/DgGXCDQKguAXfU+2SrvC7TKe0CrzC/i8iMDNSAyp4WkARcqGHA+acBFrAHNDRcRBlwEGHCxsgFNhsWEARcrG3CBnRdqQGS9PiAN+IGCARc4MOCHduMv8Tf4EoG2XgI8iKVkWy8VaOsFQFt/WMTlD8gU2oAfkp8Kgm82Yvz3LrBOCF0k3gOaxXb5PeaP7KH7WNqAHzsw4DIbZrm/QZbFMeBygVZZDuysT8hW+USgVT4GWmVZEZcfGagBkTl9ShrwUwUDLiMNuII1oLnhCsKAKwADrlQ2oMmwkjDgSmUDLrfzQg2IrNdnpAE/UzDgcgcG/Nxu/FX+Bl8l0NargAexmmzr1QJtvRxo68+LuPwBmUIb8POQBzHR5cVmQt8DfgSsFcIXyd8zBPypRazoEePFL+wB/VLai1868OIaG2atv23WxPHiWoEGWgvswK/IBvpKoIG+BBpoTRGXHxnoKULm9DXpxa8VvLiG9OI61ovmhusIL64Damq9shdNhvWEF9cre3GtnRfqRWS9viG9+I2CF9c68OK3duNv8Df4BoG23gA8iI1kW28UaOu1QFt/W8TlD8gU2ovfkp8K6O8ZsrZK5MovgDVFmCPxfvH5FLffY/7OHtDvpb34vQMvbrJhNvvbZlMcL24WaKDNwM76gWygHwQa6HuggTYVcfmRgXoRmdOPpBd/VPDiJtKLW1gvmhtuIby4BajercpeNBm2El7cquzFzXZeqBeR9fqJ9OJPCl7c7MCLP9uNv83f4NsE2nob8CC2k229XaCtNwNt/XMRlz8gU2gv/hzyICa6vNhM6PvF74C1Qvgi+X4R8KcWsaJHjBd/sQf0V2kv/urAiztsmJ3+ttkRx4s7BRpoJ7ADfyMb6DeBBvoVaKAdRVx+ZKCnCJnT76QXf1fw4g7Si7tYL5ob7iK8uAuoqd3KXjQZdhNe3K3sxZ12XqgXkfX6g/TiHwpe3OnAi3/ajb/H3+B7BNp6D/Ag9pJtvVegrXcCbf1nEZc/IFNoL/55hN4vsrZK5MpfgDVFmCPxfrF9xO33mP+yB/RvaS/+7cCL+2yY/f622RfHi/sFGmg/sLP+IRvoH4EG+htooH1FXH5koF5E5nSA9OIBBS/uI714kPWiueFBwosHgeo9pOxFk+EQ4cVDyl7cb+eFehFZr39JL/6r4MX9DrxY/EMpXuTwgOYvwra1+TeSvfYoj2vro7zwbb0faOuIx+UPyBTaixEv3EFMdHn7CPc95r+Ag4jwRfJ7zEpsih4xBjza/tAx5k/JBjH/YJLXxh3e//h3/X8RPddjvf/+LOFFDm8Q8x/8BjQXhW0V828ke+1xHtcqx3nhW+UYL/lWOdbj8iMDNSAyp+M9zoDm56QNeKzHGbCkF+KG5odRA5b0kn8YpTxdA5oM5h6oAaPnlVQQcF4l7LxQAyLrdYLHGdD8nLQBgw63lgFP9P77s7QXOTyg+YuwbV3aS/7aMh7X1mW88G0d8KkS09Ynelz+gEyhDXiix30qCL7ZiPHf0V7y80foIvEe0PyAy+8xn2R/6GTzp2SDmH8wyWvjDu9//Lv+v4iea1nvvz9TvcjhDWL+g9+A5qKwrWL+jWSvTfO4VknzwrfKyV7yrVLW4/IjAzUgMqd0jzOg+TlpA5b1OANmeCFuaH4YNWCGl/zDyPR0DWgymHugBoyeV1JBwHml2nmhBkTWK8vjDGh+TtqAQYdby4DZ3n9/5niRwwOavwjb1jle8tfmelxb53rh2zrgUyWmrbM9Ln9AptAGzPbCHcSEl6dw32M+yUs+A8IXyd8zBPypRazoEePFPPtD+eZPybYx/2CS18Yd3v/4d/1/ET3XAu+/Pwu9yOFtY/6D34vmorANZP6NZK8t8rgGKvLCN1C+l3wDFXhcfmSgpwiZk+dxXjQ/J+3FAo/zYjkvxA3ND6NeLOcl/zDKe7peNBnMPVAvRs8rqSDgvArtvFAvIut1isd50fyctBeDDreWF0/1/vuzghc5PKD5i7BtXcFL/tqKHtfWFb3wbR3wqRLT1qd6XP6ATKG9eKrHfSqgv2fI2iqRK/O85LMizJF4v/hCitvvMZ9mf+h086dk25h/MMlr4w7vf/y7/r+Inmsl778/K3uRw9vG/Ae/F81FYRvI/BvJXnuGxzXQGV74BjrdS76BKnlcfmSgXkTmdKbHedH8nLQXK3mcF6t4IW5ofhj1YhUv+YdR1dP1oslg7oF6MXpeSQUB51XZzgv1IrJeZ3mcF83PSXsx6HBrefFs778/q3mRwwOavwjb1tW85K+t7nFtXd0L39YBnyoxbX22x+UPyBTai2d74Q5iosuLzYS+XzzNSz4DwhfJ94uAP7WIFT1ivHiO/aFzzZ+SbWP+wSSvjTu8//Hv+v8ieq41vP/+rOlFDm8b8x/8XjQXhW0g828ke+15HtdA53nhG+hcL/kGquFx+ZGBniJkTud7nBfNz0l7sYbHebGWF+KG5odRL9bykn8YtT1dL5oM5h6oF6PnlVQQcF417bxQLyLrdYHHedH8nLQXgw63lhcv9P77s44XOTyg+YuwbV3HS/7auh7X1nW98G0d8KkS09YXelz+gEyhvXihx30qoO8XWVslcuU5XvJZEeZIvF/sEHH7PeaL7A/VM39Kto35B5O8Nu7w/se/6/+L6LnW9/77s4EXObxtzH/we9FcFLaBzL+R7LUXe1wDXeyFb6B6XvINVN/j8iMD9SIyp0s8zovm56S9WN/jvNjQC3FD88OoFxt6yT+MRp6uF00Gcw/Ui9HzSioIOK8Gdl6oF5H1utTjvGh+TtqLQYdby4uXef/92diLHB7Q/EXYtm7sJX9tE49r6yZe+LYO+FSJaevLPC5/QKbQXrzMC3cQE11ebCb0/eJFXvIZoj8xEw3J7zEj9403vMSXxBjwcvtDV5g/JRvE/INJXht3eP/j3/X/RfRcm3r//dnMixzeIOY/+A1oLgrbKubfSPbaKz2uVa70wrfKFV7yrdLU4/IjAzUgMqerPM6A5uekDdjU4wzY3AtxQ/PDqAGbe8k/jBaergFNBnMP1IDR80oqCDivZnZeqAGR9bra4wxofk7agEGHW8uA13j//dnSixwe0PxF2LZu6SV/bSuPa+tWXvi2DvhUiWnrazwuf0Cm0Aa8xuM+FQTfbMT473Iv+fkjdJF4D5iS4vZ7zNfaH7rO/CnZIOYfTPLauMP7H/+u/y+i59ra++/PNl7k8AYx/8FvQHNR2FYx/0ay117vca1yvRe+Va7zkm+V1h6XHxmoAZE53eBxBjQ/J23A1h5nwLZeiBuaH0YN2NZL/mG083QNaDKYe6AGjJ5XUkHAebWx80INiKzXjR5nQPNz0gYMOtxaBmzv/fdnBy9yeEDzF2HbuoOX/LUdPa6tO3rh2zrgUyWmrdt7XP6ATKEN2N4LdxATXV5sJvQ94LVe8hkQvkj+niHgTy1iRY8YL95kf+hm86dk25h/MMlr4w7vf/y7/r+Inmsn778/O3uRw9vG/Ae/F81FYRvI/BvJXnuLxzXQLV74BrrZS76BOnlcfmSgpwiZ060e50Xzc9Je7ORxXuzihbih+WHUi1285B9GV0/XiyaDuQfqxeh5JRUEnFdnOy/Ui8h63eZxXjQ/J+3FoMOt5cXbvf/+7OZFDg9o/iJsW3fzkr+2u8e1dXcvfFsHfKrEtPXtHpc/IFNoL97ucZ8K6O8ZsrZK5MqbvOSzIsyReL84McXt95jvsD90p/lTsm3MP5jktXGH9z/+Xf9fRM+1h/ffnz29yOFtY/6D34vmorANZP6NZK+9y+Ma6C4vfAPd6SXfQD08Lj8yUC8ic7rb47xofk7aiz08zou9vBA3ND+MerGXl/zD6O3petFkMPdAvRg9r6SCgPPqaeeFehFZr3s8zovm56S9GHS4tbx4r/ffn328yOEBzV+Ebes+XvLX9vW4tu7rhW/rgE+VmLa+1+PyB2QK7cV7vXAHMdHlxWZC3y/e4SWfAeGL5PtFwJ9axIoeMV68z/7Q/eZPybYx/2CS18Yd3v/4d/1/ET3Xft5/f/b3Ioe3jfkPfi+ai8I2kPk3kr32AY9roAe88A10v5d8A/XzuPzIQE8RMqcHPc6L5uekvdjP47w4wAtxQ/PDqBcHeMk/jIGerhdNBnMP1IvR80oqCDiv/nZeqBeR9XrI47xofk7ai0GHW8uLD3v//TnIixwe0PxF2LYe5CV/7WCPa+vBXvi2DvhUiWnrhz0uf0Cm0F582OM+FdD3i6ytErnyPi/5rAhzJN4vdoy4/R7zI/aHHjV/SraN+QeTvDbu8P7Hv+v/i+i5DvH++3OoFzm8bcx/8HvRXBS2gcy/key1j3lcAz3mhW+gR73kG2iIx+VHBupFZE6Pe5wXzc9Je3GIx3lxmBfihuaHUS8O85J/GMM9XS+aDOYeqBej55VUEHBeQ+28UC8i6/WEx3nR/Jy0F4MOt5YXn/T++3OEFzk8oPmLsG09wkv+2pEe19YjvfBtHfCpEtPWT3pc/oBMob34pBfuICa6vNhM6PvFR7zkMyB8kfwesxKbokeMAZ+yP/S0+VOyQcw/mOS1cYf3P/5d/19Ez3WU99+fo73I4Q1i/oPfgOaisK1i/o1kr33G41rlGS98qzztJd8qozwuPzJQAyJzetbjDGh+TtqAozzOgGO8EDc0P4wacIyX/MMY6+ka0GQw90ANGD2vpIKA8xpt54UaEFmv5zzOgObnpA0YdLi1DDjO++/P8V7k8IDmL8K29Xgv+WsneFxbT/DCt3XAp0pMW4/zuPwBmUIbcJzHfSoIvtmI8d9TXvLzR+gi8R7wqBS332N+3v7QC+ZPyQYx/2CS18Yd3v/4d/1/ET3Xid5/f07yIoc3iPkPfgOai8K2ivk3kr32RY9rlRe98K3ygpd8q0z0uPzIQA2IzOkljzOg+TlpA070OANO9kLc0PwwasDJXvIPY4qna0CTwdwDNWD0vJIKAs5rkp0XakBkvV72OAOan5M2YNDh1jLgK95/f071IocHNH8Rtq2neslfO83j2nqaF76tAz5VYtr6FY/LH5AptAFf8cIdxESXF5sJfQ/4vJd8huhPzERD8vcMAX9qESt6xHjxVftDr5k/JdvG/INJXht3eP/j3/X/RfRcp3v//TnDixzeNuY/+L1oLgrbQObfSPba1z2ugV73wjfQa17yDTTd4/IjAz1FyJze8Dgvmp+T9uJ0j/PiTC/EDc0Po16c6SX/MGZ5ul40Gcw9UC9GzyuZgc7LbHZzD9SLyHq96XFeND8n7cWgw63lxbe8//6c7UUOD2j+Imxbz/aSv3aOx7X1HC98Wwd8qsS09Vselz8gU2gvvuVxnwro7xmytkrkyle95LMizJF4v2g+slx+j/lt+0PvmD8l28b8g0leG3d4/+Pf9f9F9Fznev/9Oc+LHN425j/4vWguCttA5t9I9tp3Pa6B3vXCN9A7XvINNNfj8iMD9SIyp/c8zovm56S9ONfjvDjfC3FD88OoF+d7yT+MBZ6uF00Gcw/Ui9HzSioIOK95dl6oF5H1et/jvGh+TtqLQYdby4sLvf/+XORFDg9o/iJsWy/ykr92sce19WIvfFsHfKrEtPVCj8sfkCm0Fxd64Q5iosuLzYS+X3zbSz4DwhfJ94uAP7WIFT1ivPiB/aEPzZ+SbWP+wSSvjTu8//Hv+v8ieq5LvP/+XOpFDm8b8x/8XjQXhW0g828ke+1HHtdAH3nhG+hDL/kGWuJx+ZGBniJkTh97nBf/P+btPtqmqn8f/zklRVEURejs8/zsIRRFURRFURRFEUIIIYQQQgihKIpQFEVRFEVRhKIoiqIoiqIoQr8x7+/cY+zW3p+1z3Wt97v5m/80hnuz5jXXnNd53XOcbf6etBfXJHFeXJcU4IHmL6NeXJdU8JexPknXiyaDeQbqxch5FSgIOK+1dl6oF5H1+iSJ86L5e9Je9DvcWl7ckPT//rsxKeHfAc0fBG3rjUkF/+ymJK6tNyUFb2ufnypRbb0hicvvkymwFzckcT8V0PtF1lbxXPlBUsGzIsyRuF+8L8Ht95g/tX/pM/NfybYx/2ABPxtzJP0f/673DyLnujnp//13S1LCv9vG/A9eL5oPBW0g828U9LOfJ3EN9HlS8Ab6LKngDbQ5icuPDNSLyJy+SOK8aP6etBc3J3Fe3JoU4IHmL6Ne3JpU8JexLUnXiyaDeQbqxch5FSgIOK8tdl6oF5H1+jKJ86L5e9Je9DvcWl78Kun//Xd7UsK/A5o/CNrW25MK/tkdSVxb70gK3tY+P1Wi2vqrJC6/T6bAXvwqKdhBjPfxsJnQ+8VPkwqeAeGL5PeYldgUOaIM+LX9S9+Y/0o2iPkHC/jZmCPp//h3vX8QOdedSf/vv7uSEv7dIOZ/8BrQfChoq5h/o6Cf/TaJa5Vvk4K3yjdJBW+VnUlcfmSgBkTm9F0SZ0Dz96QNuDOJM+DupAAPNH8ZNeDupIK/jD1JugY0GcwzUANGzqtAQcB57bLzQg2IrNf3SZwBzd+TNqDf4dYy4A9J/++/e5MS/h3Q/EHQtt6bVPDP7kvi2npfUvC29vmpEtXWPyRx+X0yBTbgD0ncTwXBm40o/32dVPD5I3SRuAc8M9Ht95h/tH/pJ/NfyQYx/2ABPxtzJP0f/673DyLnuj/p//33QFLCvxvE/A9eA5oPBW0V828U9LM/J3Gt8nNS8Fb5KangrbI/icuPDNSAyJx+SeIMaP6etAH3J3EGPJgU4IHmL6MGPJhU8JdxKEnXgCaDeQZqwMh5FSgIOK8Ddl6oAZH1+jWJM6D5e9IG9DvcWgb8Len//fdwUsK/A5o/CNrWh5MK/tkjSVxbH0kK3tY+P1Wi2vq3JC6/T6bABvwtKdhBjPfxsJnQe8AfkwqeAeGL5O8ZAv7UIlbkiPLi7/Yv/WH+K9k25h8s4GdjjqT/49/1/kHkXI8m/b//HktK+HfbmP/B60XzoaANZP6Ngn72zySugf5MCt5AfyQVvIGOJnH5kYGeImROfyVxXjR/T9qLR5M4Lx5PCvBA85dRLx5PKvjLOJGk60WTwTwD9WLkvAoUBJzXMTsv1IvIev2dxHnR/D1pL/odbi0vnkz6f/89lZTw74DmD4K29amkgn/2dBLX1qeTgre1z0+VqLY+mcTl98kU2Isnk7ifCujvGbK2iufK35MKnhVhjsT94ouJbr/H/E/4L4USZNvG/IMF/GzMkfR//bue8a/FD9k/CyX8u23M/+D1ovlQ0AY6I1Twz54Z4hrozFDwBkoIFbyBEkNcfmSgXkTmVCjEebFQSN6LiSHOi2eFAjzQ/GXUi2cV/EUmFgZeBpvBPCNe43j/ncLgZkTndYadF+pFZL3OBjJEbt6zQ/JePKNghSXqxXPsxi/ibfAioeBtXQR4EUXJti4q0NZnAG19TojL75MpsBfPCXgQ4308bCb0ftFYp6AZEL5I3i8C/tQiVuSI8uK59oCeJ+3F8xx4sZgNU9zbNsVieLG4QAMVB07r+WQDnS/QQOcBDVQsxOVHBnqKkDldQHrxAgUvFiO9WCIU4IElCC+WKPiLTCwJvAw2Q0nCiyUD/pgqyGYvSXgRWa8LgQyRm/dCBS8WJ3mR4P8c3wa/yG78Ut4GLxUK3talgBdRmmzr0gJtXRxo64tCXH6fTIG9eBF4EMMDvV9kbRXPlecCa4owR+J+sV2C2+8xX2wP6CXSXrwkpBLGt23K2DBlvW1TJoYXywo0UFlgZ11KNtClAg10CdBAZUJcfmSgXkTmVI70YjkFL5YhvVg+FOCB5Qkvli/4i0ysALwMNkMFwosVwM2IzqusnRfqRWS9LgMyRG7eyxS8WJbkRYL/c3wbPMlu/JC3wUOh4G0dAl5EMtnWyQJtXRZo66QQl98nU2AvJgU8iPE+HjYTer94MbBWCF8kv8esxKbIEWXAFHvoUqUNmOrAgGk2TLq3QdJiGDBdoFXSgV2VQbZKhkCrpAKtkhbi8iMDNSAyp0zSgJkKBkwjDZgVCvDALMKAWQV/kYnZwMtgM2QTBswO+KOnIJs9mzAgsl45QIbIzZujYMB0kgwJ/s/xbfBcu/HzvA2eFwre1nnAi8gn2zpfoK3TgbbODXH5fTIFNmAueBDDQ/BmI8p/KcA6IXSRuAcslOj2e8wV7aGrJG3ASiGVML4NUtmGqeJtkMoxDFhFoFWqADvrcrJVLhdolUpAq1QOcfmRgRoQmVNV0oBVFQxYmTRgtVCAB1YjDFit4C8ysTrwMtgM1QkDVgc3IzqvKnZeqAGR9boCyBC5ea9QMGAVkgwJ/s/xbfAr7cav4W3wGqHgbV0DeBE1ybauKdDWVYC2vjLE5ffJFNiAVwY8iPE+HjYTeg9YEVgrhC+Sv2cI+FOLWJEjyotX2QN6tbQXr3bgxVo2TG1v29SK4cXaAg1UG9iB15ANdI1AA10NNFCtEJcfGegpQuZ0bYjz4rUKXqwV4rxYJxTggXUIL9YBaqou8DLYDHUJL9YN+GOqIJu9LuFFZL2uAzJEbt7rFLxYm+RFgv9zfBv8ervx63kbvF4oeFvXA15EfbKt6wu0dW2gra8Pcfl9MgX24vXgQQwP9PcMWVvFc+VVwJoizJG4X5yd6PZ7zDfYA3qjtBdvDKmE8W2bBjZMQ2/bNIjhxYYCDdQQ2Fk3kQ10k0AD3Qg0UIMQlx8ZqBeROd0c4rx4s4IXG4Q4LzYKBXhgI8KLjYDqbQy8DDZDY8KLjcHNiM6roZ0X6kVkvW4BMkRu3lsUvNiQ5EWC/3N8G/xWu/GbeBu8SSh4WzcBXkRTsq2bCrR1Q6Ctbw1x+X0yBfbirQEPYryPh82E3i/eAKwVwhfJ+0XAn1rEihxRXrzNHtDbpb14uwMvNrNhmnvbplkMLzYXaKDmwA68g2ygOwQa6HaggZqFuPzIQE8RMqc7Q5wX71TwYrMQ58UWoQAPbEF4sQVQUy2Bl8FmaEl4sWXAH1MF2ewtCS8i63UXkCFy896l4MXmJC8S/J/j2+B3243fytvgrULB27oV8CJak23dWqCtmwNtfXeIy++TKbAX7wYPYnig94usreK58jZgTRHmSNwvtk9w+z3me+wBvVfai/eGVML4tk0bG6att23axPBiW4EGagvsrPvIBrpPoIHuBRqoTYjLjwzUi8ic2oU4L7ZT8GKbEOfF9qEAD2xPeLE9UL0dgJfBZuhAeLEDuBnRebW180K9iKzX/UCGyM17v4IX25K8SPB/jm+Dd7Qbv5O3wTuFgrd1J+BFdCbburNAW7cF2rpjiMvvkymwFzsGPIjxPh42E3q/eA+wVghfJL/HrMSmyBFlwAfsoesibcAuDgzY1Ybp5m2QrjEM2E2gVboBu+pBslUeFGiVLkCrdA1x+ZGBGhCZU3fSgN0VDNiVNGCPUIAH9iAM2KPgLzKxJ/Ay2Aw9CQP2DPijpyCbvSdhQGS9HgIyRG7ehxQM2I0kQ4L/c3wbvJfd+L29Dd47FLytewMvog/Z1n0E2rob0Na9Qlx+n0yBDdgLPIjhIXizEeW/B4B1QugicQ94VqLb7zE/bA9dX2kD9g2phPFtkH42TH9vg/SLYcD+Aq3SH9hZj5Ct8ohAq/QFWqVfiMuPDNSAyJwGkAYcoGDAfqQBB4YCPHAgYcCBBX+RiYOAl8FmGEQYcBC4GdF59bfzQg2IrNejQIbIzfuoggH7k2RI8H+Ob4MPtht/iLfBh4SCt/UQ4EUMJdt6qEBb9wfaenCIy++TKbABBwc8iPE+HjYTeg/4MLBWCF8kf88Q8KcWsSJHlBcfswd0mLQXhznw4nAbZoS3bYbH8OIIgQYaAezAx8kGelyggYYBDTQ8xOVHBnqKkDmNDHFeHKngxeEhzoujQgEeOIrw4iigpkYDL4PNMJrw4uiAP6YKstlHE15E1usJIEPk5n1CwYsjSF4k+D/Ht8HH2I0/1tvgY0PB23os8CLGkW09TqCtRwBtPSbE5ffJFNiLY8CDGB7o7xmytornyseANUWYI3G/OCfR7feYn7QHdLy0F8eHVML4ts0EG2ait20mxPDiRIEGmgjsrKfIBnpKoIHGAw00IcTlRwbqRWROk0KcFycpeHFCiPPi5FCAB04mvDgZqN4pwMtgM0whvDgF3IzovCbaeaFeRNbraSBD5OZ9WsGLE0leJPg/x7fBn7Ebf6q3waeGgrf1VOBFTCPbeppAW08E2vqZEJffJ1NgLz4T8CDG+3jYTOj94pPAWiF8kbxfBPypRazIEeXFZ+0BfU7ai8858OJ0G2aGt22mx/DiDIEGmgHswOfJBnpeoIGeAxpoeojLjwz0FCFzeiHEefEFBS9OD3FenBkK8MCZhBdnAjU1C3gZbIZZhBdnBfwxVZDNPovwIrJeLwIZIjfviwpenEHyIsH/Ob4NPttu/DneBp8TCt7Wc4AXMZds67kCbT0DaOvZIS6/T6bAXpwNHsTwQO8XWVvFc+WzwJoizJG4X+yQ4PZ7zC/ZA/qytBdfDqmE8W2beTbMfG/bzIvhxfkCDTQf2FmvkA30ikADvQw00LwQlx8ZqBeROb0a4rz4qoIX54U4Ly4IBXjgAsKLC4DqXQi8DDbDQsKLC8HNiM5rvp0X6kVkvV4DMkRu3tcUvDif5EWC/3N8G/x1u/EXeRt8USh4Wy8CXsRisq0XC7T1fKCtXw9x+X0yBfbi6wEPYryPh82E3i++BKwVwhfJ7zErsSlyRBnwDXvo3pQ24JsODLjEhlnqbZAlMQy4VKBVlgK76i2yVd4SaJU3gVZZEuLyIwM1IDKnt0kDvq1gwCWkAZeFAjxwGWHAZQV/kYnLgZfBZlhOGHB5wB89BdnsywkDIuv1DpAhcvO+o2DApSQZEvyf49vg79qNv8Lb4CtCwdt6BfAiVpJtvVKgrZcCbf1uiMvvkymwAd8FD2J4CN5sRPnvDWCdELpI3AMWTnT7Peb37KF7X9qA74dUwvg2yCobZrW3QVbFMOBqgVZZDeysD8hW+UCgVd4HWmVViMuPDNSAyJw+JA34oYIBV5EGXBMK8MA1hAHXFPxFJq4FXgabYS1hwLXgZkTntdrOCzUgsl4fARkiN+9HCgZcTZIhwf85vg3+sd3467wNvi4UvK3XAS9iPdnW6wXaejXQ1h+HuPw+mQIb8OOABzHex8NmQu8B3wPWCuGL5O8ZAv7UIlbkiPLiJ/aAbpD24gYHXtxow2zyts3GGF7cJNBAm4Ad+CnZQJ8KNNAGoIE2hrj8yEBPETKnz0KcFz9T8OLGEOfFzaEAD9xMeHEzUFNbgJfBZthCeHFLwB9TBdnsWwgvIuv1OZAhcvN+ruDFTSQvEvyf49vgX9iNv9Xb4FtDwdt6K/AitpFtvU2grTcBbf1FiMvvkymwF78AD2J4oL9nyNoqnis/AdYUYY7E/eLcRLffY/7SHtCvpL34VUgljG/bbLdhdnjbZnsML+4QaKAdwM76mmygrwUa6CuggbaHuPzIQL2IzOmbEOfFbxS8uD3EeXFnKMADdxJe3AlU7y7gZbAZdhFe3AVuRnReO+y8UC8i6/UtkCFy836r4MUdJC8S/J/j2+Df2Y2/29vgu0PB23o38CL2kG29R6CtdwBt/V2Iy+8dkl78LuBBjPfxsJnQ+8UvgbVC+CJ5vwj4U4tYkSPKi9/bA/qDtBd/cODFvTbMPm/b7I3hxX0CDbQP2IE/kg30o0AD/QA00N4Qlx8Z6ClC5vRTiPPiTwpe3BvivLg/FOCB+wkv7gdq6gDwMtgMBwgvHgj4Y6ogm/0A4UVkvX4GMkRu3p8VvLiP5EWC/3N8G/wXu/EPehv8YCh4Wx8EXsQhsq0PCbT1PqCtfwlx+X0yBfbiL+BBDA/0fpG1VTxXfg+sKcIcifvF+xPcfo/5V3tAf5P24m8hlTC+bXPYhjnibZvDMbx4RKCBjgA763eygX4XaKDfgAY6HOLyIwP1IjKnP0KcF/9Q8OLhEOfFo6EADzxKePEoUL3HgJfBZjhGePEYuBnReR2x80K9iKzXn0CGyM37p4IXj5C8SPB/jm+D/2U3/nFvgx8PBW/r48CLOEG29QmBtj4CtPVfIS6/T6bAXvwr4EGM9/GwmdD7xV+BtUL4Ivk9ZiU2RY4oA/5tD91JaQOedGDAUzbMaW+DnIphwNMCrXIa2FX/kK3yj0CrnARa5VSIy48M1IDInBKSOQOavydtwFMhzoCJyQEeaP4yasDE5IK/jDOSdQ1oMphnxGsc779zRjK2GdF5nbbzQg2IrNeZQIbIzWv+nikJyQY/TZIhwf85vg1eyG78s5IT/h3wrOTgbX0W8CIKJ3NtXTg5eFufBtq6UDKX3ydTYAMWAg9ieAjebET572/gJwhCF4l7wLMT3X6P+Wx76M4x/5VskHOSVcL4NkgRG6aot0GKJEcbsKhAqxQFTuC5ZKucK9Aq5yQXvFWKJHP5kYEaEJnTeaQBz1MwYJFkzoDFWAOaBxYjDFgMMGBxZQOaDMUJAxZXNmBROy/UgMh6nU8a8HwFAxYlyZDg/xzfBr/AbvwS3gYvIdDWJYAXUZJs65ICbV0UaOsLkrn8PpkCG/CCgAcx3sfDZkLvAc8G1grhi+TvGQL+1CJW5Ijy4oX2gF4k7cWLHHixlA1T2ts2pWJ4sbRAA5UGduDFZANdLNBAFwENVCqZy48M9BQhc7qE9OIlCl4sRXqxTHKAB5YhvFgG8GJZZS+aDGUJL5ZV9mJpOy/Ui8h6XUp68VIFL5Z24MVyduOX9zZ4eYG2Lg+8iApkW1cQaOvSQFuXS+by+2QK7MVy5E8F9PcMWVvFc+WFwJoizJG4X3wp0e33mC+zBzRJ2otJDrwYsmGSvW0TiuHFZIEGSgZ2VgrZQCkCDZQENFAomcuPDNSLyJxSSS+mKngxRHoxjfWieWAa4cU0wIvpyl40GdIJL6YrezHZzgv1IrJeGaQXMxS8mOzAi5l242d5GzxLoK2zgBeRTbZ1tkBbJwNtnZnM5ffJFNiLmQEPYryPh80EvP//OfAyYK0QvkjeLwL+1CJW5IjyYo49oLnSXsx14MU8Gybf2zZ5MbyYL9BA+cAOrEg2UEWBBsoFGigvmcuPDPQUIXOqRHqxkoIX80gvVk4O8MDKhBcrAzVVRdmLJkMVwotVlL2Yb+eFehFZr8tJL16u4MV8B16sajd+NW+DVxNo62rAi6hOtnV1gbbOB9q6ajKX3ydTYC9WJX8qoPeLrK3iuTIHWFOEORL3ix0T3H6P+Qp7QK+U9uKVDrxYw4ap6W2bGjG8WFOggWoCO+sqsoGuEmigK4EGqpHM5UcG6kVkTleTXrxawYs1SC/WSg7wwFqEF2sB1Vtb2YsmQ23Ci7WVvVjTzgv1IrJe15BevEbBizUdePFau/HreBu8jkBb1wFeRF2yresKtHVNoK2vTeby+2QK7MVrAx7EeB8Pmwl4//9z4BXAWiF8kfwesxKbIkeUAa+zh+56aQNe78CA9WyY+t4GqRfDgPUFWqU+sKtuIFvlBoFWuR5olXrJXH5koAZE5nQjacAbFQxYjzRgg+QAD2xAGLABYMCGygY0GRoSBmyobMD6dl6oAZH1uok04E0KBqzvwIA3243fyNvgjQTauhHwIhqTbd1YoK3rA219czKX3ydTYAPeTP5UELzZiPLfdcA6IXSRuAc8J9Ht95hvsYfuVmkD3urAgE1smKbeBmkSw4BNBVqlKbCzbiNb5TaBVrkVaJUmyVx+ZKAGROZ0O2nA2xUM2IQ0YDPWgOaBzQgDNgMM2FzZgCZDc8KAzZUN2NTOCzUgsl53kAa8Q8GATR0Y8E678Vt4G7yFQFu3AF5ES7KtWwq0dVOgre9M5vL7ZApswDsDHsR4Hw+bCXj//3PgLcBaIXyR/D1DwJ9axIocUV68yx7Qu6W9eLcDL7ayYVp726ZVDC+2Fmig1sAOvIdsoHsEGuhuoIFaJXP5kYGeImRO95JevFfBi61IL7ZJDvDANoQX2wA11VbZiyZDW8KLbZW92NrOC/Uisl73kV68T8GLrR14sZ3d+O29Dd5eoK3bAy+iA9nWHQTaujXQ1u2Sufw+mQJ7sR35UwH9PUPWVvFceRewpghzJO4XX050+z3m++0B7SjtxY4OvNjJhunsbZtOMbzYWaCBOgM76wGygR4QaKCOQAN1SubyIwP1IjKnLqQXuyh4sRPpxa7JAR7YlfBiV6B6uyl70WToRnixm7IXO9t5oV5E1utB0osPKnixswMvdrcbv4e3wXsItHUP4EX0JNu6p0Bbdwbaunsyl98nU2Avdg94EON9PGwm4P3/z4H3A2uF8EXyfhHwpxaxIkeUFx+yB7SXtBd7OfBibxumj7dtesfwYh+BBuoD7MCHyQZ6WKCBegEN1DuZy48M9BQhc+pLerGvghd7k17slxzggf0IL/YDaqq/shdNhv6EF/sre7GPnRfqRWS9HiG9+IiCF/s48OIAu/EHeht8oEBbDwRexCCyrQcJtHUfoK0HJHP5fTIF9uIA8qcCer/I2iqeKx8C1hRhjsT9YqcEt99jftQe0MHSXhzswItDbJih3rYZEsOLQwUaaCiwsx4jG+gxgQYaDDTQkGQuPzJQLyJzGkZ6cZiCF4eQXhyeHOCBwwkvDgeqd4SyF02GEYQXRyh7caidF+pFZL0eJ734uIIXhzrw4ki78Ud5G3yUQFuPAl7EaLKtRwu09VCgrUcmc/l9MgX24siABzHex8NmAt7//xz4KLBWCF8kv8esxKbIEWXAJ+yhGyNtwDEODDjWhhnnbZCxMQw4TqBVxgG76kmyVZ4UaJUxQKuMTebyIwM1IDKn8aQBxysYcCxpwAnJAR44gTDgBMCAE5UNaDJMJAw4UdmA4+y8UAMi6/UUacCnFAw4zoEBJ9mNP9nb4JMF2noy8CKmkG09RaCtxwFtPSmZy++TKbABJ5E/FQRvNqL89wSwTghdJO4BiyS6/R7z0/bQPSNtwGccGHCqDTPN2yBTYxhwmkCrTAN21rNkqzwr0CrPAK0yNZnLjwzUgMicniMN+JyCAaeSBpzOGtA8cDphwOmAAWcoG9BkmEEYcIayAafZeaEGRNbredKAzysYcJoDA75gN/5Mb4PPFGjrmcCLmEW29SyBtp4GtPULyVx+n0yBDfhCwIMY7+NhMwHv/38OfBpYK4Qvkr9nCPhTi1iRI8qLL9oDOlvai7MdeHGODTPX2zZzYnhxrkADzQV24EtkA70k0ECzgQaak8zlRwZ6ipA5vUx68WUFL84hvTgvOcAD5xFenAfU1HxlL5oM8wkvzlf24lw7L9SLyHq9QnrxFQUvznXgxVftxl/gbfAFAm29AHgRC8m2XijQ1nOBtn41mcvvkymwF18lfyqgv2fI2iqeK18E1hRhjsT94rxEt99jfs0e0Nelvfi6Ay8usmEWe9tmUQwvLhZooMXAznqDbKA3BBrodaCBFiVz+ZGBehGZ05ukF99U8OIi0otLkgM8cAnhxSVA9S5V9qLJsJTw4lJlLy6280K9iKzXW6QX31Lw4mIHXnzbbvxl3gZfJtDWy4AXsZxs6+UCbb0YaOu3k7n8PpkCe/HtgAcx3sfDZgLe//8c+BqwVghfJO8XAX9qEStyRHnxHXtA35X24rsOvLjChlnpbZsVMby4UqCBVgI78D2ygd4TaKB3gQZakczlRwZ6ipA5vU968X0FL64gvbgqOcADVxFeXAXU1GplL5oMqwkvrlb24ko7L9SLyHp9QHrxAwUvrnTgxQ/txl/jbfA1Am29BngRa8m2XivQ1iuBtv4wmcvvkymwFz8kfyqg94usreK58h1gTRHmSNwvdk5w+z3mj+wB/Vjaix878OI6G2a9t23WxfDieoEGWg/srE/IBvpEoIE+BhpoXTKXHxmoF5E5bSC9uEHBi+tIL25MDvDAjYQXNwLVu0nZiybDJsKLm5S9uN7OC/Uisl6fkl78VMGL6x148TO78Td7G3yzQFtvBl7EFrKttwi09XqgrT9L5vL7ZArsxc8CHsR4Hw+bCXj//3PgR8BaIXyR/B6zEpsiR5QBP7eH7gtpA37hwIBbbZht3gbZGsOA2wRaZRuwq74kW+VLgVb5AmiVrclcfmSgBkTm9BVpwK8UDLiVNOD25AAP3E4YcDtgwB3KBjQZdhAG3KFswG12XqgBkfX6mjTg1woG3ObAgN/Yjb/T2+A7Bdp6J/AidpFtvUugrbcBbf1NMpffJ1NgA35D/lQQvNmI8t/nwDohdJG4Byya6PZ7zN/aQ/edtAG/c2DA3TbMHm+D7I5hwD0CrbIH2Fnfk63yvUCrfAe0yu5kLj8yUAMic/qBNOAPCgbcTRpwL2tA88C9hAH3Agbcp2xAk2EfYcB9ygbcY+eFGhBZrx9JA/6oYMA9Dgz4k934+70Nvl+grfcDL+IA2dYHBNp6D9DWPyVz+X0yBTbgTwEPYryPh80EvP//OfBbYK0Qvkj+niHgTy1iRY4oL/5sD+gv0l78xYEXD9owh7xtczCGFw8JNNAhYAf+SjbQrwIN9AvQQAeTufzIQE8RMqffSC/+puDFg6QXDycHeOBhwouHgZo6ouxFk+EI4cUjyl48ZOeFehFZr99JL/6u4MVDDrz4h934R70NflSgrY8CL+IY2dbHBNr6ENDWfyRz+X0yBfbiH+RPBfT3DFlbxXPlz8CaIsyRuF+cn+j2e8x/2gP6l7QX/3LgxeM2zAlv2xyP4cUTAg10AthZf5MN9LdAA/0FNNDxZC4/MlAvInM6SXrxpIIXj5NePJUc4IGnCC+eAqr3tLIXTYbThBdPK3vxhJ0X6kVkvf4hvfiPghdPOPBiQor9UErCvwOaPwja1ubfKOhnz0jh2vqMlOBtfQJo64QULr9PpsBeTEgJdhDjfTxsJvR+8U/gICJ8kbxfBPypRazIEeXFM+0BLWT+K9k2hVJUwvi2zVk2TGFv25j/wevFwgINVBg4rWeTDXS2QAMVSil4A52VwuVHBnqKkDmdk8J58ZwUeS+elcJ5sUhKgAeav4x6sUjBX2RiUeBlsBnMM1AvFg34Y6ogm71oCu5FZL3OBTJEbt5zU+S9WJjkRYL/c3wb/Dy78Yt5G7yYQFsXA15EcbKtiwu0dWGgrc9L4fL7ZArsxfPInwro/SJrq3iuPBNYU4Q5EveLDyS4/R7z+faAXiDtxQsceLGEDVPS2zYlYnixpEADlQR21oVkA10o0EAXAA1UIoXLjwzUi8icLiK9eJGCF0uQXizFetE8sBThxVKAF0sre9FkKE14sbSyF0vaeaFeRNbrYtKLFyt4saQDL15iN34Zb4OXEWjrMsCLKEu2dVmBti4JtPUlKVx+n0yBvXhJwIMY7+NhM6H3i+cDa4XwRfJ7zEpsihxRBrzUHrpy0gYs58CA5W2YCt4GKR/DgBUEWqUCsKsuI1vlMoFWKQe0SvkULj8yUAMic0oiDZikYMDypAFDrAHNA0OEAUOAAZOVDWgyJBMGTFY2YAU7L9SAyHqlkAZMUTBgBQcGTLUbP83b4GkCbZ0GvIh0sq3TBdq6AtDWqSlcfp9MgQ2YSv5UELzZiPLfpcA6IXSRuAc8N9Ht95gz7KHLlDZgpgMDZtkw2d4GyYphwGyBVskGdlYO2So5Aq2SCbRKVgqXHxmoAZE55ZIGzFUwYBZpwDzWgOaBeYQB8wAD5isb0GTIJwyYr2zAbDsv1IDIelUkDVhRwYDZDgxYyW78yt4GryzQ1pWBF1GFbOsqAm2dDbR1pRQuv0+mwAasFPAgxvt42EzoPWAGsFYIXyR/zxDwpxaxIkeUFy+3B7SqtBerOvBiNRumurdtqsXwYnWBBqoO7MAryAa6QqCBqgINVC2Fy48M9BQhc7qS9OKVCl6sRnqxButF88AahBdrADVVU9mLJkNNwos1lb1Y3c4L9SKyXleRXrxKwYvVHXjxarvxa3kbvJZAW9cCXkRtsq1rC7R1daCtr07h8vtkCuzFq8mfCujvGbK2iufKy4E1RZgjcb/4SqLb7zFfYw/otdJevNaBF+vYMHW9bVMnhhfrCjRQXWBnXUc20HUCDXQt0EB1Urj8yEC9iMzpetKL1yt4sQ7pxXqsF80D6xFerAdUb31lL5oM9Qkv1lf2Yl07L9SLyHrdQHrxBgUv1nXgxRvtxm/gbfAGAm3dAHgRDcm2bijQ1nWBtr4xhcvvkymwF28MeBDjfTxsJvR+8RpgrRC+SN4vAv7UIlbkiPLiTfaA3iztxZsdeLGRDdPY2zaNYnixsUADNQZ24C1kA90i0EA3Aw3UKIXLjwz0FCFzupX04q0KXmxEerEJ60XzwCaEF5sANdVU2YsmQ1PCi02VvdjYzgv1IrJet5FevE3Bi40dePF2u/GbeRu8mUBbNwNeRHOyrZsLtHVjoK1vT+Hy+2QK7MXbyZ8K6P0ia6t4rrwJWFOEORL3i10S3H6P+Q57QO+U9uKdDrzYwoZp6W2bFjG82FKggVoCO+susoHuEmigO4EGapHC5UcG6kVkTneTXrxbwYstSC+2Yr1oHtiK8GIroHpbK3vRZGhNeLG1shdb2nmhXkTW6x7Si/coeLGlAy/eazd+G2+DtxFo6zbAi2hLtnVbgbZuCbT1vSlcfp9Mgb14b8CDGO/jYTOh94t3AGuF8EXye8xKbIocUQa8zx66dtIGbOfAgO1tmA7eBmkfw4AdBFqlA7Cr7idb5X6BVmkHtEr7FC4/MlADInPqSBqwo4IB25MG7MQa0DywE2HAToABOysb0GToTBiws7IBO9h5oQZE1usB0oAPKBiwgwMDdrEbv6u3wbsKtHVX4EV0I9u6m0BbdwDauksKl98nU2ADdiF/KgjebET57z5gnRC6SNwDnpfo9nvMD9pD113agN0dGLCHDdPT2yA9Yhiwp0Cr9AR21kNkqzwk0CrdgVbpkcLlRwZqQGROvUgD9lIwYA/SgL1ZA5oH9iYM2BswYB9lA5oMfQgD9lE2YE87L9SAyHo9TBrwYQUD9nRgwL524/fzNng/gbbuB7yI/mRb9xdo655AW/dN4fL7ZApswL4BD2K8j4fNhN4DPgisFcIXyd8zBPypRazIEeXFR+wBHSDtxQEOvDjQhhnkbZuBMbw4SKCBBgE78FGygR4VaKABQAMNTOHyIwM9RcicBpNeHKzgxYGkF4ewXjQPHEJ4cQhQU0OVvWgyDCW8OFTZi4PsvFAvIuv1GOnFxxS8OMiBF4fZjT/c2+DDBdp6OPAiRpBtPUKgrQcBbT0shcvvkymwF4eRPxXQ3zNkbRXPlY8Aa4owR+J+8dVEt99jftwe0JHSXhzpwIujbJjR3rYZFcOLowUaaDSws54gG+gJgQYaCTTQqBQuPzJQLyJzGkN6cYyCF0eRXhzLetE8cCzhxbFA9Y5T9qLJMI7w4jhlL46280K9iKzXk6QXn1Tw4mgHXhxvN/4Eb4NPEGjrCcCLmEi29USBth4NtPX4FC6/T6bAXhwf8CDG+3jYTOj94uPAWiF8kbxfBPypRazIEeXFp+wBnSTtxUkOvDjZhpnibZvJMbw4RaCBpgA78GmygZ4WaKBJQANNTuHyIwM9RcicniG9+IyCFyeTXpzKetE8cCrhxalATU1T9qLJMI3w4jRlL06x80K9iKzXs6QXn1Xw4hQHXnzObvzp3gafLtDW04EXMYNs6xkCbT0FaOvnUrj8PpkCe/E58qcCer/I2iqeK58C1hRhjsT9YtcEt99jft4e0BekvfiCAy/OtGFmedtmZgwvzhJooFnAznqRbKAXBRroBaCBZqZw+ZGBehGZ02zSi7MVvDiT9OIc1ovmgXMIL84BqneushdNhrmEF+cqe3GWnRfqRWS9XiK9+JKCF2c58OLLduPP8zb4PIG2nge8iPlkW88XaOtZQFu/nMLl98kU2IsvBzyI8T4eNhN6v/g8sFYIXyS/x6zEpsgRZcBX7KF7VdqArzow4AIbZqG3QRbEMOBCgVZZCOyq18hWeU2gVV4FWmVBCpcfGagBkTm9ThrwdQUDLiANuIg1oHngIsKAiwADLlY2oMmwmDDgYmUDLrTzQg2IrNcbpAHfUDDgQgcGfNNu/CXeBl8i0NZLgBexlGzrpQJtvRBo6zdTuPw+mQIb8E3yp4LgzUaU/14B1gmhi8Q9YLFEt99jfsseurelDfi2AwMus2GWextkWQwDLhdoleXAznqHbJV3BFrlbaBVlqVw+ZGBGhCZ07ukAd9VMOAy0oArWAOaB64gDLgCMOBKZQOaDCsJA65UNuByOy/UgMh6vUca8D0FAy53YMD37cZf5W3wVQJtvQp4EavJtl4t0NbLgbZ+P4XL75MpsAHfD3gQ4308bCb0HvAtYK0Qvkj+niHgTy1iRY4oL35gD+iH0l780IEX19gwa71tsyaGF9cKNNBaYAd+RDbQRwIN9CHQQGtSuPzIQE8RMqePSS9+rODFNaQX17FeNA9cR3hxHVBT65W9aDKsJ7y4XtmLa+28UC8i6/UJ6cVPFLy41oEXN9iNv9Hb4BsF2noj8CI2kW29SaCt1wJtvSGFy++TKbAXN5A/FdDfM2RtFc+VHwBrijBH4n5xQaLb7zF/ag/oZ9Je/MyBFzfbMFu8bbM5hhe3CDTQFmBnfU420OcCDfQZ0ECbU7j8yEC9iMzpC9KLXyh4cTPpxa2sF80DtxJe3ApU7zZlL5oM2wgvblP24hY7L9SLyHp9SXrxSwUvbnHgxa/sxt/ubfDtAm29HXgRO8i23iHQ1luAtv4qhcvvkymwF78KeBDjfTxsJvR+8VNgrRC+SN4vAv7UIlbkiPLi1/aAfiPtxW8ceHGnDbPL2zY7Y3hxl0AD7QJ24LdkA30r0EDfAA20M4XLjwz0FCFz+o704ncKXtxJenE360XzwN2EF3cDNbVH2Ysmwx7Ci3uUvbjLzgv1IrJe35Ne/F7Bi7scePEHu/H3eht8r0Bb7wVexD6yrfcJtPUuoK1/SOHy+2QK7MUfyJ8K6P0ia6t4rvwaWFOEORL3i90S3H6P+Ud7QH+S9uJPDry434Y54G2b/TG8eECggQ4AO+tnsoF+Fmign4AG2p/C5UcG6kVkTr+QXvxFwYv7SS8eZL1oHniQ8OJBoHoPKXvRZDhEePGQshcP2HmhXkTW61fSi78qePGAAy/+Zjf+YW+DHxZo68PAizhCtvURgbY+ALT1bylcfp9Mgb34W8CDGO/jYTOh94s/AmuF8EXye8xKbIocUQb83R66P6QN+IcDAx61YY55G+RoDAMeE2iVY8Cu+pNslT8FWuUPoFWOpnD5kYEaEJnTX6QB/1Iw4FHSgMdZA5oHHicMeBww4AllA5oMJwgDnlA24DE7L9SAyHr9TRrwbwUDHnNgwJN245/yNvgpgbY+BbyI02RbnxZo62NAW59M4fL7ZApswJPkTwXBm40o//0OrBNCF4l7wOKJbr/H/E/4p01qgmyDmH+wgJ+NOZL+r3/XM/61+Kn2z1IT/t0g5n/wGtB8KGirnJFa8M+emcq1ypmpwVslIbXgrZKYyuVHBmpAZE6FUjkDFkqVN2BiKmfAs1IDPND8ZdSAZxX8RSYWBl4Gm8E8AzVgYXAzovM6w84LNSCyXmcDGSI379mp8gY8o2CFJWrAc+zGL+Jt8CICbV0EeBFFybYuKtDWZwBtfU4ql98nU2ADnhPwIMb7eNhM6D3gP8j/eQUySP6eIeBPLWJFjigvnmsP6HnSXjzPgReL2TDFvW1TLIYXiws0UHHgtJ5PNtD5Ag10HtBAxVK5/MhATxEypwtIL16g4MVipBdLsF40DyxBeLEE4MWSyl40GUoSXiyp7MXidl6oF5H1upD04oUKXizuwIsX2Y1fytvgpQTauhTwIkqTbV1aoK2LA219USqX3ydTYC9eRP5UKOR5TpxB2yqeK88F1hRhjsT94sJEt99jvtge0EukvXiJAy+WsWHKetumTAwvlhVooLLAzrqUbKBLBRroEqCByqRy+ZGBehGZUznSi+UUvFiG9GJ51ovmgeUJL5YHvFhB2YsmQwXCixWUvVjWzgv1IrJel5FevEzBi2UdeDHJbvyQt8FDAm0dAl5EMtnWyQJtXRZo66RULr9PpsBeTAp4EON9PGwm9H7xYmCtEL7EcmCC58+SEgqWDfCnFrEiR5QXU+wBTZX2YqoDL6bZMOnetkmL4cV0gQZKB3ZgBtlAGQINlAo0UFoqlx8Z6ClC5pRJejFTwYtppBezWC+aB2YRXswCaipb2YsmQzbhxWxlL6bbeaFeRNYrh/RijoIX0x14Mddu/Dxvg+cJtHUe8CLyybbOF2jrdKCtc1O5/D6ZAnsx9z+6X2RtFc+VKcCaIsyRuF98MMHt95gr2gNaSdqLlRx4sbINU8XbNpVjeLGKQANVAXbW5WQDXS7QQJWABqqcyuVHBupFZE5VSS9WVfBiZdKL1VgvmgdWI7xYDaje6speNBmqE16sruzFKnZeqBeR9bqC9OIVCl6s4sCLV9qNX8Pb4DUE2roG8CJqkm1dU6CtqwBtfWUql98nU2AvXhnwIMb7eNhM6P1iRWCtEL7EciCbTYlNkSPKgFfZQ3e1tAGvdmDAWjZMbW+D1IphwNoCrVIb2FXXkK1yjUCrXA20Sq1ULj8yUAMic7qWNOC1CgasRRqwDmtA88A6hAHrAAasq2xAk6EuYcC6ygasbeeFGhBZr+tIA16nYMDaDgx4vd349bwNXk+gresBL6I+2db1Bdq6NtDW16dy+X0yBTbg9eRPBcGbjSj/XQWsE0KXWP5DD9r5iW6/x3yDPXQ3ShvwRgcGbGDDNPQ2SIMYBmwo0CoNgZ11E9kqNwm0yo1AqzRI5fIjAzUgMqebSQPerGDABqQBG7EGNA9sRBiwEWDAxsoGNBkaEwZsrGzAhnZeqAGR9bqFNOAtCgZs6MCAt9qN38Tb4E0E2roJ8CKakm3dVKCtGwJtfWsql98nU2AD3hrwIMb7eNhM6D3gDcBaIXyJ5cAEz58lJRQsG+BPLWJFjigv3mYP6O3SXrzdgReb2TDNvW3TLIYXmws0UHNgB95BNtAdAg10O9BAzVK5/MhATxEypztJL96p4MVmpBdbsF40D2xBeLEFUFMtlb1oMrQkvNhS2YvN7bxQLyLrdRfpxbsUvNjcgRfvthu/lbfBWwm0dSvgRbQm27q1QFs3B9r67lQuv0+mwF68m/ypUMjznDiDtlU8V94GrCnCHIn7xdcS3X6P+R57QO+V9uK9DrzYxoZp622bNjG82FaggdoCO+s+soHuE2ige4EGapPK5UcG6kVkTu1IL7ZT8GIb0ovtWS+aB7YnvNgeqN4Oyl40GToQXuyg7MW2dl6oF5H1up/04v0KXmzrwIsd7cbv5G3wTgJt3Ql4EZ3Jtu4s0NZtgbbumMrl98kU2IsdAx7EeB8Pmwm9X7wHWCuEL7EcmOD5s6SEgmUD/KlFrMgR5cUH7AHtIu3FLg682NWG6eZtm64xvNhNoIG6ATvwQbKBHhRooC5AA3VN5fIjAz1FyJy6k17sruDFrqQXe7BeNA/sQXixB1BTPZW9aDL0JLzYU9mL3ey8UC8i6/UQ6cWHFLzYzYEXe9mN39vb4L0F2ro38CL6kG3dR6CtuwFt3SuVy++TKbAXe/1H94usreK58gFgTRHmSNwvdk9w+z3mh+0B7Svtxb4OvNjPhunvbZt+MbzYX6CB+gM76xGygR4RaKC+QAP1S+XyIwP1IjKnAaQXByh4sR/pxYGsF80DBxJeHAhU7yBlL/7vsBJeHKTsxf52XqgXkfV6lPTiowpe7O/Ai4Ptxh/ibfAhAm09BHgRQ8m2HirQ1v2Bth6cyuX3yRTYi4MDHsR4Hw+bCb1ffBhYK4QvsRzIZlNiU+SIMuBj9tANkzbgMAcGHG7DjPA2yPAYBhwh0CojgF31ONkqjwu0yjCgVYancvmRgRoQmdNI0oAjFQw4nDTgKNaA5oGjCAOOAgw4WtmAJsNowoCjlQ04ws4LNSCyXk+QBnxCwYAjHBhwjN34Y70NPlagrccCL2Ic2dbjBNp6BNDWY1K5/D6ZAhtwDPlTQfBmI8p/jwHrhNAllv/Qg3ZBotvvMT9pD914aQOOd2DACTbMRG+DTIhhwIkCrTIR2FlPka3ylECrjAdaZUIqlx8ZqAGROU0iDThJwYATSANOZg1oHjiZMOBkwIBTlA1oMkwhDDhF2YAT7bxQAyLr9TRpwKcVDDjRgQGfsRt/qrfBpwq09VTgRUwj23qaQFtPBNr6mVQuv0+mwAZ8JuBBjPfxsJnQe8AngbVC+BLLgQmeP0tKKFg2wJ9axIocUV581h7Q56S9+JwDL063YWZ422Z6DC/OEGigGcAOfJ5soOcFGug5oIGmp3L5kYGeImROL5BefEHBi9NJL85kvWgeOJPw4kygpmYpe9FkmEV4cZayF2fYeaFeRNbrRdKLLyp4cYYDL862G3+Ot8HnCLT1HOBFzCXbeq5AW88A2np2KpffJ1NgL84mfyoU8jwnzqBtFc+VzwJrijBH4n7x9US332N+yR7Ql6W9+LIDL86zYeZ722ZeDC/OF2ig+cDOeoVsoFcEGuhloIHmpXL5kYF6EZnTq6QXX1Xw4jzSiwtYL5oHLiC8uACo3oXKXjQZFhJeXKjsxfl2XqgXkfV6jfTiawpenO/Ai6/bjb/I2+CLBNp6EfAiFpNtvVigrecDbf16KpffJ1NgL74e8CDG+3jYTOj94kvAWiF8ieXABM+fJSUULBvgTy1iRY4oL75hD+ib0l5804EXl9gwS71tsySGF5cKNNBSYAe+RTbQWwIN9CbQQEtSufzIQE8RMqe3SS++reDFJaQXl7FeNA9cRnhxGVBTy5W9aDIsJ7y4XNmLS+28UC8i6/UO6cV3FLy41IEX37Ubf4W3wVcItPUK4EWsJNt6pUBbLwXa+t1ULr9PpsBefPc/ul9kbRXPlW8Aa4owR+J+sUeC2+8xv2cP6PvSXnzfgRdX2TCrvW2zKoYXVws00GpgZ31ANtAHAg30PtBAq1K5/MhAvYjM6UPSix8qeHEV6cU1rBfNA9cQXlwDVO9aZS+aDGsJL65V9uJqOy/Ui8h6fUR68SMFL6524MWP7cZf523wdQJtvQ54EevJtl4v0Nargbb+OJXL75MpsBc/DngQ4308bCb0fvE9YK0QvsRyIJtNiU2RI8qAn9hDt0HagBscGHCjDbPJ2yAbYxhwk0CrbAJ21adkq3wq0CobgFbZmMrlRwZqQGROn5EG/EzBgBtJA25mDWgeuJkw4GbAgFuUDWgybCEMuEXZgJvsvFADIuv1OWnAzxUMuMmBAb+wG3+rt8G3CrT1VuBFbCPbeptAW28C2vqLVC6/T6bABvyC/KkgeLMR5b9PgHVC6BLLf+hBK5Ho9nvMX9pD95W0Ab9yYMDtNswOb4Nsj2HAHQKtsgPYWV+TrfK1QKt8BbTK9lQuPzJQAyJz+oY04DcKBtxOGnAna0DzwJ2EAXcCBtylbECTYRdhwF3KBtxh54UaEFmvb0kDfqtgwB0ODPid3fi7vQ2+W6CtdwMvYg/Z1nsE2noH0NbfpXL5fTIFNuB3AQ9ivI+HzYTeA34JrBXCl1gOTPD8WVJCwbIB/tQiVuSI8uL39oD+IO3FHxx4ca8Ns8/bNntjeHGfQAPtA3bgj2QD/SjQQD8ADbQ3lcuPDPQUIXP6ifTiTwpe3Et6cT/rRfPA/YQX9wM1dUDZiybDAcKLB5S9uM/OC/Uisl4/k178WcGL+xx48Re78Q96G/ygQFsfBF7EIbKtDwm09T6grX9J5fL7ZArsxV/InwqFPM+JM2hbxXPl98CaIsyRuF9clOj2e8y/2gP6m7QXf3PgxcM2zBFv2xyO4cUjAg10BNhZv5MN9LtAA/0GNNDhVC4/MlAvInP6g/TiHwpePEx68SjrRfPAo4QXjwLVe0zZiybDMcKLx5S9eMTOC/Uisl5/kl78U8GLRxx48S+78Y97G/y4QFsfB17ECbKtTwi09RGgrf9K5fL7ZArsxb8CHsR4Hw+bCb1f/BVYK4QvsRyY4PmzpISCZQP8qUWsyBHlxb/tAT0p7cWTDrx4yoY57W2bUzG8eFqggU4DO/AfsoH+EWigk0ADnUrl8iMDPUXInBLSOC+avyftxVOkFxPTAjzQ/GXUi4lpBX8ZZ6TpetFkMM9AvXhGGrYZ0XmdtvNCvYis15lAhsjNa/6etBdPO/BiIbvxz0pL+HfAs9KCt/VZwIsonMa1deG04G19GmjrQmlcfp9Mgb1YCDyI4YHeL7K2iufKv4GfNicDuhI9lD0T3H6P+Wx7QM8x/5Vsm3PSVML4tk0RG6aot22KpEV7sahAAxUFTuu5ZAOdK9BA56QVvIGKpHH5kYF6EZnTeaQXz1PwYpE0zovFWC+aBxYjvFgM8GJxZS+aDMUJLxZX9mJROy/Ui8h6nU968XwFLxYleZHg/xzfBr/AbvwS3gYvIdDWJYAXUZJs65ICbV0UaOsL0rj8PpkCe/GCgAcx3sfDZkLvF88G1grhi9/94v9P2BQ5ogx4oT10F0kb8CIHBixlw5T2NkipGAYsLdAqpYFddTHZKhcLtMpFQKuUSuPyIwM1IDKnS0gDXqJgwFKkAcuwBjQPLEMYsAxgwLLKBjQZyhIGLKtswNJ2XqgBkfW6lDTgpQoGLO3AgOXsxi/vbfDyAm1dHngRFci2riDQ1qWBti6XxuX3yRTYgOXInwqCNxtR/rsQWCeELhL3gCUT3X6P+TJ76JKkDZjkwIAhGybZ2yChGAZMFmiVZGBnpZCtkiLQKklAq4TSuPzIQA2IzCmVNGCqggFDpAHTWAOaB6YRBkwDDJiubECTIZ0wYLqyAZPtvFADIuuVQRowQ8GAyQ4MmGk3fpa3wbME2joLeBHZZFtnC7R1MtDWmWlcfp9MgQ2YGfAgxvt42EzoPeBlwFohfJH8PUPAn1rEihxRXsyxBzRX2ou5DryYZ8Pke9smL4YX8wUaKB/YgRXJBqoo0EC5QAPlpXH5kYGeImROlUgvVlLwYh7pxcqsF80DKxNerAzUVBVlL5oMVQgvVlH2Yr6dF+pFZL0uJ714uYIX8x14sard+NW8DV5NoK2rAS+iOtnW1QXaOh9o66ppXH6fTIG9WJX8qYD+niFrq3iuzAHWFGGOxP3i4kS332O+wh7QK6W9eKUDL9awYWp626ZGDC/WFGigmsDOuopsoKsEGuhKoIFqpHH5kYF6EZnT1aQXr1bwYg3Si7VYL5oH1iK8WAuo3trKXjQZahNerK3sxZp2XqgXkfW6hvTiNQperOnAi9fajV/H2+B1BNq6DvAi6pJtXVegrWsCbX1tGpffJ1NgL14b8CDG+3jYTOj94hXAWiF8kbxfBPypRazIEeXF6+wBvV7ai9c78GI9G6a+t23qxfBifYEGqg/swBvIBrpBoIGuBxqoXhqXHxnoKULmdCPpxRsVvFiP9GID1ovmgQ0ILzYAaqqhshdNhoaEFxsqe7G+nRfqRWS9biK9eJOCF+s78OLNduM38jZ4I4G2bgS8iMZkWzcWaOv6QFvfnMbl98kU2Is3/0f3i6yt4rnyOmBNEeZI3C8+lOD2e8y32AN6q7QXb3XgxSY2TFNv2zSJ4cWmAg3UFNhZt5ENdJtAA90KNFCTNC4/MlAvInO6nfTi7QpebEJ6sRnrRfPAZoQXmwHV21zZiyZDc8KLzZW92NTOC/Uisl53kF68Q8GLTR148U678Vt4G7yFQFu3AF5ES7KtWwq0dVOgre9M4/L7ZArsxTsDHsR4Hw+bCb1fvAVYK4Qvkt9jVmJT5Igy4F320N0tbcC7HRiwlQ3T2tsgrWIYsLVAq7QGdtU9ZKvcI9AqdwOt0iqNy48M1IDInO4lDXivggFbkQZswxrQPLANYcA2gAHbKhvQZGhLGLCtsgFb23mhBkTW6z7SgPcpGLC1AwO2sxu/vbfB2wu0dXvgRXQg27qDQFu3Btq6XRqX3ydTYAO2I38qCN5sRPnvLmCdELpI3ANemOj2e8z320PXUdqAHR0YsJMN09nbIJ1iGLCzQKt0BnbWA2SrPCDQKh2BVumUxuVHBmpAZE5dSAN2UTBgJ9KAXVkDmgd2JQzYFTBgN2UDmgzdCAN2UzZgZzsv1IDIej1IGvBBBQN2dmDA7nbj9/A2eA+Btu4BvIieZFv3FGjrzkBbd0/j8vtkCmzA7gEPYryPh82E3gPeD6wVwhfJ3zME/KlFrMgR5cWH7AHtJe3FXg682NuG6eNtm94xvNhHoIH6ADvwYbKBHhZooF5AA/VO4/IjAz1FyJz6kl7sq+DF3qQX+7FeNA/sR3ixH1BT/ZW9aDL0J7zYX9mLfey8UC8i6/UI6cVHFLzYx4EXB9iNP9Db4AMF2nog8CIGkW09SKCt+wBtPSCNy++TKbAXB5A/FdDfM2RtFc+VDwFrijBH4n7xjUS332N+1B7QwdJeHOzAi0NsmKHethkSw4tDBRpoKLCzHiMb6DGBBhoMNNCQNC4/MlAvInMaRnpxmIIXh5BeHM560TxwOOHF4UD1jlD2oskwgvDiCGUvDrXzQr2IrNfjpBcfV/DiUAdeHGk3/ihvg48SaOtRwIsYTbb1aIG2Hgq09cg0Lr9PpsBeHBnwIMb7eNhM6P3io8BaIXyRvF8E/KlFrMgR5cUn7AEdI+3FMQ68ONaGGedtm7ExvDhOoIHGATvwSbKBnhRooDFAA41N4/IjAz1FyJzGk14cr+DFsaQXJ7BeNA+cQHhxAlBTE5W9aDJMJLw4UdmL4+y8UC8i6/UU6cWnFLw4zoEXJ9mNP9nb4JMF2noy8CKmkG09RaCtxwFtPSmNy++TKbAXJ/1H94usreK58glgTRHmSNwv9kpw+z3mp+0BfUbai8848OJUG2aat22mxvDiNIEGmgbsrGfJBnpWoIGeARpoahqXHxmoF5E5PUd68TkFL04lvTid9aJ54HTCi9OB6p2h7EWTYQbhxRnKXpxm54V6EVmv50kvPq/gxWkOvPiC3fgzvQ0+U6CtZwIvYhbZ1rME2noa0NYvpHH5fTIF9uILAQ9ivI+HzYTeLz4NrBXCF8nvMSuxKXJEGfBFe+hmSxtwtgMDzrFh5nobZE4MA84VaJW5wK56iWyVlwRaZTbQKnPSuPzIQA2IzOll0oAvKxhwDmnAeawBzQPnEQacBxhwvrIBTYb5hAHnKxtwrp0XakBkvV4hDfiKggHnOjDgq3bjL/A2+AKBtl4AvIiFZFsvFGjruUBbv5rG5ffJFNiAr5I/FQRvNqL89yKwTghdJO4BL0p0+z3m1+yhe13agK87MOAiG2axt0EWxTDgYoFWWQzsrDfIVnlDoFVeB1plURqXHxmoAZE5vUka8E0FAy4iDbiENaB54BLCgEsAAy5VNqDJsJQw4FJlAy6280INiKzXW6QB31Iw4GIHBnzbbvxl3gZfJtDWy4AXsZxs6+UCbb0YaOu307j8PpkCG/DtgAcx3sfDZkLvAV8D1grhi+TvGQL+1CJW5Ijy4jv2gL4r7cV3HXhxhQ2z0ts2K2J4caVAA60EduB7ZAO9J9BA7wINtCKNy48M9BQhc3qf9OL7Cl5cQXpxFetF88BVhBdXATW1WtmLJsNqwourlb240s4L9SKyXh+QXvxAwYsrHXjxQ7vx13gbfI1AW68BXsRasq3XCrT1SqCtP0zj8vtkCuzFD8mfCujvGbK2iufKd4A1RZgjcb/4ZqLb7zF/ZA/ox9Je/NiBF9fZMOu9bbMuhhfXCzTQemBnfUI20CcCDfQx0EDr0rj8yEC9iMxpA+nFDQpeXEd6cSPrRfPAjYQXNwLVu0nZiybDJsKLm5S9uN7OC/Uisl6fkl78VMGL6x148TO78Td7G3yzQFtvBl7EFrKttwi09XqgrT9L4/L7ZArsxc8CHsR4Hw+bCb1f/AhYK4QvkveLgD+1iBU5orz4uT2gX0h78QsHXtxqw2zzts3WGF7cJtBA24Ad+CXZQF8KNNAXQANtTePyIwM9RcicviK9+JWCF7eSXtzOetE8cDvhxe1ATe1Q9qLJsIPw4g5lL26z80K9iKzX16QXv1bw4jYHXvzGbvyd3gbfKdDWO4EXsYts610Cbb0NaOtv0rj8PpkCe/Gb/+h+kbVVPFd+DqwpwhyJ+8XeCW6/x/ytPaDfSXvxOwde3G3D7PG2ze4YXtwj0EB7gJ31PdlA3ws00HdAA+1O4/IjA/UiMqcfSC/+oODF3aQX97JeNA/cS3hxL1C9+5S9aDLsI7y4T9mLe+y8UC8i6/Uj6cUfFby4x4EXf7Ibf7+3wfcLtPV+4EUcINv6gEBb7wHa+qc0Lr9PpsBe/CngQYz38bCZ0PvFb4G1Qvgi+T1mJTZFjigD/mwP3S/SBvzFgQEP2jCHvA1yMIYBDwm0yiFgV/1KtsqvAq3yC9AqB9O4/MhADYjM6TfSgL8pGPAgacDDrAHNAw8TBjwMGPCIsgFNhiOEAY8oG/CQnRdqQGS9ficN+LuCAQ85MOAfduMf9Tb4UYG2Pgq8iGNkWx8TaOtDQFv/kcbl98kU2IB/kD8VBG82ovz3M7BOCF0k7gFLJbr9HvOf9tD9JW3AvxwY8LgNc8LbIMdjGPCEQKucAHbW32Sr/C3QKn8BrXI8jcuPDNSAyJxOkgY8qWDA46QBT7EGNA88RRjwFGDA08oGNBlOEwY8rWzAE3ZeqAGR9fqHNOA/CgY84cCACen2Q+kJ/w5o/iBoW5t/o6CfPSOda+sz0oO39QmgrRPSufw+mQIbMCE92EGM9/GwmdB7wD+Bg4jwRfL3DAF/ahErckR58Ux7QAuZ/0q2TaF0lTC+bXOWDVPY2zbmf/B6sbBAAxUGTuvZZAOdLdBAhdIL3kBnpXP5kYGeImRO56RzXjwnXd6LZ6VzXiySHuCB5i+jXixS8BeZWBR4GWwG8wzUi0UD/pgqyGYvmo57EVmvc4EMkZv33HR5LxYmeZHg/xzfBj/Pbvxi3gYvJtDWxYAXUZxs6+ICbV0YaOvz0rn8PpkCe/E88qcC+nuGrK3iufJMYE0R5kjcLy5JdPs95vPtAb1A2osXOPBiCRumpLdtSsTwYkmBBioJ7KwLyQa6UKCBLgAaqEQ6lx8ZqBeROV1EevEiBS+WIL1YivWieWApwoulAC+WVvaiyVCa8GJpZS+WtPNCvYis18WkFy9W8GJJB168xG78Mt4GLyPQ1mWAF1GWbOuyAm1dEmjrS9K5/D6ZAnvxkoAHMd7Hw2ZC7xfPB9YK4Yvk/SLgTy1iRY4oL15qD2g5aS+Wc+DF8jZMBW/blI/hxQoCDVQB2IGXkQ10mUADlQMaqHw6lx8Z6ClC5pREejFJwYvlSS+GWC+aB4YIL4aAmkpW9qLJkEx4MVnZixXsvFAvIuuVQnoxRcGLFRx4MdVu/DRvg6cJtHUa8CLSybZOF2jrCkBbp6Zz+X0yBfZi6n90v8jaKp4rLwXWFGGOxP1inwS332POsAc0U9qLmQ68mGXDZHvbJiuGF7MFGigb2Fk5ZAPlCDRQJtBAWelcfmSgXkTmlEt6MVfBi1mkF/NYL5oH5hFezAOqN1/ZiyZDPuHFfGUvZtt5oV5E1qsi6cWKCl7MduDFSnbjV/Y2eGWBtq4MvIgqZFtXEWjrbKCtK6Vz+X0yBfZipYAHMd7Hw2ZC7xczgLVC+CL5PWYlNkWOKANebg9dVWkDVnVgwGo2THVvg1SLYcDqAq1SHdhVV5CtcoVAq1QFWqVaOpcfGagBkTldSRrwSgUDViMNWIM1oHlgDcKANQAD1lQ2oMlQkzBgTWUDVrfzQg2IrNdVpAGvUjBgdQcGvNpu/FreBq8l0Na1gBdRm2zr2gJtXR1o66vTufw+mQIb8Gryp4LgzUaU/y4H1gmhi8Q9YOlEt99jvsYeumulDXitAwPWsWHqehukTgwD1hVolbrAzrqObJXrBFrlWqBV6qRz+ZGBGhCZ0/WkAa9XMGAd0oD1WAOaB9YjDFgPMGB9ZQOaDPUJA9ZXNmBdOy/UgMh63UAa8AYFA9Z1YMAb7cZv4G3wBgJt3QB4EQ3Jtm4o0NZ1gba+MZ3L75MpsAFvDHgQ4308bCb0HvAaYK0Qvkj+niHgTy1iRY4oL95kD+jN0l682YEXG9kwjb1t0yiGFxsLNFBjYAfeQjbQLQINdDPQQI3SufzIQE8RMqdbSS/equDFRqQXm7BeNA9sQnixCVBTTZW9aDI0JbzYVNmLje28UC8i63Ub6cXbFLzY2IEXb7cbv5m3wZsJtHUz4EU0J9u6uUBbNwba+vZ0Lr9PpsBevJ38qYD+niFrq3iuvAlYU4Q5EveLSxPdfo/5DntA75T24p0OvNjChmnpbZsWMbzYUqCBWgI76y6yge4SaKA7gQZqkc7lRwbqRWROd5NevFvBiy1IL7ZivWge2IrwYiugelsre9FkaE14sbWyF1vaeaFeRNbrHtKL9yh4saUDL95rN34bb4O3EWjrNsCLaEu2dVuBtm4JtPW96Vx+n0yBvXhvwIMY7+NhM6H3i3cAa4XwRfJ+EfCnFrEiR5QX77MHtJ20F9s58GJ7G6aDt23ax/BiB4EG6gDswPvJBrpfoIHaAQ3UPp3Ljwz0FCFz6kh6saOCF9uTXuzEetE8sBPhxU5ATXVW9qLJ0JnwYmdlL3aw80K9iKzXA6QXH1DwYgcHXuxiN35Xb4N3FWjrrsCL6Ea2dTeBtu4AtHWXdC6/T6bAXuzyH90vsraK58r7gDVFmCNxv/hwgtvvMT9oD2h3aS92d+DFHjZMT2/b9IjhxZ4CDdQT2FkPkQ30kEADdQcaqEc6lx8ZqBeROfUivdhLwYs9SC/2Zr1oHtib8GJvoHr7KHvRZOhDeLGPshd72nmhXkTW62HSiw8reLGnAy/2tRu/n7fB+wm0dT/gRfQn27q/QFv3BNq6bzqX3ydTYC/2DXgQ4308bCb0fvFBYK0Qvkh+j1mJTZEjyoCP2EM3QNqAAxwYcKANM8jbIANjGHCQQKsMAnbVo2SrPCrQKgOAVhmYzuVHBmpAZE6DSQMOVjDgQNKAQ1gDmgcOIQw4BDDgUGUDmgxDCQMOVTbgIDsv1IDIej1GGvAxBQMOcmDAYXbjD/c2+HCBth4OvIgRZFuPEGjrQUBbD0vn8vtkCmzAYeRPBcGbjSj/PQKsE0IXiXvAixPdfo/5cXvoRkobcKQDA46yYUZ7G2RUDAOOFmiV0cDOeoJslScEWmUk0Cqj0rn8yEANiMxpDGnAMQoGHEUacCxrQPPAsYQBxwIGHKdsQJNhHGHAccoGHG3nhRoQWa8nSQM+qWDA0Q4MON5u/AneBp8g0NYTgBcxkWzriQJtPRpo6/HpXH6fTIENOD7gQYz38bCZ0HvAx4G1Qvgi+XuGgD+1iBU5orz4lD2gk6S9OMmBFyfbMFO8bTM5hhenCDTQFGAHPk020NMCDTQJaKDJ6Vx+ZKCnCJnTM6QXn1Hw4mTSi1NZL5oHTiW8OBWoqWnKXjQZphFenKbsxSl2XqgXkfV6lvTiswpenOLAi8/ZjT/d2+DTBdp6OvAiZpBtPUOgracAbf1cOpffJ1NgLz5H/lRAf8+QtVU8Vz4FrCnCHIn7xbcS3X6P+Xl7QF+Q9uILDrw404aZ5W2bmTG8OEuggWYBO+tFsoFeFGigF4AGmpnO5UcG6kVkTrNJL85W8OJM0otzWC+aB84hvDgHqN65yl40GeYSXpyr7MVZdl6oF5H1eon04ksKXpzlwIsv240/z9vg8wTaeh7wIuaTbT1foK1nAW39cjqX3ydTYC++HPAgxvt42Ezo/eLzwFohfJG8XwT8qUWsyBHlxVfsAX1V2ouvOvDiAhtmobdtFsTw4kKBBloI7MDXyAZ6TaCBXgUaaEE6lx8Z6ClC5vQ66cXXFby4gPTiItaL5oGLCC8uAmpqsbIXTYbFhBcXK3txoZ0X6kVkvd4gvfiGghcXOvDim3bjL/E2+BKBtl4CvIilZFsvFWjrhUBbv5nO5ffJFNiLb/5H94usreK58hVgTRHmSNwv9k1w+z3mt+wBfVvai2878OIyG2a5t22WxfDicoEGWg7srHfIBnpHoIHeBhpoWTqXHxmoF5E5vUt68V0FLy4jvbiC9aJ54ArCiyuA6l2p7EWTYSXhxZXKXlxu54V6EVmv90gvvqfgxeUOvPi+3firvA2+SqCtVwEvYjXZ1qsF2no50Nbvp3P5fTIF9uL7AQ9ivI+HzYTeL74FrBXCF8nvMSuxKXJEGfADe+g+lDbghw4MuMaGWettkDUxDLhWoFXWArvqI7JVPhJolQ+BVlmTzuVHBmpAZE4fkwb8WMGAa0gDrmMNaB64jjDgOsCA65UNaDKsJwy4XtmAa+28UAMi6/UJacBPFAy41oEBN9iNv9Hb4BsF2noj8CI2kW29SaCt1wJtvSGdy++TKbABN5A/FQRvNqL89wGwTghdJO4BL0l0+z3mT+2h+0zagJ85MOBmG2aLt0E2xzDgFoFW2QLsrM/JVvlcoFU+A1plczqXHxmoAZE5fUEa8AsFA24mDbiVNaB54FbCgFsBA25TNqDJsI0w4DZlA26x80INiKzXl6QBv1Qw4BYHBvzKbvzt3gbfLtDW24EXsYNs6x0Cbb0FaOuv0rn8PpkCG/CrgAcx3sfDZkLvAT8F1grhi+TvGQL+1CJW5Ijy4tf2gH4j7cVvHHhxpw2zy9s2O2N4cZdAA+0CduC3ZAN9K9BA3wANtDOdy48M9BQhc/qO9OJ3Cl7cSXpxN+tF88DdhBd3AzW1R9mLJsMewot7lL24y84L9SKyXt+TXvxewYu7HHjxB7vx93obfK9AW+8FXsQ+sq33CbT1LqCtf0jn8vtkCuzFH8ifCujvGbK2iufKr4E1RZgjcb/4dqLb7zH/aA/oT9Je/MmBF/fbMAe8bbM/hhcPCDTQAWBn/Uw20M8CDfQT0ED707n8yEC9iMzpF9KLvyh4cT/pxYOsF80DDxJePAhU7yFlL5oMhwgvHlL24gE7L9SLyHr9SnrxVwUvHnDgxd/sxj/sbfDDAm19GHgRR8i2PiLQ1geAtv4tncvvkymwF38LeBDjfTxsJvR+8UdgrRC+SN4vAv7UIlbkiPLi7/aA/iHtxT8cePGoDXPM2zZHY3jxmEADHQN24J9kA/0p0EB/AA10NJ3Ljwz0FCFz+ov04l8KXjxKevE460XzwOOEF48DNXVC2YsmwwnCiyeUvXjMzgv1IrJef5Ne/FvBi8ccePGk3finvA1+SqCtTwEv4jTZ1qcF2voY0NYn07n8PpkCe/Hkf3S/yNoqnit/B9YUYY7E/WK/BLffY/4n/JMpI0G2bcw/WMDPxhxJ/9e/6xn/WvwM+2cZCf9uG/M/eL1oPhS0gc7IKPhnz8zgGujMjOANlJBR8AZKzODyIwP1IjKnQhmcFwtlyHsxMYPz4lkZAR5o/jLqxbMK/iITCwMvg81gnoF6sTC4GdF5nWHnhXoRWa+zgQyRm/fsDHkvnlGwwhL14jl24xfxNngRgbYuAryIomRbFxVo6zOAtj4ng8vvkymwF88JeBDjfTxsJvR+8R/k/+gCGSS/x6zEpsgRZcBz7aE7T9qA5zkwYDEbpri3QYrFMGBxgVYpDpzA88lWOV+gVc4DWqVYBpcfGagBkTldQBrwAgUDFiMNWII1oHlgCcKAJQADllQ2oMlQkjBgSWUDFrfzQg2IrNeFpAEvVDBgcQcGvMhu/FLeBi8l0NalgBdRmmzr0gJtXRxo64syuPw+mQIb8CLyp4LgzUaU/84F1gmhi8Q9YJlEt99jvtgeukukDXiJAwOWsWHKehukTAwDlhVolbLAzrqUbJVLBVrlEqBVymRw+ZGBGhCZUznSgOUUDFiGNGB51oDmgeUJA5YHDFhB2YAmQwXCgBWUDVjWzgs1ILJel5EGvEzBgGUdGDDJbvyQt8FDAm0dAl5EMtnWyQJtXRZo66QMLr9PpsAGTAp4EON9PGwm9B7wYmCtEL5I/p4h4E8tYkWOKC+m2AOaKu3FVAdeTLNh0r1tkxbDi+kCDZQO7MAMsoEyBBooFWigtAwuPzLQU4TMKZP0YqaCF9NIL2axXjQPzCK8mAXUVLayF02GbMKL2cpeTLfzQr2IrFcO6cUcBS+mO/Birt34ed4GzxNo6zzgReSTbZ0v0NbpQFvnZnD5fTIF9mIu+VMB/T1D1lbxXJkCrCnCHIn7xWWJbr/HXNEe0ErSXqzkwIuVbZgq3rapHMOLVQQaqAqwsy4nG+hygQaqBDRQ5QwuPzJQLyJzqkp6saqCFyuTXqzGetE8sBrhxWpA9VZX9qLJUJ3wYnVlL1ax80K9iKzXFaQXr1DwYhUHXrzSbvwa3gavIdDWNYAXUZNs65oCbV0FaOsrM7j8PpkCe/HKgAcx3sfDZkLvFysCa4XwRfJ+EfCnFrEiR5QXr7IH9GppL17twIu1bJja3rapFcOLtQUaqDawA68hG+gagQa6GmigWhlcfmSgpwiZ07WkF69V8GIt0ot1WC+aB9YhvFgHqKm6yl40GeoSXqyr7MXadl6oF5H1uo704nUKXqztwIvX241fz9vg9QTauh7wIuqTbV1foK1rA219fQaX3ydTYC9e/x/dL7K2iufKq4A1RZgjcb/YP8Ht95hvsAf0Rmkv3ujAiw1smIbetmkQw4sNBRqoIbCzbiIb6CaBBroRaKAGGVx+ZKBeROZ0M+nFmxW82ID0YiPWi+aBjQgvNgKqt7GyF02GxoQXGyt7saGdF+pFZL1uIb14i4IXGzrw4q124zfxNngTgbZuAryIpmRbNxVo64ZAW9+aweX3yRTYi7cGPIjxPh42E3q/eAOwVghfJL/HrMSmyBFlwNvsobtd2oC3OzBgMxumubdBmsUwYHOBVmkO7Ko7yFa5Q6BVbgdapVkGlx8ZqAGROd1JGvBOBQM2Iw3YgjWgeWALwoAtAAO2VDagydCSMGBLZQM2t/NCDYis112kAe9SMGBzBwa82278Vt4GbyXQ1q2AF9GabOvWAm3dHGjruzO4/D6ZAhvwbvKnguDNRpT/bgPWCaGLxD1g2US332O+xx66e6UNeK8DA7axYdp6G6RNDAO2FWiVtsDOuo9slfsEWuVeoFXaZHD5kYEaEJlTO9KA7RQM2IY0YHvWgOaB7QkDtgcM2EHZgCZDB8KAHZQN2NbOCzUgsl73kwa8X8GAbR0YsKPd+J28Dd5JoK07AS+iM9nWnQXaui3Q1h0zuPw+mQIbsGPAgxjv42EzofeA9wBrhfBF8vcMAX9qEStyRHnxAXtAu0h7sYsDL3a1Ybp526ZrDC92E2igbsAOfJBsoAcFGqgL0EBdM7j8yEBPETKn7qQXuyt4sSvpxR6sF80DexBe7AHUVE9lL5oMPQkv9lT2Yjc7L9SLyHo9RHrxIQUvdnPgxV524/f2NnhvgbbuDbyIPmRb9xFo625AW/fK4PL7ZArsxV7kTwX09wxZW8Vz5QPAmiLMkbhfXJ7o9nvMD9sD2lfai30deLGfDdPf2zb9Ynixv0AD9Qd21iNkAz0i0EB9gQbql8HlRwbqRWROA0gvDlDwYj/SiwNZL5oHDiS8OBCo3kHKXvzfYSW8OEjZi/3tvFAvIuv1KOnFRxW82N+BFwfbjT/E2+BDBNp6CPAihpJtPVSgrfsDbT04g8vvkymwFwcHPIjxPh42E3q/+DCwVghfJO8XAX9qEStyRHnxMXtAh0l7cZgDLw63YUZ422Z4DC+OEGigEcAOfJxsoMcFGmgY0EDDM7j8yEBPETKnkaQXRyp4cTjpxVGsF80DRxFeHAXU1GhlL5oMowkvjlb24gg7L9SLyHo9QXrxCQUvjnDgxTF244/1NvhYgbYeC7yIcWRbjxNo6xFAW4/J4PL7ZArsxTH/0f0ia6t4rnwMWFOEORL3i48kuP0e85P2gI6X9uJ4B16cYMNM9LbNhBhenCjQQBOBnfUU2UBPCTTQeKCBJmRw+ZGBehGZ0yTSi5MUvDiB9OJk1ovmgZMJL04GqneKshdNhimEF6coe3GinRfqRWS9nia9+LSCFyc68OIzduNP9Tb4VIG2ngq8iGlkW08TaOuJQFs/k8Hl98kU2IvPBDyI8T4eNhN6v/gksFYIXyS/x6zEpsgRZcBn7aF7TtqAzzkw4HQbZoa3QabHMOAMgVaZAeyq58lWeV6gVZ4DWmV6BpcfGagBkTm9QBrwBQUDTicNOJM1oHngTMKAMwEDzlI2oMkwizDgLGUDzrDzQg2IrNeLpAFfVDDgDAcGnG03/hxvg88RaOs5wIuYS7b1XIG2ngG09ewMLr9PpsAGnE3+VBC82Yjy37PAOiF0kbgHvDTR7feYX7KH7mVpA77swIDzbJj53gaZF8OA8wVaZT6ws14hW+UVgVZ5GWiVeRlcfmSgBkTm9CppwFcVDDiPNOAC1oDmgQsIAy4ADLhQ2YAmw0LCgAuVDTjfzgs1ILJer5EGfE3BgPMdGPB1u/EXeRt8kUBbLwJexGKyrRcLtPV8oK1fz+Dy+2QKbMDXAx7EeB8Pmwm9B3wJWCuEL5K/Zwj4U4tYkSPKi2/YA/qmtBffdODFJTbMUm/bLInhxaUCDbQU2IFvkQ30lkADvQk00JIMLj8y0FOEzOlt0otvK3hxCenFZawXzQOXEV5cBtTUcmUvmgzLCS8uV/biUjsv1IvIer1DevEdBS8udeDFd+3GX+Ft8BUCbb0CeBErybZeKdDWS4G2fjeDy++TKbAX3yV/KqC/Z8jaKp4r3wDWFGGOxP3iO4luv8f8nj2g70t78X0HXlxlw6z2ts2qGF5cLdBAq4Gd9QHZQB8INND7QAOtyuDyIwP1IjKnD0kvfqjgxVWkF9ewXjQPXEN4cQ1QvWuVvWgyrCW8uFbZi6vtvFAvIuv1EenFjxS8uNqBFz+2G3+dt8HXCbT1OuBFrCfber1AW68G2vrjDC6/T6bAXvw44EGM9/GwmdD7xfeAtUL4Inm/CPhTi1iRI8qLn9gDukHaixsceHGjDbPJ2zYbY3hxk0ADbQJ24KdkA30q0EAbgAbamMHlRwZ6ipA5fUZ68TMFL24kvbiZ9aJ54GbCi5uBmtqi7EWTYQvhxS3KXtxk54V6EVmvz0kvfq7gxU0OvPiF3fhbvQ2+VaCttwIvYhvZ1tsE2noT0NZfZHD5fTIF9uIX/9H9ImureK78BFhThDkS94sDEtx+j/lLe0C/kvbiVw68uN2G2eFtm+0xvLhDoIF2ADvra7KBvhZooK+ABtqeweVHBupFZE7fkF78RsGL20kv7mS9aB64k/DiTqB6dyl70WTYRXhxl7IXd9h5oV5E1utb0ovfKnhxhwMvfmc3/m5vg+8WaOvdwIvYQ7b1HoG23gG09XcZXH6fTIG9+F3Agxjv42EzofeLXwJrhfBF8nvMSmyKHFEG/N4euh+kDfiDAwPutWH2eRtkbwwD7hNolX3ArvqRbJUfBVrlB6BV9mZw+ZGBGhCZ00+kAX9SMOBe0oD7WQOaB+4nDLgfMOABZQOaDAcIAx5QNuA+Oy/UgMh6/Uwa8GcFA+5zYMBf7MY/6G3wgwJtfRB4EYfItj4k0Nb7gLb+JYPL75MpsAF/IX8qCN5sRPnve2CdELpI3AOWS3T7PeZf7aH7TdqAvzkw4GEb5oi3QQ7HMOARgVY5Auys38lW+V2gVX4DWuVwBpcfGagBkTn9QRrwDwUDHiYNeJQ1oHngUcKARwEDHlM2oMlwjDDgMWUDHrHzQg2IrNefpAH/VDDgEQcG/Mtu/OPeBj8u0NbHgRdxgmzrEwJtfQRo678yuPw+mQIb8K+ABzHex8NmQu8BfwXWCuGL5O8ZAv7UIlbkiPLi3/aAnpT24kkHXjxlw5z2ts2pGF48LdBAp4Ed+A/ZQP8INNBJoIFOZXD5kYGeImROCZmcF83fk/biKdKLiZkBHmj+MurFxMyCv4wzMnW9aDKYZ6BePCMT24zovE7beaFeRNbrTCBD5OY1f0/ai6cdeLGQ3fhnZSb8O+BZmcHb+izgRRTO5Nq6cGbwtj4NtHWhTC6/T6bAXiwEHsTwQH/PkLVVPFf+Dfy0ORnQleihfDfR7feYz7YH9BzzX8m2OSdTJYxv2xSxYYp626ZIZrQXiwo0UFHgtJ5LNtC5Ag10TmbBG6hIJpcfGagXkTmdR3rxPAUvFsnkvFiM9aJ5YDHCi8UALxZX9qLJUJzwYnFlLxa180K9iKzX+aQXz1fwYlGSFwn+z/Ft8Avsxi/hbfASAm1dAngRJcm2LinQ1kWBtr4gk8vvkymwFy8IeBDjfTxsJvR+8WxgrRC+SN4vAv7UIlbkiPLihfaAXiTtxYsceLGUDVPa2zalYnixtEADlQZ24MVkA10s0EAXAQ1UKpPLjwz0FCFzuoT04iUKXixFerEM60XzwDKEF8sAXiyr7EWToSzhxbLKXixt54V6EVmvS0kvXqrgxdIOvFjObvzy3gYvL9DW5YEXUYFs6woCbV0aaOtymVx+n0yBvVjuP7pfZG0Vz5UXAmuKMEfifnFggtvvMV9mD2iStBeTHHgxZMMke9smFMOLyQINlAzsrBSygVIEGigJaKBQJpcfGagXkTmlkl5MVfBiiPRiGutF88A0wotpgBfTlb1oMqQTXkxX9mKynRfqRWS9MkgvZih4MdmBFzPtxs/yNniWQFtnAS8im2zrbIG2TgbaOjOTy++TKbAXMwMexHgfD5sJvV+8DFgrhC+S32NWYlPkiDJgjj10udIGzHVgwDwbJt/bIHkxDJgv0Cr5wK6qSLZKRYFWyQVaJS+Ty48M1IDInCqRBqykYMA80oCVWQOaB1YmDFgZMGAVZQOaDFUIA1ZRNmC+nRdqQGS9LicNeLmCAfMdGLCq3fjVvA1eTaCtqwEvojrZ1tUF2jofaOuqmVx+n0yBDViV/KkgeLMR5b8cYJ0QukjcA5ZPdPs95ivsobtS2oBXOjBgDRumprdBasQwYE2BVqkJ7KyryFa5SqBVrgRapUYmlx8ZqAGROV1NGvBqBQPWIA1YizWgeWAtwoC1AAPWVjagyVCbMGBtZQPWtPNCDYis1zWkAa9RMGBNBwa81m78Ot4GryPQ1nWAF1GXbOu6Am1dE2jrazO5/D6ZAhvw2oAHMd7Hw2ZC7wGvANYK4Yvk7xkC/tQiVuSI8uJ19oBeL+3F6x14sZ4NU9/bNvVieLG+QAPVB3bgDWQD3SDQQNcDDVQvk8uPDPQUIXO6kfTijQperEd6sQHrRfPABoQXGwA11VDZiyZDQ8KLDZW9WN/OC/Uisl43kV68ScGL9R148Wa78Rt5G7yRQFs3Al5EY7KtGwu0dX2grW/O5PL7ZArsxZvJnwro7xmytornyuuANUWYI3G/uCLR7feYb7EH9FZpL97qwItNbJim3rZpEsOLTQUaqCmws24jG+g2gQa6FWigJplcfmSgXkTmdDvpxdsVvNiE9GIz1ovmgc0ILzYDqre5shdNhuaEF5sre7GpnRfqRWS97iC9eIeCF5s68OKdduO38DZ4C4G2bgG8iJZkW7cUaOumQFvfmcnl98kU2It3BjyI8T4eNhN6v3gLsFYIXyTvFwF/ahErckR58S57QO+W9uLdDrzYyoZp7W2bVjG82FqggVoDO/AesoHuEWigu4EGapXJ5UcGeoqQOd1LevFeBS+2Ir3YhvWieWAbwottgJpqq+xFk6Et4cW2yl5sbeeFehFZr/tIL96n4MXWDrzYzm789t4Gby/Q1u2BF9GBbOsOAm3dGmjrdplcfp9Mgb3Y7j+6X2RtFc+VdwFrijBH4n7R/IRy+T3m++0B7SjtxY4OvNjJhunsbZtOMbzYWaCBOgM76wGygR4QaKCOQAN1yuTyIwP1IjKnLqQXuyh4sRPpxa6sF80DuxJe7ApUbzdlL5oM3QgvdlP2Ymc7L9SLyHo9SHrxQQUvdnbgxe524/fwNngPgbbuAbyInmRb9xRo685AW3fP5PL7ZArsxe4BD2K8j4fNhN4v3g+sFcIXye8xK7EpckQZ8CF76HpJG7CXAwP2tmH6eBukdwwD9hFolT7ArnqYbJWHBVqlF9AqvTO5/MhADYjMqS9pwL4KBuxNGrAfa0DzwH6EAfsBBuyvbECToT9hwP7KBuxj54UaEFmvR0gDPqJgwD4ODDjAbvyB3gYfKNDWA4EXMYhs60ECbd0HaOsBmVx+n0yBDTiA/KkgeLMR5b+HgHVC6CJxD1gh0e33mB+1h26wtAEHOzDgEBtmqLdBhsQw4FCBVhkK7KzHyFZ5TKBVBgOtMiSTy48M1IDInIaRBhymYMAhpAGHswY0DxxOGHA4YMARygY0GUYQBhyhbMChdl6oAZH1epw04OMKBhzqwIAj7cYf5W3wUQJtPQp4EaPJth4t0NZDgbYemcnl98kU2IAjAx7EeB8Pmwm9B3wUWCuEL5K/Zwj4U4tYkSPKi0/YAzpG2otjHHhxrA0zzts2Y2N4cZxAA40DduCTZAM9KdBAY4AGGpvJ5UcGeoqQOY0nvThewYtjSS9OYL1oHjiB8OIEoKYmKnvRZJhIeHGishfH2XmhXkTW6ynSi08peHGcAy9Osht/srfBJwu09WTgRUwh23qKQFuPA9p6UiaX3ydTYC9OIn8qoL9nyNoqniufANYUYY7E/eLKRLffY37aHtBnpL34jAMvTrVhpnnbZmoML04TaKBpwM56lmygZwUa6BmggaZmcvmRgXoRmdNzpBefU/DiVNKL01kvmgdOJ7w4HajeGcpeNBlmEF6coezFaXZeqBeR9Xqe9OLzCl6c5sCLL9iNP9Pb4DMF2nom8CJmkW09S6CtpwFt/UIml98nU2AvvhDwIMb7eNhM6P3i08BaIXyRvF8E/KlFrMgR5cUX7QGdLe3F2Q68OMeGmettmzkxvDhXoIHmAjvwJbKBXhJooNlAA83J5PIjAz1FyJxeJr34soIX55BenMd60TxwHuHFeUBNzVf2oskwn/DifGUvzrXzQr2IrNcrpBdfUfDiXAdefNVu/AXeBl8g0NYLgBexkGzrhQJtPRdo61czufw+mQJ78dX/6H6RtVU8V74IrCnCHIn7xUcT3H6P+TV7QF+X9uLrDry4yIZZ7G2bRTG8uFiggRYDO+sNsoHeEGig14EGWpTJ5UcG6kVkTm+SXnxTwYuLSC8uYb1oHriE8OISoHqXKnvRZFhKeHGpshcX23mhXkTW6y3Si28peHGxAy++bTf+Mm+DLxNo62XAi1hOtvVygbZeDLT125lcfp9Mgb34dsCDGO/jYTOh94uvAWuF8EXye8xKbIocUQZ8xx66d6UN+K4DA66wYVZ6G2RFDAOuFGiVlcCueo9slfcEWuVdoFVWZHL5kYEaEJnT+6QB31cw4ArSgKtYA5oHriIMuAow4GplA5oMqwkDrlY24Eo7L9SAyHp9QBrwAwUDrnRgwA/txl/jbfA1Am29BngRa8m2XivQ1iuBtv4wk8vvkymwAT8kfyoI3mxE+e8dYJ0QukjcA16W6PZ7zB/ZQ/extAE/dmDAdTbMem+DrIthwPUCrbIe2FmfkK3yiUCrfAy0yrpMLj8yUAMic9pAGnCDggHXkQbcyBrQPHAjYcCNgAE3KRvQZNhEGHCTsgHX23mhBkTW61PSgJ8qGHC9AwN+Zjf+Zm+DbxZo683Ai9hCtvUWgbZeD7T1Z5lcfp9MgQ34WcCDGO/jYTOh94AfAWuF8EXy9wwBf2oRK3JEefFze0C/kPbiFw68uNWG2eZtm60xvLhNoIG2ATvwS7KBvhRooC+ABtqayeVHBnqKkDl9RXrxKwUvbiW9uJ31onngdsKL24Ga2qHsRZNhB+HFHcpe3GbnhXoRWa+vSS9+reDFbQ68+I3d+Du9Db5ToK13Ai9iF9nWuwTaehvQ1t9kcvl9MgX24jfkTwX09wxZW8Vz5efAmiLMkbhffC/R7feYv7UH9DtpL37nwIu7bZg93rbZHcOLewQaaA+ws74nG+h7gQb6Dmig3ZlcfmSgXkTm9APpxR8UvLib9OJe1ovmgXsJL+4FqnefshdNhn2EF/cpe3GPnRfqRWS9fiS9+KOCF/c48OJPduPv9zb4foG23g+8iANkWx8QaOs9QFv/lMnl98kU2Is/BTyI8T4eNhN6v/gtsFYIXyTvFwF/ahErckR58Wd7QH+R9uIvDrx40IY55G2bgzG8eEiggQ4BO/BXsoF+FWigX4AGOpjJ5UcGeoqQOf1GevE3BS8eJL14mPWieeBhwouHgZo6ouxFk+EI4cUjyl48ZOeFehFZr99JL/6u4MVDDrz4h934R70NflSgrY8CL+IY2dbHBNr6ENDWf2Ry+X0yBfbiH//R/SJrq3iu/BlYU4Q5EveLgxPcfo/5T3tA/5L24l8OvHjchjnhbZvjMbx4QqCBTgA762+ygf4WaKC/gAY6nsnlRwbqRWROJ0kvnlTw4nHSi6dYL5oHniK8eAqo3tPKXjQZThNePK3sxRN2XqgXkfX6h/TiPwpePOHAiwlZ9kNZCf8OaP4gaFubf6Ognz0ji2vrM7KCt/UJoK0Tsrj8PpkCezEhK9hBjPfxwQnc95j/BA4iwhfJ7zErsSlyRBnwTHvoCpn/SjZIoSyVML4NcpYNU9jbIOZ/8BqwsECrFAZO4Nlkq5wt0CqFsgreKmdlcfmRgRoQmdM5WZwBz8mSN+BZWZwBi2QFeKD5y6gBixT8RSYWBV4Gm8E8AzVg0YA/egqy2Ytm4QZE1utcIEPk5j03S96AhUkyJPg/x7fBz7Mbv5i3wYsJtHUx4EUUJ9u6uEBbFwba+rwsLr9PpsAGPI/8qSB4sxHlvzOBdULoInEPmJTo9nvM59tDd4G0AS9wYMASNkxJb4OUiGHAkgKtUhLYWReSrXKhQKtcALRKiSwuPzJQAyJzuog04EUKBixBGrAUa0DzwFKEAUsBBiytbECToTRhwNLKBixp54UaEFmvi0kDXqxgwJIODHiJ3fhlvA1eRqCtywAvoizZ1mUF2rok0NaXZHH5fTIFNuAlAQ9ivI+HzYTeA54PrBXCF8nfMwT8qUWsyBHlxUvtAS0n7cVyDrxY3oap4G2b8jG8WEGggSoAO/AysoEuE2igckADlc/i8iMDPUXInJJILyYpeLE86cUQ60XzwBDhxRBQU8nKXjQZkgkvJit7sYKdF+pFZL1SSC+mKHixggMvptqNn+Zt8DSBtk4DXkQ62dbpAm1dAWjr1Cwuv0+mwF5MJX8qoL9nyNoqnisvBdYUYY7E/eL7iW6/x5xhD2imtBczHXgxy4bJ9rZNVgwvZgs0UDaws3LIBsoRaKBMoIGysrj8yEC9iMwpl/RiroIXs0gv5rFeNA/MI7yYB1RvvrIXTYZ8wov5yl7MtvNCvYisV0XSixUVvJjtwIuV7Mav7G3wygJtXRl4EVXItq4i0NbZQFtXyuLy+2QK7MVKAQ9ivI+HzYTeL2YAa4XwRfJ+EfCnFrEiR5QXL7cHtKq0F6s68GI1G6a6t22qxfBidYEGqg7swCvIBrpCoIGqAg1ULYvLjwz0FCFzupL04pUKXqxGerEG60XzwBqEF2sANVVT2YsmQ03CizWVvVjdzgv1IrJeV5FevErBi9UdePFqu/FreRu8lkBb1wJeRG2yrWsLtHV1oK2vzuLy+2QK7MWr/6P7RdZW8Vx5ObCmCHMk7hfN3nL5PeZr7AG9VtqL1zrwYh0bpq63berE8GJdgQaqC+ys68gGuk6gga4FGqhOFpcfGagXkTldT3rxegUv1iG9WI/1onlgPcKL9YDqra/sRZOhPuHF+sperGvnhXoRWa8bSC/eoODFug68eKPd+A28Dd5AoK0bAC+iIdnWDQXaui7Q1jdmcfl9MgX24o0BD2K8j4fNhN4vXgOsFcIXye8xK7EpckQZ8CZ76G6WNuDNDgzYyIZp7G2QRjEM2FigVRoDu+oWslVuEWiVm4FWaZTF5UcGakBkTreSBrxVwYCNSAM2YQ1oHtiEMGATwIBNlQ1oMjQlDNhU2YCN7bxQAyLrdRtpwNsUDNjYgQFvtxu/mbfBmwm0dTPgRTQn27q5QFs3Btr69iwuv0+mwAa8nfypIHizEeW/m4B1QugicQ8YSnT7PeY77KG7U9qAdzowYAsbpqW3QVrEMGBLgVZpCeysu8hWuUugVe4EWqVFFpcfGagBkTndTRrwbgUDtiAN2Io1oHlgK8KArQADtlY2oMnQmjBga2UDtrTzQg2IrNc9pAHvUTBgSwcGvNdu/DbeBm8j0NZtgBfRlmzrtgJt3RJo63uzuPw+mQIb8N6ABzHex8NmQu8B7wDWCuGL5O8ZAv7UIlbkiPLiffaAtpP2YjsHXmxvw3Twtk37GF7sINBAHYAdeD/ZQPcLNFA7oIHaZ3H5kYGeImROHUkvdlTwYnvSi51YL5oHdiK82Amoqc7KXjQZOhNe7KzsxQ52XqgXkfV6gPTiAwpe7ODAi13sxu/qbfCuAm3dFXgR3ci27ibQ1h2Atu6SxeX3yRTYi13Inwro7xmytornyvuANUWYI3G/uCrR7feYH7QHtLu0F7s78GIPG6ant216xPBiT4EG6gnsrIfIBnpIoIG6Aw3UI4vLjwzUi8icepFe7KXgxR6kF3uzXjQP7E14sTdQvX2UvWgy9CG82EfZiz3tvFAvIuv1MOnFhxW82NOBF/vajd/P2+D9BNq6H/Ai+pNt3V+grXsCbd03i8vvkymwF/sGPIjxPh42E3q/+CCwVghfJO8XAX9qEStyRHnxEXtAB0h7cYADLw60YQZ522ZgDC8OEmigQcAOfJRsoEcFGmgA0EADs7j8yEBPETKnwaQXByt4cSDpxSGsF80DhxBeHALU1FBlL5oMQwkvDlX24iA7L9SLyHo9RnrxMQUvDnLgxWF24w/3NvhwgbYeDryIEWRbjxBo60FAWw/L4vL7ZArsxWH/0f0ia6t4rnwEWFOEORL3i0MT3H6P+XF7QEdKe3GkAy+OsmFGe9tmVAwvjhZooNHAznqCbKAnBBpoJNBAo7K4/MhAvYjMaQzpxTEKXhxFenEs60XzwLGEF8cC1TtO2YsmwzjCi+OUvTjazgv1IrJeT5JefFLBi6MdeHG83fgTvA0+QaCtJwAvYiLZ1hMF2no00Nbjs7j8PpkCe3F8wIMY7+NhM6H3i48Da4XwRfJ7zEpsihxRBnzKHrpJ0gac5MCAk22YKd4GmRzDgFMEWmUKsKueJlvlaYFWmQS0yuQsLj8yUAMic3qGNOAzCgacTBpwKmtA88CphAGnAgacpmxAk2EaYcBpygacYueFGhBZr2dJAz6rYMApDgz4nN34070NPl2gracDL2IG2dYzBNp6CtDWz2Vx+X0yBTbgc+RPBcGbjSj/PQWsE0IXiXvA5ES332N+3h66F6QN+IIDA860YWZ5G2RmDAPOEmiVWcDOepFslRcFWuUFoFVmZnH5kYEaEJnTbNKAsxUMOJM04BzWgOaBcwgDzgEMOFfZgCbDXMKAc5UNOMvOCzUgsl4vkQZ8ScGAsxwY8GW78ed5G3yeQFvPA17EfLKt5wu09SygrV/O4vL7ZApswJcDHsR4Hw+bCb0HfB5YK4Qvkr9nCPhTi1iRI8qLr9gD+qq0F1914MUFNsxCb9ssiOHFhQINtBDYga+RDfSaQAO9CjTQgiwuPzLQU4TM6XXSi68reHEB6cVFrBfNAxcRXlwE1NRiZS+aDIsJLy5W9uJCOy/Ui8h6vUF68Q0FLy504MU37cZf4m3wJQJtvQR4EUvJtl4q0NYLgbZ+M4vL75MpsBffJH8qoL9nyNoqnitfAdYUYY7E/eLqRLffY37LHtC3pb34tgMvLrNhlnvbZlkMLy4XaKDlwM56h2ygdwQa6G2ggZZlcfmRgXoRmdO7pBffVfDiMtKLK1gvmgeuILy4AqjelcpeNBlWEl5cqezF5XZeqBeR9XqP9OJ7Cl5c7sCL79uNv8rb4KsE2noV8CJWk229WqCtlwNt/X4Wl98nU2Avvh/wIMb7eNhM6P3iW8BaIXyRvF8E/KlFrMgR5cUP7AH9UNqLHzrw4hobZq23bdbE8OJagQZaC+zAj8gG+kiggT4EGmhNFpcfGegpQub0MenFjxW8uIb04jrWi+aB6wgvrgNqar2yF02G9YQX1yt7ca2dF+pFZL0+Ib34iYIX1zrw4ga78Td6G3yjQFtvBF7EJrKtNwm09VqgrTdkcfl9MgX24ob/6H6RtVU8V34ArCnCHIn7xccS3H6P+VN7QD+T9uJnDry42YbZ4m2bzTG8uEWggbYAO+tzsoE+F2igz4AG2pzF5UcG6kVkTl+QXvxCwYubSS9uZb1oHriV8OJWoHq3KXvRZNhGeHGbshe32HmhXkTW60vSi18qeHGLAy9+ZTf+dm+Dbxdo6+3Ai9hBtvUOgbbeArT1V1lcfp9Mgb34VcCDGO/jYTOh94ufAmuF8EXye8xKbIocUQb82h66b6QN+I0DA+60YXZ5G2RnDAPuEmiVXcCu+pZslW8FWuUboFV2ZnH5kYEaEJnTd6QBv1Mw4E7SgLtZA5oH7iYMuBsw4B5lA5oMewgD7lE24C47L9SAyHp9TxrwewUD7nJgwB/sxt/rbfC9Am29F3gR+8i23ifQ1ruAtv4hi8vvkymwAX8gfyoI3mxE+e9rYJ0QukjcA6Ykuv0e84/20P0kbcCfHBhwvw1zwNsg+2MY8IBAqxwAdtbPZKv8LNAqPwGtsj+Ly48M1IDInH4hDfiLggH3kwY8yBrQPPAgYcCDgAEPKRvQZDhEGPCQsgEP2HmhBkTW61fSgL8qGPCAAwP+Zjf+YW+DHxZo68PAizhCtvURgbY+ALT1b1lcfp9MgQ34W8CDGO/jYTOh94A/AmuF8EXy9wwBf2oRK3JEefF3e0D/kPbiHw68eNSGOeZtm6MxvHhMoIGOATvwT7KB/hRooD+ABjqaxeVHBnqKkDn9RXrxLwUvHiW9eJz1onngccKLx4GaOqHsRZPhBOHFE8pePGbnhXoRWa+/SS/+reDFYw68eNJu/FPeBj8l0NangBdxmmzr0wJtfQxo65NZXH6fTIG9eJL8qYD+niFrq3iu/B1YU4Q5EveLHyS6/R7zP+GfTNkJsm1j/sECfjbmSPq//l3P+NfiZ9s/y074d9uY/8HrRfOhoA10RnbBP3tmNtdAZ2YHb6CE7II3UGI2lx8ZqBeRORXK5rxYKFvei4nZnBfPyg7wQPOXUS+eVfAXmVgYeBlsBvMM1IuFwc2IzusMOy/Ui8h6nQ1kiNy8Z2fLe/GMghWWqBfPsRu/iLfBiwi0dRHgRRQl27qoQFufAbT1Odlcfp9Mgb14TsCDGO/jYTOh94v/IP9HF8ggeb8I+FOLWJEjyovn2gN6nrQXz3PgxWI2THFv2xSL4cXiAg1UHDit55MNdL5AA50HNFCxbC4/MtBThMzpAtKLFyh4sRjpxRKsF80DSxBeLAF4saSyF02GkoQXSyp7sbidF+pFZL0uJL14oYIXizvw4kV245fyNngpgbYuBbyI0mRblxZo6+JAW1+UzeX3yRTYixeRPxXQ+0XWVvFceS6wpghzJO4XhyW4/R7zxfaAXiLtxUsceLGMDVPW2zZlYnixrEADlQV21qVkA10q0ECXAA1UJpvLjwzUi8icypFeLKfgxTKkF8uzXjQPLE94sTzgxQrKXjQZKhBerKDsxbJ2XqgXkfW6jPTiZQpeLOvAi0l244e8DR4SaOsQ8CKSybZOFmjrskBbJ2Vz+X0yBfZiUsCDGO/jYTOh94sXA2uF8EXye8xKbIocUQZMsYcuVdqAqQ4MmGbDpHsbJC2GAdMFWiUd2FUZZKtkCLRKKtAqadlcfmSgBkTmlEkaMFPBgGmkAbNYA5oHZhEGzAIMmK1sQJMhmzBgtrIB0+28UAMi65VDGjBHwYDpDgyYazd+nrfB8wTaOg94EflkW+cLtHU60Na52Vx+n0yBDZhL/lQQvNmI8l8KsE4IXSTuAVMT3X6PuaI9dJWkDVjJgQEr2zBVvA1SOYYBqwi0ShVgZ11OtsrlAq1SCWiVytlcfmSgBkTmVJU0YFUFA1YmDViNNaB5YDXCgNUAA1ZXNqDJUJ0wYHVlA1ax80INiKzXFaQBr1AwYBUHBrzSbvwa3gavIdDWNYAXUZNs65oCbV0FaOsrs7n8PpkCG/DKgAcx3sfDZkLvASsCa4XwRfL3DAF/ahErckR58Sp7QK+W9uLVDrxYy4ap7W2bWjG8WFuggWoDO/AasoGuEWigq4EGqpXN5UcGeoqQOV1LevFaBS/WIr1Yh/WieWAdwot1gJqqq+xFk6Eu4cW6yl6sbeeFehFZr+tIL16n4MXaDrx4vd349bwNXk+gresBL6I+2db1Bdq6NtDW12dz+X0yBfbi9eRPBfT3DFlbxXPlVcCaIsyRuF/8MNHt95hvsAf0Rmkv3ujAiw1smIbetmkQw4sNBRqoIbCzbiIb6CaBBroRaKAG2Vx+ZKBeROZ0M+nFmxW82ID0YiPWi+aBjQgvNgKqt7GyF02GxoQXGyt7saGdF+pFZL1uIb14i4IXGzrw4q124zfxNngTgbZuAryIpmRbNxVo64ZAW9+azeX3yRTYi7cGPIjxPh42E3q/eAOwVghfJO8XAX9qEStyRHnxNntAb5f24u0OvNjMhmnubZtmMbzYXKCBmgM78A6yge4QaKDbgQZqls3lRwZ6ipA53Ul68U4FLzYjvdiC9aJ5YAvCiy2Ammqp7EWToSXhxZbKXmxu54V6EVmvu0gv3qXgxeYOvHi33fitvA3eSqCtWwEvojXZ1q0F2ro50NZ3Z3P5fTIF9uLd/9H9ImureK68DVhThDkS94vDE9x+j/kee0DvlfbivQ682MaGaettmzYxvNhWoIHaAjvrPrKB7hNooHuBBmqTzeVHBupFZE7tSC+2U/BiG9KL7Vkvmge2J7zYHqjeDspeNBk6EF7soOzFtnZeqBeR9bqf9OL9Cl5s68CLHe3G7+Rt8E4Cbd0JeBGdybbuLNDWbYG27pjN5ffJFNiLHQMexHgfD5sJvV+8B1grhC+S32NWYlPkiDLgA/bQdZE2YBcHBuxqw3TzNkjXGAbsJtAq3YBd9SDZKg8KtEoXoFW6ZnP5kYEaEJlTd9KA3RUM2JU0YA/WgOaBPQgD9gAM2FPZgCZDT8KAPZUN2M3OCzUgsl4PkQZ8SMGA3RwYsJfd+L29Dd5boK17Ay+iD9nWfQTauhvQ1r2yufw+mQIbsBf5U0HwZiPKfw8A64TQReIeMC3R7feYH7aHrq+0Afs6MGA/G6a/t0H6xTBgf4FW6Q/srEfIVnlEoFX6Aq3SL5vLjwzUgMicBpAGHKBgwH6kAQeyBjQPHEgYcCBgwEHKBvzfYSUMOEjZgP3tvFADIuv1KGnARxUM2N+BAQfbjT/E2+BDBNp6CPAihpJtPVSgrfsDbT04m8vvkymwAQcHPIjxPh42E3oP+DCwVghfJH/PEPCnFrEiR5QXH7MHdJi0F4c58OJwG2aEt22Gx/DiCIEGGgHswMfJBnpcoIGGAQ00PJvLjwz0FCFzGkl6caSCF4eTXhzFetE8cBThxVFATY1W9qLJMJrw4mhlL46w80K9iKzXE6QXn1Dw4ggHXhxjN/5Yb4OPFWjrscCLGEe29TiBth4BtPWYbC6/T6bAXhxD/lRAf8+QtVU8Vz4GrCnCHIn7xTWJbr/H/KQ9oOOlvTjegRcn2DATvW0zIYYXJwo00ERgZz1FNtBTAg00HmigCdlcfmSgXkTmNIn04iQFL04gvTiZ9aJ54GTCi5OB6p2i7EWTYQrhxSnKXpxo54V6EVmvp0kvPq3gxYkOvPiM3fhTvQ0+VaCtpwIvYhrZ1tME2noi0NbPZHP5fTIF9uIzAQ9ivI+HzYTeLz4JrBXCF8n7RcCfWsSKHFFefNYe0OekvficAy9Ot2FmeNtmegwvzhBooBnADnyebKDnBRroOaCBpmdz+ZGBniJkTi+QXnxBwYvTSS/OZL1oHjiT8OJMoKZmKXvRZJhFeHGWshdn2HmhXkTW60XSiy8qeHGGAy/Otht/jrfB5wi09RzgRcwl23quQFvPANp6djaX3ydTYC/O/o/uF1lbxXPls8CaIsyRuF8ckeD2e8wv2QP6srQXX3bgxXk2zHxv28yL4cX5Ag00H9hZr5AN9IpAA70MNNC8bC4/MlAvInN6lfTiqwpenEd6cQHrRfPABYQXFwDVu1DZiybDQsKLC5W9ON/OC/Uisl6vkV58TcGL8x148XW78Rd5G3yRQFsvAl7EYrKtFwu09XygrV/P5vL7ZArsxdcDHsR4Hw+bCb1ffAlYK4Qvkt9jVmJT5Igy4Bv20L0pbcA3HRhwiQ2z1NsgS2IYcKlAqywFdtVbZKu8JdAqbwKtsiSby48M1IDInN4mDfi2ggGXkAZcxhrQPHAZYcBlgAGXKxvQZFhOGHC5sgGX2nmhBkTW6x3SgO8oGHCpAwO+azf+Cm+DrxBo6xXAi1hJtvVKgbZeCrT1u9lcfp9MgQ34LvlTQfBmI8p/bwDrhNBF4h4wPdHt95jfs4fufWkDvu/AgKtsmNXeBlkVw4CrBVplNbCzPiBb5QOBVnkfaJVV2Vx+ZKAGROb0IWnADxUMuIo04BrWgOaBawgDrgEMuFbZgCbDWsKAa5UNuNrOCzUgsl4fkQb8SMGAqx0Y8GO78dd5G3ydQFuvA17EerKt1wu09WqgrT/O5vL7ZApswI8DHsR4Hw+bCb0HfA9YK4Qvkr9nCPhTi1iRI8qLn9gDukHaixsceHGjDbPJ2zYbY3hxk0ADbQJ24KdkA30q0EAbgAbamM3lRwZ6ipA5fUZ68TMFL24kvbiZ9aJ54GbCi5uBmtqi7EWTYQvhxS3KXtxk54V6EVmvz0kvfq7gxU0OvPiF3fhbvQ2+VaCttwIvYhvZ1tsE2noT0NZfZHP5fTIF9uIX5E8F9PcMWVvFc+UnwJoizJG4X1yb6PZ7zF/aA/qVtBe/cuDF7TbMDm/bbI/hxR0CDbQD2Flfkw30tUADfQU00PZsLj8yUC8ic/qG9OI3Cl7cTnpxJ+tF88CdhBd3AtW7S9mLJsMuwou7lL24w84L9SKyXt+SXvxWwYs7HHjxO7vxd3sbfLdAW+8GXsQesq33CLT1DqCtv8vm8vtkCuzF7wIexHgfD5sJvV/8ElgrhC+S94uAP7WIFTmivPi9PaA/SHvxBwde3GvD7PO2zd4YXtwn0ED7gB34I9lAPwo00A9AA+3N5vIjAz1FyJx+Ir34k4IX95Je3M960TxwP+HF/UBNHVD2oslwgPDiAWUv7rPzQr2IrNfPpBd/VvDiPgde/MVu/IPeBj8o0NYHgRdxiGzrQwJtvQ9o61+yufw+mQJ78Zf/6H6RtVU8V34PrCnCHIn7xccT3H6P+Vd7QH+T9uJvDrx42IY54m2bwzG8eESggY4AO+t3soF+F2ig34AGOpzN5UcG6kVkTn+QXvxDwYuHSS8eZb1oHniU8OJRoHqPKXvRZDhGePGYsheP2HmhXkTW60/Si38qePGIAy/+ZTf+cW+DHxdo6+PAizhBtvUJgbY+ArT1X9lcfp9Mgb34V8CDGO/jYTOh94u/AmuF8EXye8xKbIocUQb82x66k9IGPOnAgKdsmNPeBjkVw4CnBVrlNLCr/iFb5R+BVjkJtMqpbC4/MlADInNKyOEMaP6etAFPkQZMzAnwQPOXUQMm5hT8ZZyRo2tAk8E8AzXgGTnYZkTnddrOCzUgsl5nAhkiN6/5e9IGPO3AgIXsxj8rJ+HfAc/KCd7WZwEvonAO19aFc4K39WmgrQvlcPl9MgU2YCHwIIaH4M1GlP/+Bn6CnAzoP/SgZSS6/R7z2fbQnWP+K9kg5+SohPFtkCI2TFFvgxTJiTZgUYFWKQqcwHPJVjlXoFXOySl4qxTJ4fIjAzUgMqfzSAOep2DAIjmcAYuxBjQPLEYYsBhgwOLKBjQZihMGLK5swKJ2XqgBkfU6nzTg+QoGLEqSIcH/Ob4NfoHd+CW8DV5CoK1LAC+iJNnWJQXauijQ1hfkcPl9MgU24AUBD2K8j4fNhN4Dng2sFcIXyd8zBPypRazIEeXFC+0BvUjaixc58GIpG6a0t21KxfBiaYEGKg3swIvJBrpYoIEuAhqoVA6XHxnoKULmdAnpxUsUvFiK9GIZ1ovmgWUIL5YBvFhW2YsmQ1nCi2WVvVjazgv1IrJel5JevFTBi6UdeLGc3fjlvQ1eXqCtywMvogLZ1hUE2ro00Nblcrj8PpkCe7Ec+VMB/T1D1lbxXHkhsKYIcyTuFz9KdPs95svsAU2S9mKSAy+GbJhkb9uEYngxWaCBkoGdlUI2UIpAAyUBDRTK4fIjA/UiMqdU0oupCl4MkV5MY71oHphGeDEN8GK6shdNhnTCi+nKXky280K9iKxXBunFDAUvJjvwYqbd+FneBs8SaOss4EVkk22dLdDWyUBbZ+Zw+X0yBfZiZsCDGO/jYTOh94uXAWuF8EXyfhHwpxaxIkeUF3PsAc2V9mKuAy/m2TD53rbJi+HFfIEGygd2YEWygSoKNFAu0EB5OVx+ZKCnCJlTJdKLlRS8mEd6sTLrRfPAyoQXKwM1VUXZiyZDFcKLVZS9mG/nhXoRWa/LSS9eruDFfAderGo3fjVvg1cTaOtqwIuoTrZ1dYG2zgfaumoOl98nU2AvVv2P7hdZW8VzZQ6wpghzJO4XRya4/R7zFfaAXintxSsdeLGGDVPT2zY1YnixpkAD1QR21lVkA10l0EBXAg1UI4fLjwzUi8icria9eLWCF2uQXqzFetE8sBbhxVpA9dZW9qLJUJvwYm1lL9a080K9iKzXNaQXr1HwYk0HXrzWbvw63gavI9DWdYAXUZds67oCbV0TaOtrc7j8PpkCe/HagAcx3sfDZkLvF68A1grhi+T3mJXYFDmiDHidPXTXSxvwegcGrGfD1Pc2SL0YBqwv0Cr1gV11A9kqNwi0yvVAq9TL4fIjAzUgMqcbSQPeqGDAeqQBG7AGNA9sQBiwAWDAhsoGNBkaEgZsqGzA+nZeqAGR9bqJNOBNCgas78CAN9uN38jb4I0E2roR8CIak23dWKCt6wNtfXMOl98nU2AD3kz+VBC82Yjy33XAOiF0kbgHzEx0+z3mW+yhu1XagLc6MGATG6apt0GaxDBgU4FWaQrsrNvIVrlNoFVuBVqlSQ6XHxmoAZE53U4a8HYFAzYhDdiMNaB5YDPCgM0AAzZXNqDJ0JwwYHNlAza180INiKzXHaQB71AwYFMHBrzTbvwW3gZvIdDWLYAX0ZJs65YCbd0UaOs7c7j8PpkCG/DOgAcx3sfDZkLvAW8B1grhi+TvGQL+1CJW5Ijy4l32gN4t7cW7HXixlQ3T2ts2rWJ4sbVAA7UGduA9ZAPdI9BAdwMN1CqHy48M9BQhc7qX9OK9Cl5sRXqxDetF88A2hBfbADXVVtmLJkNbwottlb3Y2s4L9SKyXveRXrxPwYutHXixnd347b0N3l6grdsDL6ID2dYdBNq6NdDW7XK4/D6ZAnuxHflTAf09Q9ZW8Vx5F7CmCHMk7hc/TnT7Peb77QHtKO3Fjg682MmG6extm04xvNhZoIE6AzvrAbKBHhBooI5AA3XK4fIjA/UiMqcupBe7KHixE+nFrqwXzQO7El7sClRvN2UvmgzdCC92U/ZiZzsv1IvIej1IevFBBS92duDF7nbj9/A2eA+Btu4BvIieZFv3FGjrzkBbd8/h8vtkCuzF7gEPYryPh82E3i/eD6wVwhfJ+0XAn1rEihxRXnzIHtBe0l7s5cCLvW2YPt626R3Di30EGqgPsAMfJhvoYYEG6gU0UO8cLj8y0FOEzKkv6cW+Cl7sTXqxH+tF88B+hBf7ATXVX9mLJkN/wov9lb3Yx84L9SKyXo+QXnxEwYt9HHhxgN34A70NPlCgrQcCL2IQ2daDBNq6D9DWA3K4/D6ZAntxwH90v8jaKp4rHwLWFGGOxP3iqAS332N+1B7QwdJeHOzAi0NsmKHethkSw4tDBRpoKLCzHiMb6DGBBhoMNNCQHC4/MlAvInMaRnpxmIIXh5BeHM560TxwOOHF4UD1jlD2oskwgvDiCGUvDrXzQr2IrNfjpBcfV/DiUAdeHGk3/ihvg48SaOtRwIsYTbb1aIG2Hgq09cgcLr9PpsBeHBnwIMb7eNhM6P3io8BaIXyR/B6zEpsiR5QBn7CHboy0Acc4MOBYG2act0HGxjDgOIFWGQfsqifJVnlSoFXGAK0yNofLjwzUgMicxpMGHK9gwLGkASewBjQPnEAYcAJgwInKBjQZJhIGnKhswHF2XqgBkfV6ijTgUwoGHOfAgJPsxp/sbfDJAm09GXgRU8i2niLQ1uOAtp6Uw+X3yRTYgJPInwqCNxtR/nsCWCeELhL3gFmJbr/H/LQ9dM9IG/AZBwacasNM8zbI1BgGnCbQKtOAnfUs2SrPCrTKM0CrTM3h8iMDNSAyp+dIAz6nYMCppAGnswY0D5xOGHA6YMAZygY0GWYQBpyhbMBpdl6oAZH1ep404PMKBpzmwIAv2I0/09vgMwXaeibwImaRbT1LoK2nAW39Qg6X3ydTYAO+EPAgxvt42EzoPeDTwFohfJH8PUPAn1rEihxRXnzRHtDZ0l6c7cCLc2yYud62mRPDi3MFGmgusANfIhvoJYEGmg000JwcLj8y0FOEzOll0osvK3hxDunFeawXzQPnEV6cB9TUfGUvmgzzCS/OV/biXDsv1IvIer1CevEVBS/OdeDFV+3GX+Bt8AUCbb0AeBELybZeKNDWc4G2fjWHy++TKbAXXyV/KqC/Z8jaKp4rXwTWFGGOxP3iukS332N+zR7Q16W9+LoDLy6yYRZ722ZRDC8uFmigxcDOeoNsoDcEGuh1oIEW5XD5kYF6EZnTm6QX31Tw4iLSi0tYL5oHLiG8uASo3qXKXjQZlhJeXKrsxcV2XqgXkfV6i/TiWwpeXOzAi2/bjb/M2+DLBNp6GfAilpNtvVygrRcDbf12DpffJ1NgL74d8CDG+3jYTOj94mvAWiF8kbxfBPypRazIEeXFd+wBfVfai+868OIKG2alt21WxPDiSoEGWgnswPfIBnpPoIHeBRpoRQ6XHxnoKULm9D7pxfcVvLiC9OIq1ovmgasIL64Camq1shdNhtWEF1cre3GlnRfqRWS9PiC9+IGCF1c68OKHduOv8Tb4GoG2XgO8iLVkW68VaOuVQFt/mMPl98kU2Isf/kf3i6yt4rnyHWBNEeZI3C+OTnD7PeaP7AH9WNqLHzvw4jobZr23bdbF8OJ6gQZaD+ysT8gG+kSggT4GGmhdDpcfGagXkTltIL24QcGL60gvbmS9aB64kfDiRqB6Nyl70WTYRHhxk7IX19t5oV5E1utT0oufKnhxvQMvfmY3/mZvg28WaOvNwIvYQrb1FoG2Xg+09Wc5XH6fTIG9+FnAgxjv42EzofeLHwFrhfBF8nvMSmyKHFEG/Nweui+kDfiFAwNutWG2eRtkawwDbhNolW3ArvqSbJUvBVrlC6BVtuZw+ZGBGhCZ01ekAb9SMOBW0oDbWQOaB24nDLgdMOAOZQOaDDsIA+5QNuA2Oy/UgMh6fU0a8GsFA25zYMBv7Mbf6W3wnQJtvRN4EbvItt4l0NbbgLb+JofL75MpsAG/IX8qCN5sRPnvc2CdELpI3ANmJ7r9HvO39tB9J23A7xwYcLcNs8fbILtjGHCPQKvsAXbW92SrfC/QKt8BrbI7h8uPDNSAyJx+IA34g4IBd5MG3Msa0DxwL2HAvYAB9ykb0GTYRxhwn7IB99h5oQZE1utH0oA/KhhwjwMD/mQ3/n5vg+8XaOv9wIs4QLb1AYG23gO09U85XH6fTIEN+FPAgxjv42EzofeA3wJrhfBF8vcMAX9qEStyRHnxZ3tAf5H24i8OvHjQhjnkbZuDMbx4SKCBDgE78FeygX4VaKBfgAY6mMPlRwZ6ipA5/UZ68TcFLx4kvXiY9aJ54GHCi4eBmjqi7EWT4QjhxSPKXjxk54V6EVmv30kv/q7gxUMOvPiH3fhHvQ1+VKCtjwIv4hjZ1scE2voQ0NZ/5HD5fTIF9uIf5E8F9PcMWVvFc+XPwJoizJG4X1yf6PZ7zH/aA/qXtBf/cuDF4zbMCW/bHI/hxRMCDXQC2Fl/kw30t0AD/QU00PEcLj8yUC8iczpJevGkghePk148xXrRPPAU4cVTQPWeVvaiyXCa8OJpZS+esPNCvYis1z85nBf/UfDiCQdeTMi1H8pN+HdA8wdB29r8GwX97Bm5XFufkRu8rU8AbZ2Qy+X3yRTYiwm5wQ5ivI+HzYTeL/4JHESEL5L3i4A/tYgVOaK8eKY9oIXMfyXbplCuShjftjnLhinsbRvzP3i9WFiggQoDp/VssoHOFmigQrkFb6Czcrn8yEBPETKnc3I5L56TK+/Fs3I5LxbJDfBA85dRLxYp+ItMLAq8DDaDeQbqxaIBf0wVZLMXzcW9iKzXuUCGyM17bq68FwuTvEjwf45vg59nN34xb4MXE2jrYsCLKE62dXGBti4MtPV5uVx+n0yBvXge+VMBvV9kbRXPlWcCa4owR+J+8YkEt99jPt8e0AukvXiBAy+WsGFKetumRAwvlhRooJLAzrqQbKALBRroAqCBSuRy+ZGBehGZ00WkFy9S8GIJ0oulWC+aB5YivFgK8GJpZS+aDKUJL5ZW9mJJOy/Ui8h6XUx68WIFL5Z04MVL7MYv423wMgJtXQZ4EWXJti4r0NYlgba+JJfL75MpsBcvCXgQ4308bCb0fvF8YK0Qvkh+j1mJTZEjyoCX2kNXTtqA5RwYsLwNU8HbIOVjGLCCQKtUAHbVZWSrXCbQKuWAVimfy+VHBmpAZE5JpAGTFAxYnjRgiDWgeWCIMGAIMGCysgFNhmTCgMnKBqxg54UaEFmvFNKAKQoGrODAgKl246d5GzxNoK3TgBeRTrZ1ukBbVwDaOjWXy++TKbABU8mfCoI3G1H+uxRYJ4QuEveAOYluv8ecYQ9dprQBMx0YMMuGyfY2SFYMA2YLtEo2sLNyyFbJEWiVTKBVsnK5/MhADYjMKZc0YK6CAbNIA+axBjQPzCMMmAcYMF/ZgCZDPmHAfGUDZtt5oQZE1qsiacCKCgbMdmDASnbjV/Y2eGWBtq4MvIgqZFtXEWjrbKCtK+Vy+X0yBTZgpYAHMd7Hw2ZC7wEzgLVC+CL5e4aAP7WIFTmivHi5PaBVpb1Y1YEXq9kw1b1tUy2GF6sLNFB1YAdeQTbQFQINVBVooGq5XH5koKcImdOVpBevVPBiNdKLNVgvmgfWILxYA6ipmspeNBlqEl6sqezF6nZeqBeR9bqK9OJVCl6s7sCLV9uNX8vb4LUE2roW8CJqk21dW6CtqwNtfXUul98nU2AvXk3+VEB/z5C1VTxXXg6sKcIcifvFTxLdfo/5GntAr5X24rUOvFjHhqnrbZs6MbxYV6CB6gI76zqyga4TaKBrgQaqk8vlRwbqRWRO15NevF7Bi3VIL9ZjvWgeWI/wYj2geusre9FkqE94sb6yF+vaeaFeRNbrBtKLNyh4sa4DL95oN34Db4M3EGjrBsCLaEi2dUOBtq4LtPWNuVx+n0yBvXhjwIMY7+NhM6H3i9cAa4XwRfJ+EfCnFrEiR5QXb7IH9GZpL97swIuNbJjG3rZpFMOLjQUaqDGwA28hG+gWgQa6GWigRrlcfmSgpwiZ062kF29V8GIj0otNWC+aBzYhvNgEqKmmyl40GZoSXmyq7MXGdl6oF5H1uo304m0KXmzswIu3243fzNvgzQTauhnwIpqTbd1coK0bA219ey6X3ydTYC/e/h/dL7K2iufKm4A1RZgjcb84JsHt95jvsAf0Tmkv3unAiy1smJbetmkRw4stBRqoJbCz7iIb6C6BBroTaKAWuVx+ZKBeROZ0N+nFuxW82IL0YivWi+aBrQgvtgKqt7WyF02G1oQXWyt7saWdF+pFZL3uIb14j4IXWzrw4r1247fxNngbgbZuA7yItmRbtxVo65ZAW9+by+X3yRTYi/cGPIjxPh42E3q/eAewVghfJL/HrMSmyBFlwPvsoWsnbcB2DgzY3obp4G2Q9jEM2EGgVToAu+p+slXuF2iVdkCrtM/l8iMDNSAyp46kATsqGLA9acBOrAHNAzsRBuwEGLCzsgFNhs6EATsrG7CDnRdqQGS9HiAN+ICCATs4MGAXu/G7ehu8q0BbdwVeRDeyrbsJtHUHoK275HL5fTIFNmAX8qeC4M1GlP/uA9YJoYvEPWBuotvvMT9oD113aQN2d2DAHjZMT2+D9IhhwJ4CrdIT2FkPka3ykECrdAdapUculx8ZqAGROfUiDdhLwYA9SAP2Zg1oHtibMGBvwIB9lA1oMvQhDNhH2YA97bxQAyLr9TBpwIcVDNjTgQH72o3fz9vg/QTauh/wIvqTbd1foK17Am3dN5fL75MpsAH7BjyI8T4eNhN6D/ggsFYIXyR/zxDwpxaxIkeUFx+xB3SAtBcHOPDiQBtmkLdtBsbw4iCBBhoE7MBHyQZ6VKCBBgANNDCXy48M9BQhcxpMenGwghcHkl4cwnrRPHAI4cUhQE0NVfaiyTCU8OJQZS8OsvNCvYis12OkFx9T8OIgB14cZjf+cG+DDxdo6+HAixhBtvUIgbYeBLT1sFwuv0+mwF4cRv5UQH/PkLVVPFc+AqwpwhyJ+8UNiW6/x/y4PaAjpb040oEXR9kwo71tMyqGF0cLNNBoYGc9QTbQEwINNBJooFG5XH5koF5E5jSG9OIYBS+OIr04lvWieeBYwotjgeodp+xFk2Ec4cVxyl4cbeeFehFZrydJLz6p4MXRDrw43m78Cd4GnyDQ1hOAFzGRbOuJAm09Gmjr8blcfp9Mgb04PuBBjPfxsJnQ+8XHgbVC+CJ5vwj4U4tYkSPKi0/ZAzpJ2ouTHHhxsg0zxds2k2N4cYpAA00BduDTZAM9LdBAk4AGmpzL5UcGeoqQOT1DevEZBS9OJr04lfWieeBUwotTgZqapuxFk2Ea4cVpyl6cYueFehFZr2dJLz6r4MUpDrz4nN34070NPl2gracDL2IG2dYzBNp6CtDWz+Vy+X0yBfbic//R/SJrq3iufApYU4Q5EveLYxPcfo/5eXtAX5D24gsOvDjThpnlbZuZMbw4S6CBZgE760WygV4UaKAXgAaamcvlRwbqRWROs0kvzlbw4kzSi3NYL5oHziG8OAeo3rnKXjQZ5hJenKvsxVl2XqgXkfV6ifTiSwpenOXAiy/bjT/P2+DzBNp6HvAi5pNtPV+grWcBbf1yLpffJ1NgL74c8CDG+3jYTOj94vPAWiF8kfwesxKbIkeUAV+xh+5VaQO+6sCAC2yYhd4GWRDDgAsFWmUhsKteI1vlNYFWeRVolQW5XH5koAZE5vQ6acDXFQy4gDTgItaA5oGLCAMuAgy4WNmAJsNiwoCLlQ240M4LNSCyXm+QBnxDwYALHRjwTbvxl3gbfIlAWy8BXsRSsq2XCrT1QqCt38zl8vtkCmzAN8mfCoI3G1H+ewVYJ4QuEveAeYluv8f8lj10b0sb8G0HBlxmwyz3NsiyGAZcLtAqy4Gd9Q7ZKu8ItMrbQKssy+XyIwM1IDKnd0kDvqtgwGWkAVewBjQPXEEYcAVgwJXKBjQZVhIGXKlswOV2XqgBkfV6jzTgewoGXO7AgO/bjb/K2+CrBNp6FfAiVpNtvVqgrZcDbf1+LpffJ1NgA74f8CDG+3jYTOg94FvAWiF8kfw9Q8CfWsSKHFFe/MAe0A+lvfihAy+usWHWettmTQwvrhVooLXADvyIbKCPBBroQ6CB1uRy+ZGBniJkTh+TXvxYwYtrSC+uY71oHriO8OI6oKbWK3vRZFhPeHG9shfX2nmhXkTW6xPSi58oeHGtAy9usBt/o7fBNwq09UbgRWwi23qTQFuvBdp6Qy6X3ydTYC9uIH8qoL9nyNoqnis/ANYUYY7E/eLGRLffY/7UHtDPpL34mQMvbrZhtnjbZnMML24RaKAtwM76nGygzwUa6DOggTbncvmRgXoRmdMXpBe/UPDiZtKLW1kvmgduJby4FajebcpeNBm2EV7cpuzFLXZeqBeR9fqS9OKXCl7c4sCLX9mNv93b4NsF2no78CJ2kG29Q6CttwBt/VUul98nU2AvfhXwIMb7eNhM6P3ip8BaIXyRvF8E/KlFrMgR5cWv7QH9RtqL3zjw4k4bZpe3bXbG8OIugQbaBezAb8kG+laggb4BGmhnLpcfGegpQub0HenF7xS8uJP04m7Wi+aBuwkv7gZqao+yF02GPYQX9yh7cZedF+pFZL2+J734vYIXdznw4g924+/1NvhegbbeC7yIfWRb7xNo611AW/+Qy+X3yRTYiz/8R/eLrK3iufJrYE0R5kjcL45LcPs95h/tAf1J2os/OfDifhvmgLdt9sfw4gGBBjoA7KyfyQb6WaCBfgIaaH8ulx8ZqBeROf1CevEXBS/uJ714kPWieeBBwosHgeo9pOxFk+EQ4cVDyl48YOeFehFZr19JL/6q4MUDDrz4m934h70NfligrQ8DL+II2dZHBNr6ANDWv+Vy+X0yBfbibwEPYryPh82E3i/+CKwVwhfJ7zErsSlyRBnwd3vo/pA24B8ODHjUhjnmbZCjMQx4TKBVjgG76k+yVf4UaJU/gFY5msvlRwZqQGROf5EG/EvBgEdJAx5nDWgeeJww4HHAgCeUDWgynCAMeELZgMfsvFADIuv1N2nAvxUMeMyBAU/ajX/K2+CnBNr6FPAiTpNtfVqgrY8BbX0yl8vvkymwAU+SPxUEbzai/Pc7sE4IXSTuAfMT3X6P+Z/wT5u8BNkGMf9gAT8bcyT9X/+uZ/xr8fPsn+Ul/LtBzP/gNaD5UNBWOSOv4J89M49rlTPzgrdKQl7BWyUxj8uPDNSAyJwK5XEGLJQnb8DEPM6AZ+UFeKD5y6gBzyr4i0wsDLwMNoN5BmrAwuBmROd1hp0XakBkvc4GMkRu3rPz5A14RsEKS9SA59iNX8Tb4EUE2roI8CKKkm1dVKCtzwDa+pw8Lr9PpsAGPCfgQYz38bCZ0HvAf5D/8wpkkPw9Q8CfWsSKHFFePNce0POkvXieAy8Ws2GKe9umWAwvFhdooOLAaT2fbKDzBRroPKCBiuVx+ZGBniJkTheQXrxAwYvFSC+WYL1oHliC8GIJwIsllb1oMpQkvFhS2YvF7bxQLyLrdSHpxQsVvFjcgRcvshu/lLfBSwm0dSngRZQm27q0QFsXB9r6ojwuv0+mwF68iPypgP6eIWureK48F1hThDkS94ubEt1+j/lie0AvkfbiJQ68WMaGKettmzIxvFhWoIHKAjvrUrKBLhVooEuABiqTx+VHBupFZE7lSC+WU/BiGdKL5VkvmgeWJ7xYHvBiBWUvmgwVCC9WUPZiWTsv1IvIel1GevEyBS+WdeDFJLvxQ94GDwm0dQh4EclkWycLtHVZoK2T8rj8PpkCezEp4EGM9/GwmdD7xYuBtUL4Inm/CPhTi1iRI8qLKfaApkp7MdWBF9NsmHRv26TF8GK6QAOlAzswg2ygDIEGSgUaKC2Py48M9BQhc8okvZip4MU00otZrBfNA7MIL2YBNZWt7EWTIZvwYrayF9PtvFAvIuuVQ3oxR8GL6Q68mGs3fp63wfME2joPeBH5ZFvnC7R1OtDWuXlcfp9Mgb2Y+x/dL7K2iufKFGBNEeZI3C8+meD2e8wV7QGtJO3FSg68WNmGqeJtm8oxvFhFoIGqADvrcrKBLhdooEpAA1XO4/IjA/UiMqeqpBerKnixMunFaqwXzQOrEV6sBlRvdWUvmgzVCS9WV/ZiFTsv1IvIel1BevEKBS9WceDFK+3Gr+Ft8BoCbV0DeBE1ybauKdDWVYC2vjKPy++TKbAXrwx4EON9PGwm9H6xIrBWCF8kv8esxKbIEWXAq+yhu1ragFc7MGAtG6a2t0FqxTBgbYFWqQ3sqmvIVrlGoFWuBlqlVh6XHxmoAZE5XUsa8FoFA9YiDViHNaB5YB3CgHUAA9ZVNqDJUJcwYF1lA9a280INiKzXdaQBr1MwYG0HBrzebvx63gavJ9DW9YAXUZ9s6/oCbV0baOvr87j8PpkCG/B68qeC4M1GlP+uAtYJoYvEPWDFRLffY77BHrobpQ14owMDNrBhGnobpEEMAzYUaJWGwM66iWyVmwRa5UagVRrkcfmRgRoQmdPNpAFvVjBgA9KAjVgDmgc2IgzYCDBgY2UDmgyNCQM2VjZgQzsv1IDIet1CGvAWBQM2dGDAW+3Gb+Jt8CYCbd0EeBFNybZuKtDWDYG2vjWPy++TKbABbw14EON9PGwm9B7wBmCtEL5I/p4h4E8tYkWOKC/eZg/o7dJevN2BF5vZMM29bdMshhebCzRQc2AH3kE20B0CDXQ70EDN8rj8yEBPETKnO0kv3qngxWakF1uwXjQPbEF4sQVQUy2VvWgytCS82FLZi83tvFAvIut1F+nFuxS82NyBF++2G7+Vt8FbCbR1K+BFtCbburVAWzcH2vruPC6/T6bAXryb/KmA/p4ha6t4rrwNWFOEORL3i58muv0e8z32gN4r7cV7HXixjQ3T1ts2bWJ4sa1AA7UFdtZ9ZAPdJ9BA9wIN1CaPy48M1IvInNqRXmyn4MU2pBfbs140D2xPeLE9UL0dlL1oMnQgvNhB2Ytt7bxQLyLrdT/pxfsVvNjWgRc72o3fydvgnQTauhPwIjqTbd1ZoK3bAm3dMY/L75MpsBc7BjyI8T4eNhN6v3gPsFYIXyTvFwF/ahErckR58QF7QLtIe7GLAy92tWG6edumawwvdhNooG7ADnyQbKAHBRqoC9BAXfO4/MhATxEyp+6kF7sreLEr6cUerBfNA3sQXuwB1FRPZS+aDD0JL/ZU9mI3Oy/Ui8h6PUR68SEFL3Zz4MVeduP39jZ4b4G27g28iD5kW/cRaOtuQFv3yuPy+2QK7MVe/9H9ImureK58AFhThDkS94vjE9x+j/lhe0D7SnuxrwMv9rNh+nvbpl8ML/YXaKD+wM56hGygRwQaqC/QQP3yuPzIQL2IzGkA6cUBCl7sR3pxIOtF88CBhBcHAtU7SNmL/zushBcHKXuxv50X6kVkvR4lvfioghf7O/DiYLvxh3gbfIhAWw8BXsRQsq2HCrR1f6CtB+dx+X0yBfbi4IAHMd7Hw2ZC7xcfBtYK4Yvk95iV2BQ5ogz4mD10w6QNOMyBAYfbMCO8DTI8hgFHCLTKCGBXPU62yuMCrTIMaJXheVx+ZKAGROY0kjTgSAUDDicNOIo1oHngKMKAowADjlY2oMkwmjDgaGUDjrDzQg2IrNcTpAGfUDDgCAcGHGM3/lhvg48VaOuxwIsYR7b1OIG2HgG09Zg8Lr9PpsAGHEP+VBC82Yjy32PAOiF0kbgHrJTo9nvMT9pDN17agOMdGHCCDTPR2yATYhhwokCrTAR21lNkqzwl0CrjgVaZkMflRwZqQGROk0gDTlIw4ATSgJNZA5oHTiYMOBkw4BRlA5oMUwgDTlE24EQ7L9SAyHo9TRrwaQUDTnRgwGfsxp/qbfCpAm09FXgR08i2nibQ1hOBtn4mj8vvkymwAZ8JeBDjfTxsJvQe8ElgrRC+SP6eIeBPLWJFjigvPmsP6HPSXnzOgRen2zAzvG0zPYYXZwg00AxgBz5PNtDzAg30HNBA0/O4/MhATxEypxdIL76g4MXppBdnsl40D5xJeHEmUFOzlL1oMswivDhL2Ysz7LxQLyLr9SLpxRcVvDjDgRdn240/x9vgcwTaeg7wIuaSbT1XoK1nAG09O4/L75MpsBdnkz8V0N8zZG0Vz5XPAmuKMEfifvGzRLffY37JHtCXpb34sgMvzrNh5nvbZl4ML84XaKD5wM56hWygVwQa6GWggeblcfmRgXoRmdOrpBdfVfDiPNKLC1gvmgcuILy4AKjehcpeNBkWEl5cqOzF+XZeqBeR9XqN9OJrCl6c78CLr9uNv8jb4IsE2noR8CIWk229WKCt5wNt/Xoel98nU2Avvh7wIMb7eNhM6P3iS8BaIXyRvF8E/KlFrMgR5cU37AF9U9qLbzrw4hIbZqm3bZbE8OJSgQZaCuzAt8gGekuggd4EGmhJHpcfGegpQub0NunFtxW8uIT04jLWi+aBywgvLgNqarmyF02G5YQXlyt7camdF+pFZL3eIb34joIXlzrw4rt246/wNvgKgbZeAbyIlWRbrxRo66VAW7+bx+X3yRTYi+/+R/eLrK3iufINYE0R5kjcL05IcPs95vfsAX1f2ovvO/DiKhtmtbdtVsXw4mqBBloN7KwPyAb6QKCB3gcaaFUelx8ZqBeROX1IevFDBS+uIr24hvWieeAawotrgOpdq+xFk2Et4cW1yl5cbeeFehFZr49IL36k4MXVDrz4sd3467wNvk6grdcBL2I92dbrBdp6NdDWH+dx+X0yBfbixwEPYryPh82E3i++B6wVwhfJ7zErsSlyRBnwE3voNkgbcIMDA260YTZ5G2RjDANuEmiVTcCu+pRslU8FWmUD0Cob87j8yEANiMzpM9KAnykYcCNpwM2sAc0DNxMG3AwYcIuyAU2GLYQBtygbcJOdF2pAZL0+Jw34uYIBNzkw4Bd242/1NvhWgbbeCryIbWRbbxNo601AW3+Rx+X3yRTYgF+QPxUEbzai/PcJsE4IXSTuASsnuv0e85f20H0lbcCvHBhwuw2zw9sg22MYcIdAq+wAdtbXZKt8LdAqXwGtsj2Py48M1IDInL4hDfiNggG3kwbcyRrQPHAnYcCdgAF3KRvQZNhFGHCXsgF32HmhBkTW61vSgN8qGHCHAwN+Zzf+bm+D7xZo693Ai9hDtvUegbbeAbT1d3lcfp9MgQ34XcCDGO/jYTOh94BfAmuF8EXy9wwBf2oRK3JEefF7e0B/kPbiDw68uNeG2edtm70xvLhPoIH2ATvwR7KBfhRooB+ABtqbx+VHBnqKkDn9RHrxJwUv7iW9uJ/1onngfsKL+4GaOqDsRZPhAOHFA8pe3GfnhXoRWa+fSS/+rODFfQ68+Ivd+Ae9DX5QoK0PAi/iENnWhwTaeh/Q1r/kcfl9MgX24i/kTwX09wxZW8Vz5ffAmiLMkbhf3Jzo9nvMv9oD+pu0F39z4MXDNswRb9scjuHFIwINdATYWb+TDfS7QAP9BjTQ4TwuPzJQLyJz+oP04h8KXjxMevEo60XzwKOEF48C1XtM2YsmwzHCi8eUvXjEzgv1IrJef5Je/FPBi0ccePEvu/GPexv8uEBbHwdexAmyrU8ItPURoK3/yuPy+2QK7MW/Ah7EeB8Pmwm9X/wVWCuEL5L3i4A/tYgVOaK8+Lc9oCelvXjSgRdP2TCnvW1zKoYXTws00GlgB/5DNtA/Ag10EmigU3lcfmSgpwiZU0I+50Xz96S9eIr0YmJ+gAeav4x6MTG/4C/jjHxdL5oM5hmoF8/IxzYjOq/Tdl6oF5H1OhPIELl5zd+T9uJpB14sZDf+WfkJ/w54Vn7wtj4LeBGF87m2LpwfvK1PA21dKJ/L75MpsBcLgQcxPND7RdZW8Vz5N/DT5mRAV6KHcmKC2+8xn20P6Dnmv5Jtc06+ShjftiliwxT1tk2R/GgvFhVooKLAaT2XbKBzBRronPyCN1CRfC4/MlAvInM6j/TieQpeLJLPebEY60XzwGKEF4sBXiyu7EWToTjhxeLKXixq54V6EVmv80kvnq/gxaIkLxL8n+Pb4BfYjV/C2+AlBNq6BPAiSpJtXVKgrYsCbX1BPpffJ1NgL14Q8CDG+3jYTOj94tnAWiF8kfwesxKbIkeUAS+0h+4iaQNe5MCApWyY0t4GKRXDgKUFWqU0sKsuJlvlYoFWuQholVL5XH5koAZE5nQJacBLFAxYijRgGdaA5oFlCAOWAQxYVtmAJkNZwoBllQ1Y2s4LNSCyXpeSBrxUwYClHRiwnN345b0NXl6grcsDL6IC2dYVBNq6NNDW5fK5/D6ZAhuwHPlTQfBmI8p/FwLrhNBF4h6wSqLb7zFfZg9dkrQBkxwYMGTDJHsbJBTDgMkCrZIM7KwUslVSBFolCWiVUD6XHxmoAZE5pZIGTFUwYIg0YBprQPPANMKAaYAB05UNaDKkEwZMVzZgsp0XakBkvTJIA2YoGDDZgQEz7cbP8jZ4lkBbZwEvIpts62yBtk4G2jozn8vvkymwATMDHsR4Hw+bCb0HvAxYK4Qvkr9nCPhTi1iRI8qLOfaA5kp7MdeBF/NsmHxv2+TF8GK+QAPlAzuwItlAFQUaKBdooLx8Lj8y0FOEzKkS6cVKCl7MI71YmfWieWBlwouVgZqqouxFk6EK4cUqyl7Mt/NCvYis1+WkFy9X8GK+Ay9WtRu/mrfBqwm0dTXgRVQn27q6QFvnA21dNZ/L75MpsBerkj8V0N8zZG0Vz5U5wJoizJG4X9yS6PZ7zFfYA3qltBevdODFGjZMTW/b1IjhxZoCDVQT2FlXkQ10lUADXQk0UI18Lj8yUC8ic7qa9OLVCl6sQXqxFutF88BahBdrAdVbW9mLJkNtwou1lb1Y084L9SKyXteQXrxGwYs1HXjxWrvx63gbvI5AW9cBXkRdsq3rCrR1TaCtr83n8vtkCuzFawMexHgfD5sJvV+8AlgrhC+S94uAP7WIFTmivHidPaDXS3vxegderGfD1Pe2Tb0YXqwv0ED1gR14A9lANwg00PVAA9XL5/IjAz1FyJxuJL14o4IX65FebMB60TywAeHFBkBNNVT2osnQkPBiQ2Uv1rfzQr2IrNdNpBdvUvBifQdevNlu/EbeBm8k0NaNgBfRmGzrxgJtXR9o65vzufw+mQJ78eb/6H6RtVU8V14HrCnCHIn7xacS3H6P+RZ7QG+V9uKtDrzYxIZp6m2bJjG82FSggZoCO+s2soFuE2igW4EGapLP5UcG6kVkTreTXrxdwYtNSC82Y71oHtiM8GIzoHqbK3vRZGhOeLG5sheb2nmhXkTW6w7Si3coeLGpAy/eaTd+C2+DtxBo6xbAi2hJtnVLgbZuCrT1nflcfp9Mgb14Z8CDGO/jYTOh94u3AGuF8EXye8xKbIocUQa8yx66u6UNeLcDA7ayYVp7G6RVDAO2FmiV1sCuuodslXsEWuVuoFVa5XP5kYEaEJnTvaQB71UwYCvSgG1YA5oHtiEM2AYwYFtlA5oMbQkDtlU2YGs7L9SAyHrdRxrwPgUDtnZgwHZ247f3Nnh7gbZuD7yIDmRbdxBo69ZAW7fL5/L7ZApswHbkTwXBm40o/90FrBNCF4l7wMsT3X6P+X576DpKG7CjAwN2smE6exukUwwDdhZolc7AznqAbJUHBFqlI9AqnfK5/MhADYjMqQtpwC4KBuxEGrAra0DzwK6EAbsCBuymbECToRthwG7KBuxs54UaEFmvB0kDPqhgwM4ODNjdbvwe3gbvIdDWPYAX0ZNs654Cbd0ZaOvu+Vx+n0yBDdg94EGM9/GwmdB7wPuBtUL4Ivl7hoA/tYgVOaK8+JA9oL2kvdjLgRd72zB9vG3TO4YX+wg0UB9gBz5MNtDDAg3UC2ig3vlcfmSgpwiZU1/Si30VvNib9GI/1ovmgf0IL/YDaqq/shdNhv6EF/sre7GPnRfqRWS9HiG9+IiCF/s48OIAu/EHeht8oEBbDwRexCCyrQcJtHUfoK0H5HP5fTIF9uIA8qcC+nuGrK3iufIhYE0R5kjcL36e6PZ7zI/aAzpY2ouDHXhxiA0z1Ns2Q2J4cahAAw0FdtZjZAM9JtBAg4EGGpLP5UcG6kVkTsNILw5T8OIQ0ovDWS+aBw4nvDgcqN4Ryl40GUYQXhyh7MWhdl6oF5H1epz04uMKXhzqwIsj7cYf5W3wUQJtPQp4EaPJth4t0NZDgbYemc/l98kU2IsjAx7EeB8Pmwm9X3wUWCuEL5L3i4A/tYgVOaK8+IQ9oGOkvTjGgRfH2jDjvG0zNoYXxwk00DhgBz5JNtCTAg00BmigsflcfmSgpwiZ03jSi+MVvDiW9OIE1ovmgRMIL04AamqishdNhomEFycqe3GcnRfqRWS9niK9+JSCF8c58OIku/Enext8skBbTwZexBSyracItPU4oK0n5XP5fTIF9uKk/+h+kbVVPFc+AawpwhyJ+8VJCW6/x/y0PaDPSHvxGQdenGrDTPO2zdQYXpwm0EDTgJ31LNlAzwo00DNAA03N5/IjA/UiMqfnSC8+p+DFqaQXp7NeNA+cTnhxOlC9M5S9aDLMILw4Q9mL0+y8UC8i6/U86cXnFbw4zYEXX7Abf6a3wWcKtPVM4EXMItt6lkBbTwPa+oV8Lr9PpsBefCHgQYz38bCZ0PvFp4G1Qvgi+T1mJTZFjigDvmgP3WxpA852YMA5Nsxcb4PMiWHAuQKtMhfYVS+RrfKSQKvMBlplTj6XHxmoAZE5vUwa8GUFA84hDTiPNaB54DzCgPMAA85XNqDJMJ8w4HxlA86180INiKzXK6QBX1Ew4FwHBnzVbvwF3gZfINDWC4AXsZBs64UCbT0XaOtX87n8PpkCG/BV8qeC4M1GlP9eBNYJoYvEPWDVRLffY37NHrrXpQ34ugMDLrJhFnsbZFEMAy4WaJXFwM56g2yVNwRa5XWgVRblc/mRgRoQmdObpAHfVDDgItKAS1gDmgcuIQy4BDDgUmUDmgxLCQMuVTbgYjsv1IDIer1FGvAtBQMudmDAt+3GX+Zt8GUCbb0MeBHLybZeLtDWi4G2fjufy++TKbAB3w54EON9PGwm9B7wNWCtEL5I/p4h4E8tYkWOKC++Yw/ou9JefNeBF1fYMCu9bbMihhdXCjTQSmAHvkc20HsCDfQu0EAr8rn8yEBPETKn90kvvq/gxRWkF1exXjQPXEV4cRVQU6uVvWgyrCa8uFrZiyvtvFAvIuv1AenFDxS8uNKBFz+0G3+Nt8HXCLT1GuBFrCXbeq1AW68E2vrDfC6/T6bAXvyQ/KmA/p4ha6t4rnwHWFOEORL3i18kuv0e80f2gH4s7cWPHXhxnQ2z3ts262J4cb1AA60HdtYnZAN9ItBAHwMNtC6fy48M1IvInDaQXtyg4MV1pBc3sl40D9xIeHEjUL2blL1oMmwivLhJ2Yvr7bxQLyLr9SnpxU8VvLjegRc/sxt/s7fBNwu09WbgRWwh23qLQFuvB9r6s3wuv0+mwF78LOBBjPfxsJnQ+8WPgLVC+CJ5vwj4U4tYkSPKi5/bA/qFtBe/cODFrTbMNm/bbI3hxW0CDbQN2IFfkg30pUADfQE00NZ8Lj8y0FOEzOkr0otfKXhxK+nF7awXzQO3E17cDtTUDmUvmgw7CC/uUPbiNjsv1IvIen1NevFrBS9uc+DFb+zG3+lt8J0Cbb0TeBG7yLbeJdDW24C2/iafy++TKbAXv/mP7hdZW8Vz5efAmiLMkbhfnJzg9nvM39oD+p20F79z4MXdNsweb9vsjuHFPQINtAfYWd+TDfS9QAN9BzTQ7nwuPzJQLyJz+oH04g8KXtxNenEv60XzwL2EF/cC1btP2Ysmwz7Ci/uUvbjHzgv1IrJeP5Je/FHBi3scePEnu/H3ext8v0Bb7wdexAGyrQ8ItPUeoK1/yufye4ekF38KeBDjfTxsJvR+8VtgrRC+SH6PWYlNkSPKgD/bQ/eLtAF/cWDAgzbMIW+DHIxhwEMCrXII2FW/kq3yq0Cr/AK0ysF8Lj8yUAMic/qNNOBvCgY8SBrwMGtA88DDhAEPAwY8omxAk+EIYcAjygY8ZOeFGhBZr99JA/6uYMBDDgz4h934R70NflSgrY8CL+IY2dbHBNr6ENDWf+Rz+X0yBTbgH+RPBcGbjSj//QysE0IXiXvAaoluv8f8pz10f0kb8C8HBjxuw5zwNsjxGAY8IdAqJ4Cd9TfZKn8LtMpfQKscz+fyIwM1IDKnk6QBTyoY8DhpwFOsAc0DTxEGPAUY8LSyAU2G04QBTysb8ISdF2pAZL3+IQ34j4IBTzgwYEJF+6GKCf8OaP4gaFubf6Ognz2jItfWZ1QM3tYngLZOqMjl98kU2IAJFYMdxHgfD5sJvQf8EziICF8kf88Q8KcWsSJHlBfPtAe0kPmvZNsUqqgSxrdtzrJhCnvbxvwPXi8WFmigwsBpPZtsoLMFGqhQxYI30FkVufzIQE8RMqdzKnJePKeivBfPqsh5sUjFAA80fxn1YpGCv8jEosDLYDOYZ6BeLBrwx1RBNnvRirgXkfU6F8gQuXnPrSjvxcIkLxL8n+Pb4OfZjV/M2+DFBNq6GPAiipNtXVygrQsDbX1eRS6/T6bAXjyP/KmA/p4ha6t4rjwTWFOEORL3i1sT3X6P+Xx7QC+Q9uIFDrxYwoYp6W2bEjG8WFKggUoCO+tCsoEuFGigC4AGKlGRy48M1IvInC4ivXiRghdLkF4sxXrRPLAU4cVSgBdLK3vRZChNeLG0shdL2nmhXkTW62LSixcreLGkAy9eYjd+GW+DlxFo6zLAiyhLtnVZgbYuCbT1JRW5/D6ZAnvxkoAHMd7Hw2ZC7xfPB9YK4Yvk/SLgTy1iRY4oL15qD2g5aS+Wc+DF8jZMBW/blI/hxQoCDVQB2IGXkQ10mUADlQMaqHxFLj8y0FOEzCmJ9GKSghfLk14MsV40DwwRXgwBNZWs7EWTIZnwYrKyFyvYeaFeRNYrhfRiioIXKzjwYqrd+GneBk8TaOs04EWkk22dLtDWFYC2Tq3I5ffJFNiLqf/R/SJrq3iuvBRYU4Q5EveLUxLcfo85wx7QTGkvZjrwYpYNk+1tm6wYXswWaKBsYGflkA2UI9BAmUADZVXk8iMD9SIyp1zSi7kKXswivZjHetE8MI/wYh5QvfnKXjQZ8gkv5it7MdvOC/Uisl4VSS9WVPBitgMvVrIbv7K3wSsLtHVl4EVUIdu6ikBbZwNtXakil98nU2AvVgp4EON9PGwm9H4xA1grhC+S32NWYlPkiDLg5fbQVZU2YFUHBqxmw1T3Nki1GAasLtAq1YFddQXZKlcItEpVoFWqVeTyIwM1IDKnK0kDXqlgwGqkAWuwBjQPrEEYsAZgwJrKBjQZahIGrKlswOp2XqgBkfW6ijTgVQoGrO7AgFfbjV/L2+C1BNq6FvAiapNtXVugrasDbX11RS6/T6bABrya/KkgeLMR5b/LgXVC6CJxD1g90e33mK+xh+5aaQNe68CAdWyYut4GqRPDgHUFWqUusLOuI1vlOoFWuRZolToVufzIQA2IzOl60oDXKxiwDmnAeqwBzQPrEQasBxiwvrIBTYb6hAHrKxuwrp0XakBkvW4gDXiDggHrOjDgjXbjN/A2eAOBtm4AvIiGZFs3FGjrukBb31iRy++TKbABbwx4EON9PGwm9B7wGmCtEL5I/p4h4E8tYkWOKC/eZA/ozdJevNmBFxvZMI29bdMohhcbCzRQY2AH3kI20C0CDXQz0ECNKnL5kYGeImROt5JevFXBi41ILzZhvWge2ITwYhOgppoqe9FkaEp4samyFxvbeaFeRNbrNtKLtyl4sbEDL95uN34zb4M3E2jrZsCLaE62dXOBtm4MtPXtFbn8PpkCe/F28qcC+nuGrK3iufImYE0R5kjcL25LdPs95jvsAb1T2ot3OvBiCxumpbdtWsTwYkuBBmoJ7Ky7yAa6S6CB7gQaqEVFLj8yUC8ic7qb9OLdCl5sQXqxFetF88BWhBdbAdXbWtmLJkNrwoutlb3Y0s4L9SKyXveQXrxHwYstHXjxXrvx23gbvI1AW7cBXkRbsq3bCrR1S6Ct763I5ffJFNiL9wY8iPE+HjYTer94B7BWCF8k7xcBf2oRK3JEefE+e0DbSXuxnQMvtrdhOnjbpn0ML3YQaKAOwA68n2yg+wUaqB3QQO0rcvmRgZ4iZE4dSS92VPBie9KLnVgvmgd2IrzYCaipzspeNBk6E17srOzFDnZeqBeR9XqA9OIDCl7s4MCLXezG7+pt8K4Cbd0VeBHdyLbuJtDWHYC27lKRy++TKbAXu/xH94usreK58j5gTRHmSNwvPp3g9nvMD9oD2l3ai90deLGHDdPT2zY9Ynixp0AD9QR21kNkAz0k0EDdgQbqUZHLjwzUi8icepFe7KXgxR6kF3uzXjQP7E14sTdQvX2UvWgy9CG82EfZiz3tvFAvIuv1MOnFhxW82NOBF/vajd/P2+D9BNq6H/Ai+pNt3V+grXsCbd23IpffJ1NgL/YNeBDjfTxsJvR+8UFgrRC+SH6PWYlNkSPKgI/YQzdA2oADHBhwoA0zyNsgA2MYcJBAqwwCdtWjZKs8KtAqA4BWGViRy48M1IDInAaTBhysYMCBpAGHsAY0DxxCGHAIYMChygY0GYYSBhyqbMBBdl6oAZH1eow04GMKBhzkwIDD7MYf7m3w4QJtPRx4ESPIth4h0NaDgLYeVpHL75MpsAGHkT8VBG82ovz3CLBOCF0k7gGvSHT7PebH7aEbKW3AkQ4MOMqGGe1tkFExDDhaoFVGAzvrCbJVnhBolZFAq4yqyOVHBmpAZE5jSAOOUTDgKNKAY1kDmgeOJQw4FjDgOGUDmgzjCAOOUzbgaDsv1IDIej1JGvBJBQOOdmDA8XbjT/A2+ASBtp4AvIiJZFtPFGjr0UBbj6/I5ffJFNiA4wMexHgfD5sJvQd8HFgrhC+Sv2cI+FOLWJEjyotP2QM6SdqLkxx4cbINM8XbNpNjeHGKQANNAXbg02QDPS3QQJOABppckcuPDPQUIXN6hvTiMwpenEx6cSrrRfPAqYQXpwI1NU3ZiybDNMKL05S9OMXOC/Uisl7Pkl58VsGLUxx48Tm78ad7G3y6QFtPB17EDLKtZwi09RSgrZ+ryOX3yRTYi8+RPxXQ3zNkbRXPlU8Ba4owR+J+8ctEt99jft4e0BekvfiCAy/OtGFmedtmZgwvzhJooFnAznqRbKAXBRroBaCBZlbk8iMD9SIyp9mkF2creHEm6cU5rBfNA+cQXpwDVO9cZS+aDHMJL85V9uL/R93Zh9tUde/fTpIkCUWSI0pCzvu7EEIIIQlFKEIISUiSIklCCEkoryGEEEIIlaQSQgihCEXI75rPb55vZ8+zzl7rvveYe13mP67raZ09x5hzjHt+5thrj+d9bRfKi8h6fUjy4ocWePF9H3hxug78GaaCzxBQ6xnARswk1XqmgFq/D6j19Iqc/yF8CpsXp4eZiG6PZzATWl+cBKwVgi+S9UWAP20hVuaRhRdn6QSdLc2Ls33gxTnamY9MtZnjwIsfCSjQR0AEziUVaK6AAs0GFGhORc5/ZKBZhNg0j+TFeRZ4cQ7Ji/NZXlQTzid4cT4gUx9b5kXlw8cEL35smRc/0nahvIis1wKSFxdY4MWPfODFhTrwF5kKvkhArRcBG/EJqdafCKj1R4BaL6zI+R/Cp7B5cWGE6ossW7lx5SxgTRHMkagvjs3h7++YF+sEXSLNi0t84MWl2plPTbVZ6sCLnwoo0KdAZC0jFWiZgAItARRoaUXOf2SgvIjYtJzkxeUWeHEpyYsrWF5UE64geHEFIL2fWeZF5cNnBC9+ZpkXP9V2obyIrNdKkhdXWuDFT33gxVU68FebCr5aQK1XAxvxOanWnwuo9aeAWq+qyPkfwqeweXFVmIno9ngGM6H1xcXAWiH4Ivk7ZkvYlHlkYcA1OunWSjPgWh8YcJ125gtTQdY5MOAXAqryBRBV60lVWS+gKmsBVVlXkfMfGSgDIjZtIBlwgwUGXEcy4EaWAdWEGwkG3Agw4JeWGVD58CXBgF9aZsAvtF0oAyLrtYlkwE0WGPALHxhwsw78LaaCbxFQ6y3ARnxFqvVXAmr9BaDWmyty/ofwKWwG3EyeCoKVjSz8twZYJwRdJOqAyQF/f8f8tU66b6QZ8BsfGHCrduZbU0G2OjDgtwKq8i0QWdtIVdkmoCrfAKqytSLnPzJQBkRs+o5kwO8sMOBWkgG3swyoJtxOMOB2gAG/t8yAyofvCQb83jIDfqvtQhkQWa8fSAb8wQIDfusDA/6oA3+HqeA7BNR6B7ARP5Fq/ZOAWn8LqPWPFTn/Q/gUNgP+GGYiuj2ewUxoHfBrYK0QfJF8zxDgT1uIlXlk4cWdOkF3SfPiLh94cbd25mdTbXY78OLPAgr0MxCBe0gF2iOgQLsABdpdkfMfGWgWITbtJXlxrwVe3E3y4j6WF9WE+whe3AfI1C+WeVH58AvBi79Y5sWftV0oLyLrtZ/kxf0WePFnH3jxgA78g6aCHxRQ64PARvxKqvWvAmr9M6DWBypy/ofwKWxePECeCuh7hixbuXHlTmBNEcyRqC/+GPD3d8yHdIIelubFwz7w4hHtzG+m2hxx4MXfBBToNyCyjpIKdFRAgQ4DCnSkIuc/MlBeRGw6RvLiMQu8eITkxeMsL6oJjxO8eByQ3t8t86Ly4XeCF3+3zIu/abtQXkTW6w+SF/+wwIu/+cCLJ3TgnzQV/KSAWp8ENuJPUq3/FFDr3wC1PlGR8z+ET2Hz4okwE9Ht8QxmQuuLh4C1QvBFsr4I8KctxMo8svDiKZ2gp6V58bQPvHhGO/OXqTZnHHjxLwEF+guIwL9JBfpbQIFOAwp0piLnPzLQLEJsOkvy4lkLvHiG5MVzLC+qCc8RvHgOkKl/LPOi8uEfghf/scyLf2m7UF5E1us8yYvnLfDiXz7w4gUd+BdNBb8ooNYXgY34l1TrfwXU+i9ArS9U5PwP4VPYvHghQvVFlq3cuPIUsKYI5kjUF8fl8Pd3zJcyTqboHLJqoz7Q47OOIyq7zzVG0OJH6/8tOkew2qj/YPKieihcBboi2vuzOaM5BcoZHb4C5Yj2rkCBaM5/ZKC8iNh0ZTTHi1dGy/NiIJrjxVzRYUyo/hjlxVzeNzJwFbAZrA9qDpQXrwKDEbXrCm0XyovIeuUGfMgcvLmj5XnxCm+CJcqLV+vAz2MqeB4Btc4DbMQ1pFpfI6DWVwBqfXU0538In8LmxavDTES3xzOYCa0vXkIuuoAPkr9jtoRNmUcWBsyrk+5aaQa81gcGzKeduc5UkHwODHidgKpcB2RgflJV8guoyrWAquSL5vxHBsqAiE3Xkwx4vQUGzEcyYIHoMCYsQDBgAYABb7DMgMqHGwgGvMEyA16n7UIZEFmvgiQDFrTAgNf5wICFdOAXNhW8sIBaFwY24kZSrW8UUOvrALUuFM35H8KnsBmwEHkqCFY2svBfXmCdEHSRqAOmBPz9HfNNOumKSDNgER8YsKh25mZTQYo6MODNAqpyMxBZxUhVKSagKkUAVSkazfmPDJQBEZtuIRnwFgsMWJRkwOLRYUxYnGDA4gAD3mqZAZUPtxIMeKtlBrxZ24UyILJeJUgGLGGBAW/2gQGjdOCXNBW8pIBalwQ24jZSrW8TUOubAbWOiub8D+FT2AwYFWYiuj2ewUxoHfAmYK0QfJF8zxDgT1uIlXlk4cVSOkFLS/NiaR948XbtzB2m2tzuwIt3CCjQHUAEliEVqIyAApUGFOj2aM5/ZKBZhNh0J8mLd1rgxdtJXiwbHcaEZQleLAvI1F2WeVH5cBfBi3dZ5sU7tF0oLyLrVY7kxXIWePEOH3ixvA78CqaCVxBQ6wrARtxNqvXdAmp9B6DW5aM5/0P4FDYvlidPBfQ9Q5at3LiyFLCmCOZI1Bd3BPz9HXNFnaDR0rwY7QMvxmhnYk21iXHgxVgBBYoFIiuOVKA4AQWKBhQoJprzHxkoLyI2xZO8GG+BF2NIXkyIDmPCBIIXEwDpTbTMi8qHRIIXEy3zYqy2C+VFZL2SSF5MssCLsT7wYrIO/BRTwVME1DoF2IhUUq1TBdQ6FlDr5GjO/xA+hc2LyWEmotvjGcyE1hcrAmuF4ItkfRHgT1uIlXlk4cU0naDp0ryY7gMvVtLO3GOqTSUHXrxHQIHuASKwMqlAlQUUKB1QoErRnP/IQLMIsakKyYtVLPBiJZIXq0aHMWFVgherAjJ1r2VeVD7cS/DivZZ58R5tF8qLyHpVI3mxmgVevMcHXqyuA7+GqeA1BNS6BrAR95FqfZ+AWt8DqHX1aM7/ED6FzYvVyVMBrS+ybOXGlWnAmiKYI1FffCeHv79jrqkTtJY0L9bygRdra2fuN9WmtgMv3i+gQPcDkVWHVKA6AgpUC1Cg2tGc/8hAeRGxqS7Ji3Ut8GJtkhfrRYcxYT2CF+sB0vuAZV5UPjxA8OIDlnnxfm0XyovIetUnebG+BV683wdebKADv6Gp4A0F1LohsBEPkmr9oIBa3w+odYNozv8QPoXNiw3CTES3xzOYCa0v1gTWCsEXyd8xW8KmzCMLAzbSSddYmgEb+8CATbQzD5kK0sSBAR8SUJWHgKhqSqpKUwFVaQyoSpNozn9koAyI2PQwyYAPW2DAJiQDNosOY8JmBAM2AxjwEcsMqHx4hGDARywz4EPaLpQBkfVqTjJgcwsM+JAPDNhCB35LU8FbCqh1S2AjHiXV+lEBtX4IUOsW0Zz/IXwKmwFbkKeCYGUjC/81AtYJQReJOmBqwN/fMT+mk66VNAO28oEBW2tnHjcVpLUDAz4uoCqPA5HVhlSVNgKq0gpQldbRnP/IQBkQsaktyYBtLTBga5IB20WHMWE7ggHbAQz4hGUGVD48QTDgE5YZ8HFtF8qAyHo9STLgkxYY8HEfGLC9DvwOpoJ3EFDrDsBGPEWq9VMCav04oNbtozn/Q/gUNgO2DzMR3R7PYCa0DvgYsFYIvki+Zwjwpy3Eyjyy8GJHnaCdpHmxkw+82Fk787SpNp0dePFpAQV6GojALqQCdRFQoE6AAnWO5vxHBppFiE1dSV7saoEXO5O82C06jAm7EbzYDZCpZyzzovLhGYIXn7HMi09ru1BeRNarO8mL3S3w4tM+8GIPHfg9TQXvKaDWPYGNeJZU62cF1PppQK17RHP+h/ApbF7sQZ4K6HuGLFu5cWVHYE0RzJGoL/4U8Pd3zL10gj4nzYvP+cCLvbUzz5tq09uBF58XUKDngcjqQypQHwEFeg5QoN7RnP/IQHkRsakvyYt9LfBib5IX+0WHMWE/ghf7AdL7gmVe/F+yErz4gmVefF7bhfIisl79SV7sb4EXn/eBF1/UgT/AVPABAmo9ANiIl0i1fklArZ8H1PrFaM7/ED6FzYsvhpmIbo9nMBNaX+wFrBWCL5L1RYA/bSFW5pGFFwfqBH1Zmhdf9oEXB2lnXjHVZpADL74ioECvABH4KqlArwoo0MuAAg2K5vxHBppFiE2DSV4cbIEXB5G8OCQ6jAmHELw4BJCp1yzzovLhNYIXX7PMi69ou1BeRNZrKMmLQy3w4is+8OLrOvCHmQo+TECthwEb8Qap1m8IqPUrgFq/Hs35H8KnsHnxdfJUQOuLLFu5ceVAYE0RzJGoL47P4e/vmIfrBH1Tmhff9IEXR2hn3jLVZoQDL74loEBvAZE1klSgkQIK9CagQCOiOf+RgfIiYtMokhdHWeDFESQvjo4OY8LRBC+OBqT3bcu8qHx4m+DFty3z4lvaLpQXkfUaQ/LiGAu8+JYPvDhWB/44U8HHCaj1OGAj3iHV+h0BtX4LUOux0Zz/IXwKmxfHhpmIbo9nMBNaXxwOrBWCL5K/Y7aETZlHFgYcr5NugjQDTvCBASdqZ941FWSiAwO+K6Aq7wJRNYlUlUkCqjIBUJWJ0Zz/yEAZELHpPZIB37PAgBNJBpwcHcaEkwkGnAww4PuWGVD58D7BgO9bZsB3tV0oAyLrNYVkwCkWGPBdHxhwqg78aaaCTxNQ62nARnxAqvUHAmr9LqDWU6M5/0P4FDYDTiVPBcHKRhb+Gw+sE4IuEnXAtIC/v2P+UCfddGkGnO4DA87Qzsw0FWSGAwPOFFCVmUBkzSJVZZaAqkwHVGVGNOc/MlAGRGyaTTLgbAsMOINkwDnRYUw4h2DAOQADfmSZAZUPHxEM+JFlBpyp7UIZEFmvuSQDzrXAgDN9YMB5OvDnmwo+X0Ct5wMb8TGp1h8LqPVMQK3nRXP+h/ApbAacF2Yiuj2ewUxoHfBDYK0QfJF8zxDgT1uIlXlk4cUFOkEXSvPiQh94cZF25hNTbRY58OInAgr0CRCBi0kFWiygQAsBBVoUzfmPDDSLEJuWkLy4xAIvLiJ5cWl0GBMuJXhxKSBTn1rmReXDpwQvfmqZFz/RdqG8iKzXMpIXl1ngxU984MXlOvBXmAq+QkCtVwAb8Rmp1p8JqPUngFovj+b8D+FT2Ly4nDwV0PcMWbZy48oFwJoimCNRX9wZ8Pd3zCt1gq6S5sVVPvDiau3M56barHbgxc8FFOhzILLWkAq0RkCBVgEKtDqa8x8ZKC8iNq0leXGtBV5cTfLiuugwJlxH8OI6QHq/sMyLyocvCF78wjIvfq7tQnkRWa/1JC+ut8CLn/vAixt04G80FXyjgFpvBDbiS1KtvxRQ688Btd4QzfkfwqeweXFDmIno9ngGM6H1xZXAWiH4IllfBPjTFmJlHll4cZNO0M3SvLjZB17cop35ylSbLQ68+JWAAn0FRODXpAJ9LaBAmwEF2hLN+Y8MNIsQm74hefEbC7y4heTFrdFhTLiV4MWtgEx9a5kXlQ/fErz4rWVe/ErbhfIisl7bSF7cZoEXv/KBF7/Tgb/dVPDtAmq9HdiI70m1/l5Arb8C1Pq7aM7/ED6FzYvfkacCWl9k2cqNKzcBa4pgjkR9cUIOf3/H/INO0B+lefFHH3hxh3bmJ1Ntdjjw4k8CCvQTEFk7SQXaKaBAPwIKtCOa8x8ZKC8iNu0ieXGXBV7cQfLi7ugwJtxN8OJuQHp/tsyLyoefCV782TIv/qTtQnkRWa89JC/uscCLP/nAi3t14O8zFXyfgFrvAzbiF1KtfxFQ658Atd4bzfkfwqeweXFvmIno9ngGM6H1xR+AtULwRfJ3zJawKfPIwoD7ddIdkGbAAz4w4EHtzK+mghx0YMBfBVTlVyCqDpGqckhAVQ4AqnIwmvMfGSgDIjYdJhnwsAUGPEgy4JHoMCY8QjDgEYABf7PMgMqH3wgG/M0yA/6q7UIZEFmvoyQDHrXAgL/6wIDHdOAfNxX8uIBaHwc24ndSrX8XUOtfAbU+Fs35H8KnsBnwGHkqCFY2svDffmCdEHSRqAOmB/z9HfMfOulOSDPgCR8Y8KR25k9TQU46MOCfAqryJxBZp0hVOSWgKicAVTkZzfmPDJQBEZtOkwx42gIDniQZ8Ex0GBOeIRjwDMCAf1lmQOXDXwQD/mWZAf/UdqEMiKzX3yQD/m2BAf/0gQHP6sA/Zyr4OQG1PgdsxD+kWv8joNZ/Amp9NprzP4RPYTPg2TAT0e3xDGZC64B/AGuF4Ivke4YAf9pCrMwjCy+e1wl6QZoXL/jAixe1M/+aanPRgRf/FVCgf4EIvEQq0CUBBboAKNDFaM5/ZKBZhNiUI4bjRfV30rx4keTFQEwYE6o/RnkxEON9M66IscuLygc1B8qLV8RgwYja9a+2C+VFZL1yAj5kDl71d9K8+K8PvHilDvxcMTmCHcwVE75a5wI24qoYTq2viglfrf8F1PrKGM7/ED6FzYtXgomYMdD3DFm2cuPK88Bpg2CORH1xV8Df3zHn1gl6tfpXUm2ujrHiTEi1yaOducZUmzwxWXnxGgEFugbI1rykAuUVUKCrY7wrUJ4Yzn9koLyI2HQtyYvXWuDFPDEcL+ZjeVFNmI/gxXwAL15nmReVD9cRvHidZV68RtuF8iKyXvlJXsxvgRevIfEiR+h5Qir49TrwC5gKXkBArQsAG3EDqdY3CKj1NYBaXx/D+R/Cp7B58fowE9Ht8QxmQuuLuYG1QvBFsr4I8KctxMo8svBiQZ2ghaR5sZAPvFhYO3OjqTaFHXjxRgEFuhGIwJtIBbpJQIEKAQpUOIbzHxloFiE2FSF5sYgFXixM8mJRlhfVhEUJXiwK8OLNlnlR+XAzwYs3W+bFG7VdKC8i61WM5MViFnjxRh948RYd+MVNBS8uoNbFgY24lVTrWwXU+kZArW+J4fwP4VPYvHhLhOqLLFu5cWVBYE0RzJGoL07M4e/vmEvoBI2S5sUoH3ixpHbmNlNtSjrw4m0CCnQbEFmlSAUqJaBAUYAClYzh/EcGyouITaVJXixtgRdLkrx4O8uLasLbCV68HeDFOyzzovLhDoIX77DMi7dpu1BeRNarDMmLZSzw4m0+8OKdOvDLmgpeVkCtywIbcRep1ncJqPVtgFrfGcP5H8KnsHnxzjAT0e3xDGZC64slgLVC8EXyd8yWsCnzyMKA5XTSlZdmwPI+MGAF7czdpoJUcGDAuwVU5W4gqiqSqlJRQFXKA6pSIYbzHxkoAyI2RZMMGG2BASuQDBjDMqCaMIZgwBiAAWMtM6DyIZZgwFjLDHi3tgtlQGS94kgGjLPAgHf7wIDxOvATTAVPEFDrBGAjEkm1ThRQ67sBtY6P4fwP4VPYDBhPngqClY0s/FcOWCcEXSTqgJUC/v6OOUknXbI0Ayb7wIAp2plUU0FSHBgwVUBVUoHISiNVJU1AVZIBVUmJ4fxHBsqAiE3pJAOmW2DAFJIBK7EMqCasRDBgJYAB77HMgMqHewgGvMcyA6Zqu1AGRNarMsmAlS0wYKoPDFhFB35VU8GrCqh1VWAj7iXV+l4BtU4F1LpKDOd/CJ/CZsAqYSai2+MZzITWAZOAtULwRfI9Q4A/bSFW5pGFF6vpBK0uzYvVfeDFGtqZ+0y1qeHAi/cJKNB9QATWJBWopoACVQcUqEYM5z8y0CxCbKpF8mItC7xYg+TF2iwvqglrE7xYG5Cp+y3zovLhfoIX77fMi/dpu1BeRNarDsmLdSzw4n0+8GJdHfj1TAWvJ6DW9YCNeIBU6wcE1Po+QK3rxnD+h/ApbF6sS54K6HuGLFu5cWU1YE0RzJGoL+4O+Ps75vo6QRtI82IDH3ixoXbmQVNtGjrw4oMCCvQgEFmNSAVqJKBADQAFahjD+Y8MlBcRmxqTvNjYAi82JHmxCcuLasImBC82AaT3Icu8qHx4iODFhyzz4oPaLpQXkfVqSvJiUwu8+KAPvPiwDvxmpoI3E1DrZsBGPEKq9SMCav0goNYPx3D+h/ApbF58OMxEdHs8g5nQ+mJ9YK0QfJGsLwL8aQuxMo8svNhcJ2gLaV5s4QMvttTOPGqqTUsHXnxUQIEeBSLwMVKBHhNQoBaAArWM4fxHBppFiE2tSF5sZYEXW5K82JrlRTVha4IXWwMy9bhlXlQ+PE7w4uOWefFRbRfKi8h6tSF5sY0FXnzUB15sqwO/nang7QTUuh2wEU+Qav2EgFo/Cqh12xjO/xA+hc2LbSNUX2TZyo0rmwNrimCORH3x3Rz+/o75SZ2g7aV5sb0PvNhBO/OUqTYdHHjxKQEFegqIrI6kAnUUUKD2gAJ1iOH8RwbKi4hNnUhe7GSBFzuQvNiZ5UU1YWeCFzsD0vu0ZV5UPjxN8OLTlnnxKW0XyovIenUhebGLBV58ygde7KoDv5up4N0E1LobsBHPkGr9jIBaPwWoddcYzv8QPoXNi13DTES3xzOYCa0vPgmsFYIvkr9jtoRNmUcWBuyuk66HNAP28IEBe2pnnjUVpKcDAz4roCrPAlHVi1SVXgKq0gNQlZ4xnP/IQBkQsek5kgGfs8CAPUkG7M0yoJqwN8GAvQEGfN4yAyofnicY8HnLDPistgtlQGS9+pAM2McCAz7rAwP21YHfz1TwfgJq3Q/YiBdItX5BQK2fBdS6bwznfwifwmbAvuSpIFjZyMJ/3YF1QtBFog54T8Df3zH310n3ojQDvugDAw7QzrxkKsgABwZ8SUBVXgIiayCpKgMFVOVFQFUGxHD+IwNlQMSml0kGfNkCAw4gGXAQy4BqwkEEAw4CGPAVywyofHiFYMBXLDPgS9oulAGR9XqVZMBXLTDgSz4w4GAd+ENMBR8ioNZDgI14jVTr1wTU+iVArQfHcP6H8ClsBhwcZiK6PZ7BTGgdsD+wVgi+SL5nCPCnLcTKPLLw4lCdoK9L8+LrPvDiMO3MG6baDHPgxTcEFOgNIAKHkwo0XECBXgcUaFgM5z8y0CxCbHqT5MU3LfDiMJIXR7C8qCYcQfDiCECm3rLMi8qHtwhefMsyL76h7UJ5EVmvkSQvjrTAi2/4wIujdOCPNhV8tIBajwY24m1Srd8WUOs3ALUeFcP5H8KnsHlxFHkqoO8ZsmzlxpVDgTVFMEeivvhzwN/fMY/RCTpWmhfH+sCL47Qz75hqM86BF98RUKB3gMgaTyrQeAEFGgso0LgYzn9koLyI2DSB5MUJFnhxHMmLE1leVBNOJHhxIiC971rmReXDuwQvvmuZF9/RdqG8iKzXJJIXJ1ngxXd84MX3dOBPNhV8soBaTwY24n1Srd8XUOt3ALV+L4bzP4RPYfPie2EmotvjGcyE1hfHAGuF4ItkfRHgT1uIlXlk4cUpOkGnSvPiVB94cZp25gNTbaY58OIHAgr0ARCBH5IK9KGAAk0FFGhaDOc/MtAsQmyaTvLidAu8OI3kxRksL6oJZxC8OAOQqZmWeVH5MJPgxZmWefEDbRfKi8h6zSJ5cZYFXvzAB16crQN/jqngcwTUeg6wER+Rav2RgFp/AKj17BjO/xA+hc2LsyNUX2TZyo0rpwBrimCORH1xUg5/f8c8VyfoPGlenOcDL87Xznxsqs18B178WECBPgYiawGpQAsEFGgeoEDzYzj/kYHyImLTQpIXF1rgxfkkLy5ieVFNuIjgxUWA9H5imReVD58QvPiJZV78WNuF8iKyXotJXlxsgRc/9oEXl+jAX2oq+FIBtV4KbMSnpFp/KqDWHwNqvSSG8z+ET2Hz4pIwE9Ht8QxmQuuLc4G1QvBF8nfMlrAp88jCgMt00i2XZsDlPjDgCu3MZ6aCrHBgwM8EVOUzIKpWkqqyUkBVlgOqsiKG8x8ZKAMiNq0iGXCVBQZcQTLgapYB1YSrCQZcDTDg55YZUPnwOcGAn1tmwM+0XSgDIuu1hmTANRYY8DMfGHCtDvx1poKvE1DrdcBGfEGq9RcCav0ZoNZrYzj/Q/gUNgOuJU8FwcpGFv5bBqwTgi4SdcDKAX9/x7xeJ90GaQbc4AMDbtTOfGkqyEYHBvxSQFW+BCJrE6kqmwRUZQOgKhtjOP+RgTIgYtNmkgE3W2DAjSQDbmEZUE24hWDALQADfmWZAZUPXxEM+JVlBvxS24UyILJeX5MM+LUFBvzSBwb8Rgf+VlPBtwqo9VZgI74l1fpbAbX+ElDrb2I4/0P4FDYDfhNmIro9nsFMaB1wPbBWCL5IvmcI8KctxMo8svDiNp2g30nz4nc+8OJ27cz3ptpsd+DF7wUU6HsgAn8gFegHAQX6DlCg7TGc/8hAswix6UeSF3+0wIvbSV7cwfKimnAHwYs7AJn6yTIvKh9+InjxJ8u8+L22C+VFZL12kry40wIvfu8DL+7Sgb/bVPDdAmq9G9iIn0m1/llArb8H1HpXDOd/CJ/C5sVd5KmAvmfIspUbV24D1hTBHIn64p6Av79j3qMTdK80L+71gRf3aWd+MdVmnwMv/iKgQL8AkbWfVKD9Agq0F1CgfTGc/8hAeRGx6QDJiwcs8OI+khcPsryoJjxI8OJBQHp/tcyLyodfCV781TIv/qLtQnkRWa9DJC8essCLv/jAi4d14B8xFfyIgFofATbiN1KtfxNQ618AtT4cw/kfwqewefFwmIno9ngGM6H1xT3AWiH4IllfBPjTFmJlHll48ahO0GPSvHjMB148rp353VSb4w68+LuAAv0OROAfpAL9IaBAxwAFOh7D+Y8MNIsQm06QvHjCAi8eJ3nxJMuLasKTBC+eBGTqT8u8qHz4k+DFPy3z4u/aLpQXkfU6RfLiKQu8+LsPvHhaB/4ZU8HPCKj1GWAj/iLV+i8Btf4dUOvTMZz/IXwKmxdPR6i+yLKVG1ceBdaUxRwzJtzmibvCI9/9uzcw8Arv6xKfKzL2xwP2vwzY3zdC9icA9g8C7F8bIfsTAftfAey/9qrI2J8E2P8qYH/jCNmfDNg/GLB/QoTsTwHsHwLYfyBC9qcC9r8G2F8+d2TsTwPsHwrY3yNC9qcD9r8O2L88QvZXAuwfBth/5dWRsf8ewP43APvrRsj+yoD9wwH7R0XI/iqA/W8C9u+KkP1VAftHAPaXzhMZ++8F7H8LsL9ThOyvBtg/ErB/YYTsrw7YPwqw/0KE7K8B2D8asL/6NZGx/z7A/rcB+1+PkP01AfvHAPZ/FyH7awH2jwXsvyVvZOyvDdg/DrC/bYTsvx+w/x3A/tkRsr8OYP94wP7TEbK/LmD/BMD+9GsjY389wP6JgP0vR8j+BwD73wXs3xwh++sD9k8C7C+ULzL2NwDsfw+wv0WE7G8I2D8ZsH9qhOx/ELD/fcD+YxGyvxFg/xSk/n9dZOxvDNg/Fan/R8j+JoD905D6f4Tsfwiw/wOk/p8/MvY3Bez/EKn/R8j+hwH7pyP1/wjZ3wywfwZS/4+Q/Y8A9s9E6v/XR8b+5oD9s5D6f4TsbwHYPxup/0fI/paA/XOQ+n+ByNj/KGD/R0j9P0L2PwbYPxep/0fI/laA/fOQ+n+E7G8N2D8fqf/fEBn7Hwfs/xip/0fI/jaA/QuQ+n+E7G8L2L8Qqf9HyP52gP2LkPp/wcjY/wRg/ydI/T9C9j8J2L8Yqf9HyP72gP1LkPp/ocjY3wGwfylS/4+Q/U8B9n+K1P8jZH9HwP5lSP0/QvZ3AuxfjtT/C0fG/s6A/SuQ+n+E7H8asP8zpP4fIfu7APavROr/N0bG/q6A/auQ+n+E7O8G2L8aqf9HyP5nAPs/R+r/EbK/O2D/GqT+f1Nk7O8B2L8Wqf9HyP6egP3rkPp/hOx/FrD/C6T+XyQy9vcC7F+P1P8jZP9zgP0bkPp/hOzvDdi/Ean/R8j+5wH7v0Tq/0UjY38fwP5NSP0/Qvb3BezfjNT/I2R/P8D+LUj9/+bI2P8CYP9XSP0/Qvb3B+z/Gqn/R8j+FwH7v0Hq/xGyfwBg/1ak/l8sMva/BNj/LVL/j5D9nn//e6FKYBtS/4+Q/fGA/d8h9f8I2Z8A2L8dqf/fEhn7EwH7v0fq/xGyPwmw/wek/h8h+5MB+39E6v/FI2N/CmD/DqT+HyH7UwH7f0Lq/xGyPw2wfydS/4+Q/emA/buQ+v+tkbG/EmD/bqT+HyH77wHs/xmp/0fI/sqA/XuQ+n+JyNhfBbB/L1L/j5D9VQH79yH1/wjZfy9g/y9I/T9C9lcD7N+P1P+jImN/dcD+A0j9Pyoy9tcA7D+I1P+jImP/fYD9vyL1/5KRsb8mYP8hpP4fIftrAfYfRur/EbK/NmD/EaT+HyH77wfs/w2p/98WGfvrAPYfRer/EbK/LmD/MaT+HyH76wH2H0fq/6UiY/8DgP2/I/X/CNlfH7D/D6T+HyH7GwD2n0Dq/xGyvyFg/0mk/l86MvY/CNj/J1L/j5D9jQD7TyH1/wjZ3xiw/zRS/4+Q/U0A+88g9f/bI2P/Q4D9fyH1/wjZ3xSw/2+k/h8h+x8G7D+L1P/viIz9zQD7zyH1/wjZ/whg/z9I/T9C9jcH7D+P1P8jZH8LwP4LSP2/TGTsbwnYfxGp/0fI/kcB+/9F6v8Rsv8xwP5LSP3/zsjY3wqwX324h2fVCLSIkP2tAfsDgP1TI2T/44D9VwD2H4uQ/W0A+3MC9seXjYz9bQH7rwTs7xsh+9sB9ucC7F8bIfufAOy/CrD/2rsiY/+TgP25AfsbR8j+9oD9VwP2T4iQ/R0A+/MA9h+IkP1PAfZfA9hfvlxk7O8I2J8XsL9HhOzvBNh/LWD/8gjZ3xmwPx9g/5XlI2P/04D91wH2142Q/V0A+/MD9o+KkP1dAfuvB+zfFSH7uwH2FwDsL10hMvY/A9h/A2B/pwjZ3x2wvyBg/8II2d8DsL8QYP+FCNnfE7C/MGB/9bsjY/+zgP03Ava/HiH7ewH23wTY/12E7H8OsL8IYP8tFSNjf2/A/qKA/W0jZP/zgP03A/bPjpD9fQD7iwH2n46Q/X0B+28B7E+Pjoz9/QD7iwP2vxwh+18A7L8VsH9zhOzvD9hfArC/UIT+/1tfBOyPQur/EbJ/AGB/SaT+HyH7XwLsvw2p/wP2Z/z/G1/h9EH636gcnkZbj78HznZEhf7Ply59nKN00vmoQGZb/9b/59xn1b+S/0/jZ2OsOBMw/4fMtp7Tzvxj/j+Nq//wgvG//SPw/z7+D/D/Kn2e/H8fPy/w/z5+Fvh/Hz8Xw/mPDHOd3exHbLoQwqb84+cPu/Wrx76vOffT2i+88OH7mdf5go6RKzP9b1kMMex2s+VcCFvMv80838WYMCZUf+y2wObnXAT+b9f/BTaD9UHN4aY45uf8CwYjatc/2i63tTUTClmvS4APmYP3khYJSQX/x12wcuSod2nnhiv3XHJ6Jip7s4NGkK2x+qHYHMEOqv8hXLVWn+H12StiObW+IjZ8tf4HUOscsZz/2fjkuKFoouSIleE/lxHES842dRlRveKZLkuu3Ps/zvFqP4IuSMKFcZpmfFT/Szty3FDs4puOD0WF/tv/G5ltzakT7koz4dR/CBj/25UCSXglELC5yCTM5SEJw0C7LEmYM5bz3xhZNhm5XAgE9f9dEJz+Y1QOT6NtZluv0sGVOzZTFKKG5/SuJgHJ4y83qWI5Qs8TMhuv1guWx8xG9R/MC0wegWzMA0TuNWQ2XiNwJOaO9Z6NV8dy/iMDvcAgNuWN5S4weWPlLzBXx3IXmGtjw5hQ/TF6gbkWUIl8wGawPuSLxS8w+cBgRO3Ko+1CLzDIel0H+JA5eK+Llb/A5PEuWBOcnonK3uygkdnW/DrwrzcVPL8DT10voODXA5tTgFTwAgIKngdQ8PyxnP8uPv1vk9EgUviRPxZPtvxhJrMXu3ITdg2shdmFnnSKMwFka6ueVZyYy5gH4Vm3y59XPv/j0qWJVwGxByBiwMO6/x9/C36pkGIJY80RxP03aBEseDlyf0EfuL+QXrDC5qlRyIH7CwucGoWBKL+RPDVuFDg1CgKnRqFYzn9koGqI2HQTyf03WeD+QiT3F2G5X01YhOD+IoBKFLXM/cqHogT3F7XM/YW1XSj3I+t1M8n9N1vg/sI+cH8xHfi3mApezIH7bxFQ8FuAzSlOKnhxAQUvDCh4sVjOfxefaO4vRvB1sQhwf0HCrkG1rNr1P46/wYHjXUZKboDNbwDio6D3z90A3IkCyDoKcryt92nMEcTxt2pRKxGK411GAOB40VOghA8cH6UXrKR5CkQ5cHxJgVOgJJARt5GnwG0Cp0AJ4BSIiuX8RwbK8YhNpUiOL2WB46NIji/NcryasDTB8aUBjr/dMscrH24nOP52yxxfUtuFcjyyXneQHH+HBY4v6QPHl9GBf6ep4GUcOP5OAQW/E9icsqSClxVQ8JKAgpeJ5fx38cmR472UETM2NfPfeXKamKsEweZDIlyTd+Ns9eytsXjCDvGHjVMsoZ45gtj4Lh1T5S5HNi7nAxuX1wtWwVTW8g5sXEFAWSsAKnQ3qax3CyhrOUBZy8dy/iMDVRfEpookG1e0wMblSTaOZtlYTRhNsHE0wMYxltlY+RBDsHGMZTauoO1C2RhZr1iSjWMtsHEFH9g4Tgd+vKngcQ5sHC+g4PHA5iSQCp4goOAVAAWPi+X8d/GJZuM4ko2RvcxgyrtiMdvKgSytarkog3o9TVwGhFSZ50vM7jTxMmEiAelJYZ4QXuxKiuCFKykWRxbkhf1kIYxym6ccYFOKd5va/s9hwxaXEVA+pxAX2dRYf5Jvf4BLvjQ2+dSEaUTypVtOPmVXulDyuT2ukkhtuOA7PVnWoBLwLPoNZ8ZAExXZw3sAdGdsUfuNzKHW8x4iPiTbHHj8vw3PdkSF/s+ObQ4qa5+rqH8lObyKD5WUqtqZe00Or+pQSblXgMPvBSK+Gsnh1QQ4vArA4VVjOf+RgWIJYlN1spJS3UIlpSpZSanBVlLUhDWISkoNQCrvs1xJUT7cR1RS7rNcSblX24VWUpD1qklWUmpaqKTc6y5Y4m0OaunAr20qeG0Bta4NbMT9pFrfL6DW9wJqXSuW8z8bn0TaHNQiTwW0zUE80OagMrBOCLpItjkIkXAZHyXe5qCOTri6ZsLVcShd1hVIwrrARtQjk7CehyQMA+2yJGGdWM5/Y2TZZMk2Bx6CWrzNwQM6uOrHhvgq2M3wOgCaSB5/9X24wDTQC9bQzMYGDheYhgLZ2BCI3AfJbHxQ4EisD2Rjg1jOf2SgFxjEpkbkBaaRhQtMA/IC05i9wKgJGxMXmMaASjSxfIFRPjQhLjBNLF9gGmq70AsMsl4PkReYhyxcYBqC3xKaIyp7s4NGZlub6sB/2FTwpg489bCAgj8MbE4zUsGbCSh4Q0DBm8Zy/rv4RP3cSeFH01g82ZqGmcxe7KpP2DXC8iuVijMBZGurnlWciLY5qOIaI/9d/rzyufo6/gEg9gBEDIzwqc2BJYw1RxD3P6JFsPnlyP3NfeD+FnrBWpqnRgsH7m8pcGq0BKL8UfLUeFTg1GgOnBotYjn/kYGqIWLTYyT3P2aB+1uQ3N+K5X41YSuC+1sBKtHaMvcrH1oT3N/aMve31Hah3I+s1+Mk9z9ugftb+sD9bXTgtzUVvI0D97cVUPC2wOa0IxW8nYCCtwQUvE0s57+LTzT3tyH4uk0EuL85YddIy20OlF2PxOJtDuoDbP4IEB/NvX/uBuBOFBjpU5sDS+/TmCOI45/QovZkKI53GQGA40VPgSd94Pj2esE6mKdAeweO7yBwCnQAMuIp8hR4SuAUeBI4BdrHcv4jA+V4xKaOJMd3tMDx7UmO78RyvJqwE8HxnQCO72yZ45UPnQmO72yZ4ztou1COR9braZLjn7bA8R184PguOvC7mgrexYHjuwooeFdgc7qRCt5NQME7AAreJZbz38Un6qdcCj8yNjXz33lympjrSYLNx0S4Ju/G2erZJ2LxhB3jU5sDS6hnjiA2fkbHVPfLkY27+8DGPfSC9TSVtYcDG/cUUNaegAo9SyrrswLK2h1Q1h6xnP/IQNUFsakXyca9LLBxD5KNn2PZWE34HMHGzwFs3NsyGysfehNs3NsyG/fUdqFsjKzX8yQbP2+BjXv6wMZ9dOD3NRW8jwMb9xVQ8L7A5vQjFbyfgIL3BBS8Tyznv4tPNBv3IdkYbXOg5nomFrOtO8jSqpY7xqc2B91BccgYL2R3mniZ8AUC0vuHeUJ4sat/BC9c/WNxZEFe2H9RCKPc5ukO2DTAu01UmwPl8wDiIvtSrD/JdyDAJd9ANvnUhAOJ5HvZcvIpu14WSj63x1USqQ0XfKcna+sC4NmREWpzgOzhKwC6M7ao/UbmUOv5ChEfkm0OEnxoc/Cq9nmw+leSwwf7UEkZop15zeTwIQ6VlNcEOPw1IOKHkhw+VIDDBwMcPiSW8x8ZKJYgNr1OVlJet1BJGUJWUoaxlRQ14TCikjIMkMo3LFdSlA9vEJWUNyxXUl7TdqGVFGS9hpOVlOEWKimvuQuWeJuDN3XgjzAVfISAWo8ANuItUq3fElDr1wC1fjOW8z8bn0TaHLxJngpom4MEoM3Bq8A6Iegi2eYgRMJlfJR4m4OROuFGmQk30qF0OUogCUcBGzGaTMLRHpIwDLTLkoQjYzn/jZFlkyXbHHgIavE2B2/r4BoTG+KrYNfbK4AmksffGB8uMGP1go0zs3GswwVmnEA2jgMi9x0yG98ROBLHANk4NpbzHxnoBQaxaTx5gRlv4QIzlrzATGAvMGrCCcQFZgKgEhMtX2CUDxOJC8xEyxeYcdou9AKDrNe75AXmXQsXmHHgt4TmiMre7KCR2dZJOvDfMxV8kgNPvSeg4O8BmzOZVPDJAgo+DlDwSbGc/y4+UT93UvgxKRZPtklhJrMXu8Ywdll+pVJxJoBsbdWzihPRNgeDXWPkv8ufVz5XX8e/DcQegIiBST61ObCEseYI4v73tQhOuRy5f4oP3D9VL9g089SY6sD90wROjWlAlH9AnhofCJwaU4BTY2os5z8yUDVEbPqQ5P4PLXD/VJL7p7PcryacTnD/dEAlZljmfuXDDIL7Z1jm/mnaLpT7kfWaSXL/TAvcP80H7p+lA3+2qeCzHLh/toCCzwY2Zw6p4HMEFHwaoOCzYjn/XXyiuX8WwdezIsD9Uwi7Jltuc6Dsej8Wb3MwBmDz94H4mOL9czcAd6LAZJ/aHFh6n8YcQRz/kRa1uaE43mUEAI4XPQXm+sDx8/SCzTdPgXkOHD9f4BSYD2TEx+Qp8LHAKTAXOAXmxXL+IwPleMSmBSTHL7DA8fNIjl/IcryacCHB8QsBjl9kmeOVD4sIjl9kmePna7tQjkfW6xOS4z+xwPHzfeD4xTrwl5gKvtiB45cIKPgSYHOWkgq+VEDB5wMKvjiW89/FJ+qnXAo/MjY18995cpqYay7B5tMiXJN342z17EexeMJO86nNgSXUM0cQG3+qY2rZ5cjGy3xg4+V6wVaYyrrcgY1XCCjrCkCFPiOV9TMBZV0GKOvyWM5/ZKDqgti0kmTjlRbYeDnJxqtYNlYTriLYeBXAxqsts7HyYTXBxqsts/EKbRfKxsh6fU6y8ecW2HiFD2y8Rgf+WlPB1ziw8VoBBV8LbM46UsHXCSj4CkDB18Ry/rv4RLPxGpKN0TYHaq5PYzHbloEsrWq503xqc7AMFIeM8UV2p4mXCb8gIH19mCeEF7vWR/DCtT4WRxbkhf0NQhjlNs8ywKaN3m2i2hwonzcSF9kvY/1JvoMBLvk2scmnJtxEJN9my8mn7NoslHxuj6skUhsu+E5PljXYAjw7OUJtDpA9/ApAd8YWtd/IHGo9vyLiQ7LNQaIPbQ6+1j5/o/6V5PBvfKikbNXOfGty+FaHSsq3Ahz+LRDx20gO3ybA4d8AHL41lvMfGSiWIDZ9R1ZSvrNQSdlKVlK2s5UUNeF2opKyHZDK7y1XUpQP3xOVlO8tV1K+1XahlRRkvX4gKyk/WKikfOsuWOJtDn7Ugb/DVPAdAmq9A9iIn0i1/klArb8F1PrHWM7/bHwSaXPwI3kqoG0OEoE2B18D64Sgi2SbgxAJl/FR4m0OduqE22Um3E6H0uUugSTcBWzEbjIJd3tIwjDQLksS7ozl/DdGlk2WbHPgIajF2xz8rINrT2yIr4LdDN8JoInk8bfHhwvMXr1g+8xs3OtwgdknkI37gMj9hczGXwSOxD1ANu6N5fxHBnqBQWzaT15g9lu4wOwlLzAH2AuMmvAAcYE5AKjEQcsXGOXDQeICc9DyBWaftgu9wCDr9St5gfnVwgVmH/gtoTmisjc7aGS29ZAO/MOmgh9y4KnDAgp+GNicI6SCHxFQ8H2Agh+K5fx38Yn6uZPCj0OxeLIdCjOZvdi1h7BrjuVXKhVnAsjWVj2rOBFtc/CNa4z8d/nzyufq6/ifgdgDEDEwx6c2B5Yw1hxB3P+bFsGjlyP3H/WB+4/pBTtunhrHHLj/uMCpcRyI8t/JU+N3gVPjKHBqHIvl/EcGqoaITX+Q3P+HBe4/RnL/CZb71YQnCO4/AajEScvcr3w4SXD/Scvcf1zbhXI/sl5/ktz/pwXuP+4D95/SgX/aVPBTDtx/WkDBTwObc4ZU8DMCCn4cUPBTsZz/Lj7R3H+K4OtTEeD+o4Rdcy23OVB2/RaLtznYA7D5b0B8HPX+uRuAO1Fgrk9tDiy9T2OOII7/S4va36E43mUEAI4XPQX+9oHjz+oFO2eeAmcdOP6cwClwDsiIf8hT4B+BU+Bv4BQ4G8v5jwyU4xGbzpMcf94Cx58lOf4Cy/FqwgsEx18AOP6iZY5XPlwkOP6iZY4/p+1COR5Zr39Jjv/XAsef84HjL2UEflyOYAcvOXC8eihcBVef4fXZQByn4IG48BX8HKDgl2I5/118on7KpfDj/zY1h90EVXP9TbD5ggjX5N04Wz37VyyesAt8anNgCfXMEcTGV8T9/39zxl2GbJwzLvJsfKVesFymsqr/YLJxLgFlzQUo61Wksl4loKw547wr65VxnP/IQNUFsSl3HMfGuePk2fjKOI6Nr44LY0L1xygbX+19IwN5gM1gfcgTh7NxHjAYUbtyabtQNkbW6xrAh8zBe02cPBvnArHJHFHZmx00MtuaVwf+taaC543LysbXCij4tcDm5CMVPJ+AgucCFDxvHOe/i080G2dsaua/8zLQNgdqriviMNtyxmE+qVruAp/aHOQExSFjXJfdaeJlwuvi8L/LH+YJ4cWu/GRQMQGcPw5HFuSF/euFMMptnpzAvhTwbhPV5kD5XCAO348b4vxJvl8DXPIVZJNPTViQSL5ClpNP2VVIKPncHldJpDZc8J2eLGtQGFivuRFqc4Ds4Y0AujO2qP1G5lDreSMRH5JtDpJ8aHNwk/a5iPpXksOL+FBJKaqdudnk8KIOlZSbBTj8ZiDii5EcXkyAw4sAHF40jvMfGSiWIDbdQlZSbrFQSSlKVlKKs5UUNWFxopJSHJDKWy1XUpQPtxKVlFstV1Ju1nahlRRkvUqQlZQSFiopN7sLlnibgygd+CVNBS8poNYlgY24jVTr2wTU+mZAraPiOP+z8UmkzUEUeSqgbQ6SgDYHNwHrhKCLZJuDEAmX8VHibQ5K6YQrbSZcKYfSZWmBJCwNbMTtZBLe7iEJw0C7LElYKo7z3xhZNlmyzYGHoBZvc3CHDq4ycSG+CnYzvBSAJpLHXxkfLjB36gUra2bjnQ4XmLIC2VgWiNy7yGy8S+BILANk451xnP/IQC8wiE3lyAtMOQsXmDvJC0x59gKjJixPXGDKAypRwfIFRvlQgbjAVLB8gSmr7UIvMMh63U1eYO62cIEpC35LaI6o7M0OGpltragDP9pU8IoOPBUtoODRwObEkAoeI6DgZQEFrxjH+e/iE/VzJ4UfFePwZKsYZjJ7sasMYdcyy69UKs4EkK2telZxItrmoIhrjPx3+fPK5+rr+DuA2AMQMbDMpzYHljDWHEHcH6tFMO5y5P44H7g/Xi9YgnlqxDtwf4LAqZEARHkieWokCpwaccCpER/H+Y8MVA0Rm5JI7k+ywP3xJPcns9yvJkwmuD8ZUIkUy9yvfEghuD/FMvcnaLtQ7kfWK5Xk/lQL3J/gA/en6cBPNxU8zYH70wUUPB3YnEqkglcSUPAEQMHT4jj/XXyiuT+N4Ou0CHB/HGHXCsttDpRdsXF4m4MyAJvHAvER5/1zNwB3osAKn9ocWHqfxhxBHH+PFrXKoTjeZQQAjhc9BSr7wPFV9IJVNU+BKg4cX1XgFKgKZMS95Clwr8ApUBk4BarEcf4jA+V4xKZqJMdXs8DxVUiOr85yvJqwOsHx1QGOr2GZ45UPNQiOr2GZ46tqu1COR9brPpLj77PA8VV94PiaOvBrmQpe04HjawkoeC1gc2qTCl5bQMGrAgpeM47z38Un6qdcCj8yNjXz33lympirMsHmqyNck3fjbPXsPXF4wq72qc2BJdQzRxAb369jqs7lyMZ1fGDjunrB6pnKWteBjesJKGs9QIUeIJX1AQFlrQMoa904zn9koOqC2FSfZOP6Fti4LsnGDVg2VhM2INi4AcDGDS2zsfKhIcHGDS2zcT1tF8rGyHo9SLLxgxbYuJ4PbNxIB35jU8EbObBxYwEFbwxsThNSwZsIKHg9QMEbxXH+u/hEs3Ejko3RNgdqrvvjMNvqgCytarmrfWpzUAcUh4zxUHaniZcJHyIgvWmYJ4QXu5pG8MLVNA5HFuSF/YeFMMptnjqATc2820S1OVA+NyMuso/E+ZN8hwJc8jVnk09N2JxIvhaWk0/Z1UIo+dweV0mkNlzwnZ4sa9ASeHZFhNocIHv4KIDujC1qv5E51Ho+SsSHZJuDZB/aHDymfW6l/pXk8FY+VFJaa2ceNzm8tUMl5XEBDn8ciPg2JIe3EeDwVgCHt47j/EcGiiWITW3JSkpbC5WU1mQlpR1bSVETtiMqKe0AqXzCciVF+fAEUUl5wnIl5XFtF1pJQdbrSbKS8qSFSsrj7oIl3uagvQ78DqaCdxBQ6w7ARjxFqvVTAmr9OKDW7eM4/7PxSaTNQXvyVEDbHCQDbQ4eA9YJQRfJNgchEi7jo8TbHHTUCdfJTLiODqXLTgJJ2AnYiM5kEnb2kIRhoF2WJOwYx/lvjCybLNnmwENQi7c5eFoHV5e4EF8FuxneEUATyeOviw8XmK56wbqZ2djV4QLTTSAbuwGR+wyZjc8IHIldgGzsGsf5jwz0AoPY1J28wHS3cIHpSl5gerAXGDVhD+IC0wNQiZ6WLzDKh57EBaan5QtMN20XeoFB1utZ8gLzrIULTDfwW0JzRGVvdtDIbGsvHfjPmQrey4GnnhNQ8OeAzelNKnhvAQXvBih4rzjOfxefqJ87KfzoFYcnW68wk9mLXV0IuzZafqVScSaAbG3Vs4oT0TYHrVxj5L/Ln1c+V1/HPw3EHoCIgY0+tTmwhLHmCOL+57UI9rkcub+PD9zfVy9YP/PU6OvA/f0ETo1+QJS/QJ4aLwicGn2AU6NvHOc/MlA1RGzqT3J/fwvc35fk/hdZ7lcTvkhw/4uASgywzP3KhwEE9w+wzP39tF0o9yPr9RLJ/S9Z4P5+PnD/QB34L5sKPtCB+18WUPCXgc0ZRCr4IAEF7wco+MA4zn8Xn2juH0jw9cAIcH8fwq5NltscKLuej8PbHHQB2Px5ID76eP/cDcCdKLDJpzYHlt6nMUcQx7+iRe3VUBzvMgIAx4ueAq/6wPGD9YINMU+BwQ4cP0TgFBgCZMRr5CnwmsAp8CpwCgyO4/xHBsrxiE1DSY4faoHjB5Mc/zrL8WrC1wmOfx3g+GGWOV75MIzg+GGWOX6ItgvleGS93iA5/g0LHD/EB44frgP/TVPBhztw/JsCCv4msDkjSAUfIaDgQwAFHx7H+e/iE/VTLoUfGZua+e88OU3M9SrB5l9HuCbvxtnq2Vfi8IT92qc2B5ZQzxxBbPyWjqmRlyMbj/SBjUfpBRttKusoBzYeLaCsowEVeptU1rcFlHUkoKyj4jj/kYGqC2LTGJKNx1hg41EkG49l2VhNOJZg47EAG4+zzMbKh3EEG4+zzMajtV0oGyPr9Q7Jxu9YYOPRPrDxeB34E0wFH+/AxhMEFHwCsDkTSQWfKKDgowEFHx/H+e/iE83G40k2RtscqLneisNsGwmytKrlfu1Tm4ORoDhkjHezO028TPguAemTwjwhvNg1KYIXrklxOLIgL+y/J4RRbvOMBGya7N0mqs2B8nkycZF9P86f5Dsc4JJvCpt8asIpRPJNtZx8yq6pQsnn9rhKIrXhgu/0ZFmDacCzmyLU5gDZww8AdGdsUfuNzKHW8wMiPiTbHKT40ObgQ+3zdPWvJIdP96GSMkM7M9Pk8BkOlZSZAhw+E4j4WSSHzxLg8OkAh8+I4/xHBooliE2zyUrKbAuVlBlkJWUOW0lRE84hKilzAKn8yHIlRfnwEVFJ+chyJWWmtgutpCDrNZespMy1UEmZ6S5Y4m0O5unAn28q+HwBtZ4PbMTHpFp/LKDWMwG1nhfH+Z+NTyJtDuaRpwLa5iAFaHPwIbBOCLpItjkIkXAZHyXe5mCBTriFZsItcChdLhRIwoXARiwik3CRhyQMA+2yJOGCOM5/Y2TZZMk2Bx6CWrzNwSc6uBbHhfgq2M3wBQCaSB5/i324wCzRC7bUzMYlDheYpQLZuBSI3E/JbPxU4EhcDGTjkjjOf2SgFxjEpmXkBWaZhQvMEvICs5y9wKgJlxMXmOWASqywfIFRPqwgLjArLF9glmq70AsMsl6fkReYzyxcYJaC3xKaIyp7s4NGZltX6sBfZSr4SgeeWiWg4KuAzVlNKvhqAQVfCij4yjjOfxefqJ87KfxYGYcn28owk9mLXYsJu36w/Eql4kwA2dqqZxUnom0OprvGyH+XP698rr6O/wSIPQARAz/41ObAEsaaI4j7P9ciuOZy5P41PnD/Wr1g68xTY60D968TODXWAVH+BXlqfCFwaqwBTo21cZz/yEDVELFpPcn96y1w/1qS+zew3K8m3EBw/wZAJTZa5n7lw0aC+zda5v512i6U+5H1+pLk/i8tcP86H7h/kw78zaaCb3Lg/s0CCr4Z2JwtpIJvEVDwdYCCb4rj/Hfxieb+TQRfb4oA968h7Nphuc2BsuvzOLzNwWKAzT8H4mON98/dANyJAjt8anNg6X0acwRx/Fda1L4OxfEuIwBwvOgp8LUPHP+NXrCt5inwjQPHbxU4BbYCGfEteQp8K3AKfA2cAt/Ecf4jA+V4xKZtJMdvs8Dx35Ac/x3L8WrC7wiO/w7g+O2WOV75sJ3g+O2WOX6rtgvleGS9vic5/nsLHL/VB47/QQf+j6aC/+DA8T8KKPiPwObsIBV8h4CCbwUU/Ic4zn8Xn6ifcin8yNjUzH/nyWlirq8JNt8d4Zq8G2erZ7+KwxN2t09tDiyhnjmC2PgnHVM7L0c23ukDG+/SC7bbVNZdDmy8W0BZdwMq9DOprD8LKOtOQFl3xXH+IwNVF8SmPSQb77HAxrtINt7LsrGacC/BxnsBNt5nmY2VD/sINt5nmY13a7tQNkbW6xeSjX+xwMa7fWDj/TrwD5gKvt+BjQ8IKPgBYHMOkgp+UEDBdwMKvj+O89/FJ5qN95NsjLY5UHP9FIfZthNkaVXL3e1Tm4OdoDhkjF+zO028TPgrAemHwjwhvNh1KIIXrkNxOLIgL+wfFsIot3l2AjYd8W4T1eZA+XyEuMj+FudP8h0JcMl3lE0+NeFRIvmOWU4+ZdcxoeRze1wlkdpwwXd6sqzBcaQ6FqE2B8ge/g6gO2OL2m9kDrWevxPxIdnmINWHNgd/aJ9PqH8lOfyED5WUk9qZP00OP+lQSflTgMP/BCL+FMnhpwQ4/ATA4SfjOP+RgWIJYtNpspJy2kIl5SRZSTnDVlLUhGeISsoZQCr/slxJUT78RVRS/rJcSflT24VWUpD1+puspPxtoZLyp7tgibc5OKsD/5yp4OcE1PocsBH/kGr9j4Ba/wmo9dk4zv9sfBJpc3CWPBXQNgepQJuDP4B1QtBFss1BiITL+CjxNgfndcJdMBPuvEPp8oJAEl4ANuIimYQXPSRhGGiXJQnPx3H+GyPLJku2OfAQ1OJtDv7VwXUpLsRXwW6GnwfQRPL4u+TDBSZHvH4oPkdw5qn/YF5g1EPhZqP6DK/PXhHPZeMV8eEfiZeAbMwRz/mPDPQCg9iUM567wOSMl7/A5IjnLjBXxocxofpj9AJzpfeNDOQCNoP1Qc2BXmBygcGI2hXQdqEXGGS9rgJ8yBy8V8XLX2AC3gVL7Kvg3DrwrzYVPHd8Vp66WkDBrwY2Jw+p4HkEFDzESZNFwXPHc/67+ET93EnhR+54PNlyh5nMXuy6RHwTddDyK5WKMwFka6ueVZyItjk44crc/13+vPK5+jr+X4DlAUQMHPSpzYEljDVHEPdfo0Uwb/xlyP15460sWMhT41q9YPnMU+NaB+7PJ3Bq5AMU9jry1LhO4NTIC5wa18Zz/iMDVUPEpvwk9+e3wP3Xktx/Pcv9asLrCe6/HuD+Apa5X/lQgOD+Apa5P5+2C+V+ZL1uILn/Bgvcn88H7i+oA7+QqeAFHbi/kICCFwI2pzCp4IUFFDwfoOAF4zn/XXyiub8gwf0FI8D9eQm7Dlluc6DsUtyHtjm4BLD5NUB85I33/LkbgDtR4JBPbQ5O+MDxN2pRuykUx7uMAMDxoqfATT5wfBG9YEXNU6CIA8cXFTgFigIZcTN5CtwscArcBJwCReI5/5GBcjxiUzGS44tZ4PgiJMffwnK8mvAWguNvATi+uGWOVz4UJzi+uGWOL6rtQjkeWa9bSY6/1QLHF/WB40vowI8yFbyEA8dHCSh4FLA5JUkFLymg4EUBBS8Rz/nv4hP1Uy6FHxmbmvnvPDlNzHUTweZHI1yTd+Ns9eyN8XjCHvWpzYEl1DNHEBvfpmOq1OXIxqV8YOPSesFuN5W1tAMb3y6grLcDKnQHqax3CChrKUBZS8dz/iMDVRfEpjIkG5exwMalSTa+k2VjNeGdBBvfCbBxWctsrHwoS7BxWctsfLu2C2VjZL3uItn4LgtsfLsPbFxOB355U8HLObBxeQEFLw9sTgVSwSsIKPjtgIKXi+f8d/GJZuNyJBujbQ7UXLfFY7aVAlla1XKP+tTmoBQoDhnj7uxOEy8T3k1AesUwTwgvdlWM4IWrYjyOLMgL+9FCGOU2TylgX2K820S1OVA+xxAX2dh4f5LvtwCXfHFs8qkJ44jki7ecfMqueKHkc3tcJZHacMF3erKsQQLw7KEItTlA9jARQHfGFrXfyBxqPROJ+JBsc5DmQ5uDJO1zsvpXksOTfaikpGhnUk0OT3GopKQKcHgqEPFpJIenCXB4MsDhKfGc/8hAsQSxKZ2spKRbqKSkkJWUSmwlRU1YiaikVAKk8h7LlRTlwz1EJeUey5WUVG0XWklB1qsyWUmpbKGSkuouWOJtDqrowK9qKnhVAbWuCmzEvaRa3yug1qmAWleJ5/zPxieRNgdVyFMBbXOQBrQ5SALWCUEXyTYHIRIu46PE2xxU0wlX3Uy4ag6ly+oCSVgd2IgaZBLW8JCEYaBdliSsFs/5b4wsmyzZ5sBDUIu3ObhPB1fN+BBfBbsZXg1AE8njr6YPF5haesFqm9lYy+ECU1sgG2sDkXs/mY33CxyJNYFsrBXP+Y8M9AKD2FSHvMDUsXCBqUVeYOqyFxg1YV3iAlMXUIl6li8wyod6xAWmnuULTG1tF3qBQdbrAfIC84CFC0xt8FtCc0Rlb3bQyGxrfR34DUwFr+/AUw0EFLwBsDkNSQVvKKDgtQEFrx/P+e/iE/VzJ4Uf9ePxZKsfZjJ7sasmYdcpy69UKs4EkK2telZxItrmINk1Rv67/Hnlc/V1/H1A7AGIGDjlU5sDSxhrjiDuf1CLYKPLkfsb+cD9jfWCNTFPjcYO3N9E4NRoAkT5Q+Sp8ZDAqdEIODUax3P+IwNVQ8SmpiT3N7XA/Y1J7n+Y5X414cME9z8MqEQzy9yvfGhGcH8zy9zfRNuFcj+yXo+Q3P+IBe5v4gP3N9eB38JU8OYO3N9CQMFbAJvTklTwlgIK3gRQ8ObxnP8uPtHc35zg6+YR4P5GhF1nLLc5UHY9GI+3OagJsPmDQHw08v65G4A7UeCMT20OLL1PY44gjn9Ui9pjoTjeZQQAjhc9BR7zgeNb6QVrbZ4CrRw4vrXAKdAayIjHyVPgcYFT4DHgFGgVz/mPDJTjEZvakBzfxgLHtyI5vi3L8WrCtgTHtwU4vp1ljlc+tCM4vp1ljm+t7UI5HlmvJ0iOf8ICx7f2geOf1IHf3lTwJx04vr2AgrcHNqcDqeAdBBS8NaDgT8Zz/rv4RP2US+FHxqZm/jtPThNzPUaw+bkI1+TdOFs9+2g8nrDnfGpzYAn1zBHExk/pmOp4ObJxRx/YuJNesM6msnZyYOPOAsraGVChp0llfVpAWTsCytopnvMfGai6IDZ1Idm4iwU27kSycVeWjdWEXQk27gqwcTfLbKx86EawcTfLbNxZ24WyMbJez5Bs/IwFNu7sAxt314Hfw1Tw7g5s3ENAwXsAm9OTVPCeAgreGVDw7vGc/y4+0WzcnWRjtM2BmuupeMy2jiBLq1ruOZ/aHHQExSFjPJvdaeJlwmcJSO8V5gnhxa5eEbxw9YrHkQV5Yf85IYxym6cjYFNv7zZRbQ6Uz72Ji+zz8f4k39EAl3x92ORTE/Yhkq+v5eRTdvUVSj63x1USqQ0XfKcnyxr0A549E6E2B8gevgCgO2OL2m9kDrWeLxDxIdnmIN2HNgf9tc8vqn8lOfxFHyopA7QzL5kcPsChkvKSAIe/BET8QJLDBwpw+IsAhw+I5/xHBooliE0vk5WUly1UUgaQlZRBbCVFTTiIqKQMAqTyFcuVFOXDK0Ql5RXLlZSXtF1oJQVZr1fJSsqrFiopL7kLlnibg8E68IeYCj5EQK2HABvxGqnWrwmo9UuAWg+O5/zPxieRNgeDyVMBbXOQDrQ56A+sE4Iukm0OQiRcxkeJtzkYqhPudTPhhjqULl8XSMLXgY0YRibhMA9JGAbaZUnCofGc/8bIssmSbQ48BLV4m4M3dHANjw/xVbCb4UMBNJE8/ob7cIF5Uy/YCDMb33S4wIwQyMYRQOS+RWbjWwJH4nAgG9+M5/xHBnqBQWwaSV5gRlq4wLxJXmBGsRcYNeEo4gIzClCJ0ZYvMMqH0cQFZrTlC8wIbRd6gUHW623yAvO2hQvMCPBbQnNEZW920Mhs6xgd+GNNBR/jwFNjBRR8LLA540gFHyeg4CMABR8Tz/nv4hP1cyeFH2Pi8WQbE2Yye7FrOGFXoDZmF3rSKc4EkK2telZxItrm4EXXGPnv8ueVz9XX8W8AsQcgYsDDultpc2AJY80RxP3vaBEcfzly/3gfuH+CXrCJ5qkxwYH7JwqcGhOBKH+XPDXeFTg1xgOnxoR4zn9koGqI2DSJ5P5JFrh/Asn977HcryZ8j+D+9wCVmGyZ+5UPkwnun2yZ+ydqu1DuR9brfZL737fA/RN94P4pOvCnmgo+xYH7pwoo+FRgc6aRCj5NQMEnAgo+JZ7z38UnmvunEHw9JQLcP56wK2dtq3b9j+PficfbHAwH2PwdID7Ge//cDcCdKICso2SbA0vv05gjiOM/0KL2YSiOdxkBgONFT4EPfeD46XrBZpinwHQHjp8hcArMADJiJnkKzBQ4BT4EToHp8Zz/yEA5HrFpFsnxsyxw/HSS42ezHK8mnE1w/GyA4+dY5njlwxyC4+dY5vgZ2i6U45H1+ojk+I8scPwMHzh+rg78eaaCz3Xg+HkCCj4P2Jz5pILPF1DwGYCCz43n/Hfxifopl8KPjE3N/HeenCbm+pBg89wRrsm7cbZ69oN4PGFz+8PGKZZQzxxBbPyxjqkFlyMbL/CBjRfqBVtkKutCBzZeJKCsiwAV+oRU1k8ElHUBoKwL4zn/kYGqC2LTYpKNF1tg44UkGy9h2VhNuIRg4yUAGy+1zMbKh6UEGy+1zMaLtF0oGyPr9SnJxp9aYONFPrDxMh34y00FX+bAxssFFHw5sDkrSAVfIaDgiwAFXxbP+e/iE83Gy0g2RtscqLk+jsdsWwCytKrlogzq9TRxGRBSZZ7vs+xOEy8TfkZA+sowTwgvdq2M4IVrZTyOLMgL+6uEMMptngWATau920S1OVA+ryYusp/H+5N8xwJc8q1hk09NuIZIvrWWk0/ZtVYo+dweV0mkNlzwnZ4sa7AOeBb9hjNjoImK7OEXALoztqj9RuZQ6/kFER+SbQ4q+dDmYL32eYP6V5LDN/hQSdmonfnS5PCNDpWULwU4/Esg4jeRHL5JgMM3ABy+MZ7zHxkoliA2bSYrKZstVFI2kpWULWwlRU24haikbAGk8ivLlRTlw1dEJeUry5WUL7VdaCUFWa+vyUrK1xYqKV+6C5Z4m4NvdOBvNRV8q4BabwU24ltSrb8VUOsvAbX+Jp7zPxufRNocfEOeCmibg0pAm4P1wDoh6CLZ5iBEwmV8lHibg2064b4zE26bQ+nyO4Ek/A7YiO1kEm73kIRhoF2WJNwWz/lvjCybLNnmwENQi7c5+F4H1w/xIb4KdjN8G4AmksffDz5cYH7UC7bDzMYfHS4wOwSycQcQuT+R2fiTwJH4A5CNP8Zz/iMDvcAgNu0kLzA7LVxgfiQvMLvYC4yacBdxgdkFqMRuyxcY5cNu4gKz2/IFZoe2C73AIOv1M3mB+dnCBWYH+C2hOaKyNztoZLZ1jw78vaaC73Hgqb0CCr4X2Jx9pILvE1DwHYCC74nn/Hfxifq5k8KPPfF4su0JM5m92PUDYVd+y69UKs4EkK2telZxItrmYINrjPx3+fPK5+rr+O+B2AMQMZDfpzYHljDWHEHc/4sWwf2XI/fv94H7D+gFO2ieGgccuP+gwKlxEIjyX8lT41eBU2M/cGociOf8RwaqhohNh0juP2SB+w+Q3H+Y5X414WGC+w8DKnHEMvcrH44Q3H/EMvcf1Hah3I+s128k9/9mgfsP+sD9R3XgHzMV/KgD9x8TUPBjwOYcJxX8uICCHwQU/Gg857+LTzT3HyX4+mgEuH8/YVcBy20OlF2/xONtDn4A2PwXID72e//cDcCdKFDApzYHlt6nMUcQx/+uRe2PUBzvMgIAx4ueAn/4wPEn9IKdNE+BEw4cf1LgFDgJZMSf5Cnwp8Ap8AdwCpyI5/xHBsrxiE2nSI4/ZYHjT5Acf5rleDXhaYLjTwMcf8YyxysfzhAcf8Yyx5/UdqEcj6zXXyTH/2WB40/6wPF/68A/ayr43w4cf1ZAwc8Cm3OOVPBzAgp+ElDwv+M5/118on7KpfAjY1Mz/50np4m5/iDYvHCEa/JunK2e/T0eT9jCPrU5sIR65ghi4390TJ2/HNn4vA9sfEEv2EVTWS84sPFFAWW9CKjQv6Sy/iugrOcBZb0Qz/mPDFRdEJsukWx8yQIbXyDZOEdCGBOqP0bZWP1Nds8aIxBIsMvGygc1B8rGgQQsGFG7Lmq7UDZG1usKwIfMwav+TpqNL/rAxjl14F+ZkCPYwZwJWdn4yoTwFfxKYHNyJXAKnishfAW/CCh4zgTOfxefaDbO2NTMf+dloG0O1Fz/xGO2nQdZWtVyC/vU5gBBqszzXZXdaeJlwqsS8L/LHeYJ4cWu3GRQMQGcOwFHFuSF/avBkytjoGJ3HrApj3ebqDYHyuc8Cfh+XJPgT/IdD3DJl5dNPjVhXiL5rrWcfMqua4WSz+1xlURqwwXf6cmyBvmA9SoQoTYHyB5eB6A7Y4vab2QOtZ7XEfEh2ebgHh/aHOTXPl+v/pXk8OsTrDiTRRQz21pAO3ODyeHqP5iVlBsEOPwGIOILkhxeUIDDr0/wzuEFEjj/kYFiCWJToQSuklIoQb6SUiCBq6QUZispasLCRCWlMCCVN1qupCgfbiQqKTdarqTcoO1CKynIet1EVlJuslBJucFdsMTbHBTRgV/UVPCiAmpdFNiIm0m1vllArW8A1LpIAud/Nj6JtDkoQp4KaJuDe4A2B/mBdULQRbLNQYiEy/go8TYHxXTC3WImXDGH0uUtAkl4C7ARxckkLO4hCcNAuyxJWCyB898YWTZZss2Bh6AWb3Nwqw6uEgkhvgp2M7wYgCaSx18JHy4wUXrBSprZGOVwgSkpkI0lgci9jczG2wSOxBJANkYlcP4jA73AIDaVIi8wpSxcYKLIC0xp9gKjJixNXGBKAypxu+ULjPLhduICc7vlC0xJbRd6gUHW6w7yAnOHhQtMSfBbQnNEZW920Mhsaxkd+HeaCl7GgafuFFDwO4HNKUsqeFkBBS8JKHiZBM5/F5+onzsp/CiTgCdbmTCT2YtdJQi7ilt+pVJxJoBsbdWzihPRNgfXu8bIf5c/r3yuvo6/FYg9ABEDxX1qc2AJY80RxP13aREsdzlyfzkfuL+8XrAK5qlR3oH7KwicGhWAKL+bPDXuFjg1ygGnRvkEzn9koGqI2FSR5P6KFri/PMn90Sz3qwmjCe6PBlQixjL3Kx9iCO6Pscz9FbRdKPcj6xVLcn+sBe6v4AP3x+nAjzcVPM6B++MFFDwe2JwEUsETBBS8AqDgcQmc/y4+0dwfR/B1XAS4vxxhVwnLbQ6UXXcl4G0OSgBsfhcQH+W8f+4G4E4UKOFTmwNL79OYI4jjE7WoJYXieJcRADhe9BRI8oHjk/WCpZinQLIDx6cInAIpQEakkqdAqsApkAScAskJnP/IQDkesSmN5Pg0CxyfTHJ8OsvxasJ0guPTAY6vZJnjlQ+VCI6vZJnjU7RdKMcj63UPyfH3WOD4FB84vrIO/Cqmgld24PgqAgpeBdicqqSCVxVQ8BRAwSsncP67+ET9lEvhR8amZv47T04TcyURbF4qwjV5N85WzyYm4Albyqc2B5ZQzxxBbHyvjqlqlyMbV/OBjavrBathKmt1BzauIaCsNQAVuo9U1vsElLUaoKzVEzj/kYGqC2JTTZKNa1pg4+okG9di2VhNWItg41oAG9e2zMbKh9oEG9e2zMY1tF0oGyPrdT/JxvdbYOMaPrBxHR34dU0Fr+PAxnUFFLwusDn1SAWvJ6DgNQAFr5PA+e/iE83GdUg2RtscqLnuTcBsqwaytKrllvKpzUE1UBwyxgPZnSZeJnyAgPT6YZ4QXuyqH8ELV/0EHFmQF/YbCGGU2zzVAJsaereJanOgfG5IXGQfTPAn+X4PcMnXiE0+NWEjIvkaW04+ZVdjoeRze1wlkdpwwXd6sqxBE+DZEhFqc4Ds4UMAujO2qP1G5lDr+RARH5JtDir70Oagqfb5YfWvJIc/7EMlpZl25hGTw5s5VFIeEeDwR4CIb05yeHMBDn8Y4PBmCZz/yECxBLGpBVlJaWGhktKMrKS0ZCspasKWRCWlJSCVj1qupCgfHiUqKY9arqQ8ou1CKynIej1GVlIes1BJecRdsMTbHLTSgd/aVPDWAmrdGtiIx0m1flxArR8B1LpVAud/Nj6JtDloRZ4KaJuDykCbg6bAOiHoItnmIETCZXyUeJuDNjrh2poJ18ahdNlWIAnbAhvRjkzCdh6SMAy0y5KEbRI4/42RZZMl2xx4CGrxNgdP6OB6MiHEV8FuhrcB0ETy+HvShwtMe71gHcxsbO9wgekgkI0dgMh9iszGpwSOxCeBbGyfwPmPDPQCg9jUkbzAdLRwgWlPXmA6sRcYNWEn4gLTCVCJzpYvMMqHzsQFprPlC0wHbRd6gUHW62nyAvO0hQtMB/BbQnNEZW920Mhsaxcd+F1NBe/iwFNdBRS8K7A53UgF7yag4B0ABe+SwPnv4hP1cyeFH10S8GTrEmYye7HrScKucpZfqVScCSBbW/Ws4kS0zcHDrjHy3+XPK5+rr+OfAGIPQMRAOZ/aHFjCWHMEcf8zWgS7X47c390H7u+hF6yneWr0cOD+ngKnRk8gyp8lT41nBU6N7sCp0SOB8x8ZqBoiNvUiub+XBe7vQXL/cyz3qwmfI7j/OUAlelvmfuVDb4L7e1vm/p7aLpT7kfV6nuT+5y1wf08fuL+PDvy+poL3ceD+vgIK3hfYnH6kgvcTUPCegIL3SeD8d/GJ5v4+BF/3iQD3dyfsqmC5zYGy65kEvM3BkwCbPwPER3fvn7sBuBMFKvjU5sDS+zTmCOL4F7So9Q/F8S4jAHC86CnQ3weOf1Ev2ADzFHjRgeMHCJwCA4CMeIk8BV4SOAX6A6fAiwmc/8hAOR6xaSDJ8QMtcPyLJMe/zHK8mvBlguNfBjh+kGWOVz4MIjh+kGWOH6DtQjkeWa9XSI5/xQLHD/CB41/VgT/YVPBXHTh+sICCDwY2Zwip4EMEFHwAoOCvJnD+u/hE/ZRL4UfGpmb+O09OE3P1J9g8JsI1eTfOVs++kIAnbIxPbQ4soZ45gtj4NR1TQy9HNh7qAxu/rhdsmKmsrzuw8TABZR0GqNAbpLK+IaCsQwFlfT2B8x8ZqLogNg0n2Xi4BTZ+nWTjN1k2VhO+SbDxmwAbj7DMxsqHEQQbj7DMxsO0XSgbI+v1FsnGb1lg42E+sPFIHfijTAUf6cDGowQUfBSwOaNJBR8toODDAAUfmcD57+ITzcYjSTZG2xyouV5LwGwbCrK0quXG+NTmYCgoDhnj7exOEy8Tvk1A+pgwTwgvdo2J4IVrTAKOLMgL+2OFMMptnqGATeO820S1OVA+jyMusu8k+JN8fwS45BvPJp+acDyRfBMsJ5+ya4JQ8rk9rpJIbbjgOz1Z1mAi8GyFCLU5QPbwXQDdGVvUfiNzqPV8l4gPyTYHVXxoczBJ+/ye+leSw9/zoZIyWTvzvsnhkx0qKe8LcPj7QMRPITl8igCHvwdw+OQEzn9koFiC2DSVrKRMtVBJmUxWUqaxlRQ14TSikjINkMoPLFdSlA8fEJWUDyxXUt7XdqGVFGS9PiQrKR9aqKS87y5Y4m0OpuvAn2Eq+AwBtZ4BbMRMUq1nCqj1+4BaT0/g/M/GJ5E2B9PJUwFtc1AFaHMwCVgnBF0k2xyESLiMjxJvczBLJ9xsM+FmOZQuZwsk4WxgI+aQSTjHQxKGgXZZknBWAue/MbJssmSbAw9BLd7m4CMdXHMTQnwV7Gb4LABNJI+/uT5cYObpBZtvZuM8hwvMfIFsnA9E7sdkNn4scCTOBbJxXgLnPzLQCwxi0wLyArPAwgVmHnmBWcheYNSEC4kLzEJAJRZZvsAoHxYRF5hFli8w87Vd6AUGWa9PyAvMJxYuMPPBbwnNEZW92UEjs62LdeAvMRV8sQNPLRFQ8CXA5iwlFXypgILPBxR8cQLnv4tP1M+dFH4sTsCTbXGYyezFrrmEXSmWX6lUnAkgW1v1rOJEtM3Be64x8t/lzyufq6/jPwJiD0DEQIpPbQ4sYaw5grj/Uy2Cyy5H7l/mA/cv1wu2wjw1ljtw/wqBU2MFEOWfkafGZwKnxjLg1FiewPmPDFQNEZtWkty/0gL3Lye5fxXL/WrCVQT3rwJUYrVl7lc+rCa4f7Vl7l+h7UK5H1mvz0nu/9wC96/wgfvX6MBfayr4GgfuXyug4GuBzVlHKvg6AQVfASj4mgTOfxefaO5fQ/D1mghw/zLCrjTLbQ6UXZ8m4G0O5gJs/ikQH8u8f+4G4E4USPOpzYGl92nMEcTxX2hRWx+K411GAOB40VNgvQ8cv0Ev2EbzFNjgwPEbBU6BjUBGfEmeAl8KnALrgVNgQwLnPzJQjkds2kRy/CYLHL+B5PjNLMerCTcTHL8Z4Pgtljle+bCF4Pgtljl+o7YL5Xhkvb4iOf4rCxy/0QeO/1oH/jemgn/twPHfCCj4N8DmbCUVfKuAgm8EFPzrBM5/F5+on3Ip/MjY1Mx/58lpYq71BJtXjnBN3o2z1bNfJOAJW9mnNgeWUM8cQWz8rY6pbZcjG2/zgY2/0wu23VTW7xzYeLuAsm4HVOh7Ulm/F1DWbYCyfpfA+Y8MVF0Qm34g2fgHC2z8HcnGP7JsrCb8kWDjHwE23mGZjZUPOwg23mGZjbdru1A2RtbrJ5KNf7LAxtt9YOOdOvB3mQq+04GNdwko+C5gc3aTCr5bQMG3Awq+M4Hz38Unmo13kmyMtjlQc32bgNm2DWRpVcut7FObg22gOGSMn7M7TbxM+DMB6XvCPCG82LUngheuPQk4siAv7O8Vwii3ebYBNu3zbhPV5kD5vI+4yP6S4E/ynQhwybefTT414X4i+Q5YTj5l1wGh5HN7XCWR2nDBd3qyrMFB4Nm0CLU5QPbwVwDdGVvUfiNzqPX8lYgPyTYHVX1oc3BI+3xY/SvJ4Yd9qKQc0c78ZnL4EYdKym8CHP4bEPFHSQ4/KsDhhwEOP5LA+Y8MFEsQm46RlZRjFiopR8hKynG2kqImPE5UUo4DUvm75UqK8uF3opLyu+VKym/aLrSSgqzXH2Ql5Q8LlZTf3AVLvM3BCR34J00FPymg1ieBjfiTVOs/BdT6N0CtTyRw/mfjk0ibgxPkqYC2OagKtDk4BKwTgi6SbQ5CJFzGR4m3OTilE+60mXCnHEqXpwWS8DSwEWfIJDzjIQnDQLssSXgqgfPfGFk2WbLNgYegFm9z8JcOrr8TQnwV7Gb4KQBNJI+/v324wJzVC3bOzMazDheYcwLZeA6I3H/IbPxH4Ej8G8jGswmc/8hALzCITefJC8x5CxeYs+QF5gJ7gVETXiAuMBcAlbho+QKjfLhIXGAuWr7AnNN2oRcYZL3+JS8w/1q4wJwDvyU0R1T2ZgeNzLZeygj8xBzBDl5y4Cn1ULgKrj7D67OBRE7BA4nhK/g5QMEvJXD+u/hE/dxJ4ccl4hufS2Emsxe7/ibsqmn5lUrFmQCytVXPKk5E2xwcdo2R/y5/XvlcfR3/FxB7ACIGavrU5sASxpojiPuvSPz//+ZMvAy5P2di5Ln/Sr1gucxTQ/0Hk/tzCZwauYBT4yry1LhK4NTImej91LgykfMfGagaIjblTuS4P3eiPPdfmchx/9WJYUyo/hjl/qu9b2QgD7AZrA95EnHuzwMGI2pXLm0Xyv3Iel0D+JA5eK9JlOf+XCASmiMqe7ODRmZb8+rAv9ZU8LyJWbn/WgEFvxbYnHykgucTUPBcgILnTeT8d/GJ5v68iXiy5Q0zmb3YlZOwq7blNgfKLsV9aJuDvwE2vwKIj5yJnj93A3AnCtT2qc3BYR84/jotavlDcbzLCAAcL3oK5PeB46/XC1bAPAWud+D4AgKnQAEgI24gT4EbBE6B/MApcH0i5z8yUI5HbCpIcnxBCxx/PcnxhViOVxMWIji+EMDxhS1zvPKhMMHxhS1zfAFtF8rxyHrdSHL8jRY4voAPHH+TDvwipoLf5MDxRQQUvAiwOUVJBS8qoOAFAAW/KZHz38Un6qdcCj8yNjXz33lympgrP8Hm9SJck3fjbPXsdYl4wtbzqc2BJdQzRxAb36xjqtjlyMbFfGDjW/SCFTeV9RYHNi4uoKzFARW6lVTWWwWUtRigrLckcv4jA1UXxKYSJBuXsMDGt5BsHMWy8f8mJNg4CmDjkpbZWPlQkmDjkpbZuLi2C2VjZL1uI9n4NgtsXNwHNi6lA7+0qeClHNi4tICClwY253ZSwW8XUPDigIKXSuT8d/GJZuNSJBujbQ7UXDcnYrYVA1la1XLr+dTmoBgoDhnjjuxOEy8T3kFAepkwTwgvdpWJ4IWrTCKOLMgL+3cKYZTbPMWAfSnr3SaqzYHyuSxxkb0r0Z/kOxngkq8cm3xqwnJE8pW3nHzKrvJCyef2uEoiteGC7/RkWYMKwLO1I9TmANnDuwF0Z2xR+43ModbzbiI+JNsc3OtDm4OK2udo9a8kh0f7UEmJ0c7Emhwe41BJiRXg8Fgg4uNIDo8T4PBogMNjEjn/kYFiCWJTPFlJibdQSYkhKykJbCVFTZhAVFISAKlMtFxJUT4kEpWURMuVlFhtF1pJQdYriaykJFmopMS6C5Z4m4NkHfgppoKnCKh1CrARqaRapwqodSyg1smJnP/Z+CTS5iCZPBXQNgf3Am0OKgLrhKCLZJuDEAmX8VHibQ7SdMKlmwmX5lC6TBdIwnRgIyqRSVjJQxKGgXZZkjAtkfPfGFk2WbLNgYegFm9zcI8OrsqJIb4KdjM8DUATyeOvsg8XmCp6waqa2VjF4QJTVSAbqwKRey+ZjfcKHImVgWysksj5jwz0AoPYVI28wFSzcIGpQl5gqrMXGDVhdeICUx1QiRqWLzDKhxrEBaaG5QtMVW0XeoFB1us+8gJzn4ULTFXwW0JzRGVvdtDIbGtNHfi1TAWv6cBTtQQUvBZSCCYVvLaAglcFFLxmIue/i0/Uz50UftRMxJOtZpjJ7MWuyoRdTSy/Uqk4E0C2tupZxYlom4No1xj57/Lnlc/V1/H3ALEHIGKgiU9tDixhrDmCuP9+LYJ1Lkfur+MD99fVC1bPPDXqOnB/PYFTox4Q5Q+Qp8YDAqdGHeDUqJvI+Y8MVA0Rm+qT3F/fAvfXJbm/Acv9asIGBPc3AFSioWXuVz40JLi/oWXur6ftQrkfWa8HSe5/0AL31/OB+xvpwG9sKngjB+5vLKDgjYHNaUIqeBMBBa8HKHijRM5/F59o7m9E8HWjCHB/HcKuppbbHCi77k/E2xxUBtj8fiA+6nj/3A3AnSjQ1Kc2B5bepzFHEMc/pEWtaSiOdxkBgONFT4GmPnD8w3rBmpmnwMMOHN9M4BRoBmTEI+Qp8IjAKdAUOAUeTuT8RwbK8YhNzUmOb26B4x8mOb4Fy/FqwhYEx7cAOL6lZY5XPrQkOL6lZY5vpu1COR5Zr0dJjn/UAsc384HjH9OB38pU8MccOL6VgIK3AjanNangrQUUvBmg4I8lcv67+ET9lEvhR8amZv47T04TczUl2Lx5hGvybpytnn0oEU/Y5j61ObCEeuYIYuPHdUy1uRzZuI0PbNxWL1g7U1nbOrBxOwFlbQeo0BOksj4hoKxtAGVtm8j5jwxUXRCbniTZ+EkLbNyWZOP2LBurCdsTbNweYOMOltlY+dCBYOMOltm4nbYLZWNkvZ4i2fgpC2zczgc27qgDv5Op4B0d2LiTgIJ3AjanM6ngnQUUvB2g4B0TOf9dfKLZuCPJxmibAzXX44mYbW1Alla13OY+tTloA4pDxng6u9PEy4RPE5DeJcwTwotdXSJ44eqSiCML8sJ+VyGMcpunDWBTN+82UW0OlM/diIvsM4n+JN+fAS75urPJpybsTiRfD8vJp+zqIZR8bo+rJFIbLvhOT5Y16Ak82zRCbQ6QPXwWQHfGFrXfyBxqPZ8l4kOyzUE1H9oc9NI+P6f+leTw53yopPTWzjxvcnhvh0rK8wIc/jwQ8X1IDu8jwOHPARzeO5HzHxkoliA29SUrKX0tVFJ6k5WUfmwlRU3Yj6ik9AOk8gXLlZT/JStRSXnBciXleW0XWklB1qs/WUnpb6GS8ry7YIm3OXhRB/4AU8EHCKj1AGAjXiLV+iUBtX4eUOsXEzn/s/FJpM3Bi+SpgLY5qAa0OegFrBOCLpJtDkIkXMZHibc5GKgT7mUz4QY6lC5fFkjCl4GNGEQm4SAPSRgG2mVJwoGJnP/GyLLJkm0OPAS1eJuDV3RwvZoY4qtgN8MHAmgiefy96sMFZrBesCFmNg52uMAMEcjGIUDkvkZm42sCR+KrQDYOTuT8RwZ6gUFsGkpeYIZauMAMJi8wr7MXGDXh68QF5nVAJYZZvsAoH4YRF5hhli8wQ7Rd6AUGWa83yAvMGxYuMEPAbwnNEZW92UEjs63DdeC/aSr4cAeeelNAwd8ENmcEqeAjBBR8CKDgwxM5/118on7upPBjeCKebMPDTGYvdr1K2NXG8iuVijMBZGurnlWciLY5eM41Rv67/Hnlc/V1/CtA7AGIGGjjU5sDSxhrjiDuf0uL4MjLkftH+sD9o/SCjTZPjVEO3D9a4NQYDUT52+Sp8bbAqTESODVGJXL+IwNVQ8SmMST3j7HA/aNI7h/Lcr+acCzB/WMBlRhnmfuVD+MI7h9nmftHa7tQ7kfW6x2S+9+xwP2jfeD+8TrwJ5gKPt6B+ycIKPgEYHMmkgo+UUDBRwMKPj6R89/FJ5r7xxN8PT4C3D+SsKud5TYHyq63EvE2B68CbP4WEB8jvX/uBuBOFGjnU5sDS+/TmCOI49/VojYpFMe7jADA8aKnwCQfOP49vWCTzVPgPQeOnyxwCkwGMuJ98hR4X+AUmAScAu8lcv4jA+V4xKYpJMdPscDx75EcP5XleDXhVILjpwIcP80yxysfphEcP80yx0/WdqEcj6zXByTHf2CB4yf7wPEf6sCfbir4hw4cP11AwacDmzODVPAZAgo+GVDwDxM5/118on7KpfAjY1Mz/50np4m5JhFs3iHCNXk3zlbPvpuIJ2wHn9ocWEI9cwSx8UwdU7MuRzae5QMbz9YLNsdU1tkObDxHQFnnACr0EamsHwko6yxAWWcncv4jA1UXxKa5JBvPtcDGs0k2nseysZpwHsHG8wA2nm+ZjZUP8wk2nm+Zjedou1A2RtbrY5KNP7bAxnN8YOMFOvAXmgq+wIGNFwoo+EJgcxaRCr5IQMHnAAq+IJHz38Unmo0XkGyMtjlQc81MxGybBbK0quV28KnNwSxQHDLGJ9mdJl4m/ISA9MVhnhBe7FocwQvX4kQcWZAX9pcIYZTbPLMAm5Z6t4lqc6B8XkpcZD9N9Cf5TgW45FvGJp+acBmRfMstJ5+ya7lQ8rk9rpJIbbjgOz1Z1mAF8Gy7CLU5QPbwMwDdGVvUfiNzqPX8jIgPyTYH1X1oc7BS+7xK/SvJ4at8qKSs1s58bnL4aodKyucCHP45EPFrSA5fI8DhqwAOX53I+Y8MFEsQm9aSlZS1Fiopq8lKyjq2kqImXEdUUtYBUvmF5UqK8uELopLyheVKyufaLrSSgqzXerKSst5CJeVzd8ESb3OwQQf+RlPBNwqo9UZgI74k1fpLAbX+HFDrDYmc/9n4JNLmYAN5KqBtDqoDbQ5WAuuEoItkm4MQCZfxUeJtDjbphNtsJtwmh9LlZoEk3AxsxBYyCbd4SMIw0C5LEm5K5Pw3RpZNlmxz4CGoxdscfKWD6+vEEF8Fuxm+CUATyePvax8uMN/oBdtqZuM3DheYrQLZuBWI3G/JbPxW4Ej8GsjGbxI5/5GBXmAQm7aRF5htFi4w35AXmO/YC4ya8DviAvMdoBLbLV9glA/biQvMdssXmK3aLvQCg6zX9+QF5nsLF5it4LeE5ojK3uygkdnWH3Tg/2gq+A8OPPWjgIL/CGzODlLBdwgo+FZAwX9I5Px38Yn6uZPCjx8S8WT7Icxk9mLX14Rd3Sy/Uqk4E0C2tupZxYlom4NVrjHy3+XPK5+rr+O/AmIPQMRAN5/aHFjCWHMEcf9PWgR3Xo7cv9MH7t+lF2y3eWrscuD+3QKnxm4gyn8mT42fBU6NncCpsSuR8x8ZqBoiNu0huX+PBe7fRXL/Xpb71YR7Ce7fC6jEPsvcr3zYR3D/Psvcv1vbhXI/sl6/kNz/iwXu3+0D9+/XgX/AVPD9Dtx/QEDBDwCbc5BU8IMCCr4bUPD9iZz/Lj7R3L+f4Ov9EeD+nYRd3S23OVB2/ZSItzn4GmDzn4D42On9czcAd6JAd5/aHFh6n8YcQRz/qxa1Q6E43mUEAI4XPQUO+cDxh/WCHTFPgcMOHH9E4BQ4AmTEb+Qp8JvAKXAIOAUOJ3L+IwPleMSmoyTHH7XA8YdJjj/Gcrya8BjB8ccAjj9umeOVD8cJjj9umeOPaLtQjkfW63eS43+3wPFHfOD4P3TgnzAV/A8Hjj8hoOAngM05SSr4SQEFPwIo+B+JnP8uPlE/5VL4kbGpmf/Ok9PEXIcINu8V4Zq8G2erZ39NxBO2l09tDiyhnjmC2PhPHVOnLkc2PuUDG5/WC3bGVNbTDmx8RkBZzwAq9BeprH8JKOspQFlPJ3L+IwNVF8Smv0k2/tsCG58m2fgsy8ZqwrMEG58F2PicZTZWPpwj2PicZTY+o+1C2RhZr39INv7HAhuf8YGNz+vAv2Aq+HkHNr4goOAXgM25SCr4RQEFPwMo+PlEzn8Xn2g2Pk+yMdrmQM31ZyJm2ymQpVUtt5dPbQ5OgeKQMf7N7jTxMuG/BKRfCvOE8GLXpQheuC4l4siCvLCfI0kGo1x/sQzYFPBuE9XmQPms5kD344okf5LvdIBLvpxJYUyYMwn/uyuT7CafsuvKpP/+h6gc3gdzeVUbLvhOT5Y1yAWsV/cItTlA9vCqJCDpCFvUfiNzqPW8iogPyTYHNXxoc5Bb+3y1+leSw69OsuJMFlHMbGse7cw1STmCmVv9B7OSoh4Kl8OvASI+bxLH4XmTwufwq5O8c3ieJM5/ZKBYgth0bRJXSbk2Sb6SkieJq6TkSwpjQvXHaCUlHyCV14V5VHvx4ToPCGF+znVgMKJ2XaPtQispyHrlB3zIHLz5k+QrKde4C5Z4m4PrdeAXMBW8gIBaFwA24gZSrW8QUOtrALW+PonzPxufRNocXE+eCmibgxpAm4PcwDoh6CLZ5iBEwmV8lHibg4I64QqZCVcwKWvpspBAEhYCNqIwmYSFPSRhGGiXJQkLJnH+GyPLJku2OfAQ1OJtDm7UwXVTUoivgt0MLwigieTxd5MPF5giesGKmtlYxOECU1QgG4sCkXszmY03CxyJNwHZWCSJ8x8Z6AUGsakYeYEpZuECU4S8wNzCXmDUhLcQF5hbAJUobvkCo3woTlxgilu+wBTVdqEXGGS9biUvMLdauMAU9S5YYl8Fl9CBH2UqeAkHnooSUPAoYHNKkgpeUkDBiwIKXiKJ89/FJ+rnTgo/SiThyVYizGT2YtdNhF39Lb9SqTgTQLa26lnFiWibg6tdY+S/y59XPldfx98IxB6AiIH+PrU5sISx5gji/tu0CJa6HLm/lA/cX1ov2O3mqVHagftvFzg1bgei/A7y1LhD4NQoBZwapZM4/5GBqiFiUxmS+8tY4P7SJPffyXK/mvBOgvvvBFSirGXuVz6UJbi/rGXuv13bhXI/sl53kdx/lwXuv90H7i+nA7+8qeDlHLi/vICClwc2pwKp4BUEFPx2QMHLJXH+u/hEc385gq/LRYD7SxF2DbDc5kDZdVsS3ubgJoDNbwPio5T3z90A3IkCA3xqc2DpfRpzBHH83VrUKobieJcRADhe9BSo6APHR+sFizFPgWgHjo8ROAVigIyIJU+BWIFToCJwCkQncf4jA+V4xKY4kuPjLHB8NMnx8SzHqwnjCY6PBzg+wTLHKx8SCI5PsMzxMdoulOOR9UokOT7RAsfH+MDxSTrwk00FT3Lg+GQBBU8GNieFVPAUAQWPARQ8KYnz38Un6qdcCj8yNjXz33lympirIsHmgyJck3fjbPXs3Ul4wg7yqc2BJdQzRxAbp+qYSrsc2TjNBzZO1wtWyVTWdAc2riSgrJUAFbqHVNZ7BJQ1DVDW9CTOf2Sg6oLYVJlk48oW2DidZOMqLBurCasQbFwFYOOqltlY+VCVYOOqltm4krYLZWNkve4l2fheC2xcyQc2rqYDv7qp4NUc2Li6gIJXBzanBqngNQQUvBKg4NWSOP9dfKLZuBrJxmibAzVXahJmWxrI0qqWO8inNgdpoDhkjPuyO028THgfAek1wzwhvNhVM4IXrppJOLIgL+zXEsIot3nSAJtqe7eJanOgfK5NXGTvT/In+c4EuOSrwyafmrAOkXx1LSefsquuUPK5Pa6SSG244Ds9WdagHvDsgAi1OUD28AEA3Rlb1H4jc6j1fICID8k2B/f50Oagvva5gfpXksMb+FBJaaidedDk8IYOlZQHBTj8QSDiG5Ec3kiAwxsAHN4wifMfGSiWIDY1JispjS1UUhqSlZQmbCVFTdiEqKQ0AaTyIcuVFOXDQ0Ql5SHLlZQHtV1oJQVZr6ZkJaWphUrKg+6CJd7m4GEd+M1MBW8moNbNgI14hFTrRwTU+kFArR9O4vzPxieRNgcPk6cC2ubgPqDNQX1gnRB0kWxzECLhMj5KvM1Bc51wLcyEa+5QumwhkIQtgI1oSSZhSw9JGAbaZUnC5kmc/8bIssmSbQ48BLV4m4NHdXA9lhTiq2A3w5sDaCJ5/D3mwwWmlV6w1mY2tnK4wLQWyMbWQOQ+Tmbj4wJH4mNANrZK4vxHBnqBQWxqQ15g2li4wLQiLzBt2QuMmrAtcYFpC6hEO8sXGOVDO+IC087yBaa1tgu9wCDr9QR5gXnCwgWmNfgtoTmisjc7aGS29Ukd+O1NBX/SgafaCyh4e2BzOpAK3kFAwVsDCv5kEue/i0/Uz50UfjyZhCfbk2Emsxe7HiPsGmb5lUrFmQCytVXPKk5E2xw0cI2R/y5/XvlcfR3/KBB7ACIGhvnU5sASxpojiPuf0iLY8XLk/o4+cH8nvWCdzVOjkwP3dxY4NToDUf40eWo8LXBqdAROjU5JnP/IQNUQsakLyf1dLHB/J5L7u7LcrybsSnB/V0AlulnmfuVDN4L7u1nm/s7aLpT7kfV6huT+Zyxwf2cfuL+7DvwepoJ3d+D+HgIK3gPYnJ6kgvcUUPDOgIJ3T+L8d/GJ5v7uBF93jwD3dyTsGm65zYGy66kkvM3BYwCbPwXER0fvn7sBuBMFhvvU5sDS+zTmCOL4Z7Wo9QrF8S4jAHC86CnQyweOf04vWG/zFHjOgeN7C5wCvYGMeJ48BZ4XOAV6AafAc0mc/8hAOR6xqQ/J8X0scPxzJMf3ZTleTdiX4Pi+AMf3s8zxyod+BMf3s8zxvbVdKMcj6/UCyfEvWOD43j5wfH8d+C+aCt7fgeNfFFDwF4HNGUAq+AABBe8NKHj/JM5/F5+on3Ip/MjY1Mx/58lpYq5eBJuPjHBN3o2z1bPPJuEJO9KnNgeWUM8cQWz8ko6pgZcjGw/0gY1f1gs2yFTWlx3YeJCAsg4CVOgVUllfEVDWgYCyvpzE+Y8MVF0Qm14l2fhVC2z8MsnGg1k2VhMOJth4MMDGQyyzsfJhCMHGQyyz8SBtF8rGyHq9RrLxaxbYeJAPbDxUB/7rpoIPdWDj1wUU/HVgc4aRCj5MQMEHAQo+NInz38Unmo2HkmyMtjlQc72UhNk2EGRpVcsd6VObg4GgOGSMN7I7TbxM+AYB6cPDPCG82DU8gheu4Uk4siAv7L8phFFu8wwEbBrh3SaqzYHyeQRxkX0ryZ/k+yvAJd9INvnUhCOJ5BtlOfmUXaOEks/tcZVEasMF3+nJsgajgWeHR6jNAbKHbwPoztii9huZQ63n20R8SLY5qOlDm4Mx2uex6l9JDh/rQyVlnHbmHZPDxzlUUt4R4PB3gIgfT3L4eAEOHwtw+Lgkzn9koFiC2DSBrKRMsFBJGUdWUiaylRQ14USikjIRkMp3LVdSlA/vEpWUdy1XUt7RdqGVFGS9JpGVlEkWKinvuAuWeJuD93TgTzYVfLKAWk8GNuJ9Uq3fF1DrdwC1fi+J8z8bn0TaHLxHngpom4OaQJuDMcA6Iegi2eYgRMJlfJR4m4MpOuGmmgk3xaF0OVUgCacCGzGNTMJpHpIwDLTLkoRTkjj/jZFlkyXbHHgIavE2Bx/o4PowKcRXwW6GTwHQRPL4+9CHC8x0vWAzzGyc7nCBmSGQjTOAyJ1JZuNMgSPxQyAbpydx/iMDvcAgNs0iLzCzLFxgppMXmNnsBUZNOJu4wMwGVGKO5QuM8mEOcYGZY/kCM0PbhV5gkPX6iLzAfGThAjMD/JbQHFHZmx00Mts6Vwf+PFPB5zrw1DwBBZ8HbM58UsHnCyj4DEDB5yZx/rv4RP3cSeHH3CQ82eaGmcxe7PqQsGu85VcqFWcCyNZWPas4EW1zMNY1Rv67/Hnlc/V1/AdA7AGIGBjvU5sDSxhrjiDu/1iL4ILLkfsX+MD9C/WCLTJPjYUO3L9I4NRYBET5J+Sp8YnAqbEAODUWJnH+IwNVQ8SmxST3L7bA/QtJ7l/Ccr+acAnB/UsAlVhqmfuVD0sJ7l9qmfsXabtQ7kfW61OS+z+1wP2LfOD+ZTrwl5sKvsyB+5cLKPhyYHNWkAq+QkDBFwEKviyJ89/FJ5r7lxF8vSwC3L+AsGui5TYHyq6Pk/A2Bx8CbP4xEB8LvH/uBuBOFJjoU5sDS+/TmCOI4z/TorYyFMe7jADA8aKnwEofOH6VXrDV5imwyoHjVwucAquBjPicPAU+FzgFVgKnwKokzn9koByP2LSG5Pg1Fjh+Fcnxa1mOVxOuJTh+LcDx6yxzvPJhHcHx6yxz/GptF8rxyHp9QXL8FxY4frUPHL9eB/4GU8HXO3D8BgEF3wBszkZSwTcKKPhqQMHXJ3H+u/hE/ZRL4UfGpmb+O09OE3OtJNh8coRr8m6crZ79LAlP2Mk+tTmwhHrmCGLjL3VMbboc2XiTD2y8WS/YFlNZNzuw8RYBZd0CqNBXpLJ+JaCsmwBl3ZzE+Y8MVF0Qm74m2fhrC2y8mWTjb1g2VhN+Q7DxNwAbb7XMxsqHrQQbb7XMxlu0XSgbI+v1LcnG31pg4y0+sPE2HfjfmQq+zYGNvxNQ8O+AzdlOKvh2AQXfAij4tiTOfxefaDbeRrIx2uZAzfVlEmbbJpClVS13sk9tDjaB4pAxvs/uNPEy4fcEpP8Q5gnhxa4fInjh+iEJRxbkhf0fhTDKbZ5NgE07vNtEtTlQPu8gLrI/JfmTfH8HuOTbySafmnAnkXy7LCefsmuXUPK5Pa6SSG244Ds9WdZgN/DsxAi1OUD28GcA3Rlb1H4jc6j1/JmID8k2B7V8aHOwR/u8V/0ryeF7faik7NPO/GJy+D6HSsovAhz+CxDx+0kO3y/A4XsBDt+XxPmPDBRLEJsOkJWUAxYqKfvISspBtpKiJjxIVFIOAlL5q+VKivLhV6KS8qvlSsov2i60koKs1yGyknLIQiXlF3fBEm9zcFgH/hFTwY8IqPURYCN+I9X6NwG1/gVQ68NJnP/Z+CTS5uAweSqgbQ5qAW0O9gDrhKCLZJuDEAmX8VHibQ6O6oQ7ZibcUYfS5TGBJDwGbMRxMgmPe0jCMNAuSxIeTeL8N0aWTZZsc+AhqMXbHPyug+uPpBBfBbsZfhRAE8nj7w8fLjAn9IKdNLPxhMMF5qRANp4EIvdPMhv/FDgS/wCy8UQS5z8y0AsMYtMp8gJzysIF5gR5gTnNXmDUhKeJC8xpQCXOWL7AKB/OEBeYM5YvMCe1XegFBlmvv8gLzF8WLjAnwW8JzRGVvdlBI7Otf+vAP2sq+N8OPHVWQMHPAptzjlTwcwIKfhJQ8L+TOP9dfKJ+7qTw4+8kPNn+DjOZvdj1B2HXDMuvVCrOBJCtrXpWcSLa5mCva4z8d/nzyufq6/jfgdgDEDEww6c2B5Yw1hxB3P+PFsHzlyP3n/eB+y/oBbtonhoXHLj/osCpcRGI8n/JU+NfgVPjPHBqXEji/EcGqoaITZdI7r9kgfsvkNyfIzmMCdUfo9yv/ia7Z40RCCTb5X7lg5oD5f5AMhaMqF0XtV0o9yPrdQXgQ+bgVX8nzf0XfeD+nDrwr0zOEexgzuSs3H9lcvgKfiWwObmSOQXPlRy+gl8EFDxnMue/i0809+dMxpMtZ5jJ7MWu8wT3z7Lc5kDZ9U8S3ubgD4DN/wFO0/PeP3cDcCcKzPKpzYGl92nMEcTxV2lRy50cguNdRgDgeNFTIHeylQULeQpcrRcsj3kKqP9gcnwegVMgD6CY15CnwDUCp0DuZO+nwNXJnP/IQDkesSlvMsfxeZPlOf7qZI7jr2U5Xk14LcHx1wIcn88yxysf8hEcn88yx+fRdqEcj6zXdSTHX2eB4/OAiGeOqOzNDhqZbc2vA/96U8HzO3D89QIKfj2wOQVIBS8goOB5AAXPn8z57+IT9VMuhR8Zm5r57zw5TcyVm7gzzI1wTd6Ns9WzVyXjCTvXpzYHllDPHEFsfIOOqYKXIxsX9IGNC+kFK2wqayEHNi4soKyFARW6kVTWGwWUtSCgrIWSOf+RgaoLYtNNJBvfZIGNC5FsXIRlYzVhEYKNiwBsXNQyGysfihJsXNQyGxfWdqFsjKzXzSQb32yBjQv7wMbFdODfYip4MQc2vkVAwW8BNqc4qeDFBRS8MKDgxZI5/118otm4GMnGaJsDNdcNyZhtBUGWVrXcuT61OSgIikPGuDW708TLhLcSkF4izBPCi10lInjhKpGMIwvywn6UEEa5zVMQ2JeS3m2i2hwon0sSF9nbkv1JvrMBLvlKscmnJixFJF9py8mn7CotlHxuj6skUhsu+E5PljW4HVivWRFqc4Ds4R0AujO2qP1G5lDreQcRH5JtDmr70OagjPb5TvWvJIff6UMlpax25i6Tw8s6VFLuEuDwu4CIL0dyeDkBDr8T4PCyyZz/yECxBLGpPFlJKW+hklKWrKRUYCspasIKRCWlAiCVd1uupCgf7iYqKXdbrqTcpe1CKynIelUkKykVLVRS7nIXLPE2B9E68GNMBY8RUOsYYCNiSbWOFVDruwC1jk7m/M/GJ5E2B9HkqYC2OagNtDkoA6wTgi6SbQ5CJFzGR4m3OYjTCRdvJlycQ+kyXiAJ44GNSCCTMMFDEoaBdlmSMC6Z898YWTZZss2Bh6AWb3OQqIMrKTnEV8FuhscBaCJ5/CX5cIFJ1guWYmZjssMFJkUgG1OAyE0lszFV4EhMArIxOZnzHxnoBQaxKY28wKRZuMAkkxeYdPYCoyZMJy4w6YBKVLJ8gVE+VCIuMJUsX2BStF3oBQZZr3vIC8w9Fi4wKeC3hOaIyt7soJHZ1so68KuYCl7ZgaeqCCh4FWBzqpIKXlVAwVMABa+czPnv4hP1cyeFH5WT8WSrHGYye7EribBrseVXKhVnAsjWVj2rOBFtc3Cna4z8d/nzyufq6/hEIPYARAws9qnNgSWMNUcQ99+rRbDa5cj91Xzg/up6wWqYp0Z1B+6vIXBq1ACi/D7y1LhP4NSoBpwa1ZM5/5GBqiFiU02S+2ta4P7qJPfXYrlfTViL4P5agErUtsz9yofaBPfXtsz9NbRdKPcj63U/yf33W+D+Gj5wfx0d+HVNBa/jwP11BRS8LrA59UgFryeg4DUABa+TzPnv4hPN/XUIvq4TAe6vRti11HKbA2XXvcl4m4MkgM3vBeKjmvfP3QDciQJLfWpzYOl9GnMEcfwDWtTqh+J4lxEAOF70FKjvA8c30AvW0DwFGjhwfEOBU6AhkBEPkqfAgwKnQH3gFGiQzPmPDJTjEZsakRzfyALHNyA5vjHL8WrCxgTHNwY4volljlc+NCE4volljm+o7UI5Hlmvh0iOf8gCxzf0geOb6sB/2FTwpg4c/7CAgj8MbE4zUsGbCSh4Q0DBmyZz/rv4RP2US+FHxqZm/jtPThNz1SfYfEWEa/JunK2efSAZT9gVPrU5sIR65ghi40d0TDW/HNm4uQ9s3EIvWEtTWVs4sHFLAWVtCajQo6SyPiqgrM0BZW2RzPmPDFRdEJseI9n4MQts3IJk41YsG6sJWxFs3Apg49aW2Vj50Jpg49aW2biltgtlY2S9HifZ+HELbNzSBzZuowO/rangbRzYuK2AgrcFNqcdqeDtBBS8JaDgbZI5/118otm4DcnGaJsDNdcjyZhtzUGWVrXcFT61OWgOikPGeCK708TLhE8QkP5kmCeEF7uejOCF68lkHFmQF/bbC2GU2zzNAZs6eLeJanOgfO5AXGSfSvYn+c4FuOTryCafmrAjkXydLCefsquTUPK5Pa6SSG244Ds9WdagM/Ds0gi1OUD28GkA3Rlb1H4jc6j1fJqID8k2B/f70Oagi/a5q/pXksO7+lBJ6aadecbk8G4OlZRnBDj8GSDiu5Mc3l2Aw7sCHN4tmfMfGSiWIDb1ICspPSxUUrqRlZSebCVFTdiTqKT0BKTyWcuVFOXDs0Ql5VnLlZRntF1oJQVZr15kJaWXhUrKM+6CJd7m4Dkd+L1NBe8toNa9gY14nlTr5wXU+hlArZ9L5vzPxieRNgfPkacC2ubgfqDNQRdgnRB0kWxzECLhMj5KvM1BH51wfc2E6+NQuuwrkIR9gY3oRyZhPw9JGAbaZUnCPsmc/8bIssmSbQ48BLV4m4MXdHD1Tw7xVbCb4X0ANJE8/vr7cIF5US/YADMbX3S4wAwQyMYBQOS+RGbjSwJHYn8gG19M5vxHBnqBQWwaSF5gBlq4wLxIXmBeZi8wasKXiQvMy4BKDLJ8gVE+DCIuMIMsX2AGaLvQCwyyXq+QF5hXLFxgBoDfEpojKnuzg0ZmW1/VgT/YVPBXHXhqsICCDwY2Zwip4EMEFHwAoOCvJnP+u/hE/dxJ4ceryXiyvRpmMnuxqz9h1zrLr1QqzgSQra16VnEi2uagq2uM/Hf588rn6uv4F4DYAxAxsM6nNgeWMNYcQdz/mhbBoZcj9w/1gftf1ws2zDw1Xnfg/mECp8YwIMrfIE+NNwROjaHAqfF6Muc/MlA1RGwaTnL/cAvc/zrJ/W+y3K8mfJPg/jcBlRhhmfuVDyMI7h9hmfuHabtQ7kfW6y2S+9+ywP3DfOD+kTrwR5kKPtKB+0cJKPgoYHNGkwo+WkDBhwEKPjKZ89/FJ5r7RxJ8PTIC3D+UsGu95TYHyq7XkvE2B/0BNn8NiI+h3j93A3AnCqz3qc2BpfdpzBHE8W9rURsTiuNdRgDgeNFTYIwPHD9WL9g48xQY68Dx4wROgXFARrxDngLvCJwCY4BTYGwy5z8yUI5HbBpPcvx4Cxw/luT4CSzHqwknEBw/AeD4iZY5XvkwkeD4iZY5fpy2C+V4ZL3eJTn+XQscP84Hjp+kA/89U8EnOXD8ewIK/h6wOZNJBZ8soODjAAWflMz57+IT9VMuhR8Zm5r57zw5Tcw1hmDzTRGuybtxtnr27WQ8YTf51ObAEuqZI4iN39cxNeVyZOMpPrDxVL1g00xlnerAxtMElHUaoEIfkMr6gYCyTgGUdWoy5z8yUHVBbPqQZOMPLbDxVJKNp7NsrCacTrDxdICNZ1hmY+XDDIKNZ1hm42naLpSNkfWaSbLxTAtsPM0HNp6lA3+2qeCzHNh4toCCzwY2Zw6p4HMEFHwaoOCzkjn/XXyi2XgWycZomwM11/vJmG1TQJZWtdxNPrU5mAKKQ8b4KLvTxMuEHxGQPjfME8KLXXMjeOGam4wjC/LC/jwhjHKbZwpg03zvNlFtDpTP84mL7MfJ/iTfPwEu+RawyacmXEAk30LLyafsWiiUfG6PqyRSGy74Tk+WNVgEPLs+Qm0OkD38BEB3xha138gcaj0/IeJDss1BHR/aHCzWPi9R/0py+BIfKilLtTOfmhy+1KGS8qkAh38KRPwyksOXCXD4EoDDlyZz/iMDxRLEpuVkJWW5hUrKUrKSsoKtpKgJVxCVlBWAVH5muZKifPiMqKR8ZrmS8qm2C62kIOu1kqykrLRQSfnUXbDE2xys0oG/2lTw1QJqvRrYiM9Jtf5cQK0/BdR6VTLnfzY+ibQ5WEWeCmibgzpAm4PFwDoh6CLZ5iBEwmV8lHibgzU64daaCbfGoXS5ViAJ1wIbsY5MwnUekjAMtMuShGuSOf+NkWWTJdsceAhq8TYHX+jgWp8c4qtgN8PXAGgiefyt9+ECs0Ev2EYzGzc4XGA2CmTjRiByvySz8UuBI3E9kI0bkjn/kYFeYBCbNpEXmE0WLjAbyAvMZvYCoybcTFxgNgMqscXyBUb5sIW4wGyxfIHZqO1CLzDIen1FXmC+snCB2Qh+S2iOqOzNDhqZbf1aB/43poJ/7cBT3wgo+DfA5mwlFXyrgIJvBBT862TOfxefqJ87Kfz4OhlPtq/DTGYvdq0n7Npm+ZVKxZkAsrVVzypORNscLHGNkf8uf175XH0d/wXyxQpw6Gzzqc2BJYw1RxD3f6tFcNvlyP3bfOD+7/SCbTdPje8cuH+7wKmxHYjy78lT43uBU2MbcGp8l8z5jwxUDRGbfiC5/wcL3P8dyf0/styvJvyR4P4fAZXYYZn7lQ87CO7fYZn7t2u7UO5H1usnkvt/ssD9233g/p068HeZCr7Tgft3CSj4LmBzdpMKvltAwbcDCr4zmfPfxSea+3cSfL0zAty/jbBru+U2B8qub5PxNgfrATb/FoiPbd4/dwNwJwps96nNgaX3acwRxPE/a1HbE4rjXUYA4HjRU2CPDxy/Vy/YPvMU2OvA8fsEToF9QEb8Qp4CvwicAnuAU2BvMuc/MlCOR2zaT3L8fgscv5fk+AMsx6sJDxAcfwDg+IOWOV75cJDg+IOWOX6ftgvleGS9fiU5/lcLHL/PB44/pAP/sKnghxw4/rCAgh8GNucIqeBHBBR8H6Dgh5I5/118on7KpfAjY1Mz/50np4m59hBsviPCNXk3zlbP/pyMJ+wOn9ocWEI9cwSx8W86po5ejmx81Ac2PqYX7LiprMcc2Pi4gLIeB1Tod1JZfxdQ1qOAsh5L5vxHBqouiE1/kGz8hwU2Pkay8QmWjdWEJwg2PgGw8UnLbKx8OEmw8UnLbHxc24WyMbJef5Js/KcFNj7uAxuf0oF/2lTwUw5sfFpAwU8Dm3OGVPAzAgp+HFDwU8mc/y4+0Wx8imRjtM2Bmuu3ZMy2oyBLq1ruDp/aHBwFxSFj/JXdaeJlwr8ISP87zBPCi11/R/DC9XcyjizIC/tnhTDKbZ6jgE3nvNtEtTlQPp8jLrL/JPuTfOcDXPKdZ5NPTXieSL4LlpNP2XVBKPncHldJpDZc8J2eLGtwEXh2e4TaHCB7+C+A7owtar+ROdR6/kvEh2Sbg7o+tDm4lOFzSg5ZDlcf6PFZxxGV3ecaI7OtgRT9v6XkCGZu9R/MSop6KFwOvyLF+7M5UzgOz5kSPofnSPHO4YEUzn9koFiC2HRlCldJuTJFvpISSOEqKblSwphQ/TFaScnlfSMDVwGbwfqg5nBTHPNzrgKDEbXrCm0XWklB1is34EPm4M2dIl9JucJdsMTbHFytAz+PqeB5BNQ6D7AR15BqfY2AWl8BqPXVKZz/2fgk0ubgavJUQNsc1AXaHFxC7heA/ZJtDkIkXMZHibc5yKsT7loz4fKmZC1dXiuQhNcCAZuPTMJ8HpIwDLTLkoR5Uzj/jZFlkyXbHHgIavE2B9fp4MqfEuKrYDfD8wJoInn85ffhAnO9XrACZjZe73CBKSCQjQWAyL2BzMYbBI7E/EA2Xp/C+Y8M9AKD2FSQvMAUtHCBuZ68wBRiLzBqwkLEBaYQoBKFLV9glA+FiQtMYcsXmALaLvQCg6zXjeQF5kYLF5gC3gVL7Kvgm3TgFzEV/CYHnioioOBFgM0pSip4UQEFLwAo+E0pnP8uPlE/d1L4cVMKnmw3hZnMXuzKT9i1z/IrlYozAWRrq55VnIi2OcjhGiP/Xf688rn6Ov46IPYARAzs86nNgSWMNUcQ99+sRbDY5cj9xXzg/lv0ghU3T41bHLi/uMCpURyI8lvJU+NWgVOjGHBq3JLC+Y8MVA0Rm0qQ3F/CAvffQnJ/FMv9/5uQ4P4oQCVKWuZ+5UNJgvtLWub+4toulPuR9bqN5P7bLHB/cR+4v5QO/NKmgpdy4P7SAgpeGtic20kFv11AwYsDCl4qhfPfxSea+0sRfF0qAtxfjLBrv+U2B8qum1PwNgf5ATa/GYiPYt4/dwNwJwrs96nNgaX3acwRxPF3aFErE4rjXUYA4HjRU6CMDxx/p16wsuYpcKcDx5cVOAXKAhlxF3kK3CVwCpQBToE7Uzj/kYFyPGJTOZLjy1ng+DtJji/PcryasDzB8eUBjq9gmeOVDxUIjq9gmePLartQjkfW626S4++2wPFlfeD4ijrwo00Fr+jA8dECCh4NbE4MqeAxAgpeFlDwiimc/y4+UT/lUviRsamZ/86T08RcZQg2PxThmrwbZ6tn70jBE/aQT20OLKGeOYLYOFbHVNzlyMZxPrBxvF6wBFNZ4x3YOEFAWRMAFUoklTVRQFnjAGWNT+H8RwaqLohNSSQbJ1lg43iSjZNZNlYTJhNsnAywcYplNlY+pBBsnGKZjRO0XSgbI+uVSrJxqgU2TvCBjdN04KebCp7mwMbpAgqeDmxOJVLBKwkoeAKg4GkpnP8uPtFsnEayMdrmQM0Vm4LZFgeytKrlHvKpzUEcKA4Z457sThMvE95DQHrlME8IL3ZVjuCFq3IKjizIC/tVhDDKbZ44wKaq3m2i2hwon6sSF9l7U/xJvgsBLvmqscmnJqxGJF91y8mn7KoulHxuj6skUhsu+E5PljWoATy7P0JtDpA9vA9Ad8YWtd/IHGo97yPiQ7LNQT0f2hzU1D7XUv9KcngtHyoptbUz95scXtuhknK/AIffD0R8HZLD6whweC2Aw2uncP4jA8USxKa6ZCWlroVKSm2yklKPraSoCesRlZR6gFQ+YLmSonx4gKikPGC5knK/tgutpCDrVZ+spNS3UEm5312wxNscNNCB39BU8IYCat0Q2IgHSbV+UECt7wfUukEK5382Pom0OWhAngpom4N6QJuDmsA6Iegi2eYgRMJlfJR4m4NGOuEamwnXyKF02VggCRsDG9GETMImHpIwDLTLkoSNUjj/jZFlkyXbHHgIavE2Bw/p4GqaEuKrYDfDGwFoInn8NfXhAvOwXrBmZjY+7HCBaSaQjc2AyH2EzMZHBI7EpkA2PpzC+Y8M9AKD2NScvMA0t3CBeZi8wLRgLzBqwhbEBaYFoBItLV9glA8tiQtMS8sXmGbaLvQCg6zXo+QF5lELF5hm4LeE5ojK3uygkdnWx3TgtzIV/DEHnmoloOCtgM1pTSp4awEFbwYo+GMpnP8uPlE/d1L48VgKnmyPhZnMXuxqStj1h+VXKhVnAsjWVj2rOBFtc1DLNUb+u/x55XP1dfxDQOwBiBj4w6c2B5Yw1hxB3P+4FsE2lyP3t/GB+9vqBWtnnhptHbi/ncCp0Q6I8ifIU+MJgVOjDXBqtE3h/EcGqoaITU+S3P+kBe5vS3J/e5b71YTtCe5vD6hEB8vcr3zoQHB/B8vc307bhXI/sl5Pkdz/lAXub+cD93fUgd/JVPCODtzfSUDBOwGb05lU8M4CCt4OUPCOKZz/Lj7R3N+R4OuOEeD+NoRdJy23OVB2PZ6CtzloCrD540B8tPH+uRuAO1HgpE9tDiy9T2OOII5/Wotal1Ac7zICAMeLngJdfOD4rnrBupmnQFcHju8mcAp0AzLiGfIUeEbgFOgCnAJdUzj/kYFyPGJTd5Lju1vg+K4kx/dgOV5N2IPg+B4Ax/e0zPHKh54Ex/e0zPHdtF0oxyPr9SzJ8c9a4PhuPnB8Lx34z5kK3suB458TUPDngM3pTSp4bwEF7wYoeK8Uzn8Xn6ifcin8yNjUzH/nyWliri4Em5+JcE3ejbPVs0+n4Al7xqc2B5ZQzxxBbPy8jqk+lyMb9/GBjfvqBetnKmtfBzbuJ6Cs/QAVeoFU1hcElLUPoKx9Uzj/kYGqC2JTf5KN+1tg474kG7/IsrGa8EWCjV8E2HiAZTZWPgwg2HiAZTbup+1C2RhZr5dINn7JAhv384GNB+rAf9lU8IEObPyygIK/DGzOIFLBBwkoeD9AwQemcP67+ESz8UCSjdE2B2qu51Mw2/qALK1quWd8anPQBxSHjPFKdqeJlwlfISD91TBPCC92vRrBC9erKTiyIC/sDxbCKLd5+gA2DfFuE9XmQPk8hLjIvpbiT/JdDHDJN5RNPjXhUCL5XrecfMqu14WSz+1xlURqwwXf6cmyBsOAZ09GqM0BsodvAOjO2KL2G5lDrecbRHxItjl4wIc2B8O1z2+qfyU5/E0fKikjtDNvmRw+wqGS8pYAh78FRPxIksNHCnD4mwCHj0jh/EcGiiWITaPISsooC5WUEWQlZTRbSVETjiYqKaMBqXzbciVF+fA2UUl523Il5S1tF1pJQdZrDFlJGWOhkvKWu2CJtzkYqwN/nKng4wTUehywEe+Qav2OgFq/Baj12BTO/2x8EmlzMJY8FdA2Bw8AbQ6GA+uEoItkm4MQCZfxUeJtDsbrhJtgJtx4h9LlBIEknABsxEQyCSd6SMIw0C5LEo5P4fw3RpZNlmxz4CGoxdscvKuDa1JKiK+C3QwfD6CJ5PE3yYcLzHt6wSab2fiewwVmskA2TgYi930yG98XOBInAdn4XgrnPzLQCwxi0xTyAjPFwgXmPfICM5W9wKgJpxIXmKmASkyzfIFRPkwjLjDTLF9gJmu70AsMsl4fkBeYDyxcYCaD3xKaIyp7s4NGZls/1IE/3VTwDx14arqAgk8HNmcGqeAzBBR8MqDgH6Zw/rv4RP3cSeHHhyl4sn0YZjJ7sWsSYddFy69UKs4EkK2telZxItrm4E3XGPnv8ueVz9XX8e8CsQcgYuCiT20OLGGsOYK4f6YWwVmXI/fP8oH7Z+sFm2OeGrMduH+OwKkxB4jyj8hT4yOBU2MWcGrMTuH8RwaqhohNc0nun2uB+2eT3D+P5X414TyC++cBKjHfMvcrH+YT3D/fMvfP0Xah3I+s18ck939sgfvn+MD9C3TgLzQVfIED9y8UUPCFwOYsIhV8kYCCzwEUfEEK57+LTzT3LyD4ekEEuH8WYdcly20OlF0zU/A2B5MANp8JxMcs75+7AbgTBS751ObA0vs05gji+E+0qC0OxfEuIwBwvOgpsNgHjl+iF2ypeQosceD4pQKnwFIgIz4lT4FPBU6BxcApsCSF8x8ZKMcjNi0jOX6ZBY5fQnL8cpbj1YTLCY5fDnD8Csscr3xYQXD8Csscv1TbhXI8sl6fkRz/mQWOX+oDx6/Ugb/KVPCVDhy/SkDBVwGbs5pU8NUCCr4UUPCVKZz/Lj5RP+VS+JGxqZn/zpPTxFyLCTbPeT9mV7g1eTfOVs9+koInLOKHZI3bEuqZI4iNP9cxteZyZOM1PrDxWr1g60xlXevAxusElHUdoEJfkMr6hYCyrgGUdW0K5z8yUHVBbFpPsvF6C2y8lmTjDSwbqwk3EGy8AWDjjZbZWPmwkWDjjZbZeJ22C2VjZL2+JNn4SwtsvM4HNt6kA3+zqeCbHNh4s4CCbwY2Zwup4FsEFHwdoOCbUjj/XXyi2XgTycZomwM11+cpmG1rQJZWtVyUQb2eJi4DQqrM832V3WniZcKvCEj/OswTwotdX0fwwvV1Co4syAv73whhlNs8awCbtnq3iWpzoHzeSlxkv03xJ/n+DXDJt41NPjXhNiL5vrOcfMqu74SSz+1xlURqwwXf6cmyBtuBZy9FqM0BsoffA+jO2KL2G5lDref3RHxItjmo70Obgx+0zz+qfyU5/EcfKik7tDM/mRy+w6GS8pMAh/8ERPxOksN3CnD4jwCH70jh/EcGiiWITbvISsouC5WUHWQlZTdbSVET7iYqKbsBqfzZciVF+fAzUUn52XIl5SdtF1pJQdZrD1lJ2WOhkvKTu2CJtznYqwN/n6ng+wTUeh+wEb+Qav2LgFr/BKj13hTO/2x8EmlzsJc8FdA2B/WBNgc/AOuEoItkm4MQCZfxUeJtDvbrhDtgJtx+h9LlAYEkPABsxEEyCQ96SMIw0C5LEu5P4fw3RpZNlmxz4CGoxdsc/KqD61BKiK+C3QzfD6CJ5PF3yIcLzGG9YEfMbDzscIE5IpCNR4DI/Y3Mxt8EjsRDQDYeTuH8RwZ6gUFsOkpeYI5auMAcJi8wx9gLjJrwGHGBOQaoxHHLFxjlw3HiAnPc8gXmiLYLvcAg6/U7eYH53cIF5gj4LaE5orI3O2hktvUPHfgnTAX/w4GnTggo+Algc06SCn5SQMGPAAr+Rwrnv4tP1M+dFH78kYIn2x9hJrMXuw4RduW1/Eql4kwA2dqqZxUnom0OfnSNkf8uf175XH0d/ysQewAiBjysu5U2B5Yw1hxB3P+nFsFTlyP3n/KB+0/rBTtjnhqnHbj/jMCpcQaI8r/IU+MvgVPjFHBqnE7h/EcGqoaITX+T3P+3Be4/TXL/WZb71YRnCe4/C6jEOcvcr3w4R3D/Ocvcf0bbhXI/sl7/kNz/jwXuP+MD95/XgX/BVPDzDtx/QUDBLwCbc5FU8IsCCn4GUPDzKZz/Lj7R3H+e4OvzEeD+U4Rd+e63atf/OP7PFLzNwSGAzf8E4uOU98/dANyJAvn8+SmXrfdpzBHE8f9qUbsUiuNdRgDgeNFT4JIPHJ8jVT+UmiNY8dV/MDlePRTuKaA+w+uzV6Ryp8AVqeGfApeAUyBHKuc/MlCOR2zKmcpxfM5UeY7Pkcpx/JWpYUyo/hjl+Cu9b2QgF7AZrA9qDpTjc4HBiNoV0HahHI+s11WAD5mD96pUeY4PeBcsMY7PrQP/alPBc6dm5firBRT8amBz8pAKnkdAwUOcNFkUPHcq57+LT9RPuRR+ZGxq5r/z5DQx1yWCzQtEuCbvxtnq2X9T8IQt4FObg0s+sPE1Oqbypl6GbJw31cqChVTWa/WC5TOV9VoHNs4noKz5ABW6jlTW6wSUNS+grNemcv4jA1UXxKb8JBvnt8DG15JsfD3LxmrC6wk2vh5g4wKW2Vj5UIBg4wKW2TiftgtlY2S9biDZ+AYLbJzPBzYuqAO/kKngBR3YuJCAghcCNqcwqeCFBRQ8H6DgBVM5/118otm4IMnGaJsDNdc1qZhteVMxn1Qtt4BPbQ7yguKQMW7M7jTxMuGNqfjf3RTmCeHFrpsieOG6KRVHFuSF/SJCGOX6YhawL0W920S1OVA+F03F9+PmVH+STym6x2eD5ivGJp+asBiRfLdYTj5l1y1Cyef2uEoiteGC7/RkWYPiyH0HrKJkDDRRkT28FUB3xha138gcaj1vJeJDss1BAx/aHJTQPkepfyU5PMqHSkpJ7cxtJoeXdKik3CbA4bcBEV+K5PBSAhweBXB4yVTOf2SgWILYVJqspJS2UEkpSVZSbmcrKWrC24lKyu2AVN5huZKifLiDqKTcYbmScpu2C62kIOtVhqyklLFQSbnNXbDE2xzcqQO/rKngZQXUuiywEXeRan2XgFrfBqj1namc/9n4JNLm4E7yVEDbHDQA2hyUANYJQRfJNgchEi7jo8TbHJTTCVfeTLhyDqXL8gJJWB7YiApkElbwkIRhoF2WJCyXyvlvjCybLNnmwENQi7c5uFsHV8XUEF8FuxleDkATyeOvog8XmGi9YDFmNkY7XGBiBLIxBojcWDIbYwWOxIpANkancv4jA73AIDbFkReYOAsXmGjyAhPPXmDUhPHEBSYeUIkEyxcY5UMCcYFJsHyBidF2oRcYZL0SyQtMooULTAz4LaE5orI3O2hktjVJB36yqeBJDjyVLKDgycDmpJAKniKg4DGAgielcv67+ET93EnhR1IqnmxJYSazF7sqEnYVtfxKpeJMANnaqmcVJ6JtDqJcY+S/y59XPldfx98NxB6AiIGiPrU5sISx5gji/lQtgmmXI/en+cD96XrBKpmnRroD91cSODUqAVF+D3lq3CNwaqQBp0Z6Kuc/MlA1RGyqTHJ/ZQvcn05yfxWW+9WEVQjurwKoRFXL3K98qEpwf1XL3F9J24VyP7Je95Lcf68F7q/kA/dX04Ff3VTwag7cX11AwasDm1ODVPAaAgpeCVDwaqmc/y4+0dxfjeDrahHg/jTCrmKW2xwou1JT8TYHFQE2TwXiI837524A7kSBYj61ObD0Po05gjj+Pi1qNUNxvMsIABwvegrU9IHja+kFq22eArUcOL62wClQG8iI+8lT4H6BU6AmcArUSuX8RwbK8YhNdUiOr2OB42uRHF+X5Xg1YV2C4+sCHF/PMscrH+oRHF/PMsfX1nahHI+s1wMkxz9ggeNr+8Dx9XXgNzAVvL4DxzcQUPAGwOY0JBW8oYCC1wYUvH4q57+LT9RPuRR+ZGxq5r/z5DQxV02CzUtEuCbvxtnq2ftS8YQt4VObA0uoZ44gNn5Qx1Sjy5GNG/nAxo31gjUxlbWxAxs3EVDWJoAKPUQq60MCytoIUNbGqZz/yEDVBbGpKcnGTS2wcWOSjR9m2VhN+DDBxg8DbNzMMhsrH5oRbNzMMhs30XahbIys1yMkGz9igY2b+MDGzXXgtzAVvLkDG7cQUPAWwOa0JBW8pYCCNwEUvHkq57+LTzQbNyfZGG1zoOZ6MBWzrRHI0qqWW8KnNgeNQHHIGI9md5p4mfBRAtIfC/OE8GLXYxG8cD2WiiML8sJ+KyGMcpunEWBTa+82UW0OlM+tiYvs46n+JF+OK7jka8Mmn5qwDZF8bS0nn7KrrVDyuT2ukkhtuOA7PVnWoB3wbLEItTlA9vAJAN0ZW9QfIHOo9XyCiA/JNgcNr+D2KYe3eRzbHDypfW6v/pXk8PY+VFI6aGeeMjm8g0Ml5SkBDn8KiPiOJId3FODw9gCHd0jl/EcGiiWITZ3ISkonC5WUDmQlpTNbSVETdiYqKZ0BqXzaciVF+fA0UUl52nIl5SltF1pJQdarC1lJ6WKhkvKUu2CJtznoqgO/m6ng3QTUuhuwEc+Qav2MgFo/Bah111TO/2x8Emlz0JU8FdA2Bw2BNgdPAuuEoItkm4MQCZfxUeJtDrrrhOthJlx3h9JlD4Ek7AFsRE8yCXt6SMIw0C5LEnZP5fw3RpZNlmxz4CGoxdscPKuDq1dqiK+C3QzvDqCJ5PHXy4cLzHN6wXqb2ficwwWmt0A29gYi93kyG58XOBJ7Adn4XCrnPzLQCwxiUx/yAtPHwgXmOfIC05e9wKgJ+xIXmL6ASvSzfIFRPvQjLjD9LF9gemu70AsMsl4vkBeYFyxcYHqD3xKaIyp7s4NGZlv768B/0VTw/g489aKAgr8IbM4AUsEHCCh4b0DB+6dy/rv4RP3cSeFH/1Q82fqHmcxe7OpF2FXG8iuVijMBZGurnlWciLY5aO8aI/9d/rzyufo6/lkg9gBEDJTxqc2BJYw1RxD3v6RFcODlyP0DfeD+l/WCDTJPjZcduH+QwKkxCIjyV8hT4xWBU2MgcGq8nMr5jwxUDRGbXiW5/1UL3P8yyf2DWe5XEw4muH8woBJDLHO/8mEIwf1DLHP/IG0Xyv3Ier1Gcv9rFrh/kA/cP1QH/uumgg914P7XBRT8dWBzhpEKPkxAwQcBCj40lfPfxSea+4cSfD00Atw/kLCrrOU2B8qul1LxNge9ADZ/CYiPgd4/dwNwJwqU9anNgaX3acwRxPFvaFEbHorjXUYA4HjRU2C4Dxz/pl6wEeYp8KYDx48QOAVGABnxFnkKvCVwCgwHToE3Uzn/kYFyPGLTSJLjR1rg+DdJjh/FcryacBTB8aMAjh9tmeOVD6MJjh9tmeNHaLtQjkfW622S49+2wPEjfOD4MTrwx5oKPsaB48cKKPhYYHPGkQo+TkDBRwAKPiaV89/FJ+qnXAo/MjY18995cpqYazjB5hUiXJN342z17BupeMJW8KnNgSXUM0cQG7+jY2r85cjG431g4wl6wSaayjrBgY0nCijrRECF3iWV9V0BZR0PKOuEVM5/ZKDqgtg0iWTjSRbYeALJxu+xbKwmfI9g4/cANp5smY2VD5MJNp5smY0nartQNkbW632Sjd+3wMYTfWDjKTrwp5oKPsWBjacKKPhUYHOmkQo+TUDBJwIKPiWV89/FJ5qNp5BsjLY5UHO9k4rZNh5kaVXLreBTm4PxoDhkjA+yO028TPgBAekfhnlCeLHrwwheuD5MxZEFeWF/uhBGuc0zHrBphnebqDYHyucZxEV2Zqo/yRcg2xzMYpNPTTiLSL7ZlpNP2TVbKPncHldJpDZc8J2eLGswB3i2bITaHCB7+BGA7owtar+ROdR6fkTEh2Sbgwev4PYph7d5HNsczNU+z1P/SnL4PB8qKfO1Mx+bHD7foZLysQCHfwxE/AKSwxcIcPg8gMPnp3L+IwPFEsSmhWQlZaGFSsp8spKyiK2kqAkXEZWURYBUfmK5kqJ8+ISopHxiuZLysbYLraQg67WYrKQstlBJ+dhdsMTbHCzRgb/UVPClAmq9FNiIT0m1/lRArT8G1HpJKud/Nj6JtDlYQp4KaJuDB4E2B3OBdULQRbLNQYiEy/go8TYHy3TCLTcTbplD6XK5QBIuBzZiBZmEKzwkYRholyUJl6Vy/hsjyyZLtjnwENTibQ4+08G1MjXEV8Fuhi8D0ETy+FvpwwVmlV6w1WY2rnK4wKwWyMbVQOR+Tmbj5wJH4kogG1elcv4jA73AIDatIS8wayxcYFaRF5i17AVGTbiWuMCsBVRineULjPJhHXGBWWf5ArNa24VeYJD1+oK8wHxh4QKzGvyW0BxR2ZsdNDLbul4H/gZTwdc78NQGAQXfAGzORlLBNwoo+GpAwdencv67+ET93Enhx/pUPNnWh5nMXuxaSdiVYPmVSsWZALK1Vc8qTkTbHMxzjZH/Ln9e+Vx9Hf8ZEHsAIgYSfGpzYAljzRHE/V9qEdx0OXL/Jh+4f7NesC3mqbHZgfu3CJwaW4Ao/4o8Nb4SODU2AafG5lTOf2SgaojY9DXJ/V9b4P7NJPd/w3K/mvAbgvu/AVRiq2XuVz5sJbh/q2Xu36LtQrkfWa9vSe7/1gL3b/GB+7fpwP/OVPBtDtz/nYCCfwdsznZSwbcLKPgWQMG3pXL+u/hEc/82gq+3RYD7NxF2JVluc6Ds+jIVb3OwEmDzL4H42OT9czcAd6JAkk9tDiy9T2OOII7/XovaD6E43mUEAI4XPQV+8IHjf9QLtsM8BX504PgdAqfADiAjfiJPgZ8EToEfgFPgx1TOf2SgHI/YtJPk+J0WOP5HkuN3sRyvJtxFcPwugON3W+Z45cNuguN3W+b4HdoulOOR9fqZ5PifLXD8Dh84fo8O/L2mgu9x4Pi9Agq+F9icfaSC7xNQ8B2Agu9J5fx38Yn6KZfCj4xNzfx3npwm5vqBYPO0CNfk3ThbPft9Kp6waT61ObCEeuYIYuNfdEztvxzZeL8PbHxAL9hBU1kPOLDxQQFlPQio0K+ksv4qoKz7AWU9kMr5jwxUXRCbDpFsfMgCGx8g2fgwy8ZqwsMEGx8G2PiIZTZWPhwh2PiIZTY+qO1C2RhZr99INv7NAhsf9IGNj+rAP2Yq+FEHNj4moODHgM05Tir4cQEFPwgo+NFUzn8Xn2g2PkqyMdrmQM31Sypm236QpVUtN82nNgf7QXHIGL9nd5p4mfB3AtL/CPOE8GLXHxG8cP2RiiML8sL+CSGMcptnP2DTSe82UW0OlM8niYvsn6n+JN8VZJuDU2zyqQlPEcl32nLyKbtOCyWf2+MqidSGC77Tk2UNzgDPJkWozQGyh38B6M7YovYbmUOt519EfEi2OWh0BbdPObzN49jm4G/t81n1rySHn/WhknJOO/OPyeHnHCop/whw+D9AxJ8nOfy8AIefBTj8XCrnPzJQLEFsukBWUi5YqKScIyspF9lKiprwIlFJuQhI5b+WKynKh3+JSsq/lisp/2i70EoKsl6XyErKJQuVlH/cBUu8zUGONP1QWo5gB9X/EK5aq8/w+uwVaZxaX5EWvlr/A6h1jjTO/2x8EmlzkCONOxXQNgeNgDYHfwNJiKCLZJuDEAmX8VHibQ5y6oS70kw49R8Cxv92pUASXgkEbC4yCXN5SMIw0C5LEuZM4/w3RpZNlmxz4CGoxdscXKWDK3daiK+C3QzP6V1NRH/ulJtUsRyh5wmZjVfrBctjZqP6D+YFJo9ANuYBIvcaMhuvETgSc6d5z8ar0zj/kYFeYBCb8qZxF5i8afIXmKvTuAvMtWlhTKj+GL3AXAuoRD5gM1gf8qXhF5h8YDCiduXRdqEXGGS9rgN8yBy816XJX2DyeBcssa+C8+vAv95U8PwOPHW9gIJfD2xOAVLBCwgoeB5AwfOncf67+ET93EnhR/40PNnyh5nMXuzKTdhVzfIrlYozAWRrq55VnIi2OTjreqH77/Lnlc/V1/FXAbEHIGKgmk9tDixhrDmCuP8GLYIFL0fuL+gD9xfSC1bYPDUKOXB/YYFTozAQ5TeSp8aNAqdGQeDUKJTG+Y8MVA0Rm24iuf8mC9xfiOT+Iiz3qwmLENxfBFCJopa5X/lQlOD+opa5v7C2C+V+ZL1uJrn/ZgvcX9gH7i+mA/8WU8GLOXD/LQIKfguwOcVJBS8uoOCFAQUvlsb57+ITzf3FCL4uFgHuL0jYVcNymwNl1w1peJuD3ACb3wDER0Hvn7sBuBMFavjU5sDS+zTmCOL4W7WolQjF8S4jAHC86ClQwgeOj9ILVtI8BaIcOL6kwClQEsiI28hT4DaBU6AEcApEpXH+IwPleMSmUiTHl7LA8VEkx5dmOV5NWJrg+NIAx99umeOVD7cTHH+7ZY4vqe1COR5ZrztIjr/DAseX9IHjy+jAv9NU8DIOHH+ngILfCWxOWVLBywooeElAwcukcf67+ET9lEvhR8amZv47T04Tc5Ug2Lx2hGvybpytnr01DU/Y2j61ObCEeuYIYuO7dEyVuxzZuJwPbFxeL1gFU1nLO7BxBQFlrQCo0N2kst4toKzlAGUtn8b5jwxUXRCbKpJsXNECG5cn2TiaZWM1YTTBxtEAG8dYZmPlQwzBxjGW2biCtgtlY2S9Ykk2jrXAxhV8YOM4HfjxpoLHObBxvICCxwObk0AqeIKAglcAFDwujfPfxSeajeNINkbbHKi57krDbCsHsrSq5db2qc1BOVAcMkZidqeJlwkTCUhPCvOE8GJXUgQvXElpOLIgL+wnC2GU2zzlAJtSvNtEtTlQPqcQF9nUNH+SLyfZ5iCNTT41YRqRfOmWk0/ZlS6UfK5zpf3/DRd8pyfLGlQCnq0RoTYHyB7eA6A7Y4vab2QOtZ73EPEh2eag8RXcPuXwNo9jm4PK2ucq6l9JDq/iQyWlqnbmXpPDqzpUUu4V4PB7gYivRnJ4NQEOrwJweNU0zn9koFiC2FSdrKRUt1BJqUpWUmqwlRQ1YQ2iklIDkMr7LFdSlA/3EZWU+yxXUu7VdqGVFGS9apKVlJoWKin3uguWeJuDWjrwa5sKXltArWsDG3E/qdb3C6j1vYBa10rj/M/GJ5E2B7XIUwFtc9AYaHNQGVgnBF0k2xyESLiMjxJvc1BHJ1xdM+HqOJQu6wokYV1gI+qRSVjPQxKGgXZZkrBOGue/MbJssmSbAw9BLd7m4AEdXPXTQnwV7GZ4HQBNJI+/+j5cYBroBWtoZmMDhwtMQ4FsbAhE7oNkNj4ocCTWB7KxQRrnPzLQCwxiUyPyAtPIwgWmAXmBacxeYNSEjYkLTGNAJZpYvsAoH5oQF5gmli8wDbVd6AUGWa+HyAvMQxYuMA3BbwnNEZW92UEjs61NdeA/bCp4UweeelhAwR8GNqcZqeDNBBS8IaDgTdM4/118on7upPCjaRqebE3DTGYvdtUn7Gpo+ZVKxZkAsrVVzypORNscVHGNkf8uf175XH0d/wAQewAiBhr61ObAEsaaI4j7H9Ei2Pxy5P7mPnB/C71gLc1To4UD97cUODVaAlH+KHlqPCpwajQHTo0WaZz/yEDVELHpMZL7H7PA/S1I7m/Fcr+asBXB/a0AlWhtmfuVD60J7m9tmftbartQ7kfW63GS+x+3wP0tfeD+Njrw25oK3saB+9sKKHhbYHPakQreTkDBWwIK3iaN89/FJ5r72xB83SYC3N+csKuR5TYHyq5H0vA2B/UBNn8EiI/m3j93A3AnCjTyqc2BpfdpzBHE8U9oUXsyFMe7jADA8aKnwJM+cHx7vWAdzFOgvQPHdxA4BToAGfEUeQo8JXAKPAmcAu3TOP+RgXI8YlNHkuM7WuD49iTHd2I5Xk3YieD4TgDHd7bM8cqHzgTHd7bM8R20XSjHI+v1NMnxT1vg+A4+cHwXHfhdTQXv4sDxXQUUvCuwOd1IBe8moOAdAAXvksb57+IT9VMuhR8Zm5r57zw5Tcz1JPNdQYRr8m6crZ59Ig1P2KY+tTmwhHrmCGLjZ3RMdb8c2bi7D2zcQy9YT1NZeziwcU8BZe0JqNCzpLI+K6Cs3QFl7ZHG+Y8MVF0Qm3qRbNzLAhv3INn4OZaN1YTPEWz8HMDGvS2zsfKhN8HGvS2zcU9tF8rGyHo9T7Lx8xbYuKcPbNxHB35fU8H7OLBxXwEF7wtsTj9SwfsJKHhPQMH7pHH+u/hEs3Efko3RNgdqrmfSMNu6gyytarlNfWpz0B0Uh4zxQnaniZcJXyAgvX+YJ4QXu/pH8MLVPw1HFuSF/ReFMMptnu6ATQO820S1OVA+DyAusi+l+ZN8V5JtDgayyacmHEgk38uWk0/Z9bJQ8rk9rpJIbbjgOz1Z1mAQ8GyjCLU5QPbwFQDdGVvUfiNzqPV8hYgPyTYHTa7g9imHt3kc2xy8qn0erP6V5PDBPlRShmhnXjM5fIhDJeU1AQ5/DYj4oSSHDxXg8MEAhw9J4/xHBooliE2vk5WU1y1UUoaQlZRhbCVFTTiMqKQMA6TyDcuVFOXDG0Ql5Q3LlZTXtF1oJQVZr+FkJWW4hUrKa+6CJd7m4E0d+CNMBR8hoNYjgI14i1TrtwTU+jVArd9M4/zPxieRNgdvkqcC2uagCdDm4FVgnRB0kWxzECLhMj5KvM3BSJ1wo8yEG+lQuhwlkISjgI0YTSbhaA9JGAbaZUnCkWmc/8bIssmSbQ48BLV4m4O3dXCNSQvxVbCb4SMBNJE8/sb4cIEZqxdsnJmNYx0uMOMEsnEcELnvkNn4jsCROAbIxrFpnP/IQC8wiE3jyQvMeAsXmLHkBWYCe4FRE04gLjATAJWYaPkCo3yYSFxgJlq+wIzTdqEXGGS93iUvMO9auMCMA78lNEdU9mYHjcy2TtKB/56p4JMceOo9AQV/D9icyaSCTxZQ8HGAgk9K4/x38Yn6uZPCj0lpeLJNCjOZvdg1hrDrMcuvVCrOBJCtrXpWcSLa5mCwa4z8d/nzyufq6/i3gdgDEDHwmE9tDixhrDmCuP99LYJTLkfun+ID90/VCzbNPDWmOnD/NIFTYxoQ5R+Qp8YHAqfGFODUmJrG+Y8MVA0Rmz4kuf9DC9w/leT+6Sz3qwmnE9w/HVCJGZa5X/kwg+D+GZa5f5q2C+V+ZL1mktw/0wL3T/OB+2fpwJ9tKvgsB+6fLaDgs4HNmUMq+BwBBZ8GKPisNM5/F59o7p9F8PWsCHD/FMKu1pbbHCi73k/D2xyMAdj8fSA+pnj/3A3AnSjQ2qc2B5bepzFHEMd/pEVtbiiOdxkBgONFT4G5PnD8PL1g881TYJ4Dx88XOAXmAxnxMXkKfCxwCswFToF5aZz/yEA5HrFpAcnxCyxw/DyS4xeyHK8mXEhw/EKA4xdZ5njlwyKC4xdZ5vj52i6U45H1+oTk+E8scPx8Hzh+sQ78JaaCL3bg+CUCCr4E2JylpIIvFVDw+YCCL07j/Hfxifopl8KPjE3N/HeenCbmmkuwebsI1+TdOFs9+1EanrDtfGpzYAn1zBHExp/qmFp2ObLxMh/YeLlesBWmsi53YOMVAsq6AlChz0hl/UxAWZcByro8jfMfGai6IDatJNl4pQU2Xk6y8SqWjdWEqwg2XgWw8WrLbKx8WE2w8WrLbLxC24WyMbJen5Ns/LkFNl7hAxuv0YG/1lTwNQ5svFZAwdcCm7OOVPB1Agq+AlDwNWmc/y4+0Wy8hmRjtM2BmuvTNMy2ZSBLq1puO5/aHCwDxSFjfJHdaeJlwi8ISF8f5gnhxa71EbxwrU/DkQV5YX+DEEa5zbMMsGmjd5uoNgfK543ERfbLNH+SLxfZ5mATm3xqwk1E8m22nHzKrs1Cyef2uEoiteGC7/RkWYMtwLOtI9TmANnDrwB0Z2xR+43ModbzKyI+JNscPHQFt085vM3j2Obga+3zN+pfSQ7/xodKylbtzLcmh291qKR8K8Dh3wIRv43k8G0CHP4NwOFb0zj/kYFiCWLTd2Ql5TsLlZStZCVlO1tJURNuJyop2wGp/N5yJUX58D1RSfneciXlW20XWklB1usHspLyg4VKyrfugiXe5uBHHfg7TAXfIaDWO4CN+IlU658E1PpbQK1/TOP8z8YnkTYHP5KnAtrm4CGgzcHXwDoh6CLZ5iBEwmV8lHibg5064XaZCbfToXS5SyAJdwEbsZtMwt0ekjAMtMuShDvTOP+NkWWTJdsceAhq8TYHP+vg2pMW4qtgN8N3Amgiefzt8eECs1cv2D4zG/c6XGD2CWTjPiByfyGz8ReBI3EPkI170zj/kYFeYBCb9pMXmP0WLjB7yQvMAfYCoyY8QFxgDgAqcdDyBUb5cJC4wBy0fIHZp+1CLzDIev1KXmB+tXCB2Qd+S2iOqOzNDhqZbT2kA/+wqeCHHHjqsICCHwY25wip4EcEFHwfoOCH0jj/XXya8D9DQLsVfhxKw5PtUJjJ7MWuPYRdnS2/Uqk4E0C2tupZxYlom4NvXGPkv8ufVz5XX8f/DMQegIiBzj61ObCEseYI4v7ftAgevRy5/6gP3H9ML9hx89Q45sD9xwVOjeNAlP9Onhq/C5waR4FT41ga5z8yUDVEbPqD5P4/LHD/MZL7T7DcryY8QXD/CUAlTlrmfuXDSYL7T1rm/uPaLpT7kfX6k+T+Py1w/3EfuP+UDvzTpoKfcuD+0wIKfhrYnDOkgp8RUPDjgIKfSuP8d/GJ5v5TBF+figD3HyXs6mK5zYGy67c0vM3BHoDNfwPi46j3z90A3IkCXXxqc2DpfRpzBHH8X1rU/g7F8S4jAHC86Cnwtw8cf1Yv2DnzFDjrwPHnBE6Bc0BG/EOeAv8InAJ/A6fA2TTOf2SgHI/YdJ7k+PMWOP4syfEXWI5XE14gOP4CwPEXLXO88uEiwfEXLXP8OW0XyvHIev1Lcvy/Fjj+nA8cfykj8NNzBDt4yYHj1UPhKrj6DK/PBtI5BQ+kh6/g5wAFv5TG+e/ikyPHeykj/t+m5rCboGquvwk27x7hmrwbZ6tn/0rDE7a7T20OLKGeOYLY+Ir0//9vzvTLkI1zpkeeja/UC5bLVFb1H0w2ziWgrLkAZb2KVNarBJQ1Z7p3Zb0ynfMfGai6IDblTufYOHe6PBtfmc6x8dXpYUyo/hhl46u9b2QgD7AZrA950nE2zgMGI2pXLm0XysbIel0D+JA5eK9Jl2fjXCA2mSMqe7ODRmZb8+rAv9ZU8LzpWdn4WgEFvxbYnHykgucTUPBcgILnTef8d/GJZuOMTc38d14G2uZAzXVFOmZbznTMJ1XL7e5Tm4OcoDhkjOuyO028THhdOv53+cM8IbzYlZ8MKiaA86fjyIK8sH+9EEa5zZMT2JcC3m2i2hwonwuk4/txQ7o/yXcV2eagIJt8asKCRPIVspx8yq5CQsnn9rhKIrXhgu/0ZFmDwsB6dYlQmwNkD28E0J2xRe03ModazxuJ+JBsc9D0Cm6fcnibx7HNwU3a5yLqX0kOL+JDJaWoduZmk8OLOlRSbhbg8JuBiC9GcngxAQ4vAnB40XTOf2SgWILYdAtZSbnFQiWlKFlJKc5WUtSExYlKSnFAKm+1XElRPtxKVFJutVxJuVnbhVZSkPUqQVZSSliopNzsLljibQ6idOCXNBW8pIBalwQ24jZSrW8TUOubAbWOSuf8z8YnkTYHUeSpgLY5aAq0ObgJWCcEXSTbHIRIuIyPEm9zUEonXGkz4Uo5lC5LCyRhaWAjbieT8HYPSRgG2mVJwlLpnP/GyLLJkm0OPAS1eJuDO3RwlUkP8VWwm+GlADSRPP7K+HCBuVMvWFkzG+90uMCUFcjGskDk3kVm410CR2IZIBvvTOf8RwZ6gUFsKkdeYMpZuMDcSV5gyrMXGDVheeICUx5QiQqWLzDKhwrEBaaC5QtMWW0XeoFB1utu8gJzt4ULTFnwW0JzRGVvdtDIbGtFHfjRpoJXdOCpaAEFjwY2J4ZU8BgBBS8LKHjFdM5/F5/+t8loECn8qJiOJ1vFMJPZi11lCLv6WH6lUnEmgGxt1bOKE9E2B0VcY+S/y59XPldfx98BxB6AiIE+PrU5sISx5gji/lgtgnGXI/fH+cD98XrBEsxTI96B+xMETo0EIMoTyVMjUeDUiANOjfh0zn9koGqI2JREcn+SBe6PJ7k/meV+NWEywf3JgEqkWOZ+5UMKwf0plrk/QduFcj+yXqkk96da4P4EH7g/TQd+uqngaQ7cny6g4OnA5lQiFbySgIInAAqels757+ITzf1pBF+nRYD74wi7+lluc6Dsik3H2xyUAdg8FoiPOO+fuwG4EwX6+dTmwNL7NOYI4vh7tKhVDsXxLiMAcLzoKVDZB46vohesqnkKVHHg+KoCp0BVICPuJU+BewVOgcrAKVAlnfMfGSjHIzZVIzm+mgWOr0JyfHWW49WE1QmOrw5wfA3LHK98qEFwfA3LHF9V24VyPLJe95Ecf58Fjq/qA8fX1IFfy1Twmg4cX0tAwWsBm1ObVPDaAgpeFVDwmumc/y4+OXK8lzJixqZm/jtPThNzVSbYfECEa/JunK2evScdT9gBPrU5sIR65ghi4/t1TNW5HNm4jg9sXFcvWD1TWes6sHE9AWWtB6jQA6SyPiCgrHUAZa2bzvmPDFRdEJvqk2xc3wIb1yXZuAHLxmrCBgQbNwDYuKFlNlY+NCTYuKFlNq6n7ULZGFmvB0k2ftACG9fzgY0b6cBvbCp4Iwc2biyg4I2BzWlCKngTAQWvByh4o3TOfxefaDZuRLIx2uZAzXV/OmZbHZClVS13gE9tDuqA4pAxHsruNPEy4UMEpDcN84TwYlfTCF64mqbjyIK8sP+wEEa5zVMHsKmZd5uoNgfK52bERfaRdH+SLzfZ5qA5m3xqwuZE8rWwnHzKrhZCyef2uEoiteGC7/RkWYOWwLP9ItTmANnDRwF0Z2xR+43ModbzUSI+JNscPHwFt085vM3j2ObgMe1zK/WvJIe38qGS0lo787jJ4a0dKimPC3D440DEtyE5vI0Ah7cCOLx1Ouc/MlAsQWxqS1ZS2lqopLQmKynt2EqKmrAdUUlpB0jlE5YrKcqHJ4hKyhOWKymPa7vQSgqyXk+SlZQnLVRSHncXLPE2B+114HcwFbyDgFp3ADbiKVKtnxJQ68cBtW6fzvmfjU8ibQ7ak6cC2ubgYaDNwWPAOiHoItnmIETCZXyUeJuDjjrhOpkJ19GhdNlJIAk7ARvRmUzCzh6SMAy0y5KEHdM5/42RZZMl2xx4CGrxNgdP6+Dqkh7iq2A3wzsCaCJ5/HXx4QLTVS9YNzMbuzpcYLoJZGM3IHKfIbPxGYEjsQuQjV3TOf+RgV5gEJu6kxeY7hYuMF3JC0wP9gKjJuxBXGB6ACrR0/IFRvnQk7jA9LR8gemm7UIvMMh6PUteYJ61cIHpBn5LaI6o7M0OGplt7aUD/zlTwXs58NRzAgr+HLA5vUkF7y2g4N0ABe+Vzvnv4tP/NhkNIoUfvdLxZOsVZjJ7sasLYdcQy69UKs4EkK2telZxItrmoJVrjPx3+fPK5+rr+KeB2AMQMTDEpzYHljDWHEHc/7wWwT6XI/f38YH7++oF62eeGn0duL+fwKnRD4jyF8hT4wWBU6MPcGr0Tef8RwaqhohN/Unu72+B+/uS3P8iy/1qwhcJ7n8RUIkBlrlf+TCA4P4Blrm/n7YL5X5kvV4iuf8lC9zfzwfuH6gD/2VTwQc6cP/LAgr+MrA5g0gFHySg4P0ABR+Yzvnv4hPN/QMJvh4YAe7vQ9g11HKbA2XX8+l4m4MuAJs/D8RHH++fuwG4EwWG+tTmwNL7NOYI4vhXtKi9GorjXUYA4HjRU+BVHzh+sF6wIeYpMNiB44cInAJDgIx4jTwFXhM4BV4FToHB6Zz/yEA5HrFpKMnxQy1w/GCS419nOV5N+DrB8a8DHD/MMscrH4YRHD/MMscP0XahHI+s1xskx79hgeOH+MDxw3Xgv2kq+HAHjn9TQMHfBDZnBKngIwQUfAig4MPTOf9dfHLkeC9lxIxNzfx3npwm5nqVYPPhEa7Ju3G2evaVdDxhh/vU5sAS6pkjiI3f0jE18nJk45E+sPEovWCjTWUd5cDGowWUdTSgQm+Tyvq2gLKOBJR1VDrnPzJQdUFsGkOy8RgLbDyKZOOxLBurCccSbDwWYONxltlY+TCOYONxltl4tLYLZWNkvd4h2fgdC2w82gc2Hq8Df4Kp4OMd2HiCgIJPADZnIqngEwUUfDSg4OPTOf9dfKLZeDzJxmibAzXXW+mYbSNBlla13OE+tTkYCYpDxng3u9PEy4TvEpA+KcwTwotdkyJ44ZqUjiML8sL+e0IY5TbPSMCmyd5totocKJ8nExfZ99P9Sb6ryTYHU9jkUxNOIZJvquXkU3ZNFUo+t8dVEqkNF3ynJ8saTEPq7hFqc4Ds4QcAujO2qP1G5lDr+QERH5JtDppdwe1TDm/zOLY5+FD7PF39K8nh032opMzQzsw0OXyGQyVlpgCHzwQifhbJ4bMEOHw6wOEz0jn/kYFiCWLTbLKSMttCJWUGWUmZw1ZS1IRziErKHEAqP7JcSVE+fERUUj6yXEmZqe1CKynIes0lKylzLVRSZroLlnibg3k68OebCj5fQK3nAxvxManWHwuo9UxAreelc/5n45NIm4N55KmAtjloBrQ5+BBYJwRdJNschEi4jI8Sb3OwQCfcQjPhFjiULhcKJOFCYCMWkUm4yEMShoF2WZJwQTrnvzGybLJkmwMPQS3e5uATHVyL00N8Fexm+AIATSSPv8U+XGCW6AVbambjEocLzFKBbFwKRO6nZDZ+KnAkLgaycUk65z8y0AsMYtMy8gKzzMIFZgl5gVnOXmDUhMuJC8xyQCVWWL7AKB9WEBeYFZYvMEu1XegFBlmvz8gLzGcWLjBLwW8JzRGVvdlBI7OtK3XgrzIVfKUDT60SUPBVwOasJhV8tYCCLwUUfGU657+LT//bZDSIFH6sTMeTbWWYyezFrsWEXWMsv1KpOBNAtrbqWcWJaJuD6a4x8t/lzyufq6/jPwFiD0DEwBif2hxYwlhzBHH/51oE11yO3L/GB+5fqxdsnXlqrHXg/nUCp8Y6IMq/IE+NLwROjTXAqbE2nfMfGagaIjatJ7l/vQXuX0ty/waW+9WEGwju3wCoxEbL3K982Ehw/0bL3L9O24VyP7JeX5Lc/6UF7l/nA/dv0oG/2VTwTQ7cv1lAwTcDm7OFVPAtAgq+DlDwTemc/y4+0dy/ieDrTRHg/jWEXeMstzlQdn2ejrc5WAyw+edAfKzx/rkbgDtRYJxPbQ4svU9jjv/X3pvAWzW98f/33CSpVJIkdJOQJAlJ3Xv3uWNJQoaSVLqpJKFCMmUmU5IpmTJnSjJlzlDmJCQJmZKQOaH/Wt/W+TlnnX333p/Pedbdv/6v33q91uv4tof1PGut57Pea51zn28Gx79tRO2dII4PKQmA40VXgXdi4Ph3TYcttFeBd304fqHAKrAQiIj3yFXgPYFV4B1gFXi3G+c/UlCOR2xaRHL8Igcc/y7J8e+zHK8bfJ/g+PcBjl/smOO1D4sJjl/smOMXGrtQjkf66wOS4z9wwPELY+D4D83E/8hW8A99OP4jAQX/CBicJaSCLxFQ8IWAgn/YjfM/xCdfjo9yjJga1PTnIjlNtPUOwebTa/hMPoyz9b1vd8MDdnpMaQ4coZ5dMtj4YzOnlm6MbLw0Bjb+xHTYMltZP/Fh42UCyroMUKFPSWX9VEBZlwLK+kk3zn+koOqC2LScZOPlDtj4E5KNP2PZWDf4GcHGnwFs/LljNtY+fE6w8eeO2XiZsQtlY6S/viDZ+AsHbLwsBjZeYSb+l7aCr/Bh4y8FFPxLYHC+IhX8KwEFXwYo+IpunP8hPtFsvIJkYzTNgW7r426YbUtBltZnudNjSnOwFBSHVPm6utUkSoNfE5D+TY4rRBS7vqnBDdc33XBkQX6w/60QRoW1sxSwaWV0m6g0B9rnlcRG9rtu8QRfXTLNwSo2+HSDq4jg+95x8Gm7vhcKvrDbdRDpARf8TU9WH6wG7r2xhtIcIGP4A4DujC16vJE2dH/+QMwPyTQHR+Vz45QXrR3fNAc/Gp9/0p+SHP5TDCcpa4wzP9scvsbnJOVnAQ7/GZjxv5Ac/osAh/8EcPiabpz/SEGxBLHpV/Ik5VcHJylryJOU39iTFN3gb8RJym+AVP7u+CRF+/A7cZLyu+OTlJ+NXehJCtJff5AnKX84OEn5OVywxNMc/Gkm/lpbwdcKqPVaYCD+ItX6LwG1/hlQ6z+7cf5X45NImoM/yVUBTXNwFJDm4EegnxB0kUxzEBBwqVeJpzlYZwLubzvg1vkcXf4tEIR/AwPxDxmE/0QIwhzQLisI13Xj/LdK1iBLpjmIMKnF0xz8aybX+m4BXwWHGb4OQBPJ5W99DBuYvEJzU2FeZuTpC/YGRt+UazTqd0S9N7+Qi8b8wtyXxPVANOYVcv4jBd3AIDbVKuQ2MLUK5TcweYXcBmaTwhwa1A+jG5hNog9kojYwGKwPug10A1MbnIyoXQljF7qBQfprU8CH9Mm7aaH8BiYRXbBu9runoHqzM0q6rXXMxN/MVvA6hdk8tZmAgm8GDE5dUsHrCih4wEqTpeB1Cjn/Q3zy/So4zG6NH3UK8WCrk2MwR7FrPfFN1F2Of1KpORNAtip9r+ZENM3BT6HM/d/mLyqf66/j/wVYHkDExF0xpTlwhLF2yeD+zY0I1ivcCLm/XqGTDgtcNeqbDmtgrxr1fbi/gcCq0QBQ2C3IVWMLgVWjHrBq1C/k/EcKqoaITQ1J7m/ogPvrk9zfiOV+3WAjgvsbAdzf2DH3ax8aE9zf2DH3NzB2odyP9NeWJPdv6YD7G8TA/U3MxN/KVvAmPty/lYCCbwUMTlNSwZsKKHgDQMGbFHL+h/hEc38Tgvub1AD31yPsusdxmgNtl+Y+NM3BeoDNNwfmR73CyO+dD+yJEvfElObgpxg4fmsjas2COD6kJACOF10FmsXA8duYDmturwLb+HB8c4FVoDkQEduSq8C2AqtAM2AV2KaQ8x8pKMcjNrUgOb6FA47fhuT47ViO1w1uR3D8dgDHb++Y47UP2xMcv71jjm9u7EI5HumvHUiO38EBxzePgeNbmolfYCt4Sx+OLxBQ8AJgcFqRCt5KQMGbAwrespDzP8Qn6k+5NH6kBjX9uUhOE201I9h8Zg2fyYdxtr5360I8YGfGlObAEerZJYONdzRzqvXGyMatY2DjnUyHtbGVdScfNm4joKxtABXamVTWnQWUtTWgrDsVcv4jBVUXxKZdSDbexQEb70Sy8a4sG+sGdyXYeFeAjds6ZmPtQ1uCjds6ZuM2xi6UjZH+2o1k490csHGbGNi4nZn4u9sK3s6HjXcXUPDdgcFpTyp4ewEFbwMoeLtCzv8Qn2g2bkeyMZrmQLe1YyFmW2uQpfVZ7syY0hy0BsUhVfaobjWJ0uAeBKR3yHGFiGJXhxrccHUoxJEF+cH+nkIYFdZOa2BcOka3iUpzoH3uSGxk9yqMJ/g2J9McdGKDTzfYiQi+vR0Hn7Zrb6HgC7tdB5EecMHf9GT1wT7AvffUUJoDZAz3BdCdsUWPN9KG7s99ifkhmeagfz43TnnR2vFNc9DZ+Lyf/pTk8P1iOEnpYpzZ3+bwLj4nKfsLcPj+wIzvSnJ4VwEO3w/g8C6FnP9IQbEEsakbeZLSzcFJShfyJKWQPUnRDRYSJymFgFQWOT5J0T4UEScpRY5PUvY3dqEnKUh/FZMnKcUOTlL2Dxcs8TQHnpn4SVvBkwJqnQQGooRU6xIBtd4fUGuvkPO/Gp9E0hx45KqApjnoD6Q56Az0E4IukmkOAgIu9SrxNAelJuDK7IAr9Tm6LBMIwjJgIMrJICyPEIQ5oF1WEJYWcv5bJWuQJdMcRJjU4mkOKszkqiwM+Co4zPBSAE0kl7/KGDYw3U2H9bCjsbvPBqaHQDT2AGbuAWQ0HiCwJFYC0di9kPMfKegGBrGpJ7mB6elgA9Od3MAcyG5gdIMHEhuYAwGV6OV4A6N96EVsYHo53sD0MHahGxikvw4iNzAHOdjA9AC/JbRLQfVmZ5R0W3ubiX+wreC9fXjqYAEFPxgYnENIBT9EQMF7AAreu5DzP8Qn6s+dNH70LsSDrXeOwRzFrkrCrtmOf1KpORNAtip9r+ZENM3BfqFz5L/NX1Q+11/HVwBzD0DExOyY0hw4wli7ZHD/oUYE+2yM3N8nBu4/zHTY4faqcZgP9x8usGocDszyI8hV4wiBVaMPsGocVsj5jxRUDRGbjiS5/0gH3H8Yyf19We7XDfYluL8voBL9HHO/9qEfwf39HHP/4cYulPuR/jqK5P6jHHD/4TFwf38z8Y+2Fby/D/cfLaDgRwODM4BU8AECCn44oOD9Czn/Q3yiub8/wdf9a4D7+xB2zXGc5kDbdWghnuagEmDzQ4H50Sf6e+cDe6LEnJjSHDj6PY1dMjj+GCNqA4M4PqQkAI4XXQUGxsDxg0yHDbZXgUE+HD9YYBUYDETEseQqcKzAKjAQWAUGFXL+IwXleMSmISTHD3HA8YNIjq9iOV43WEVwfBXA8UMdc7z2YSjB8UMdc/xgYxfK8Uh/HUdy/HEOOH5wDBw/zEz84baCD/Ph+OECCj4cGJwRpIKPEFDwwYCCDyvk/A/xifpTLo0fqUFNfy6S00RbAwk2f6qGz+TDOFvfe0whHrBPxZTmwBHq2SWDjY83c2rkxsjGI2Ng4xNMh42ylfUEHzYeJaCsowAVOpFU1hMFlHUkoKwnFHL+IwVVF8Sm0SQbj3bAxieQbHwSy8a6wZMINj4JYOOTHbOx9uFkgo1PdszGo4xdKBsj/XUKycanOGDjUTGw8Rgz8cfaCj7Gh43HCij4WGBwxpEKPk5AwUcBCj6mkPM/xCeajceQbIymOdBtHV+I2TYSZGl9lvtUTGkORoLikCqnVreaRGnwVALST8txhYhi12k1uOE6rRBHFuQH+6cLYVRYOyMBm8ZHt4lKc6B9Hk9sZM8ojCf46pFpDiawwacbnEAE35mOg0/bdaZQ8IXdroNID7jgb3qy+uAs4N45NZTmABnDswF0Z2zR4420ofvzbGJ+SKY5ODqfG6e8aO34pjk4x/h8rv6U5PBzYzhJmWicOc/m8Ik+JynnCXD4ecCMP5/k8PMFOPxcgMMnFnL+IwXFEsSmC8iTlAscnKRMJE9SLmRPUnSDFxInKRcCUnmR45MU7cNFxEnKRY5PUs4zdqEnKUh/XUyepFzs4CTlvHDBEk9zcImZ+JfaCn6pgFpfCgzEZaRaXyag1ucBan1JIed/NT6JpDm4hFwV0DQHRwNpDs4B+glBF8k0BwEBl3qVeJqDSSbgLrcDbpLP0eXlAkF4OTAQV5BBeEWEIMwB7bKCcFIh579VsgZZMs1BhEktnubgSjO5rioM+Co4zPBJAJpILn9XxbCBudp02GQ7Gq/22cBMFojGycDMvYaMxmsElsSrgGi8upDzHynoBgaxaQq5gZniYANzNbmBuZbdwOgGryU2MNcCKjHV8QZG+zCV2MBMdbyBmWzsQjcwSH9dR25grnOwgZkMfktol4Lqzc4o6bZebyb+DbaCX+/DUzcIKPgNwODcSCr4jQIKPhlQ8OsLOf9DfKL+3Enjx/WFeLBdn2MwR7HrKsKuFx3/pFJzJoBsVfpezYlomoNzQ+fIf5u/qHyuv46/Eph7ACImXowpzYEjjLVLBvffZERw2sbI/dNi4P6bTYdNt1eNm324f7rAqjEdmOW3kKvGLQKrxjRg1bi5kPMfKagaIjbdSnL/rQ64/2aS+29juV83eBvB/bcBKnG7Y+7XPtxOcP/tjrl/urEL5X6kv+4guf8OB9w/PQbun2Em/p22gs/w4f47BRT8TmBw7iIV/C4BBZ8OKPiMQs7/EJ9o7p9B8PWMGuD+aYRd8xynOdB23VSIpzm4CmDzm4D5MS36e+cDe6LEvJjSHDj6PY1dMjj+biNq9wRxfEhJABwvugrcEwPH32s67D57FbjXh+PvE1gF7gMi4n5yFbhfYBW4B1gF7i3k/EcKyvGITTNJjp/pgOPvJTn+AZbjdYMPEBz/AMDxDzrmeO3DgwTHP+iY4+8zdqEcj/TXQyTHP+SA4++LgeMfNhP/EVvBH/bh+EcEFPwRYHBmkQo+S0DB7wMU/OFCzv8Qn6g/5dL4kRrU9OciOU20dQ/B5q/V8Jl8GGfre+8uxAP2tZjSHDhCPbtksPGjZk7N3hjZeHYMbPyY6bA5trI+5sPGcwSUdQ6gQo+Tyvq4gLLOBpT1sULOf6Sg6oLY9ATJxk84YOPHSDZ+kmVj3eCTBBs/CbDxU47ZWPvwFMHGTzlm4znGLpSNkf56mmTjpx2w8ZwY2HiumfjP2Ao+14eNnxFQ8GeAwXmWVPBnBRR8DqDgcws5/0N8otl4LsnGaJoD3dajhZhts0GW1me5r8WU5mA2KA6p8lx1q0mUBp8jIP35HFeIKHY9X4MbrucLcWRBfrD/ghBGhbUzG7Dpxeg2UWkOtM8vEhvZlwrjCb76ZJqDeWzw6QbnEcH3suPg03a9LBR8YbfrINIDLvibnqw+eAW4d14NpTlAxvBVAN0ZW/R4I23o/nyVmB+SaQ4G5HPjlBetHd80B68Zn+frT0kOnx/DScoC48zrNocv8DlJeV2Aw18HZvwbJIe/IcDh8wEOX1DI+Y8UFEsQm94kT1LedHCSsoA8SXmLPUnRDb5FnKS8BUjl245PUrQPbxMnKW87Pkl53diFnqQg/fUOeZLyjoOTlNfDBUs8zcG7ZuIvtBV8oYBaLwQG4j1Srd8TUOvXAbV+t5DzvxqfRNIcvEuuCmiagwFAmoPXgH5C0EUyzUFAwKVeJZ7mYJEJuPftgFvkc3T5vkAQvg8MxGIyCBdHCMIc0C4rCBcVcv5bJWuQJdMcRJjU4mkOPjCT68PCgK+CwwxfBKCJ5PL3YQwbmI9Mhy2xo/Ejnw3MEoFoXALM3I/JaPxYYEn8EIjGjwo5/5GCbmAQm5aSG5ilDjYwH5EbmE/YDYxu8BNiA/MJoBLLHG9gtA/LiA3MMscbmCXGLnQDg/TXp+QG5lMHG5gl4LeEdimo3uyMkm7rcjPxP7MVfLkPT30moOCfAYPzOangnwso+BJAwZcXcv6H+ET9uZPGj+WFeLAtzzGYo9j1IWHXO45/Uqk5E0C2Kn2v5kQ0zcH80Dny3+YvKp/rr+M/AOYegIiJd2JKc+AIY+2Swf1fGBFcsTFy/4oYuP9L02Ff2avGlz7c/5XAqvEVMMu/JleNrwVWjRXAqvFlIec/UlA1RGz6huT+bxxw/5ck93/Lcr9u8FuC+78FVGKlY+7XPqwkuH+lY+7/ytiFcj/SX9+R3P+dA+7/KgbuX2Um/ve2gq/y4f7vBRT8e2BwVpMKvlpAwb8CFHxVIed/iE80968i+HpVDXD/CsKuhY7THGi7vijE0xx8CLD5F8D8WBH9vfOBPVFiYUxpDhz9nsYuGRz/gxG1H4M4PqQkAI4XXQV+jIHjfzIdtsZeBX7y4fg1AqvAGiAifiZXgZ8FVoEfgVXgp0LOf6SgHI/Y9AvJ8b844PifSI7/leV43eCvBMf/CnD8b445XvvwG8Hxvznm+DXGLpTjkf76neT43x1w/JoYOP4PM/H/tBX8Dx+O/1NAwf8EBmctqeBrBRR8DaDgfxRy/of4RP0pl8aP1KCmPxfJaaKtHwk2X1zDZ/JhnK3v/aEQD9jFMaU5cIR6dslg47/MnFq3MbLxuhjY+G/TYf/Yyvq3Dxv/I6Cs/wAq9C+prP8KKOs6QFn/LuT8RwqqLohN60k2Xu+Ajf8m2TivKIcG9cMoG+tnqrvXKolEkVs21j7oNlA2ThRhkxG16x9jF8rGSH/lAz6kT179nDQb/xMDG9cyE3+TorxMB2sVZbPxJkW5K/gmwODULuIUvHZR7gr+D6DgtYo4/0N8otk4Najpz0UpaJoD3dZfhZht60CW1me5i2NKc4AgVXp7m1a3mkRpcNMi/Lk6Oa4QUeyqQ04qZgLXKcKRBfnB/mbgypUqqNitA2yqG90mKs2B9rluET4emxfFE3wNyDQH9djg0w3WI4KvvuPg03bVFwq+sNt1EOkBF/xNT1YfNAD6a2ENpTlAxnALAN0ZW/R4I23o/tyCmB+SaQ6OyefGKS9aO75pDhoanxvpT0kOb1TkxJksUUy3tbFxZkubw/WFs61/21KAw7cEZnwTksObCHB4o6LoHN64iPMfKSiWIDZtVcSdpGxVJH+S0riIO0lpyp6k6AabEicpTQGp3NrxSYr2YWviJGVrxycpWxq70JMUpL+akScpzRycpGwZLljiaQ62MRO/ua3gzQXUujkwENuSar2tgFpvCaj1NkWc/9X4JJLmYBtyVUDTHBwDpDloCPQTgi6SaQ4CAi71KvE0By1MwG1nB1wLn6PL7QSCcDtgILYng3D7CEGYA9plBWGLIs5/q2QNsmSagwiTWjzNwQ5mcrUsCvgqOMzwFgCaSC5/LWPYwBSYDmtlR2OBzwamlUA0tgJm7o5kNO4osCS2BKKxoIjzHynoBgaxqTW5gWntYANTQG5gdmI3MLrBnYgNzE6ASrRxvIHRPrQhNjBtHG9gWhm70A0M0l87kxuYnR1sYFqB3xLapaB6szNKuq27mIm/q63gu/jw1K4CCr4rMDhtSQVvK6DgrQAF36WI8z/EJ+rPnTR+7FKEB9suOQZzFLtaEnYtc/yTSs2ZALJV6Xs1J6JpDhqFzpH/Nn9R+Vx/Hb8DMPcAREwsiynNgSOMtUsG9+9mRLDdxsj97WLg/t1Nh7W3V43dfbi/vcCq0R6Y5XuQq8YeAqtGO2DV2L2I8x8pqBoiNnUgub+DA+7fneT+PVnu1w3uSXD/noBKdHTM/dqHjgT3d3TM/e2NXSj3I/21F8n9ezng/vYxcH8nM/H3thW8kw/37y2g4HsDg7MPqeD7CCh4e0DBOxVx/of4RHN/J4KvO9UA97cj7FruOM2Btmu3IjzNQUuAzXcD5ke76O+dD+yJEstjSnPg6Pc0dsng+H2NqHUO4viQkgA4XnQV6BwDx+9nOqyLvQrs58PxXQRWgS5AROxPrgL7C6wCnYFVYL8izn+koByP2NSV5PiuDjh+P5Lju7EcrxvsRnB8N4DjCx1zvPahkOD4Qscc38XYhXI80l9FJMcXOeD4LjFwfLGZ+J6t4MU+HO8JKLgHDE6SVPCkgIJ3ARS8uIjzP8Qn6k+5NH6kBjX9uUhOE211Jth8RQ2fyYdxtr533yI8YFfElObAEerZJYONS8ycKt0Y2bg0BjYuMx1WbitrmQ8blwsoazmgQhWkslYIKGspoKxlRZz/SEHVBbGpkmTjSgdsXEaycXeWjXWD3Qk27g6wcQ/HbKx96EGwcQ/HbFxu7ELZGOmvA0g2PsABG5fHwMY9zcQ/0Fbwnj5sfKCAgh8IDE4vUsF7CSh4OaDgPYs4/0N8otm4J8nGaJoD3VZJEWZbKcjS+ix3RUxpDkpBcUiVg6pbTaI0eBAB6b1zXCGi2NW7BjdcvYtwZEF+sH+wEEaFtVMK2HRIdJuoNAfa50OIjeyhRfEE3xZkmoM+bPDpBvsQwXeY4+DTdh0mFHxht+sg0gMu+JuerD44HLh3eQ2lOUDG8AgA3Rlb9Hgjbej+PIKYH5JpDgbmc+OUF60d3zQHRxqf++pPSQ7vG8NJSj/jzFE2h/fzOUk5SoDDjwJmfH+Sw/sLcHhfgMP7FXH+IwXFEsSmo8mTlKMdnKT0I09SBrAnKbrBAcRJygBAKo9xfJKifTiGOEk5xvFJylHGLvQkBemvgeRJykAHJylHhQuWeJqDQWbiD7YVfLCAWg8GBuJYUq2PFVDrowC1HlTE+V+NTyJpDgaRqwKa5mAgkObgSKCfEHSRTHMQEHCpV4mnORhiAq7KDrghPkeXVQJBWAUMxFAyCIdGCMIc0C4rCIcUcf5bJWuQJdMcRJjU4mkOjjOTa1hRwFfBYYYPAdBEcvkbFsMGZrjpsBF2NA732cCMEIjGEcDMPZ6MxuMFlsRhQDQOL+L8Rwq6gUFsGkluYEY62MAMJzcwJ7AbGN3gCcQG5gRAJUY53sBoH0YRG5hRjjcwI4xd6AYG6a8TyQ3MiQ42MCPAbwntUlC92Rkl3dbRZuKfZCv4aB+eOklAwU8CBudkUsFPFlDwEYCCjy7i/A/xifpzJ40fo4vwYBudYzBHsWsYYdcqxz+p1JwJIFuVvldzIprmoG/oHPlv8xeVz/XX8ccBcw9AxMSqmNIcOMJYu2Rw/ylGBMdsjNw/JgbuH2s6bJy9aoz14f5xAqvGOGCWn0quGqcKrBpjgFVjbBHnP1JQNURsOo3k/tMccP9YkvtPZ7lfN3g6wf2nAyox3jH3ax/GE9w/3jH3jzN2odyP9NcZJPef4YD7x8XA/RPMxD/TVvAJPtx/poCCnwkMzlmkgp8loODjAAWfUMT5H+ITzf0TCL6eUAPcP4awa7XjNAfarlOK8DQHwwA2PwWYH2Oiv3c+sCdKrI4pzYGj39PYJYPjzzaidk4Qx4eUBMDxoqvAOTFw/Lmmwybaq8C5Phw/UWAVmAhExHnkKnCewCpwDrAKnFvE+Y8UlOMRm84nOf58Bxx/LsnxF7Acrxu8gOD4CwCOv9Axx2sfLiQ4/kLHHD/R2IVyPNJfF5Ecf5EDjp8YA8dfbCb+JbaCX+zD8ZcIKPglwOBcSir4pQIKPhFQ8IuLOP9DfKL+lEvjR2pQ05+L5DTR1jkEm6+p4TP5MM7W955dhAfsmpjSHDhCPbtksPFlZk5N2hjZeFIMbHy56bArbGW93IeNrxBQ1isAFbqSVNYrBZR1EqCslxdx/iMFVRfEpqtINr7KARtfTrLx1Swb6wavJtj4aoCNJztmY+3DZIKNJztm4yuMXSgbI/11DcnG1zhg4ytiYOMpZuJfayv4FB82vlZAwa8FBmcqqeBTBRT8CkDBpxRx/of4RLPxFJKN0TQHuq3LijDbJoEsrc9y18SU5mASKA6pcl11q0mUBq8jIP36HFeIKHZdX4MbruuLcGRBfrB/gxBGhbUzCbDpxug2UWkOtM83EhvZm4riCb6GZJqDaWzw6QanEcF3s+Pg03bdLBR8YbfrINIDLvibnqw+mA7cu7qG0hwgY3gLgO6MLXq8kTZ0f95CzA/JNAeD8rlxyovWjm+ag1uNz7fpT0kOvy2Gk5TbjTN32Bx+u89Jyh0CHH4HMONnkBw+Q4DDbwM4/PYizn+koFiC2HQneZJyp4OTlNvJk5S72JMU3eBdxEnKXYBU3u34JEX7cDdxknK345OUO4xd6EkK0l/3kCcp9zg4SbkjXLDE0xzcayb+fbaC3yeg1vcBA3E/qdb3C6j1HYBa31vE+V+NTyJpDu4lVwU0zcEgIM3BrUA/IegimeYgIOBSrxJPczDTBNwDdsDN9Dm6fEAgCB8ABuJBMggfjBCEOaBdVhDOLOL8t0rWIEumOYgwqcXTHDxUtOHz4aKAr4LDDJ8JoInk8vdwDBuYR0yHzbKj8RGfDcwsgWicBczcR8lofFRgSXwYiMZHijj/kYJuYBCbZpMbmNkONjCPkBuYx9gNjG7wMWID8xigEnMcb2C0D3OIDcwcxxuYWcYudAOD9Nfj5AbmcQcbmFngt4R2Kaje7IySbusTZuI/aSv4Ez489aSAgj8JDM5TpII/JaDgswAFf6KI8z/EJ+rPnTR+PFGEB9sTOQZzFLseJuxa6/gnlZozAWSr0vdqTkTTHNwWOkf+2/xF5XP9dfxDwNwDEDGxNqY0B44w1i4Z3P+0EcG5GyP3z42B+58xHfasvWo848P9zwqsGs8Cs/w5ctV4TmDVmAusGs8Ucf4jBVVDxKbnSe5/3gH3P0Ny/wss9+sGXyC4/wVAJV50zP3ahxcJ7n/RMfc/a+xCuR/pr5dI7n/JAfc/GwP3zzMT/2Vbwef5cP/LAgr+MjA4r5AK/oqAgj8LKPi8Is7/EJ9o7p9H8PW8GuD+uYRd6xynOdB2PV2Epzl4GGDzp4H5MTf6e+cDe6LEupjSHDj6PY1dMjj+VSNqrwVxfEhJABwvugq8FgPHzzcdtsBeBeb7cPwCgVVgARARr5OrwOsCq8BrwCowv4jzHykoxyM2vUFy/BsOOH4+yfFvshyvG3yT4Pg3AY5/yzHHax/eIjj+Lcccv8DYhXI80l9vkxz/tgOOXxADx79jJv67toK/48Px7woo+LvA4CwkFXyhgIIvABT8nSLO/xCfqD/l0viRGtT05yI5TbT1GsHm62v4TD6Ms/W9rxbhAbs+pjQHjlDPLhls/J6ZU4s2RjZeFAMbv286bLGtrO/7sPFiAWVdDKjQB6SyfiCgrIsAZX2/iPMfKai6IDZ9SLLxhw7Y+H2SjT9i2Vg3+BHBxh8BbLzEMRtrH5YQbLzEMRsvNnahbIz018ckG3/sgI0Xx8DGS83E/8RW8KU+bPyJgIJ/AgzOMlLBlwko+GJAwZcWcf6H+ESz8VKSjdE0B7qt94ow2xaBLK3PctfHlOZgESgOqfJpdatJlAY/JSB9eY4rRBS7ltfghmt5EY4syA/2PxPCqLB2FgE2fR7dJirNgfb5c2Ij+0VRPMHXiExzsIINPt3gCiL4vnQcfNquL4WCL+x2HUR6wAV/05PVB18B966roTQHyBh+DaA7Y4seb6QN3Z9fE/NDMs3B4HxunPKiteOb5uAb4/O3+lOSw7+N4SRlpXHmO5vDV/qcpHwnwOHfATN+FcnhqwQ4/FuAw1cWcf4jBcUSxKbvyZOU7x2cpKwkT1JWsycpusHVxEnKakAqf3B8kqJ9+IE4SfnB8UnKd8Yu9CQF6a8fyZOUHx2cpHwXLljiaQ5+MhN/ja3gawTUeg0wED+Tav2zgFp/B6j1T0Wc/9X4JJLm4CdyVUDTHAwG0hx8A/QTgi6SaQ4CAi71KvE0B7+YgPvVDrhffI4ufxUIwl+BgfiNDMLfIgRhDmiXFYS/FHH+WyVrkCXTHESY1OJpDn43k+uPooCvgsMM/wVAE8nl748YNjB/mg5ba0fjnz4bmLUC0bgWmLl/kdH4l8CS+AcQjX8Wcf4jBd3AIDatIzcw6xxsYP4kNzB/sxsY3eDfxAbmb0Al/nG8gdE+/ENsYP5xvIFZa+xCNzBIf/1LbmD+dbCBWQt+S2iXgurNzijptq5PTfzivEwH1/vwlL4pVwXX74h6b6KYU/BEce4KvhZQ8PVFnP8hPlF/7qTxYz3xjc/6HIM5il1/EHbV6YnZha50mjMBZKvS92pORNMcfBs6R/7b/EXlc/11/O/A3AMQMRGh352kOXCEsXbJ4P784g2ftYo3Qu6vVVzz3L+J6bDa9qqhL9jcX1tg1agNrBqbkqvGpgKrRq3i6KvGJsWc/0hB1RCxqU4xx/11iuW5f5Nijvs3K86hQf0wyv2bRR/IRF1gMFgf6hbj3F8XnIyoXbWNXSj3I/21OeBD+uTdvFie+2uDSGiXgurNzijpttYzE7++reD1irO5v76AgtcHBqcBqeANBBS8NqDg9Yo5/0N8orm/XjEebPVyDOYodtUi7Krb06ld/+N4zX1omoM/ADbPB+ZHreLI750P7IkSSD9Kpjn4NgaO38KIWsMgjg8pCYDjRVeBhjFwfCPTYY3tVaCRD8c3FlgFGgMRsSW5CmwpsAo0BFaBRsWc/0hBOR6xqQnJ8U0ccHwjkuO3YjleN7gVwfFbARzf1DHHax+aEhzf1DHHNzZ2oRyP9NfWJMdv7YDjG8fA8c3MxN/GVvBmPhy/jYCCbwMMTnNSwZsLKHhjQMGbFXP+h/hE/SmXxo/UoKY/F8lpoq2GBJs3qOEz+TDO1vduUYwHbIN42LiLI9SzSwYbb2vmVIuNkY1bxMDG25kO295W1u182Hh7AWXdHlChHUhl3UFAWVsAyrpdMec/UlB1QWxqSbJxSwdsvB3JxgUsG/+vQYKNCwA2buWYjbUPrQg2buWYjbc3dqFsjPTXjiQb7+iAjbePgY1bm4m/k63grX3YeCcBBd8JGJw2pIK3EVDw7QEFb13M+R/iE83GrUk2RtMc6La2LcZsawGytD7LRRk06moSUiCkSm9v5+pWkygN7kxA+i45rhBR7NqlBjdcuxTjyIL8YH9XIYwKa6cFMC5to9tEpTnQPrclNrK7FccTfI3JNAft2ODTDbYjgm93x8Gn7dpdKPjCbtdBpAdc8Dc9WX3QHrgX/YYzVdBARcZwDwDdGVv0eCNt6P7cg5gfkmkOjs3nxikvWju+aQ46GJ/31J+SHL5nDCcpHY0ze9kc3tHnJGUvAQ7fC5jxnUgO7yTA4XsCHN6xmPMfKSiWIDbtTZ6k7O3gJKUjeZKyD3uSohvchzhJ2QeQyn0dn6RoH/YlTlL2dXySspexCz1JQfqrM3mS0tnBScpe4YIlnuZgPzPxu9gK3kVArbsAA7E/qdb7C6j1XoBa71fM+V+NTyJpDvYjVwU0zcGxQJqDDkA/IegimeYgIOBSrxJPc9DVBFw3O+C6+hxddhMIwm7AQBSSQVgYIQhzQLusIOxazPlvlaxBlkxzEGFSi6c5KDKTq7g44KvgMMO7AmgiufwVx7CB8UyHJe1o9Hw2MEmBaEwCM7eEjMYSgSWxGIhGr5jzHynoBgaxqZTcwJQ62MB45AamjN3A6AbLiA1MGaAS5Y43MNqHcmIDU+54A5M0dqEbGKS/KsgNTIWDDUwS/JbQLgXVm51R0m2tNBO/u63glT481V1AwbsDg9ODVPAeAgqeBBS8spjzP8Qn6s+dNH5UFuPBVpljMEexq5iwq6njn1RqzgSQrUrfqzkRTXOwZ+gc+W/zF5XP9dfxRcDcAxAx0TSmNAeOMNYuGdx/gBHBnhsj9/eMgfsPNB3Wy141DvTh/l4Cq0YvYJYfRK4aBwmsGj2BVePAYs5/pKBqiNjUm+T+3g64/0CS+w9muV83eDDB/QcDKnGIY+7XPhxCcP8hjrm/l7EL5X6kvw4luf9QB9zfKwbu72Mm/mG2gvfx4f7DBBT8MGBwDicV/HABBe8FKHifYs7/EJ9o7u9D8HWfGuD+noRdzRynOdB2HVCMpzkoBtj8AGB+9Iz+3vnAnijRLKY0B45+T2OXDI4/wojakUEcH1ISAMeLrgJHxsDxfU2H9bNXgb4+HN9PYBXoB0TEUeQqcJTAKnAksAr0Leb8RwrK8YhN/UmO7++A4/uSHH80y/G6waMJjj8a4PgBjjle+zCA4PgBjjm+n7EL5Xikv44hOf4YBxzfLwaOH2gm/iBbwQf6cPwgAQUfBAzOYFLBBwsoeD9AwQcWc/6H+ET9KZfGj9Sgpj8XyWmirSMJNm9Rw2fyYZyt7z2iGA/YFjGlOXCEenbJYONjzZwasjGy8ZAY2LjKdNhQW1mrfNh4qICyDgVU6DhSWY8TUNYhgLJWFXP+IwVVF8SmYSQbD3PAxlUkGw9n2Vg3OJxg4+EAG49wzMbahxEEG49wzMZDjV0oGyP9dTzJxsc7YOOhMbDxSDPxT7AVfKQPG58goOAnAIMzilTwUQIKPhRQ8JHFnP8hPtFsPJJkYzTNgW7r2GLMtiEgS+uz3BYxpTkYAopDqpxY3WoSpcETCUgfneMKEcWu0TW44RpdjCML8oP9k4QwKqydIYBNJ0e3iUpzoH0+mdjInlIcT/BtSaY5GMMGn25wDBF8Yx0Hn7ZrrFDwhd2ug0gPuOBverL6YBxwb7MaSnOAjOGpALoztujxRtrQ/XkqMT8k0xwMyefGKS9aO75pDk4zPp+uPyU5/PQYTlLGG2fOsDl8vM9JyhkCHH4GMOMnkBw+QYDDTwc4fHwx5z9SUCxBbDqTPEk508FJynjyJOUs9iRFN3gWcZJyFiCVZzs+SflfsBInKWc7Pkk5w9iFnqQg/XUOeZJyjoOTlDPCBUs8zcG5ZuJPtBV8ooBaTwQG4jxSrc8TUOszALU+t5jzvxqfRNIcnEuuCmiagyFAmoPTgH5C0EUyzUFAwKVeJZ7m4HwTcBfYAXe+z9HlBQJBeAEwEBeSQXhhhCDMAe2ygvD8Ys5/q2QNsmSagwiTWjzNwUVmcl1cHPBVcJjh5wNoIrn8XRzDBuYS02GX2tF4ic8G5lKBaLwUmLmXkdF4mcCSeDEQjZcUc/4jBd3AIDZNIjcwkxxsYC4hNzCXsxsY3eDlxAbmckAlrnC8gdE+XEFsYK5wvIG51NiFbmCQ/rqS3MBc6WADcyn4LaFdCqo3O6Ok23qVmfhX2wp+lQ9PXS2g4FcDgzOZVPDJAgp+KaDgVxVz/of4RP25k8aPq4rxYLsqx2COYtfFhF2tHf+kUnMmgGxV+l7NiWiag9ND58h/m7+ofK6/jr8ImHsAIiZax5TmwBHG2iWD+68xIjhlY+T+KTFw/7Wmw6baq8a1Ptw/VWDVmArM8uvIVeM6gVVjCrBqXFvM+Y8UVA0Rm64nuf96B9x/Lcn9N7Dcrxu8geD+GwCVuNEx92sfbiS4/0bH3D/V2IVyP9JfN5Hcf5MD7p8aA/dPMxP/ZlvBp/lw/80CCn4zMDjTSQWfLqDgUwEFn1bM+R/iE8390wi+nlYD3D+FsKuN4zQH2q5rivE0BxcDbH4NMD+mRH/vfGBPlGgTU5oDR7+nsUsGx99iRO3WII4PKQmA40VXgVtj4PjbTIfdbq8Ct/lw/O0Cq8DtQETcQa4CdwisArcCq8BtxZz/SEE5HrFpBsnxMxxw/G0kx9/Jcrxu8E6C4+8EOP4uxxyvfbiL4Pi7HHP87cYulOOR/rqb5Pi7HXD87TFw/D1m4t9rK/g9Phx/r4CC3wsMzn2kgt8noOC3Awp+TzHnf4hP1J9yafxIDWr6c5GcJtq6lWDztjV8Jh/G2freW4rxgG0bU5oDR6hnlww2vt/MqZkbIxvPjIGNHzAd9qCtrA/4sPGDAsr6IKBCD5HK+pCAss4ElPWBYs5/pKDqgtj0MMnGDztg4wdINn6EZWPd4CMEGz8CsPEsx2ysfZhFsPEsx2z8oLELZWOkvx4l2fhRB2z8YAxsPNtM/MdsBZ/tw8aPCSj4Y8DgzCEVfI6Agj8IKPjsYs7/EJ9oNp5NsjGa5kC3dX8xZttMkKX1WW7bmNIczATFIVUer241idLg4wSkP5HjChHFridqcMP1RDGOLMgP9p8UwqiwdmYCNj0V3SYqzYH2+SliI/t0cTzB14RMczCXDT7d4Fwi+J5xHHzarmeEgi/sdh1EesAFf9OT1QfPAve2qaE0B8gYPgegO2OLHm+kDd2fzxHzQzLNQVU+N0550drxTXPwvPH5Bf0pyeEvxHCS8qJx5iWbw1/0OUl5SYDDXwJm/DySw+cJcPgLAIe/WMz5jxQUSxCbXiZPUl52cJLyInmS8gp7kqIbfIU4SXkFkMpXHZ+kaB9eJU5SXnV8kvKSsQs9SUH66zXyJOU1BycpL4ULlniag/lm4i+wFXyBgFovAAbidVKtXxdQ65cAtZ5fzPlfjU8iaQ7mk6sCmuagCkhz8DzQTwi6SKY5CAi41KvE0xy8YQLuTTvg3vA5unxTIAjfBAbiLTII34oQhDmgXVYQvlHM+W+VrEGWTHMQYVKLpzl420yud4oDvgoOM/wNAE0kl793YtjAvGs6bKEdje/6bGAWCkTjQmDmvkdG43sCS+I7QDS+W8z5jxR0A4PYtIjcwCxysIF5l9zAvM9uYHSD7xMbmPcBlVjseAOjfVhMbGAWO97ALDR2oRsYpL8+IDcwHzjYwCwEvyW0S0H1ZmeUdFs/NBP/I1vBP/ThqY8EFPwjYHCWkAq+REDBFwIK/mEx53+IT9SfO2n8+LAYD7YPcwzmKHa9Q9jV0fFPKjVnAshWpe/VnIimOXghdI78t/mLyuf66/i3gbkHIGKiY0xpDhxhrF0yuP9jI4JLN0buXxoD939iOmyZvWp84sP9ywRWjWXALP+UXDU+FVg1lgKrxifFnP9IQdUQsWk5yf3LHXD/JyT3f8Zyv27wM4L7PwNU4nPH3K99+Jzg/s8dc/8yYxfK/Uh/fUFy/xcOuH9ZDNy/wkz8L20FX+HD/V8KKPiXwOB8RSr4VwIKvgxQ8BXFnP8hPtHcv4Lg6xU1wP1LCbs6OU5zoO36uBhPc/AOwOYfA/NjafT3zgf2RIlOMaU5cPR7GrtkcPzXRtS+CeL4kJIAOF50FfgmBo7/1nTYSnsV+NaH41cKrAIrgYj4jlwFvhNYBb4BVoFvizn/kYJyPGLTKpLjVzng+G9Jjv+e5Xjd4PcEx38PcPxqxxyvfVhNcPxqxxy/0tiFcjzSXz+QHP+DA45fGQPH/2gm/k+2gv/ow/E/CSj4T8DgrCEVfI2Agq8EFPzHYs7/EJ+oP+XS+JEa1PTnIjlNtPUNweada/hMPoyz9b1fF+MB2zmmNAeOUM8uGWz8s5lTv2yMbPxLDGz8q+mw32xl/dWHjX8TUNbfABX6nVTW3wWU9RdAWX8t5vxHCqouiE1/kGz8hwM2/pVk4z9ZNtYN/kmw8Z8AG691zMbah7UEG691zMa/GbtQNkb66y+Sjf9ywMa/xcDG68zE/9tW8HU+bPy3gIL/DQzOP6SC/yOg4L8BCr6umPM/xCeajdeRbIymOdBt/VyM2fYLyNL6LLdzTGkOfgHFIVX+rW41idLgvwSkr89xhYhi1/oa3HCtL8aRBfnBfp4ng1Fh7fwC2JTwom9a/uewZUtISWifdRvoeOR78QTfVmSag1peDg3qh9HnNvHcBp+2S7eRhz1HtaWDKN8T/U1PVh/U9qLf26mG0hwgY7ipBwQdYYseb6QN3Z/6/jyrnbAimeZgaD43TnnR2vFNc1DH2/C5mf6U5HD9woj3+paCat5r/0O6rXW9DZ+be3mZzK0v2Ccp+qZcOVy/I+q99TyOw+t5uXP4Zl50Dq/rcf4jBcUSxKb6HneSop+TPkmp63EnKQ28HBrUD6MnKQ286IOxhZfbUh3FB91GmOLY70m3K5IjoF2bG7vQkxSkvxp6GK+lJqp+TouEpIIHBbfRKfE0B428DZ+NvbxMB/U/5KrWjb3o927pcWq9pZe7WgesKllq3cjj/K/GJ5E0B408blVA0xwMBdIc1PGi24+gi2Sag4CAS71KPM1BE2/D51ZeXmbA6QsJ69/0TbkGoX5H1HubelwQNvVyT3OABGETj/PfKlmDLJnmIMKkFk9zsLW34bOZF/BVcJjh6Z0bUkT/3KlZ9HZ9S0E177X/Id3WbbwNn829vMzI0xfsDYy+Kddo1O+Ieu+2HheN23q5L4nNvOjRuI3H+Y8UdAOD2NTC4zYw+jnpDcw2HreB2c7LoUH9MLqB2c6LPhjbe243MNoH3Qa6gUm3K5IjoF3NjV3oBgbprx08bgOjn5PewAQFt9+3hHYpqN7sjJJua0vPPOvlZTqoL9g8pW/KVcELvOj3tvI4BW/l5a7gAStNloK39Dj/Q3yi/txJ40dq7NKfC7Mr3YdIDVnvj2JXM8KuYsc/qdScCSBblb5XcyKa5iDgSDNr8xeVz/XX8Vt70W0AEDFRHFOaA0cYa5cM7t/R2/DZ2tsIub+156TDAleNnbwNn228vMwVQl+wuV/flOuqod8R9d6dPW7V2NnLfdVo7UVfNXbyOP+RgqohYtMuHsf9+jlp7t/J47h/Vy+HBvXDKPfv6kUfjLaeW+7XPug2UO5PtyuSI6BdbYxdKPcj/bWbx3G/fk6a+4OC2xX3t/M2fO7u5WU6qC/Y3K9vylXBd/ei39ve4xS8vZe7ggesNFkK3s7j/A/xieb+1NilPxdmV7oPkRqy3h/FrtaEXUnHaQ60XTt6eJqDgJO9LDbf0Yvub+vo750P7IkSyZjSHDj6PY1dMjh+D2/DZwcvgONDSgLgeNFVoIPnpMMCV4E9vQ2fHb28TMXXF2yO1zflugrod0S9dy+PWwX28nJfBTp40VeBPT3Of6SgHI/Y1MnjOF4/J83xe3ocx+/t5dCgfhjl+L296IOxj+eW47UPug2U49PtiuQIaFdHYxfK8Uh/7etxHK+fk+b4oOB2xfGdvQ2f+3l5mQ7qCzbH65tyVfD9vOj3dvE4Be/i5a7gAStNloJ39jj/Q3yi/pRL40dqUNOfi+Q00VY6K0V9rryGz+TDOFvfu4eHB2x5TGkOHKGeXTLYeH9vw2dXbyNk466ekw4LVNZu3obPQi8vU0X1BZuN9U25Kqt+R9R7izxOWYu83JW1qxddWbt5nP9IQdUFsanY49hYPyfNxt08jo09L4cG9cMoG3secDzhuWVj7YNuA2XjdLsiOQLaVWjsQtkY6a8Sj2Nj/Zw0GwcFtys2LvU2fJZ5eZkO6gs2G+ubclXwMg9gKI9T8HIvdwUPWGmyFLzU4/wP8Ylm49Sgpj8XpaBpDnRb+3uYbelsFbGd+eUxpTlAkCq9vQovhwb1w+hzlV5uK0QUu3Qbedhzvm1FmSS6LRRZkB/sd/dkMCqsna6ATT286JuW/zls2RJSEtpn3QY6Hgd48QRfUzLNQU8vhwb1w+hzB3pug0/bpdvIw56j2tJBpAdc8Dc9WX3QC7g3WUNpDpAxPMiL3i+MLXq8kTZ0f+r786x2wopkmoPj8rlxyovWjm+ag97ehs+D9ackh+sXRrzXtxRU8177H9JtPcTb8Hmol5fJ3PqCfZKib8qVw/U7ot7bx+M4vI+XO4cf7EXn8EM8zn+koFiC2HSYx52k6OekT1IO8biTlMO9HBrUD6MnKYd70QfjCC+3pTqKD7qNMMWx33OE55apDzV2oScp6XaFtXGkh/FaaqLq57RISCp4UHAbnRJPc9DX2/DZz8vLdFD/Q65q3c+Lfu9RHqfWR3m5q3XAqpKl1n09zv9qfBJJc9DX41YFNM3BcUCag95edPsRdJFMcxAQcKlXiac56O9t+Dzay8sMOH0hYf2bvinXINTviHrvAI8LwgFe7mkOkCDs73H+WyVrkCXTHESY1OJpDo7xNnwO9AK+Cg4zPL1zQ4ronzsNjN6ubymo5r32P6TbOsjb8DnYy8uMPH3B3sDom3KNRv2OqPce63HReKyX+5I40IsejYM8zn+koBsYxKYhHreB0c9Jb2AGedwGpsrLoUH9MLqBqfKiD8ZQz+0GRvug2whTHPs96XZFcgS0a7CxC93AIP11nMdtYPRz0huYoOD2+5bQLgXVm51R0m0d5m34HO7lZTqoL9g8pW/KVcGHe9HvHeFxCj7Cy13BA1aaLAUf5nH+h/hE/bmTxo/U2KU/F2ZXug+RGrLeH8WugYRdvRz/pFJzJoBsVfpezYlomoOAI82szV9UPtdfxx/jRbcBQMREr5jSHDjCWLtkcP/x3obPkd5GyP0jPScdFrhqnOBt+Bzl5WWuEPqCzf36plxXDf2OqPee6HGrxole7qvGSC/6qnGCx/mPFFQNEZtGexz36+ekuf8Ej+P+k7wcGtQPo9x/khd9ME723HK/9kG3gXJ/ul2RHAHtGmXsQrkf6a9TPI779XPS3B8U3K64f4y34XOsl5fpoL5gc7++KVcFH+tFv3ecxyn4OC93BQ9YabIUfIzH+R/iE839qbFLfy7MrnQfIjVkvT+KXSMJu3o7TnOg7dLch6Y5CDjZy2Lz473o/o6M/t75wJ4o0TumNAeOfk9jlwyOP9Xb8HmaF8DxISUBcLzoKnCa56TDAleB070Nn+O9vEzF1xdsjtc35boK6HdEvfcMj1sFzvByXwVO86KvAqd7nP9IQTkesWmCx3G8fk6a40/3OI4/08uhQf0wyvFnetEH4yzPLcdrH3QbKMen2xXJEdCu8cYulOOR/jrb4zhePyfN8UHB7Yrjz/E2fJ7r5WU6qC/YHK9vylXBz/Wi3zvR4xR8ope7ggesNFkKfo7H+R/iE/WnXBo/UoOa/lwkp4m20lkp6nN9avhMPoyz9b2nenjA9okpzYEj1LNLBhuf5234PN/bCNn4fM9JhwUq6wXehs8LvbxMFdUXbDbWN+WqrPodUe+9yOOU9SIvd2U934uurBd4nP9IQdUFselij2Nj/Zw0G1/gcWx8iZdDg/phlI0v8aIPxqWeWzbWPug2UDZOtyuSI6BdFxq7UDZG+usyj2Nj/Zw0GwcFtys2nuRt+Lzcy8t0UF+w2VjflKuCX+5Fv/cKj1PwK7zcFTxgpclS8Eke53+ITzQbpwY1/bkoBU1zoNs6z8NsS2eriO3M7xNTmgMEqdLbu9LLoUH9MPrcVV5uK0QUu3Qbedhzvm1FmSS6LRRZkB/sX+3JYFRYO+cDNk32om9a/uewZUtISWifdRvoeFzjxRN8W5NpDqZ4OTSoH0afu9ZzG3zaLt1GHvYc1ZYOIj3ggr/pyeqDqcC9vWsozQEyhtd50fuFsUWPN9KG7k99f57VTliRTHMwLJ8bp7xo7fimObje2/B5g/6U5HD9woj3+paCat5r/0O6rTd6Gz5v8vIymVtfsE9S9E25crh+R9R7p3kch0/zcufwG7zoHH6jx/mPFBRLEJtu9riTFP2c9EnKjR53kjLdy6FB/TB6kjLdiz4Yt3i5LdVRfNBthCmO/Z50uyI5Atp1k7ELPUlB+utWD+O11ETVz2mRkFTwoOA2OiWe5uA2b8Pn7V5epoP6H3JV69u96Pfe4XFqfYeXu1oHrCpZan2bx/lfjU8iaQ5u87hVAU1zMAxIc3C9F91+BF0k0xwEBFzqVeJpDmZ4Gz7v9PIyA05fSFj/pm/KNQj1O6Lee5fHBeFdXu5pDpAgnOFx/lsla5Al0xxEmNTiaQ7u9jZ83uMFfBUcZnh654YU0T93uid6u76loJr32v+Qbuu93obP+7y8zMjTF+wNjL4p12jU74h67/0eF433e7kvifd40aPxXo/zHynoBgaxaabHbWD0c9IbmHs9bgPzgJdDg/phdAPzgBd9MB703G5gtA+6jTDFsd+TblckR0C77jN2oRsYpL8e8rgNjH5OegMTFNx+3xLapaB6szNKuq0Pexs+H/HyMh3UF2ye0jflquCPeNHvneVxCj7Ly13BA1aaLAV/2OP8D/GJ+nMnjR+psUt/LsyudB8iNWS9P4pd9xB29Xf8k0rNmQCyVel7NSeiaQ4CjjSzNn9R+Vx/HX+3F90GABET/WNKc+AIY+2Swf2Pehs+Z3sbIffP9px0WOCq8Zi34XOOl5e5QugLNvfrm3JdNfQ7ot77uMetGo97ua8as73oq8ZjHuc/UlA1RGx6wuO4Xz8nzf2PeRz3P+nl0KB+GOX+J73og/GU55b7tQ+6DZT70+2K5Aho1xxjF8r9SH897XHcr5+T5v6g4HbF/XO9DZ/PeHmZDuoLNvfrm3JV8Ge86Pc+63EK/qyXu4IHrDRZCj7X4/wP8Ynm/tTYpT8XZle6D5East4fxa7ZhF0DHKc50HZp7kPTHASc7GWx+aNedH9nR3/vfGBPlBgQU5oDR7+nsUsGxz/nbfh83gvg+JCS8eVIWJFcBZ73nHRY4Crwgrfh80UvL1Px9QWb4/VNua4C+h1R733J41aBl7zcV4HnveirwAse5z9SUI5HbJrncRyvn5Pm+Bc8juNf9nJoUD+McvzLXvTBeMVzy/HaB90GyvHpdkVyBLTrRWMXyvFIf73qcRyvn5Pm+KDgdsXxr3kbPud7eZkO6gs2x+ubclXw+V70exd4nIIv8HJX8ICVJkvBX/M4/0N8ov6US+NHalDTn4vkNNFWOitFfW5wDZ/Jh3G2vvc5Dw/YwTGlOXCEenbJYOPXvQ2fb3gbIRu/4TnpsEBlfdPb8PmWl5epovqCzcb6plyVVb8j6r1ve5yyvu3lrqxveNGV9U2P8x8pqLogNr3jcWysn5Nm4zc9jo3f9XJoUD+MsvG7XvTBWOi5ZWPtg24DZeN0uyI5Atr1lrELZWOkv97zODbWz0mzcVBwu2LjRd6Gz/e9vEwH9QWbjfVNuSr4+170exd7nIIv9nJX8ICVJkvBF3mc/yE+0WycGtT056IUNM2Bbut1D7Mtna0itjN/cExpDhCkSm/vAy+HBvXD6HMfermtEFHs0m3kYc/5thVlkui2UGSJuhnSbXzkyWBUWDtvADYt8aJvWv7nsGVLSElon3Ub6Hh87MUTfM3INAdLvRwa1A+jz33iuQ0+bZduIw97jmpLB5EecMHf9GT1wTLg3gE1lOYAGcNPvej9wtiixxtpQ/envj/PaiesSKY5GJ7PjVNetHZ80xws9zZ8fqY/JTlcvzDivb6loJr32v+Qbuvn3obPL7y8TObWF+yTFH1Trhyu3xH13hUex+ErvNw5/DMvOod/7nH+IwXFEsSmLz3uJEU/J32S8rnHnaR85eXQoH4YPUn5yos+GF97uS3VUXzQbYQpjv2edLsiOQLa9YW3wS70JAXpr288jNdSE1U/p0VCUsG/8EIFSzzNwbfehs+VXl6mg/ofclXrlV70e7/zOLX+zstdrb/woqv1tx7nfzU+iaQ5+NbjVgU0zcFwIM3Bci+6/Qi6SKY5+MILDRrxNAervA2f33t5mQGnLySsf9M35RqE+h1R713tcUG42ss9zcEXXvQgXOVx/lsla5Al0xxEmNTiaQ5+8DZ8/ugFfBUcZnh654YU0T93+jF6u76loJr32v+QbutP3obPNV5eZuTpC/YGRt+UazTqd0S992ePi8afvdyXxB+96NH4k8f5jxR0A4PY9IvHbWD0c9IbmJ88bgPzq5dDg/phdAPzqxd9MH7z3G5gtA+6DXQDk25XJEdAu9YYu9ANDNJfv3vcBkY/J72BCQpuv28J7VJQvdkZJd3WP7wNn396eZkO6gs2T+mbclXwP73o9671OAVf6+Wu4AErTZaC/+Fx/of4RP25k8aP1NilPxdmV7oPkRqy3h/Frh8Ju0Y4/kml5kwA2ar0vZoT0TQHAUeaWZu/qHyuv47/wYtuA4CIiRExpTlwhLF2yeD+v7wNn+u8jZD713lOOixw1fjb2/D5j5eXuULoCzb365tyXTX0O6Le+6/HrRr/ermvGuu86KvG3x7nP1JQNURsWu9x3K+fk+b+vz2O+/OSOTSoH0a5Xz9T3b1WSSSSbrlf+6DbCFOcrA5MYpMRtesfYxfK/Uh/5QM+pE9e/ZwWCUkFDwpuV9xfy0z8TZJ5mQ7WSmZz/ybJ3BV8E2Bwaic5Ba+dzF3BA1aaLAWvleT8D/GJ5v5aSTzYauUYzFHsSueqgoh2jXSc5kDbpbkPTXMQcLKXxeZ/edH9XRf9vfOBPVFiZExpDhz9nsYuGRy/qRG1OskAjg8pCYDjRVeBOkknHRa4CmxmOqyuvQroCzbH1xVYBeoCirk5uQpsLrAK1ElGXwU2S3L+IwXleMSmekmO4+sl5Tl+syTH8fWTOTRYP4lzfP3oA5loAAwG60ODJM7xDXJc+qNM9gZJnOOR/toC8CF98m6RlOf4uiDi2aWgerMzSrqtDc3Eb2QreMNkNsc3Suau4I2AwWlMKnhjAQWvCyh4wyTnf4hP1J9yafxIDWr6c5GcJtqqk8SfG13DZ/JhnK3v3TSJB+zomNIcOEI9u2Sw8ZZmTjVJboRs3MRNhwUq61amw5rayrpVMpuNmwooa1NAhbYmlXVrAWVtAijrVknOf6Sg6oLY1CzJsXGzpDwbb5Xk2HibZA4NbpPE2Xib6AOZaA4MButD8whLg/2e5uBkRO1qauxC2Rjpr20BH9In77ZJeTZuCmKTXQqqNzujpNvawkz87WwFb5HMZuPtkrkr+HbA4GxPKvj2AgreFFDwFknO/xCfaDZODWr6c1EKmuZAt7VlErOtSRLzSZ/ljo4pzQGCVOnt7VDdahKlwR2S+HMtc1whotjVkpxUzARumcSRBfnBfkES8yFVULFrAoxLq+g2UWkOtM+tkvh47JiMJ/i2IdMctGaDTzfYmgi+nRwHn7ZrJ6HgC7tdB5EecMHf9GT1QRugv0bWUJoDZAx3jh4QCcYWPd5IG7o/dybmh2SagxH53DjlRWvHN83BLsbnXfWnJIfvmnTiTJYoptva1jizWzIvk7n1BfskZTcBDt8NmPHtkhyHtxPg8F0BDm+b5PxHCooliE27J7mTlN2T8icpbZPcSUr7ZA4Ntk/iJyntAancAxgM1oc9IiCE/Z49wMmI2rWbsQs9SUH6qwPgQ/rk7ZCUP0nZLVywxNMc7GkmfkdbwTsmc1frjsBA7EWq9V4Car0boNZ7Jjn/q/FJJM3BnmAgpgqa5mAEkOZgF6CfEHSRTHMQEHCpV4mnOehkAm5vO+A6JbOPLvcWCMK9gYHYhwzCfSIEYQ5olxWEnZKc/1bJGmTJNAcRJrV4moN9zeTqnAz4KjjM8E7Ro1H0z506kyqWF9xOYDTuZzqsix2N+oK9gekiEI1dgJm7PxmN+wssiZ2BaNwvyfmPFHQDg9jUNcltYLom5Tcw+yW5DUy3ZA4N6ofRDUw3QCUKgcFgfShM4huYQnAyonZ1MXahGxikv4oAH9Inb1FSfgPTJbpgiX0VXGwmvmcreLEPT3nJ3BXcAwYnSSp4UkDBuwAKXpzk/A/xifpzJ40fxUk82IpzDOYodnUm7DrN8U8qNWcCyFal79WciKY52DV0jvy3+YvK5/rr+H2BuQcgYuK0mNIcOMJYu2Rwf4kRwdLkRsj9pW46LGH/Q7qtZabDyu1VoyyZzf3lAqtGOTDLK8hVo0Jg1SgFVo2yJOc/UlA1RGyqTHLcX5mU5/6yJMf93ZM5NKgfRrm/O6ASPYDBYH3okcS5v0eOqBBlsvdI4tyP9NcBgA/pk/eApDz3l4NIaJeC6s3OKOm29jQT/0BbwXsms7n/wGTuCn4gMDi9SAXvJaDg5YCC90xy/of4RHN/zyQebD1zDOYodpUSdo13nOZA26W5D01z0DnimGs2LwHmR2n0984H9kSJ8TGlOXD0exq7ZHD8QUbUeicDOD6kJACOF10FervpsIT9D+m2Hmw67BB7FTg4mc3xhwisAocAEXEouQocKrAK9AZWgYOTnP9IQTkesalPkuP4Pkl5jj84yXH8YckcGtQPoxx/WPSBTBwODAbrw+FJnOMPz3HpjzLZD0/iHI/01xGAD+mT94ikPMcfAiKeXQqqNzujpNt6pJn4fW0FPzKZzfF9k7kreF9gcPqRCt5PQMEPART8yCTnf4hP1J9yafxIDWr6c5GcJtrqncSfO6uGz+TDOFvfe1ASD9izYkpz4Aj17JLBxkeZOdU/uRGycX83HRaorEebDhtgK+vRyWw2HiCgrAMAFTqGVNZjBJS1P6CsRyc5/5GCqgti08Akx8YDk/JsfHSSY+NByRwaHJTE2XhQ9IFMDAYGg/VhcISlwX7PYHAyonYNMHahbIz017GAD+mT99ikPBsPALHJLgXVm51R0m0dYiZ+la3gQ5LZbFyVzF3Bq4DBGUoq+FABBR8AKPiQJOd/iE80G6cGNf25KAVNc6DbOiqJ2dY/ifmkz3LPiinNAYJU6e0dV91qEqXB45L4c8OAQWDtGkZOKmYCD0viyIL8YH94EvMhVVCx6w/YNCK6TVSaA+3ziCQ+Hscn4wm+5mSag5Fs8OkGRxLBd4Lj4NN2nSAUfGG36yDSAy74m56sPhgF3Du+htIcIGN4YvSASDC26PFG2tD9eSIxPyTTHByfz41TXrR2fNMcjDY+n6Q/JTn8pKQTZ7JEMd3Wk40zpyTzMplbX7BPUk5J5s7h+h1R7x2T5DhcP2fbiSrLScnoHH5ykvMfKSiWIDaNTXInKfo56ZOUk5PcScq4ZA4N6ofRk5Rx0QcycSowGKwPug37uTAfTgUnI2rXKcYu9CQF6a/TAB/SJ+9pSfmTlFPCBUs8zcHpZuKPT+ZlOjg+mbtajwcG4gxSrc8QUOtTALU+Pcn5X41PImkOTgcDMVXQNAfHA2kORgP9hKCLZJqDgIBLvUo8zcEEE3Bn2gE3IZl9dHmmQBCeCQzEWWQQnhUhCHNAu6wgnJDk/LdK1iBLpjmIMKnF0xycbSbXOcmAr4LDDJ8QPRpF/9zpHFLF8oLbCYzGc02HTbSjUV+wNzATBaJxIjBzzyOj8TyBJfEcIBrPTXL+IwXdwCA2nZ/kNjDnJ+U3MOcmuQ3MBckcGtQPoxuYCwCVuBAYDNaHC5P4BuZCcDKidk00dqEbGKS/LgJ8SJ+8FyXlNzATowuW2FfBF5uJf4mt4Bf78NQlydwV/BJgcC4lFfxSAQWfCCj4xUnO/xCfqD930vhxcRIPtotzDOYodp1D2HWh459Uas4EkK1K36s5EU1zcFLoHPlv8xeVz/XX8WcDcw9AxMSFMaU5cISxdsng/suMCE5KboTcP8lNhyXsf0i39XLTYVfYq8blyWzuv0Jg1bgCmOVXkqvGlQKrxiRg1bg8yfmPFFQNEZuuSnLcf1VSnvsvT3Lcf3Uyhwb1wyj3Xw2oxGRgMFgfJidx7p+cIypEmeyTkzj3I/11DeBD+uS9JinP/VeASGiXgurNzijptk4xE/9aW8GnJLO5/9pk7gp+LTA4U0kFnyqg4FcACj4lyfkf4hPN/VOSeLBNyTGYo9g1ibDrYsdpDrRdmvvQNAfnRBxzzeaXAfNjUvT3zgf2RImLY0pz4Oj3NHbJ4PjrjKhdnwzg+JCSADhedBW43k2HJex/SLf1BtNhN9qrwA3JbI6/UWAVuBGIiJvIVeAmgVXgemAVuCHJ+Y8UlOMRm6YlOY6flpTn+BuSHMffnMyhQf0wyvE3Rx/IxHRgMFgfpidxjp+e49IfZbJPT+Icj/TXLYAP6ZP3lqQ8x98IIp5dCqo3O6Ok23qrmfi32Qp+azKb429L5q7gtwGDczup4LcLKPiNgILfmuT8D/GJ+lMujR+pQU1/LpLTRFvXJ/HnJtXwmXwYZ+t7r0sSR6cxpTlwhHp2yWDjO8ycmpHcCNl4hpsOC1TWO02H3WUr653JbDa+S0BZ7wJU6G5SWe8WUNYZgLLemeT8RwqqLohN9yQ5Nr4nKc/GdyY5Nr43mUOD9yZxNr43+kAm7gMGg/XhvghLg/2e+8DJiNp1l7ELZWOkv+4HfEifvPcn5dn4LhCb7FJQvdkZJd3WmWbiP2Ar+MxkNhs/kMxdwR8ABudBUsEfFFDwuwAFn5nk/A/xiWbj1KCmPxeloGkOdFt3JDHbZiQxn/RZ7qSY0hwgSJXe3kPVrSZRGnwoiT/3MDAIrF0Pk5OKmcAPJ3FkQX6w/0gS8yFVULGbAdg0K7pNVJoD7fOsJD4ejybjCb5tyTQHs9ng0w3OJoLvMcfBp+16TCj4wm7XQaQHXPA3PVl9MAe49+IaSnOAjOHj0QMiwdiixxtpQ/fn48T8kExzMDKfG6e8aO34pjl4wvj8pP6U5PAnk06cyRLFdFufMs48nczLZG59wT5JeTqZO4c/Dcz4uUmOw+cmc+fwJ5PROfypJOc/UlAsQWx6JsmdpDyTlD9JeSrJnaQ8m8yhwWeT+EnKs4BUPgcMBuvDcxEQwn7Pc+BkRO162tiFnqQg/fU84EP65H0+KX+S8nS4YImnOXjBTPwXbQV/MZm7Wr8IDMRLpFq/JKDWTwNq/UKS878an0TSHLwABmKqoGkORgJpDp4A+glBF8k0BwEBl3qVeJqDeSbgXrYDbl4y++jyZYEgfBkYiFfIIHwlQhDmgHZZQTgvyflvlaxBlkxzEGFSi6c5eNVMrteSAV8Fhxk+L3o0iv6502ukiuUFtxMYjfNNhy2wo1FfsDcwCwSicQEwc18no/F1gSXxNSAa5yc5/5GCbmAQm95IchuYN5LyG5j5SW4D82Yyhwb1w+gG5k1AJd4CBoP14a0kvoF5C5yMqF0LjF3oBgbpr7cBH9In79tJ+Q3MguiCJfZV8Dtm4r9rK/g7Pjz1bjJ3BX8XGJyFpIIvFFDwBYCCv5Pk/A/xifpzJ40f7yTxYHsnx2COYtdrhF1THP+kUnMmgGxV+l7NiWiagydD58h/m7+ofK6/jn8VmHsAIiamxJTmwBHG2iWD+98zIrgouRFy/yI3HZaw/yHd1vdNhy22V433k9ncv1hg1VgMzPIPyFXjA4FVYxGwaryf5PxHCqqGiE0fJjnu/zApz/3vJznu/yiZQ4P6YZT7PwJUYgkwGKwPS5I49y/JERWiTPYlSZz7kf76GPAhffJ+nJTn/sUgEtqloHqzM0q6rUvNxP/EVvClyWzu/ySZu4J/AgzOMlLBlwko+GJAwZcmOf9DfKK5f2kSD7alOQZzFLsWEXZNdZzmQNuluQ9Nc/BaxDHXbP4eMD8WRX/vfGBPlJgaU5oDR7+nsUsGx39qRG15MoDjQ0oC4HjRVWC5mw5L2P+QbutnpsM+t1eBz5LZHP+5wCrwORARX5CrwBcCq8ByYBX4LMn5jxSU4xGbViQ5jl+RlOf4z5Icx3+ZzKFB/TDK8V9GH8jEV8BgsD58lcQ5/qscl/4ok/2rJM7xSH99DfiQPnm/Tspz/Ocg4tmloHqzM0q6rd+Yif+treDfJLM5/ttk7gr+LTA4K0kFXymg4J8DCv5NkvM/xCfqT7k0fqQGNf25SE4TbS1P4s/dWMNn8mGcre/9NIkH7I0xpTlwhHp2yWDj78ycWpXcCNl4lZsOC1TW702HrbaV9ftkNhuvFlDW1YAK/UAq6w8CyroKUNbvk5z/SEHVBbHpxyTHxj8m5dn4+yTHxj8lc2jwpyTOxj9FH8jEGmAwWB/WRFga7PesAScjatdqYxfKxkh//Qz4kD55f07Ks/FqEJvsUlC92Rkl3dZfzMT/1VbwX5LZbPxrMncF/xUYnN9IBf9NQMFXAwr+S5LzP8Qnmo1Tg5r+XJSCpjnQbX2XxGxblcR80me5N8aU5gBBqvT2fq9uNYnS4O9J/Lk/gEFg7fqDnFTMBP4jiSML8oP9P5OYD6mCit0qwKa10W2i0hxon9cm8fH4KxlP8LUg0xysY4NPN7iOCL6/HQeftutvoeALu10HkR5wwd/0ZPXBP8C9U2sozQEyhv9GD4gEY4seb6QN3Z//EvNDMs3BCfncOOVFa8c3zcH6lM8lebIcrl8Y8V7fUlDde62SbmuixPxbSV4mc+sL9kmKvmliNS8rMJ9hsyy/JPq9tUo4Dq9VkjuH55VE5/BECec/UlAsQWzapIQ7SdmkRP4kJVHCnaTULsmhQf0wepJSO/pAJjYFBoP1QbcRpjj2ezYFJyNqV76xCz1JQfqrDuBD+uStUyJ/kpIfLljiaQ42MxO/rq3gdQXUui4wEJuTar25gFrnA2q9WQnnfzU+iaQ52IxcFdA0BycAaQ7WI/sLwH7JNAcBAZd6lXiag3om4OrbAVevJPvosr5AENYHJmwDMggbRAjCHNAuKwjrlXD+WyVrkCXTHESY1OJpDrYwk6thScBXwWGG1wPQRHL5axjDBqaR6bDGdjQ28tnANBaIxsbAzN2SjMYtBZbEhkA0Nirh/EdKGAPa9iM2NSE3ME0cbGAakRuYrUpyaHArYgOzFaASTR1vYLQPTYkNTFPHG5jGxi50A4P019bkBmZrBxuYxtEFS+yr4GZm4m9jK3gzH57aRkDBtwEGpzmp4M0FFLwxoODNSjj/Q3yi/txJ40ezEjzYmuUYzFHsakjYdbvjn1RqzgSQrUrfqzkRTXOQFzpH/tv8ReVz/XX8FsDcAxAxcXtMaQ4cYaxdMrh/WyOCLUo2Qu5vEQP3b2c6bHt71djOh/u3F1g1tgdm+Q7kqrGDwKrRAlg1tivh/EcKqoaITS1J7m/pgPu3I7m/oCSXBgnuLwBUopVj7tc+tCK4v5Vj7t/e2IVyP9JfO5Lcv6MD7t8+Bu5vbSb+TraCt/bh/p0EFHwnYHDakAreRkDBtwcUvHUJ53+ITzT3tyb4unWOwRzFrhaEXTMcpznQdm1bgqc5aAiw+bbA/GgR/b3zgT1RYkZMaQ4c/Z7GLhkcv7MRtV2COD6kJACOF10FdomB43c1HdbWXgV29eH4tgKrQFsgInYjV4HdBFaBXYBVYNcSzn+khKGQbT9iUzuS49s54PhdSY7fvSSHBncnOH53gOPbO+Z47UN7guPbO+b4tsYulOOR/tqD5Pg9HHB82xg4voOZ+HvaCt7Bh+P3FFDwPYHB6UgqeEcBBW8LKHiHEs7/EJ+oP+XS+JEa1PTnIjlNtLULweb31PCZfBhn63t3LsED9p6Y0hw4Qj27ZLDxXmZOdSrZCNm4UwxsvLfpsH1sZd3bh433EVDWfQAV2pdU1n0FlLUToKx7l3D+IwVVF8SmziQbd3bAxnuTbLwfy8a6wf0INt4PYOMujtlY+9CFYOMujtl4H2MXysZIf+1PsvH+Dth4nxjYuKuZ+N1sBe/qw8bdBBS8GzA4haSCFwoo+D6Agnct4fwP8Ylm49Sgpj8XpSBjmWLKvUow2zqBLK3Pcu+JKc1BJ1AcUqWoutUkSoNFJfhzxTmuEFHsKq7BDVdxCY4syA/2PSGMCmunE2BTMrpNVJoD7XOS2MiWlMQTfNvlc8FXygafbrCUCL4yx8Gn7SoTCr6w23UQ6QEX/E1PVh+UA/fOqKE0B8gYVgDoztiixxtpQ/dnBTE/JNMcjMrnxikvWju+aQ4qjc/d9ackh3cvceJMliim29rDOHOAzeE9fE5SDhDg8AOAGd+T5PCeAhzeHeDwHiWc/0hBsQSx6UDyJOVABycpPciTlF7sSYpusBdxktILkMqDclyqo/hwEHGScpDjk5QDjF3oSQrSX73Jk5TeDk5SDggXLPE0BwebiX+IreCHCKj1IcBAHEqq9aECan0AoNYHl3D+V+OTSJqDg8lVAU1zkM5LYX/pUgn0E4IukmkOAgIu9SrxNAd9TMAdZgdcH5+jy8MEgvAwYCAOJ4Pw8AhBmAPaZQVhnxLOf6tkDbJkmoMIk1o8zcERZnIdWRLwVXCY4X0ANJFc/o6MYQPT13RYPzsa+/psYPoJRGM/YOYeRUbjUQJL4pFANPYt4fxHShgD2vYjNvUnNzD9HWxg+pIbmKNLcmjwaGIDczSgEgMcb2C0DwOIDcwAxxuYfsYudAOD9Ncx5AbmGAcbmH7RBUvsq+CBZuIPshV8oA9PDRJQ8EHA4AwmFXywgIL3AxR8YAnnf4hP1J87afwYWIIH28AcgzmKXUcSdj3s+CeVmjMBZKvS92pORNMcdA+dI/9t/qLyuf46/ghg7gGImHg4pjQHjjDWLhncf6wRwSElGyH3D4mB+6tMhw21V40qH+4fKrBqDAVm+XHkqnGcwKoxBFg1qko4/5GCqiFi0zCS+4c54P4qkvuHl+TQ4HCC+4cDKjHCMfdrH0YQ3D/CMfcPNXah3I/01/Ek9x/vgPuHxsD9I83EP8FW8JE+3H+CgIKfAAzOKFLBRwko+FBAwUeWcP6H+ERz/0iCr0fmGMxR7BpC2DXLcZoDbdexJXiagyMBNj8WmB9Dor93PrAnSsyKKc2Bo9/T2CWD4080ojY6iONDSgLgeNFVYHQMHH+S6bCT7VXgJB+OP1lgFTgZiIhTyFXgFIFVYDSwCpxUwvmPlDAUsu1HbBpDcvwYBxx/EsnxY0tyaHAswfFjAY4f55jjtQ/jCI4f55jjTzZ2oRyP9NepJMef6oDjT46B408zE/90W8FP8+H40wUU/HRgcMaTCj5eQMFPBhT8tBLO/xCfqD/l0viRGtT05yI5TbQ1mmDzOTV8Jh/G2freE0vwgJ0TU5oDR6hnlww2PsPMqQklGyEbT4iBjc80HXaWraxn+rDxWQLKehagQmeTynq2gLJOAJT1zBLOf6Sg6oLYdA7Jxuc4YOMzSTY+l2Vj3eC5BBufC7DxRMdsrH2YSLDxRMdsfJaxC2VjpL/OI9n4PAdsfFYMbHy+mfgX2Ap+vg8bXyCg4BcAg3MhqeAXCij4WYCCn1/C+R/iE83GqUFNfy5KQcYyxZRnlGC2TQBZWp/lzokpzcEEUBxS5aLqVpMoDV5Ugj93cY4rRBS7Lq7BDdfFJTiyID/Yv0QIo8LamQDYdGl0m6g0B9rnS4mN7GUl8QTf9vlc8E1ig083OIkIvssdB5+263Kh4Au7XQeRHnDB3/Rk9cEVwL2zaijNATKGVwLoztiixxtpQ/fnlcT8kExzcGI+N0550drxTXNwlfH5av0pyeFXlzhxJksU022dbJy5xubwyT4nKdcIcPg1wIyfQnL4FAEOvxrg8MklnP9IQbEEsela8iTlWgcnKZPJk5Sp7EmKbnAqcZIyFZDK63JcqqP4cB1xknKd45OUa4xd6EkK0l/Xkycp1zs4SbkmXLDE0xzcYCb+jbaC3yig1jcCA3ETqdY3Caj1NYBa31DC+V+NTyJpDm4gVwU0zUE6L4X9pctVQD8h6CKZ5iAg4FKvEk9zMM0E3M12wE3zObq8WSAIbwYGYjoZhNMjBGEOaJcVhNNKOP+tkjXIkmkOIkxq8TQHt5jJdWtJwFfBYYZPA9BEcvm7NYYNzG2mw263o/E2nw3M7QLReDswc+8go/EOgSXxViAabyvh/EdKGAPa9iM2zSA3MDMcbGBuIzcwd5bk0OCdxAbmTkAl7nK8gdE+3EVsYO5yvIG53diFbmCQ/rqb3MDc7WADc3t0wRL7KvgeM/HvtRX8Hh+euldAwe8FBuc+UsHvE1Dw2wEFv6eE8z/EJ+rPnTR+3FOCB9s9OQZzFLtuJex61vFPKjVnAshWpe/VnIimObg6dI78t/mLyuf66/hbgLkHIGLi2ZjSHDjCWLtkcP/9RgRnlmyE3D8zBu5/wHTYg/aq8YAP9z8osGo8CMzyh8hV4yGBVWMmsGo8UML5jxRUDRGbHia5/2EH3P8Ayf2PlOTQ4CME9z8CqMQsx9yvfZhFcP8sx9z/oLEL5X6kvx4luf9RB9z/YAzcP9tM/MdsBZ/tw/2PCSj4Y8DgzCEVfI6Agj8IKPjsEs7/EJ9o7p9N8PXsHIM5il0zCbued5zmQNt1fwme5uBWgM3vB+bHzOjvnQ/siRLPx5TmwNHvaeySwfGPG1F7IojjQ0oC4HjRVeCJGDj+SdNhT9mrwJM+HP+UwCrwFBART5OrwNMCq8ATwCrwZAnnP1LCUMi2H7FpLsnxcx1w/JMkxz9TkkODzxAc/wxylOKY47UPzxIc/6xjjn/K2IVyPNJfz5Ec/5wDjn8qBo5/3kz8F2wFf96H418QUPAXgMF5kVTwFwUU/ClAwZ8v4fwP8Yn6Uy6NH6lBTX8uktNEW08QbD6vhs/kwzhb3/t4CR6w82JKc+AI9eySwcYvmTk1r2QjZON5MbDxy6bDXrGV9WUfNn5FQFlfAVToVVJZXxVQ1nmAsr5cwvmPFFRdEJteI9n4NQds/DLJxvNZNtYNzifYeD7Axgscs7H2YQHBxgscs/Erxi6UjZH+ep1k49cdsPErMbDxG2biv2kr+Bs+bPymgIK/CQzOW6SCvyWg4K8ACv5GCed/iE80G6cGNf25KAUZyxRTvlSC2TYPZGl9ljsvpjQH80BxSJW3q1tNojT4dgn+3Ds5rhBR7HqnBjdc75TgyIL8YP9dIYwK3QQCNi2MbhOV5kD7vJDYyL5XEk/w7ZDPBd8iNvh0g4uI4HvfcfBpu94XCr6w23UQ6QEX/E1PVh8sBu59vobSHCBj+AGA7owteryRNnR/fkDMD8k0B6PzuXHKi9aOb5qDD43PH+lPSQ7/qMSJM1mimG7rEuPMxzaHL/E5SflYgMM/Bmb8UpLDlwpw+EcAhy8p4fxHCooliE2fkCcpnzg4SVlCnqQsY09SdIPLiJOUZYBUfprjUh3Fh0+Jk5RPHZ+kfGzsQk9SkP5aTp6kLHdwkvJxuGCJpzn4zEz8z20F/1xArT8HBuILUq2/EFDrjwG1/qyE878an0TSHHxGrgpomoN0Xgr7S5cPgX5C0EUyzUFAwKVeJZ7mYIUJuC/tgFvhc3T5pUAQfgkMxFdkEH4VIQhzQLusIFxRwvlvlaxBlkxzEGFSi6c5+NpMrm9KAr4KDjN8BYAmksvfNzFsYL41HbbSjsZvfTYwKwWicSUwc78jo/E7gSXxGyAavy3h/EdKGAPa9iM2rSI3MKscbGC+JTcw35fk0OD3xAbme0AlVjvewGgfVhMbmNWONzArjV3oBgbprx/IDcwPDjYwK6MLlthXwT+aif+TreA/+vDUTwIK/hMwOGtIBV8joOArAQX/sYTzP8Qn6s+dNH78WIIH2485BnMUu74h7HrD8U8qNWcCyFal79WciKY5+Ch0jvy3+YvK5/rr+K+BuQcgYuKNmNIcOMJYu2Rw/89GBH8p2Qi5/5cYuP9X02G/2avGrz7c/5vAqvEbMMt/J1eN3wVWjV+AVePXEs5/pKBqiNj0B8n9fzjg/l9J7v+zJIcG/yS4/09AJdY65n7tw1qC+9c65v7fjF0o9yP99RfJ/X854P7fYuD+dWbi/20r+Dof7v9bQMH/BgbnH1LB/xFQ8N8ABV9Xwvkf4hPN/esIvl6XYzBHsesXwq63HKc50Hb9XIKnOfgGYPOfgfnxS/T3zgf2RIm3Ykpz4Oj3NHbJ4Ph/jaitD+L4kJIAOF50FVgfA8fnlZqbSvMyFV9fsDle35TrKqDfEfXe/FJuFcgvzX0VWA+sAnmlnP9IQTkesalWKcfxtUrlOT6vlOP4TUpzaFA/jHL8JtEHMlEbGAzWB90GyvG1wcmI2pUwdqEcj/TXpoAP6ZN301J5jk9EFywxjq9jJv5mtoLXKc3m+M0EFHwzYHDqkgpeV0DBA1aaLAWvU8r5H+IT9adcGj9Sg5r+XCSnibbWE2y+sIbP5MM4W9/7bwkesAtjSnPgCPXsksHGm5s5Va90I2TjeqVOOixQWeubDmtgK2t9HzZuIKCsDQAV2oJU1i0ElLUeoKz1Szn/kYKqC2JTQ5KNGzpg4/okGzdi2Vg32Ihg40YAGzd2zMbah8YEGzd2zMYNjF0oGyP9tSXJxls6YOMGMbBxEzPxt7IVvIkPG28loOBbAYPTlFTwpgIK3gBQ8CalnP8hPtFs3IRkY2QsU0y5eSlmW71SzCd9lrswpjQH9UBxSJWtq1tNojS4dSn+XLMcV4godjWrwQ1Xs1IcWZAf7G8jhFFh7dQDxqV5dJuoNAfa5+al+HhsWxpP8LXM54KvBRt8usEWRPBt5zj4tF3bCQVf2O06iPSAo6vlL0DwbQ/011s1lOYAGcMdAHRnbNHjjbSh+3MHYn5Ipjk4KZ8bp7xo7fimOWhpfC7Qn5IcXlDqxJksUUy3tZVxZkebw1v5nKTsKMDhOwIzvjXJ4a0FOLwA4PBWpZz/SEGxBLFpJ/IkZScHJymtyJOUNuxJim6wDXGS0gaQyp0dn6RoH3YmTlJ2dnySsqOxCz1JQfprF/IkZRcHJyk7hguWeJqDXc3Eb2sreFsBtW4LDMRupFrvJqDWOwJqvWsp5381PomkOdiVXBXAfsrgpbC/dGkJ9BOCLpJpDgICLvUq8TQH7UzA7W4HXDufo8vdBYJwd2Ag2pNB2D5CEOaAdllB2K6U898qWYMsmeYgwqQWT3Owh5lcHUoDvgoOM7wdgCaSy1+HGDYwe5oO62hH454+G5iOAtHYEZi5e5HRuJfAktgBiMY9Szn/kYJuYBCbOpEbmE4ONjB7khuYvUtzaHBvYgOzN6AS+zjewGgf9iE2MPs43sB0NHahGxikv/YlNzD7OtjAdIwuWGJfBXc2E38/W8E7+/DUfgIKvh8wOF1IBe8ioOAdAQXvXMr5H+IT9edOGj86l+LB1jnHYI5iVwfCriWOf1KpORNAtip9r+ZENM1BQegc+W/zF5XP9dfxewBzD0DExJKY0hw4wli7ZHD//kYEu5ZuhNzfNQbu72Y6rNBeNbr5cH+hwKpRCMzyInLVKBJYNboCq0a3Us5/pKBqiNhUTHJ/sQPu70Zyv1eaQ4Mewf0eoBJJx9yvfUgS3J90zP2Fxi6U+5H+KiG5v8QB9xfGwP2lZuKX2Qpe6sP9ZQIKXgYMTjmp4OUCCl4IKHhpKed/iE8095cSfF1aA9zflbBrqeM0B9qu/UvxNAcdADbfH5gfXaO/dz6wJ0osjSnNgaPf09glg+MrjKhVBnF8SEkAHC+6ClTGwPHdTYf1sFeB7j4c30NgFegBRMQB5CpwgMAqUAmsAt1LOf+RgnI8YlNPkuN7OuD47iTHH1iaQ4MHEhx/IMDxvRxzvPahF8HxvRxzfA9jF8rxSH8dRHL8QQ44vkcMHN/bTPyDbQXv7cPxBwso+MHA4BxCKvghAgreA1Dw3qWc/yE+UX/KpfEjNajpz0VymmirkmDz5TV8Jh/G2freilI8YJfHlObAEerZJYONDzVzqs/GyMZ9YmDjw0yHHW4r62E+bHy4gLIeDqjQEaSyHiGgrH0AZT2slPMfKai6IDYdSbLxkQ7Y+DCSjfuybKwb7EuwcV+Ajfs5ZmPtQz+Cjfs5ZuPDjV0oGyP9dRTJxkc5YOPDY2Dj/mbiH20reH8fNj5aQMGPBgZnAKngAwQU/HBAwfuXcv6H+ESzcX+SjdE0B7qtQ0sx2/qALK3PcpfHlOagDygOqXJMdatJlAaPISB9YI4rRBS7BtbghmtgKY4syA/2BwlhVFg7fQCbBke3iUpzoH0eTGxkjy2NJ/gKyDQHQ9jg0w0OIYKvynHwabuqhIIv7HYdRHrA0dWyK9AHQ4F7l9ZQmgNkDI8D0J2xRY830obuz+OI+SGZ5uDkfG6c8qK145vmYJjxebj+lOTw4aVOnMkSxXRbRxhnjrc5fITPScrxAhx+PDDjR5IcPlKAw4cDHD6ilPMfKSiWIDadQJ6knODgJGUEeZIyij1J0Q2OIk5SRgFSeWKOS3UUH04kTlJOdHyScryxCz1JQfprNHmSMtrBScrx4YIlnubgJDPxT7YV/GQBtT4ZGIhTSLU+RUCtjwfU+qRSzv9qfBJJc3ASuSqA/ZTBS2F/6TIM6CcEXSTTHAQEXOpV4mkOxpiAG2sH3Bifo8uxAkE4FhiIcWQQjosQhDmgXVYQjinl/LdK1iBLpjmIMKnF0xycaibXaaUBXwWHGT4GQBPJ5e+0GDYwp5sOG29H4+k+G5jxAtE4Hpi5Z5DReIbAkngaEI2nl3L+IwXdwCA2TSA3MBMcbGBOJzcwZ5bm0OCZxAbmTEAlznK8gdE+nEVsYM5yvIEZb+xCNzBIf51NbmDOdrCBGR9dsMS+Cj7HTPxzbQU/x4enzhVQ8HOBwZlIKvhEAQUfDyj4OaWc/yE+UX/upPHjnFI82M7JMZij2HUaYdc3jn9SqTkTQLYqfa/mRDTNwfDQOfLf5i8qn+uv408F5h6AiIlvYkpz4Ahj7ZLB/ecZETy/dCPk/vNj4P4LTIddaK8aF/hw/4UCq8aFwCy/iFw1LhJYNc4HVo0LSjn/kYKqIWLTxST3X+yA+y8guf+S0hwavITg/ksAlbjUMfdrHy4luP9Sx9x/obEL5X6kvy4juf8yB9x/YQzcP8lM/MttBZ/kw/2XCyj45cDgXEEq+BUCCn4hoOCTSjn/Q3yiuX8SwdeTaoD7zyfsWuk4zYG267xSPM3BaQCbnwfMj/Ojv3c+sCdKrIwpzYGj39PYJYPjrzSidlUQx4eUBMDxoqvAVTFw/NWmwybbq8DVPhw/WWAVmAxExDXkKnCNwCpwFbAKXF3K+Y8UlOMRm6aQHD/FAcdfTXL8taU5NHgtwfHXAhw/1THHax+mEhw/1THHTzZ2oRyP9Nd1JMdf54DjJ8fA8debiX+DreDX+3D8DQIKfgMwODeSCn6jgIJPBhT8+lLO/xCfqD/l0viRGtT05yI5TbR1FcHmq2v4TD6Ms/W9V5biAbs6pjQHjlDPLhlsfJOZU9M2RjaeFgMb32w6bLqtrDf7sPF0AWWdDqjQLaSy3iKgrNMAZb25lPMfKai6IDbdSrLxrQ7Y+GaSjW9j2Vg3eBvBxrcBbHy7YzbWPtxOsPHtjtl4urELZWOkv+4g2fgOB2w8PQY2nmEm/p22gs/wYeM7BRT8TmBw7iIV/C4BBZ8OKPiMUs7/EJ9oNp5BsjGa5kC3dVMpZts0kKX1We7qmNIcTAPFIVXurm41idLg3QSk35PjChHFrntqcMN1TymOLMgP9u8VwqiwdqYBNt0X3SYqzYH2+T5iI3t/aTzB14pMczCTDT7d4Ewi+B5wHHzargeEgi/sdh1EesDR1fJ8oA8eBO5dWUNpDpAxfAhAd8YWPd5IG7o/HyLmh2Sag1PyuXHKi9aOb5qDh43Pj+hPSQ5/pNSJM1mimG7rLOPMozaHz/I5SXlUgMMfBWb8bJLDZwtw+CMAh88q5fxHCooliE2PkScpjzk4SZlFnqTMYU9SdINziJOUOYBUPp7jUh3Fh8eJk5THHZ+kPGrsQk9SkP56gjxJecLBScqj4YIlnubgSTPxn7IV/CkBtX4KGIinSbV+WkCtHwXU+slSzv9qfBJJc/AkuSqA/ZTBS2F/6fIw0E8IukimOQgIuNSrxNMczDUB94wdcHN9ji6fEQjCZ4CBeJYMwmcjBGEOaJcVhHNLOf+tkjXIkmkOIkxq8TQHz5nJ9XxpwFfBYYbPBdBEcvl7PoYNzAumw160o/EFnw3MiwLR+CIwc18io/ElgSXxeSAaXyjl/EcKuoFBbJpHbmDmOdjAvEBuYF4uzaHBl4kNzMuASrzieAOjfXiF2MC84ngD86KxC93AIP31KrmBedXBBubF6IIl9lXwa2biz7cV/DUfnpovoODzgcFZQCr4AgEFfxFQ8NdKOf9DfKL+3Enjx2uleLC9lmMwR7HrecKu3xz/pFJzJoBsVfpezYlomoNHQufIf5u/qHyuv45/Dph7ACImfospzYEjjLVLBve/bkTwjdKNkPvfiIH73zQd9pa9arzpw/1vCawabwGz/G1y1XhbYNV4A1g13izl/EcKqoaITe+Q3P+OA+5/k+T+d0tzaPBdgvvfBVRioWPu1z4sJLh/oWPuf8vYhXI/0l/vkdz/ngPufysG7l9kJv77toIv8uH+9wUU/H1gcBaTCr5YQMHfAhR8USnnf4hPNPcvIvh6UQ1w/xuEXX84TnOg7Xq9FE9z8DzA5q8D8+ON6O+dD+yJEn/ElObA0e9p7JLB8R8YUfswiONDSgLgeNFV4MMYOP4j02FL7FXgIx+OXyKwCiwBIuJjchX4WGAV+BBYBT4q5fxHCsrxiE1LSY5f6oDjPyI5/pPSHBr8hOD4TwCOX+aY47UPywiOX+aY45cYu1COR/rrU5LjP3XA8Uti4PjlZuJ/Ziv4ch+O/0xAwT8DBudzUsE/F1DwJYCCLy/l/A/xifpTLo0fqUFNfy6S00RbHxJsvq6Gz+TDOFvf+0EpHrDrYkpz4Aj17JLBxl+YObViY2TjFTGw8Zemw76ylfVLHzb+SkBZvwJU6GtSWb8WUNYVgLJ+Wcr5jxRUXRCbviHZ+BsHbPwlycbfsmysG/yWYONvATZe6ZiNtQ8rCTZe6ZiNvzJ2oWyM9Nd3JBt/54CNv4qBjVeZif+9reCrfNj4ewEF/x4YnNWkgq8WUPCvAAVfVcr5H+ITzcarSDZG0xzotr4oxWxbAbK0PstdF1OagxWgOKTKD9WtJlEa/IGA9B9zXCGi2PVjDW64fizFkQX5wf5PQhgV1s4KwKY10W2i0hxon9cQG9mfS+MJvh3JNAe/sMGnG/yFCL5fHQeftutXoeALu10HkR5wdLV8A+iD34B7/6ihNAfIGP4OoDtjix5vpA3dn78T80MyzcGYfG6c8qK145vm4A/j85/6U5LD/yx14kyWKKbbutY485fN4Wt9TlL+EuDwv4AZv47k8HUCHP4nwOFrSzn/kYJiCWLT3+RJyt8OTlLWkicp/7AnKbrBf4iTlH8Aqfw3x6U6ig//Eicp/zo+SfnL2IWepCD9tZ48SVnv4CTlr3DBEk9zkFdmbirLy3RQ/0Ouaq3fEfXe/DJOrfPLclfrvwC1zivj/K/GJ5E0B3ll3KoA9lMGL4X9pcsfQBAi6CKZ5iAg4FKvEk9zUMsE3CZ2wOkLCevfNhEIwk2ACVubDMLaEYIwB7TLCsJaZZz/VskaZMk0BxEmtXiag03N5KpTFvBVcJjhtaKrieifO9UhVSwvuJ3AaNzMdFhdOxr1BXsDU1cgGusCM3dzMho3F1gS65RFj8bNyjj/kYJuYBCb6pVxG5h6ZfIbmM3KuA1M/bIcGtQPoxuY+oBKNAAGg/WhQRm+gWkATkbUrrrGLnQDg/TXFoAP6ZN3izL5DUzd6IIl9lVwQzPxG9kK3tCHpxoJKHgjYHAakwreWEDB6wIK3rCM8z/EJ+rPnTR+NCzDg61hjsEcxa46hF21DsTsQlc6zZkAslXpezUnomkO/gzd0P23+YvK5/rr+E2BuQcgYiJCvztJc+AIY+2Swf1bGhFssjFyf5MYuH8r02FN7VVjKx/ubyqwajQFZvnW5KqxtcCq0QRYNbYq4/xHCqqGiE3NSO5v5oD7tyK5fxuW+3WD2xDcvw2gEs0dc7/2oTnB/c0dc39TYxfK/Uh/bUty/7YOuL9pDNzfwkz87WwFb+HD/dsJKPh2wOBsTyr49gIK3hRQ8BZlnP8hPtHc34Lg6xY1wP1NCLtqH+jUrv9x/JZleJqDOgCbbwnMjybR3zsf2BMlkH4U5HhXv6exSwbH72BErWUQx4eUBMDxoqtAyxg4vsB0WCt7FSjw4fhWAqtAKyAidiRXgR0FVoGWwCpQUMb5jxSU4xGbWpMc39oBxxeQHL8Ty/G6wZ0Ijt8J4Pg2jjle+9CG4Pg2jjm+lbEL5Xikv3YmOX5nBxzfKgaO38VM/F1tBd/Fh+N3FVDwXYHBaUsqeFsBBW8FKPguZZz/IT5Rf8ql8SM1qOnPRXKaaKslweZ1a/hMPoyz9b07lOEBWzceNu7iCPXsksHGu5k51W5jZON2MbDx7qbD2tvKursPG7cXUNb2gArtQSrrHgLK2g5Q1t3LOP+RgqoLYlMHko07OGDj3Uk23pNlY93gngQb7wmwcUfHbKx96EiwcUfHbNze2IWyMdJfe5FsvJcDNm4fAxt3MhN/b1vBO/mw8d4CCr43MDj7kAq+j4CCtwcUvFMZ53+ITzQbdyLZGE1zoNvarQyzrR3I0vosF2XQqKtJSIGQKr29fatbTaI0uC8B6Z1zXCGi2NW5BjdcnctwZEF+sL+fEEaFtdMOsKlLdJuq/uewZUtISWifuxAb2f3L4gm+1mSag65s8OkGuxLB181x8Gm7ugkFX9jtOoj0gAv+pierDwqBe9FvOFMFDVRkDIsAdGds0eONtKH7s4iYH4KnNVVj87lxyovWjm+ag2Ljs6c/JTncK3PiTJYoptuaNM6U2Bye9DlJKRHg8BJgxpeSHF4qwOEewOHJMs5/pKBYgthURp6klDk4SUmSJynl7EmKbrCcOEkpB6SywvFJivahgjhJqXB8klJi7EJPUpD+qiRPUiodnKSUhAuWeJqD7mbi97AVvIeAWvcABuIAUq0PEFDrEkCtu5dx/lfjk0iag+7kqoCmORgLpDkoBvoJQRck4HJYTVOvEk9z0NME3IF2wPX0Obo8UCAIDwQGohcZhL0iBGEOaJcVhD3LOP+tkjXIyOZCYFKLpzk4yEyu3mUBXwWHGd4TQBPJ5a93DBuYg02HHWJH48E+G5hDBKLxEGDmHkpG46ECS2JvIBoPLuP8Rwq6gUFs6kNuYPo42MAcTG5gDivLocHDiA3MYYBKHO54A6N9OJzYwBzueANziLEL3cAg/XUEuYE5wsEG5pDogiX2VfCRZuL3tRX8SB+e6iug4H2BwelHKng/AQU/BFDwI8s4/0N8ov7cSePHkWV4sB2ZYzBHsas3YVdjxz+p1JwJIFuVvldzIprmwAudI/9t/qLyuf46/iBg7gGImGgcU5oDRxhrlwzuP8qIYP+Nkfv7x8D9R5sOG2CvGkf7cP8AgVVjADDLjyFXjWMEVo3+wKpxdBnnP1JQNURsGkhy/0AH3H80yf2DWO7XDQ4iuH8QoBKDHXO/9mEwwf2DHXP/AGMXyv1Ifx1Lcv+xDrh/QAzcP8RM/CpbwYf4cH+VgIJXAYMzlFTwoQIKPgBQ8CFlnP8hPtHcP4Tg6yE1wP39CbuaOE5zoO06qgxPc9AbYPOjgPnRP/p75wN7okSTmNIcOPo9jV0yOP44I2rDgjg+pCQAjhddBYbFwPHDTYeNsFeB4T4cP0JgFRgBRMTx5CpwvMAqMAxYBYaXcf4jBeV4xKaRJMePdMDxw0mOP4HleN3gCQTHnwBw/CjHHK99GEVw/CjHHD/C2IVyPNJfJ5Icf6IDjh8RA8ePNhP/JFvBR/tw/EkCCn4SMDgnkwp+soCCjwAUfHQZ53+IT9Sfcmn8SA1q+nORnCbaGkawebMaPpMP42x973FleMA2iynNgSPUs0sGG59i5tSYjZGNx8TAxmNNh42zlXWsDxuPE1DWcYAKnUoq66kCyjoGUNaxZZz/SEHVBbHpNJKNT3PAxmNJNj6dZWPd4OkEG58OsPF4x2ysfRhPsPF4x2w8ztiFsjHSX2eQbHyGAzYeFwMbTzAT/0xbwSf4sPGZAgp+JjA4Z5EKfpaAgo8DFHxCGed/iE80G08g2RhNc6DbOqUMs20MyNL6LLdZTGkOxoDikCpnV7eaRGnwbALSz8lxhYhi1zk1uOE6pwxHFuQH++cKYVRYO2MAmyZGt6nqfw5btoSUhPZ5IrGRPa8snuDbiUxzcD4bfLrB84ngu8Bx8Gm7LhAKvrDbdRDpARf8TU9WH1wI3NukhtIcIGN4EYDujC16vJE2dH9eRMwPwdOaqnH53DjlRWvHN83BxcbnS/SnJIdfUubEmSxRTLf1UuPMZTaHX+pzknKZAIdfBsz4SSSHTxLg8EsADr+0jPMfKSiWIDZdTp6kXO7gJOVS8iTlCvYkRTd4BXGScgUglVc6PknRPlxJnKRc6fgk5TJjF3qSgvTXVeRJylUOTlIuCxcs8TQHV5uJP9lW8MkCaj0ZGIhrSLW+RkCtLwPU+uoyzv9qfBJJc3A1uSqgaQ7GAWkOLgb6CUEXJOByWE1TrxJPczDFBNy1dsBN8Tm6vFYgCK8FBmIqGYRTIwRhDmiXFYRTyjj/rZI1yMjmQmBSi6c5uM5MruvLAr4KDjN8CoAmksvf9TFsYG4wHXajHY03+GxgbhSIxhuBmXsTGY03CSyJ1wPReEMZ5z9S0A0MYtM0cgMzzcEG5gZyA3NzWQ4N3kxsYG4GVGK64w2M9mE6sYGZ7ngDc6OxC93AIP11C7mBucXBBubG6IIl9lXwrWbi32Yr+K0+PHWbgILfBgzO7aSC3y6g4DcCCn5rGed/iE/Unztp/Li1DA+2W3MM5ih2XU/Y1dLxTyo1ZwLIVqXv1ZyIpjm4JHSO/Lf5i8rn+uv464C5ByBiomVMaQ4cYaxdMrj/DiOCMzZG7p8RA/ffaTrsLnvVuNOH++8SWDXuAmb53eSqcbfAqjEDWDXuLOP8RwqqhohN95Dcf48D7r+T5P57We7XDd5LcP+9gErc55j7tQ/3Edx/n2Puv8vYhXI/0l/3k9x/vwPuvysG7p9pJv4DtoLP9OH+BwQU/AFgcB4kFfxBAQW/C1DwmWWc/yE+0dw/k+DrmTXA/TMIu1o5TnOg7bqjDE9zcD3A5ncA82NG9PfOB/ZEiVYxpTlw9Hsau2Rw/ENG1B4O4viQkgA4XnQVeDgGjn/EdNgsexV4xIfjZwmsArOAiHiUXAUeFVgFHgZWgUfKOP+RgnI8YtNskuNnO+D4R0iOf4zleN3gYwTHPwZw/BzHHK99mENw/BzHHD/L2IVyPNJfj5Mc/7gDjp8VA8c/YSb+k7aCP+HD8U8KKPiTwOA8RSr4UwIKPgtQ8CfKOP9DfKL+lEvjR2pQ05+L5DTR1sMEm7ep4TP5MM7W9z5Uhgdsm5jSHDhCPbtksPHTZk7N3RjZeG4MbPyM6bBnbWV9xoeNnxVQ1mcBFXqOVNbnBJR1LqCsz5Rx/iMFVRfEpudJNn7eARs/Q7LxCywb6wZfINj4BYCNX3TMxtqHFwk2ftExGz9r7ELZGOmvl0g2fskBGz8bAxvPMxP/ZVvB5/mw8csCCv4yMDivkAr+ioCCPwso+Lwyzn+7SLHxPJKN0TQHuq2nyzDb5oIsrc9y28SU5mAuKA6p8mp1q0mUBl8lIP21HFeIKHa9VoMbrtfKcGRBfrA/XwijwtqZC9i0ILpNVf9z2LIlpCS0zwuIjezrZfEEXxsyzcEbbPDpBt8ggu9Nx8Gn7XpTKPjCbtdBpAdc8Dc9WX3wFnBvqxpKc4CM4dsAujO26PFG2tD9+TYxPwRPa6pOzefGKS9aO75pDt4xPr+rPyU5/N0yJ85kiWK6rQuNM+/ZHL7Q5yTlPQEOfw+Y8YtIDl8kwOHvAhy+sIzzHykoliA2vU+epLzv4CRlIXmSspg9SdENLiZOUhYDUvmB45MU7cMHxEnKB45PUt4zdqEnKUh/fUiepHzo4CTlvXDBEk9z8JGZ+EtsBV8ioNZLgIH4mFTrjwXU+j1ArT8q4/yvxieRNAcfkasCmubgVCDNwTtAPyHoggRcDqtp6lXiaQ6WmoD7xA64pT5Hl58IBOEnwEAsI4NwWYQgzAHtsoJwaRnnv1WyBhnZXAhMavE0B5+aybW8LOCr4DDDlwJoIrn8LY9hA/OZ6bDP7Wj8zGcD87lANH4OzNwvyGj8QmBJXA5E42dlnP9IQTcwiE0ryA3MCgcbmM/IDcyXZTk0+CWxgfkSUImvHG9gtA9fERuYrxxvYD43dqEbGKS/viY3MF872MB8Hl2wxL4K/sZM/G9tBf/Gh6e+FVDwb4HBWUkq+EoBBf8cUPBvyjj/Q3yi/txJ48c3ZXiwfZNjMEexazlhV3vHP6nUnAkgW5W+V3Mimubg3dA58t/mLyqf66/jPwXmHoCIifYxpTlwhLF2yeD+74wIrtoYuX9VDNz/vemw1faq8b0P968WWDVWA7P8B3LV+EFg1VgFrBrfl3H+IwVVQ8SmH0nu/9EB939Pcv9PLPfrBn8iuP8nQCXWOOZ+7cMagvvXOOb+1cYulPuR/vqZ5P6fHXD/6hi4/xcz8X+1FfwXH+7/VUDBfwUG5zdSwX8TUPDVgIL/Usb5H+ITzf2/EHz9Sw1w/yrCrg6O0xxou74rw9McLAfY/DtgfqyK/t75wJ4o0SGmNAeOfk9jlwyO/92I2h9BHB9SEgDHi64Cf8TA8X+aDltrrwJ/+nD8WoFVYC0QEX+Rq8BfAqvAH8Aq8GcZ5z9SUI5HbFpHcvw6Bxz/J8nxf7Mcrxv8m+D4vwGO/8cxx2sf/iE4/h/HHL/W2IVyPNJf/5Ic/68Djl8bA8evT0388rxMB9f7cLy+KVcF1++Iem+inFPwRHnuCr4WUPD1ZZz/IT5Rf8ql8eP/DGqe2wDVbf1BsHmnGj6TD+Nsfe/vZXjAdoopzYEj1LNLBhvnl2/4rFW+EbJxrfKaZ+NNTIfVtpVVX7DZuLaAstYGlHVTUlk3FVDWWuXRlXWTcs5/pKDqgthUp5xj4zrl8my8STnHxpuV59Cgfhhl482iD2SiLjAYrA91y3E2rgtORtSu2sYulI2R/toc8CF98m5eLs/GtUFssktB9WZnlHRb65mJX99W8Hrl2WxcX0DB6wOD04BU8AYCCl4bUPB65Zz/IT7RbJwa1PTnohQ0zYFuK78cs61WOeaTPsvtFFOag1qgOKTKFtWtJlEa3KIcf65hjitEFLsakpOKmcANy3FkQX6w30gIo8LaqQWMS+PoNlX9z2HLlpCS0D43LsfHY8vyeIJvZzLNQRM2+HSDTYjg28px8Gm7thIKvrDbdRDpARf8TU9WHzQF+qtDDaU5QMZwawDdGVv0eCNt6P7cmpgfgqc1Vaflc+OUF60d3zQHzYzP2+hPSQ7fJoaTlObGmW1tDm/uc5KyrQCHbwvM+BYkh7cQ4PBtAA5vXs75jxQUSxCbtiNPUrZzcJLSnDxJ2Z49SdENbk+cpGwPSOUOjk9StA87ECcpOzg+SdnW2IWepCD91ZI8SWnp4CRl23DBEk9zUGAmfitbwVsJqHUrYCB2JNV6RwG13hZQ64Jyzv9qfBJJc1BArgpomoPTgDQHzYB+QtAFCbgcVtPUq8TTHLQ2AbeTHXCtfY4udxIIwp2AgWhDBmGbCEGYA9plBWHrcs5/q2QNMrK5EJjU4mkOdjaTa5fygK+CwwxvDaCJ5PK3SwwbmF1Nh7W1o3FXnw1MW4FobAvM3N3IaNxNYEncBYjGXcs5/5GCbmAQm9qRG5h2DjYwu5IbmN3ZDYxucHdiA7M7oBLtHW9gtA/tiQ1Me8cbmLbGLnQDg/TXHuQGZg8HG5i24LeEdimo3uyMkm5rBzPx97QVvIMPT+0poOB7AoPTkVTwjgIK3hZQ8A7lnP8hPlF/7qTxo0M5HmwdcgzmKHbtQtjV1fFPKjVnAshWpe/VnFjbagfh2bDNX1Q+11/H7wzMPQARE11jSnPgCGPtksH9exkR7LQxcn+nGLh/b9Nh+9irxt4+3L+PwKqxDzDL9yVXjX0FVo1OwKqxdznnP1JQNURs6kxyf2cH3L83yf37sdyvG9yP4P79AJXo4pj7tQ9dCO7v4pj79zF2odyP9Nf+JPfv74D794mB+7uaid/NVvCuPtzfTUDBuwGDU0gqeKGAgu8DKHjXcs7/EJ9o7u/K8HUNcH8nwq5Cx2kOtF17leNpDnYB2HwvYH50iv7e+cCeKFEYU5oDR7+nsUsGxxcZUSsO4viQkgA4XnQVKI6B4z3TYUl7FfB8OD4psAokgYgoIVeBEoFVoBhYBbxyzn+koByP2FRKcnypA473SI4vYzleN1hGcHwZwPHljjle+1BOcHy5Y45PGrtQjkf6q4Lk+AoHHJ+MgeMrzcTvbit4pQ/HdxdQ8O7A4PQgFbyHgIInAQWvLOf8D/GJ+lMujR+pQU1/LpLTRFvFBJsna/hMPoyz9b1F5UTAxpTmwBHq2SWDjQ8wc6rnxsjGPWNg4wNNh/WylfVAHzbuJaCsvQAVOohU1oMElLUnoKwHlnP+IwVVF8Sm3iQb93bAxgeSbHwwy8a6wYMJNj4YYONDHLOx9uEQgo0PcczGvYxdKBsj/XUoycaHOmDjXjGwcR8z8Q+zFbyPDxsfJqDghwGDczip4IcLKHgvQMH7lHP+h/hEs3Efko3RNAe6rQPKMdt6giytz3KTMaU56AmKQ6ocUd1qEqXBIwhIPzLHFSKKXUfW4IbryHIcWZAf7PcVwqiwdnoCNvWLbhOV5kD73I/YyB5VHk/w7UKmOejPBp9usD8RfEc7Dj5t19FCwRd2uw4iPeCCv+nJ6oMBwL2FNZTmABnDYwB0Z2zR4420ofvzGGJ+SKY5OD2fG6e8aO34pjkYaHwepD8lOXxQDCcpg40zx9ocPtjnJOVYAQ4/FpjxQ0gOHyLA4YMADh9czvmPFBRLEJuqyJOUKgcnKYPJk5Sh7EmKbnAocZIyFJDK4xyfpGgfjiNOUo5zfJJyrLELPUlB+msYeZIyzMFJyrHhgiWe5mC4mfgjbAUfIaDWI4CBOJ5U6+MF1PpYQK2Hl3P+V+OTSJqD4eSqgKY5OB1IczAQ6CcEXSTTHAQEXOpV4mkORpqAO8EOuJE+R5cnCAThCcBAjCKDcFSEIMwB7bKCcGQ5579VsgZZMs1BhEktnubgRDO5RpcHfBUcZvhIAE0kl7/RMWxgTjIddrIdjSf5bGBOFojGk4GZewoZjacILImjgWg8qZzzHynoBgaxaQy5gRnjYANzErmBGctuYHSDY4kNzFhAJcY53sBoH8YRG5hxjjcwJxu70A0M0l+nkhuYUx1sYE4GvyW0S0H1ZmeUdFtPMxP/dFvBT/PhqdMFFPx0YHDGkwo+XkDBTwYU/LRyzv8Qn6g/d9L4cVo5Hmyn5RjMUewaTdjVw/FPKjVnAshWpe/VnFjbagfh2bDNX1Q+11/HnwjMPQAREz1iSnPgCGPtksH9ZxgRnLAxcv+EGLj/TNNhZ9mrxpk+3H+WwKpxFjDLzyZXjbMFVo0JwKpxZjnnP1JQNURsOofk/nMccP+ZJPefy3K/bvBcgvvPBVRiomPu1z5MJLh/omPuP8vYhXI/0l/nkdx/ngPuPysG7j/fTPwLbAU/34f7LxBQ8AuAwbmQVPALBRT8LEDBzy/n/A/xieb+8wm+Pr8GuH8CYVdPx2kOtF1nlONpDkYDbH4GMD8mRH/vfGBPlOgZU5oDR7+nsUsGx19kRO3iII4PKQmA40VXgYtj4PhLTIddaq8Cl/hw/KUCq8ClQERcRq4ClwmsAhcDq8Al5Zz/SEE5HrFpEsnxkxxw/CUkx1/Ocrxu8HKC4y8HOP4KxxyvfbiC4PgrHHP8pcYulOOR/rqS5PgrHXD8pTFw/FVm4l9tK/hVPhx/tYCCXw0MzmRSwScLKPilgIJfVc75H+IT9adcGj9Sg5r+XCSnibYuJti8dw2fyYdxtr73onI8YHvHlObAEerZJYONrzFzasrGyMZTYmDja02HTbWV9VofNp4qoKxTARW6jlTW6wSUdQqgrNeWc/4jBVUXxKbrSTa+3gEbX0uy8Q0sG+sGbyDY+AaAjW90zMbahxsJNr7RMRtPNXahbIz0100kG9/kgI2nxsDG08zEv9lW8Gk+bHyzgILfDAzOdFLBpwso+FRAwaeVc/6H+ESz8TSSjdE0B7qta8ox26aALK3PcnvHlOZgCigOqXJLdatJlAZvISD91hxXiCh23VqDG65by3FkQX6wf5sQRoW1MwWw6fboNlFpDrTPtxMb2TvK4wm+Xck0BzPY4NMNziCC707HwaftulMo+MJu10GkB1zwNz1ZfXAXcG/PGkpzgIzh3QC6M7bo8Uba0P15NzE/JNMcjM/nxikvWju+aQ7uMT7fqz8lOfzeGE5S7jPO3G9z+H0+Jyn3C3D4/cCMn0ly+EwBDr8X4PD7yjn/kYJiCWLTA+RJygMOTlLuI09SHmRPUnSDDxInKQ8CUvmQ45MU7cNDxEnKQ45PUu43dqEnKUh/PUyepDzs4CTl/nDBEk9z8IiZ+LNsBZ8loNazgIF4lFTrRwXU+n5ArR8p5/yvxieRNAePkKsCmuZgPJDm4B6gnxB0kUxzEBBwqVeJpzmYbQLuMTvgZvscXT4mEISPAQMxhwzCORGCMAe0ywrC2eWc/1bJGmTJNAcRJrV4moPHzeR6ojzgq+Aww2cDaCK5/D0RwwbmSdNhT9nR+KTPBuYpgWh8Cpi5T5PR+LTAkvgEEI1PlnP+IwXdwCA2zSU3MHMdbGCeJDcwz7AbGN3gM8QG5hlAJZ51vIHRPjxLbGCedbyBecrYhW5gkP56jtzAPOdgA/MU+C2hXQqqNzujpNv6vJn4L9gK/rwPT70goOAvAIPzIqngLwoo+FOAgj9fzvkf4hP1504aP54vx4Pt+RyDOYpdTxB2Hen4J5WaMwFkq9L3ak6sbbWD8GzY5i8qn+uv4x8H5h6AiIkjY0pz4Ahj7ZLB/S8ZEZy3MXL/vBi4/2XTYa/Yq8bLPtz/isCq8Qowy18lV41XBVaNecCq8XI55z9SUDVEbHqN5P7XHHD/yyT3z2e5Xzc4n+D++YBKLHDM/dqHBQT3L3DM/a8Yu1DuR/rrdZL7X3fA/a/EwP1vmIn/pq3gb/hw/5sCCv4mMDhvkQr+loCCvwIo+BvlnP8hPtHc/wbB12/UAPfPI+zq5zjNgbbrpXI8zcETAJu/BMyPedHfOx/YEyX6xZTmwNHvaeySwfFvG1F7J4jjQ0oC4HjRVeCdGDj+XdNhC+1V4F0fjl8osAosBCLiPXIVeE9gFXgHWAXeLef8RwrK8YhNi0iOX+SA498lOf59luN1g+8THP8+wPGLHXO89mExwfGLHXP8QmMXyvFIf31AcvwHDjh+YQwc/6GZ+B/ZCv6hD8d/JKDgHwGDs4RU8CUCCr4QUPAPyzn/Q3yi/pRL40dqUNOfi+Q00dY7BJsPqOEz+TDO1ve+XY4H7ICY0hw4Qj27ZLDxx2ZOLd0Y2XhpDGz8iemwZbayfuLDxssElHUZoEKfksr6qYCyLgWU9ZNyzn+koOqC2LScZOPlDtj4E5KNP2PZWDf4GcHGnwFs/LljNtY+fE6w8eeO2XiZsQtlY6S/viDZ+AsHbLwsBjZeYSb+l7aCr/Bh4y8FFPxLYHC+IhX8KwEFXwYo+Ipyzv8Qn2g2XkGyMZrmQLf1cTlm21KQpfVZ7oCY0hwsBcUhVb6ubjWJ0uDXBKR/k+MKEcWub2pww/VNBNW3m0F+sP+tEEaFtbMUsGlldJuoNAfa55XERva78niCry2Z5mAVG3y6wVVE8H3vOPi0Xd8LBV/Y7TqI9IAL/qYnqw9WA/f2q6E0B8gY/gCgO2OLHm+kDd2fPxDzQzLNwRn53DjlRWvHN83Bj8bnn/SnJIf/FMNJyhrjzM82h6/xOUn5WYDDfwZm/C8kh/8iwOE/ARy+ppzzHykoliA2/UqepPzq4CRlDXmS8ht7kqIb/I04SfkNkMrfHZ+kaB9+J05Sfnd8kvKzsQs9SUH66w/yJOUPBycpP4cLlniagz/NxF9rK/haAbVeCwzEX6Ra/yWg1j8Dav1nOed/NT6JpDn4k1wV0DQHZwBpDn4E+glBF8k0BwEBl3qVeJqDdSbg/rYDbp3P0eXfAkH4NzAQ/5BB+E+EIMwB7bKCcF05579VsgZZMs1BhEktnubgXzO51pcHfBUcZvg6AE0kl7/1MWxg8irMTRV5mZGnL9gbGH1TrtGo3xH13vwKLhrzK3JfEtcD0ZhXwfmPFHQDg9hUq4LbwNSqkN/A5FVwG5hNKnJoUD+MbmA2iT6QidrAYLA+6DbQDUxtcDKidiWMXegGBumvTQEf0ifvphXyG5hEdMES+yq4jpn4m9kKXqcim6c2E1DwzYDBqUsqeF0BBQ9YabIUvE4F53+IT9SfO2n8qFOBB1udHIM5il3riW+ihjr+SaXmTADZqvS9mhNrW+0gPBu2+YvK5/rr+H8BlgcQMTE0pjQHjjDWLhncv7kRwXoVGyH316tw0mGBq0Z902EN7FWjvg/3NxBYNRoACrsFuWpsIbBq1ANWjfoVnP9IQdUQsakhyf0NHXB/fZL7G7HcrxtsRHB/I4D7Gzvmfu1DY4L7Gzvm/gbGLpT7kf7akuT+LR1wf4MYuL+Jmfhb2QrexIf7txJQ8K2AwWlKKnhTAQVvACh4kwrO/xCfaO5vQnB/kxrg/nqEXcMcpznQdmnuq40912U9wOabA/OjXkXk984H9kSJYTGlOfgpBo7f2ohasyCODykJgONFV4FmMXD8NqbDmturwDY+HN9cYBVoDkTEtuQqsK3AKtAMWAW2qeD8RwrK8YhNLUiOb+GA47chOX47luN1g9sRHL8dwPHbO+Z47cP2BMdv75jjmxu7UI5H+msHkuN3cMDxzWPg+JZm4hfYCt7Sh+MLBBS8ABicVqSCtxJQ8OaAgres4PwP8Yn6Uy6NH6lBTX8uktNEW80INh9Zw2fyYZyt7926Ag/YkTGlOXCEenbJYOMdzZxqvTGycesY2Hgn02FtbGXdyYeN2wgoaxtAhXYmlXVnAWVtDSjrThWc/0hB1QWxaReSjXdxwMY7kWy8K8vGusFdCTbeFWDjto7ZWPvQlmDjto7ZuI2xC2VjpL92I9l4Nwds3CYGNm5nJv7utoK382Hj3QUUfHdgcNqTCt5eQMHbAAreroLzP8Qnmo3bkWyMpjnQbe1YgdnWGmRpfZY7MqY0B61BcUiVPapbTaI0uAcB6R1yXCGi2NWhBjdcHSpwZEF+sL+nEEaFtdMaGJeO0W2i0hxonzsSG9m9KuIJvt3INAed2ODTDXYigm9vx8Gn7dpbKPjCbtdBpAdc8Dc9WX2wD3DvsBpKc4CM4b4AujO26PFG2tD9uS8xPyTTHEzI58YpL1o7vmkOOhuf99Ofkhy+XwwnKV2MM/vbHN7F5yRlfwEO3x+Y8V1JDu8qwOH7ARzepYLzHykoliA2dSNPUro5OEnpQp6kFLInKbrBQuIkpRCQyiLHJynahyLiJKXI8UnK/sYu9CQF6a9i8iSl2MFJyv7hgiWe5sAzEz9pK3hSQK2TwECUkGpdIqDW+wNq7VVw/lfjk0iaA49cFdA0BxOANAedgX5C0EUyzUFAwKVeJZ7moNQEXJkdcKU+R5dlAkFYBgxEORmE5RGCMAe0ywrC0grOf6tkDbJkmoMIk1o8zUGFmVyVFQFfBYcZXgqgieTyVxnDBqa76bAedjR299nA9BCIxh7AzD2AjMYDBJbESiAau1dw/iMF3cAgNvUkNzA9HWxgupMbmAPZDYxu8EBiA3MgoBK9HG9gtA+9iA1ML8cbmB7GLnQDg/TXQeQG5iAHG5ge4LeEdimo3uyMkm5rbzPxD7YVvLcPTx0soOAHA4NzCKnghwgoeA9AwXtXcP6H+ET9uZPGj94VeLD1zjGYo9hVSdg1xvFPKjVnAshWpe/VnIimOdgvdI78t/mLyuf66/gKYO4BiJgYE1OaA0cYa5cM7j/UiGCfjZH7+8TA/YeZDjvcXjUO8+H+wwVWjcOBWX4EuWocIbBq9AFWjcMqOP+RgqohYtORJPcf6YD7DyO5vy/L/brBvgT39wVUop9j7tc+9CO4v59j7j/c2IVyP9JfR5Hcf5QD7j88Bu7vbyb+0baC9/fh/qMFFPxoYHAGkAo+QEDBDwcUvH8F53+ITzT39yf4un8NcH8fwq5xjtMcaLsOrcDTHFQCbH4oMD/6RH/vfGBPlBgXU5oDR7+nsUsGxx9jRG1gEMeHlATA8aKrwMAYOH6Q6bDB9iowyIfjBwusAoOBiDiWXAWOFVgFBgKrwKAKzn+koByP2DSE5PghDjh+EMnxVSzH6warCI6vAjh+qGOO1z4MJTh+qGOOH2zsQjke6a/jSI4/zgHHD46B44eZiT/cVvBhPhw/XEDBhwODM4JU8BECCj4YUPBhFZz/IT5Rf8ql8SM1qOnPRXKaaGsgwebja/hMPoyz9b3HVOABOz6mNAeOUM8uGWx8vJlTIzdGNh4ZAxufYDpslK2sJ/iw8SgBZR0FqNCJpLKeKKCsIwFlPaGC8x8pqLogNo0m2Xi0AzY+gWTjk1g21g2eRLDxSQAbn+yYjbUPJxNsfLJjNh5l7ELZGOmvU0g2PsUBG4+KgY3HmIk/1lbwMT5sPFZAwccCgzOOVPBxAgo+ClDwMRWc/yE+0Ww8hmRjNM2Bbuv4Csy2kSBL67Pc8TGlORgJikOqnFrdahKlwVMJSD8txxUiil2n1eCG67QKHFmQH+yfLoRRYe2MBGwaH90mKs2B9nk8sZE9oyKe4GtHpjmYwAafbnACEXxnOg4+bdeZQsEXdrsOIj3ggr/pyeqDsxACqKE0B8gYng2gO2OLHm+kDd2fZxPzQzLNwZn53DjlRWvHN83BOcbnc/WnJIefG8NJykTjzHk2h0/0OUk5T4DDzwNm/Pkkh58vwOHnAhw+sYLzHykoliA2XUCepFzg4CRlInmSciF7kqIbvJA4SbkQkMqLHJ+kaB8uIk5SLnJ8knKesQs9SUH662LyJOViBycp54ULlniag0vMxL/UVvBLBdT6UmAgLiPV+jIBtT4PUOtLKjj/q/FJJM3BJeSqgKY5OBNIc3AO0E8IukimOQgIuNSrxNMcTDIBd7kdcJN8ji4vFwjCy4GBuIIMwisiBGEOaJcVhJMqOP+tkjXIkmkOIkxq8TQHV5rJdVVFwFfBYYZPAtBEcvm7KoYNzNWmwybb0Xi1zwZmskA0TgZm7jVkNF4jsCReBUTj1RWc/0hBNzCITVPIDcwUBxuYq8kNzLXsBkY3eC2xgbkWUImpjjcw2oepxAZmquMNzGRjF7qBQfrrOnIDc52DDcxk8FtCuxRUb3ZGSbf1ejPxb7AV/HofnrpBQMFvAAbnRlLBbxRQ8MmAgl9fwfkf4hP1504aP66vwIPt+hyDOYpdVxF2TXT8k0rNmQCyVel7NSeiaQ7ODZ0j/23+ovK5/jr+SmDuAYiYmBhTmgNHGGuXDO6/yYjgtI2R+6fFwP03mw6bbq8aN/tw/3SBVWM6MMtvIVeNWwRWjWnAqnFzBec/UlA1RGy6leT+Wx1w/80k99/Gcr9u8DaC+28DVOJ2x9yvfbid4P7bHXP/dGMXyv1If91Bcv8dDrh/egzcP8NM/DttBZ/hw/13Cij4ncDg3EUq+F0CCj4dUPAZFZz/IT7R3D+D4OsZNcD90wi7znec5kDbdVMFnubgKoDNbwLmx7To750P7IkS58eU5sDR72nsksHxdxtRuyeI40NKAuB40VXgnhg4/l7TYffZq8C9Phx/n8AqcB8QEfeTq8D9AqvAPcAqcG8F5z9SUI5HbJpJcvxMBxx/L8nxD7Acrxt8gOD4BwCOf9Axx2sfHiQ4/kHHHH+fsQvleKS/HiI5/iEHHH9fDBz/sJn4j9gK/rAPxz8ioOCPAIMzi1TwWQIKfh+g4A9XcP6H+ET9KZfGj9Sgpj8XyWmirXsINr+4hs/kwzhb33t3BR6wF8eU5sAR6tklg40fNXNq9sbIxrNjYOPHTIfNsZX1MR82niOgrHMAFXqcVNbHBZR1NqCsj1Vw/iMFVRfEpidINn7CARs/RrLxkywb6wafJNj4SYCNn3LMxtqHpwg2fsoxG88xdqFsjPTX0yQbP+2AjefEwMZzzcR/xlbwuT5s/IyAgj8DDM6zpII/K6DgcwAFn1vB+R/iE83Gc0k2RtMc6LYercBsmw2ytD7LvTimNAezQXFIleeqW02iNPgcAenP57hCRLHr+RrccD1fgSML8oP9F4QwKqyd2YBNL0a3iUpzoH1+kdjIvlQRT/DtTqY5mMcGn25wHhF8LzsOPm3Xy0LBF3a7DiI94IK/6cnqg1eAe8+voTQHyBi+CqA7Y4seb6QN3Z+vEvNDMs3BWfncOOVFa8c3zcFrxuf5+lOSw+fHcJKywDjzus3hC3xOUl4X4PDXgRn/Bsnhbwhw+HyAwxdUcP4jBcUSxKY3yZOUNx2cpCwgT1LeYk9SdINvEScpbwFS+bbjkxTtw9vEScrbjk9SXjd2oScpSH+9Q56kvOPgJOX1cMEST3Pwrpn4C20FXyig1guBgXiPVOv3BNT6dUCt363g/K/GJ5E0B++SqwKa5uAsIM3Ba0A/IegimeYgIOBSrxJPc7DIBNz7dsAt8jm6fF8gCN8HBmIxGYSLIwRhDmiXFYSLKjj/rZI1yJJpDiJMavE0Bx+YyfVhRcBXwWGGLwLQRHL5+zCGDcxHpsOW2NH4kc8GZolANC4BZu7HZDR+LLAkfghE40cVnP9IQTcwiE1LyQ3MUgcbmI/IDcwn7AZGN/gJsYH5BFCJZY43MNqHZcQGZpnjDcwSYxe6gUH661NyA/Opgw3MEvBbQrsUVG92Rkm3dbmZ+J/ZCr7ch6c+E1Dwz4DB+ZxU8M8FFHwJoODLKzj/Q3yi/txJ48fyCjzYlucYzFHs+pCw6yrHP6nUnAkgW5W+V3MimuZgfugc+W/zF5XP9dfxHwBzD0DExFUxpTlwhLF2yeD+L4wIrtgYuX9FDNz/pemwr+xV40sf7v9KYNX4CpjlX5OrxtcCq8YKYNX4soLzHymoGiI2fUNy/zcOuP9Lkvu/ZblfN/gtwf3fAiqx0jH3ax9WEty/0jH3f2XsQrkf6a/vSO7/zgH3fxUD968yE/97W8FX+XD/9wIK/j0wOKtJBV8toOBfAQq+qoLzP8QnmvtXEXy9qga4fwVh12THaQ60XV9U4GkOPgTY/AtgfqyI/t75wJ4oMTmmNAeOfk9jlwyO/8GI2o9BHB9SEgDHi64CP8bA8T+ZDltjrwI/+XD8GoFVYA0QET+Tq8DPAqvAj8Aq8FMF5z9SUI5HbPqF5PhfHHD8TyTH/8pyvG7wV4LjfwU4/jfHHK99+I3g+N8cc/waYxfK8Uh//U5y/O8OOH5NDBz/h5n4f9oK/ocPx/8poOB/AoOzllTwtQIKvgZQ8D8qOP9DfKL+lEvjR2pQ05+L5DTR1o8Em0+t4TP5MM7W9/5QgQfs1JjSHDhCPbtksPFfZk6t2xjZeF0MbPy36bB/bGX924eN/xFQ1n8AFfqXVNZ/BZR1HaCsf1dw/iMFVRfEpvUkG693wMZ/k2ycV5lDg/phlI31M9Xda5VEotItG2sfdBsoGycqscmI2vWPsQtlY6S/8gEf0ievfk6ajf+JgY1rmYm/SWVepoO1KrPZeJPK3BV8E2BwaldyCl67MncF/wdQ8FqVnP8hPtFsnBrU9OeiFDTNgW7rrwrMtnUgS+uz3KkxpTlAkCq9vU2rW02iNLhpJf5cnRxXiCh21SEnFTOB61TiyIL8YH8zcOVKFVTs1gE21Y1uE5XmQPtctxIfj80r4wm+9mSag3ps8OkG6xHBV99x8Gm76gsFX9jtOoj0gAv+pierDxoA/TW5htIcIGO4BYDujC16vJE2dH9uQcwPyTQHZ+dz45QXrR3fNAcNjc+N9KckhzeqdOJMliim29rYOLOlzeH6gn2SsqUAh28JzPgmJIc3EeDwRpXRObxxJec/UlAsQWzaqpI7SdmqUv4kpXEld5LSlD1J0Q02JU5SmgJSubXjkxTtw9bEScrWjk9StjR2oScpSH81I09Smjk4SdkyXLDE0xxsYyZ+c1vBmwuodXNgILYl1XpbAbXeElDrbSo5/6vxSSTNwTbkqoCmOTgbSHPQEOgnBF0k0xwEBFzqVeJpDlqYgNvODrgWPkeX2wkE4XbAQGxPBuH2EYIwB7TLCsIWlZz/VskaZMk0BxEmtXiagx3M5GpZGfBVcJjhLQA0kVz+WsawgSkwHdbKjsYCnw1MK4FobAXM3B3JaNxRYElsCURjQSXnP1LQDQxiU2tyA9PawQamgNzA7MRuYHSDOxEbmJ0AlWjjeAOjfWhDbGDaON7AtDJ2oRsYpL92JjcwOzvYwLQCvyW0S0H1ZmeUdFt3MRN/V1vBd/HhqV0FFHxXYHDakgreVkDBWwEKvksl53+IT9SfO2n82KUSD7ZdcgzmKHa1JOya7vgnlZozAWSr0vdqTkTTHDQKnSP/bf6i8rn+On4HYO4BiJiYHlOaA0cYa5cM7t/NiGC7jZH728XA/bubDmtvrxq7+3B/e4FVoz0wy/cgV409BFaNdsCqsXsl5z9SUDVEbOpAcn8HB9y/O8n9e7Lcrxvck+D+PQGV6OiY+7UPHQnu7+iY+9sbu1DuR/prL5L793LA/e1j4P5OZuLvbSt4Jx/u31tAwfcGBmcfUsH3EVDw9oCCd6rk/A/xieb+TgRfd6oB7m9H2HWr4zQH2q7dKvE0By0BNt8NmB/tor93PrAnStwaU5oDR7+nsUsGx+9rRK1zEMeHlATA8aKrQOcYOH4/02Fd7FVgPx+O7yKwCnQBImJ/chXYX2AV6AysAvtVcv4jBeV4xKauJMd3dcDx+5Ec343leN1gN4LjuwEcX+iY47UPhQTHFzrm+C7GLpTjkf4qIjm+yAHHd4mB44vNxPdsBS/24XhPQME9YHCSpIInBRS8C6DgxZWc/yE+UX/KpfEjNajpz0VymmirM8HmM2r4TD6Ms/W9+1biATsjpjQHjlDPLhlsXGLmVOnGyMalMbBxmemwcltZy3zYuFxAWcsBFaoglbVCQFlLAWUtq+T8RwqqLohNlSQbVzpg4zKSjbuzbKwb7E6wcXeAjXs4ZmPtQw+CjXs4ZuNyYxfKxkh/HUCy8QEO2Lg8BjbuaSb+gbaC9/Rh4wMFFPxAYHB6kQreS0DBywEF71nJ+R/iE83GPUk2RtMc6LZKKjHbSkGW1me5M2JKc1AKikOqHFTdahKlwYMISO+d4woRxa7eNbjh6l2JIwvyg/2DhTAqrJ1SwKZDottEpTnQPh9CbGQPrYwn+PYg0xz0YYNPN9iHCL7DHAeftuswoeALu10HkR5wwd/0ZPXB4cC9t9ZQmgNkDI8A0J2xRY830obuzyOI+SGZ5uCcfG6c8qK145vm4Ejjc1/9KcnhfWM4SelnnDnK5vB+PicpRwlw+FHAjO9Pcnh/AQ7vC3B4v0rOf6SgWILYdDR5knK0g5OUfuRJygD2JEU3OIA4SRkASOUxjk9StA/HECcpxzg+STnK2IWepCD9NZA8SRno4CTlqHDBEk9zMMhM/MG2gg8WUOvBwEAcS6r1sQJqfRSg1oMqOf+r8UkkzcEgclVA0xycA6Q5OBLoJwRdJNMcBARc6lXiaQ6GmICrsgNuiM/RZZVAEFYBAzGUDMKhEYIwB7TLCsIhlZz/VskaZMk0BxEmtXiag+PM5BpWGfBVcJjhQwA0kVz+hsWwgRluOmyEHY3DfTYwIwSicQQwc48no/F4gSVxGBCNwys5/5GCbmAQm0aSG5iRDjYww8kNzAnsBkY3eAKxgTkBUIlRjjcw2odRxAZmlOMNzAhjF7qBQfrrRHIDc6KDDcwI8FtCuxRUb3ZGSbd1tJn4J9kKPtqHp04SUPCTgME5mVTwkwUUfASg4KMrOf9DfKL+3Enjx+hKPNhG5xjMUewaRtg10/FPKjVnAshWpe/VnIimOegbOkf+2/xF5XP9dfxxwNwDEDExM6Y0B44w1i4Z3H+KEcExGyP3j4mB+8eaDhtnrxpjfbh/nMCqMQ6Y5aeSq8apAqvGGGDVGFvJ+Y8UVA0Rm04juf80B9w/luT+01nu1w2eTnD/6YBKjHfM/dqH8QT3j3fM/eOMXSj3I/11Bsn9Zzjg/nExcP8EM/HPtBV8gg/3nymg4GcCg3MWqeBnCSj4OEDBJ1Ry/of4RHP/BIKvJ9QA948h7HrQcZoDbdcplXiag2EAm58CzI8x0d87H9gTJR6MKc2Bo9/T2CWD4882onZOEMeHlATA8aKrwDkxcPy5psMm2qvAuT4cP1FgFZgIRMR55CpwnsAqcA6wCpxbyfmPFJTjEZvOJzn+fAccfy7J8RewHK8bvIDg+AsAjr/QMcdrHy4kOP5Cxxw/0diFcjzSXxeRHH+RA46fGAPHX2wm/iW2gl/sw/GXCCj4JcDgXEoq+KUCCj4RUPCLKzn/Q3yi/pRL40dqUNOfi+Q00dY5BJvPquEz+TDO1veeXYkH7KyY0hw4Qj27ZLDxZWZOTdoY2XhSDGx8uemwK2xlvdyHja8QUNYrABW6klTWKwWUdRKgrJdXcv4jBVUXxKarSDa+ygEbX06y8dUsG+sGrybY+GqAjSc7ZmPtw2SCjSc7ZuMrjF0oGyP9dQ3Jxtc4YOMrYmDjKWbiX2sr+BQfNr5WQMGvBQZnKqngUwUU/ApAwadUcv6H+ESz8RSSjdE0B7qtyyox2yaBLK3PcmfFlOZgEigOqXJddatJlAavIyD9+hxXiCh2XV+DG67rK3FkQX6wf4MQRoW1Mwmw6cboNlFpDrTPNxIb2Zsq4wm+DmSag2ls8OkGpxHBd7Pj4NN23SwUfGG36yDSAy74m56sPpgO3PtgDaU5QMbwFgDdGVv0eCNt6P68hZgfkmkOzs3nxikvWju+aQ5uNT7fpj8lOfy2GE5SbjfO3GFz+O0+Jyl3CHD4HcCMn0Fy+AwBDr8N4PDbKzn/kYJiCWLTneRJyp0OTlJuJ09S7mJPUnSDdxEnKXcBUnm345MU7cPdxEnK3Y5PUu4wdqEnKUh/3UOepNzj4CTljnDBEk9zcK+Z+PfZCn6fgFrfBwzE/aRa3y+g1ncAan1vJed/NT6JpDm4l1wV0DQH5wJpDm4F+glBF8k0BwEBl3qVeJqDmSbgHrADbqbP0eUDAkH4ALJxIYPwwQhBmAPaZQXhzErOf6tkDbJkmoMIk1o8zcFDZnI9XBnwVXDo3+UBaCK5/D0cwwbmEdNhs+xofMRnAzNLIBpnATP3UTIaHxVYEh8GovGRSs5/pKAbGMSm2eQGZraDDcwj5AbmMXYDoxt8jNjAPAaoxBzHGxjtwxxiAzPH8QZmlrEL3cAg/fU4uYF53MEGZhb4LaFdCqo3O6Ok2/qEmfhP2gr+hA9PPSmg4E8Cg/MUqeBPCSj4LEDBn6jk/A/xifpzJ40fT1TiwfZEjsEcxa6HCbuecvyTSs2ZALJV6Xs1J6JpDm4LnSP/bf6i8rn+Ov4hYO4BiJh4KqY0B44w1i4Z3P+0EcG5GyP3z42B+58xHfasvWo848P9zwqsGs8Cs/w5ctV4TmDVmAusGs9Ucv4jBVVDxKbnSe5/3gH3P0Ny/wss9+sGXyC4/wVAJV50zP3ahxcJ7n/RMfc/a+xCuR/pr5dI7n/JAfc/GwP3zzMT/2Vbwef5cP/LAgr+MjA4r5AK/oqAgj8LKPi8Ss7/EJ9o7p9H8PW8GuD+uYRdcx2nOdB2PV2Jpzl4GGDzp4H5MTf6e+cDe6LE3JjSHDj6PY1dMjj+VSNqrwVxfEhJABwvugq8FgPHzzcdtsBeBeb7cPwCgVVgARARr5OrwOsCq8BrwCowv5LzHykoxyM2vUFy/BsOOH4+yfFvshyvG3yT4Pg3AY5/yzHHax/eIjj+Lcccv8DYhXI80l9vkxz/tgOOXxADx79jJv67toK/48Px7woo+LvA4CwkFXyhgIIvABT8nUrO/xCfqD/l0viRGtT05yI5TbT1GsHmz9fwmXwYZ+t7X63EA/b5mNIcOEI9u2Sw8XtmTi3aGNl4UQxs/L7psMW2sr7vw8aLBZR1MaBCH5DK+oGAsi4ClPX9Ss5/pKDqgtj0IcnGHzpg4/dJNv6IZWPd4EcEG38EsPESx2ysfVhCsPESx2y82NiFsjHSXx+TbPyxAzZeHAMbLzUT/xNbwZf6sPEnAgr+CTA4y0gFXyag4IsBBV9ayfkf4hPNxktJNkbTHOi23qvEbFsEsrQ+y30+pjQHi0BxSJVPq1tNojT4KQHpy3NcIaLYtbwGN1zLK3FkQX6w/5kQRoW1swiw6fPoNlFpDrTPnxMb2S8q4wm+Pck0ByvY4NMNriCC70vHwaft+lIo+MJu10GkB1zwNz1ZffAV8o1fDaU5QMbwawDdGVv0eCNt6P78mpgfkmkOJuZz45QXrR3fNAffGJ+/1Z+SHP5tDCcpK40z39kcvtLnJOU7AQ7/Dpjxq0gOXyXA4d8CHL6ykvMfKSiWIDZ9T56kfO/gJGUleZKymj1J0Q2uJk5SVgNS+YPjkxTtww/EScoPjk9SvjN2oScpSH/9SJ6k/OjgJOW7cMEST3Pwk5n4a2wFXyOg1muAgfiZVOufBdT6O0Ctf6rk/K/GJ5E0Bz+RqwKa5mAikObgG6CfEHSRTHMQEHCpV4mnOfjFBNyvdsD94nN0+atAEP4KDMRvZBD+FiEIc0C7rCD8pZLz3ypZgyyZ5iDCpBZPc/C7mVx/VAZ8FRxm+C8Amkguf3/EsIH503TYWjsa//TZwKwViMa1wMz9i4zGvwSWxD+AaPyzkvMfKegGBrFpHbmBWedgA/MnuYH5m93A6Ab/JjYwfwMq8Y/jDYz24R9iA/OP4w3MWmMXuoFB+utfcgPzr4MNzFrwW0K7FFRvdkZJt3V9auJ3z8t0cL0PT+mbclVw/Y6o9ya6cwqe6J67gq8FFHx9Jed/iE/Unztp/FhPfOOzPsdgjmLXH4Rdrzn+SaXmTADZqvS9mhPRNAffhs6R/zZ/Uflcfx3/OzD3AERMvBZTmgNHGGuXDO7P777hs1b3jZD7a3Wvee7fxHRYbXvV0Bds7q8tsGrUBlaNTclVY1OBVaNW9+irxibdOf+RgqohYlOd7hz31+kuz/2bdOe4f7PuOTSoH0a5f7PoA5moCwwG60Pd7jj31wUnI2pXbWMXyv1If20O+JA+eTfvLs/9tUEktEtB9WZnlHRb65mJX99W8Hrds7m/voCC1wcGpwGp4A0EFLw2oOD1unP+h/hEc3+97niw1csxmKPYVYuwa4HjNAfaLs19aJqDPwA2zwfmR63ukd87H9gTJRbElObg2xg4fgsjag2DOD6kJACOF10FGsbA8Y1MhzW2V4FGPhzfWGAVaAxExJbkKrClwCrQEFgFGnXn/EcKyvGITU1Ijm/igOMbkRy/FcvxusGtCI7fCuD4po45XvvQlOD4po45vrGxC+V4pL+2Jjl+awcc3zgGjm9mJv42toI38+H4bQQUfBtgcJqTCt5cQMEbAwrerDvnf4hP1J9yafxIDWr6c5GcJtpqSLD5WzV8Jh/G2freLbrjAftWTGkOHKGeXTLYeFszp1psjGzcIgY23s502Pa2sm7nw8bbCyjr9oAK7UAq6w4CytoCUNbtunP+IwVVF8SmliQbt3TAxtuRbFzAsvH/GiTYuABg41aO2Vj70Ipg41aO2Xh7YxfKxkh/7Uiy8Y4O2Hj7GNi4tZn4O9kK3tqHjXcSUPCdgMFpQyp4GwEF3x5Q8NbdOf9DfKLZuDXJxmiaA93Wtt0x21qALK3Pct+KKc1BC1AcUmXn6laTKA3uTED6LjmuEFHs2qUGN1y7dMeRBfnB/q5CGBXWTgtgXNpGt4lKc6B9bktsZHfrHk/wdSTTHLRjg0832I4Ivt0dB5+2a3eh4Au7XQeRHnDB3/Rk9UF74N4FNZTmABnDPQB0Z2zR4420oftzD2J+SKY5OC+fG6e8aO34pjnoYHzeU39KcvieMZykdDTO7GVzeEefk5S9BDh8L2DGdyI5vJMAh+8JcHjH7pz/SEGxBLFpb/IkZW8HJykdyZOUfdiTFN3gPsRJyj6AVO7r+CRF+7AvcZKyr+OTlL2MXehJCtJfncmTlM4OTlL2Chcs8TQH+5mJ38VW8C4Cat0FGIj9SbXeX0Ct9wLUer/unP/V+CSS5mA/clVA0xycB6Q56AD0E4IukmkOAgIu9SrxNAddTcB1swOuq8/RZTeBIOwGDEQhGYSFEYIwB7TLCsKu3Tn/rZI1yJJpDiJMavE0B0VmchV3D/gqOMzwrgCaSC5/xTFsYDzTYUk7Gj2fDUxSIBqTwMwtIaOxRGBJLAai0evO+Y8UdAOD2FRKbmBKHWxgPHIDU8ZuYHSDZcQGpgxQiXLHGxjtQzmxgSl3vIFJGrvQDQzSXxXkBqbCwQYmCX5LaJeC6s3OKOm2VpqJ391W8EofnuouoODdgcHpQSp4DwEFTwIKXtmd8z/EJ+rPnTR+VHbHg60yx2COYlcxYddixz+p1JwJIFuVvldzIprmYM/QOfLf5i8qn+uv44uAuQcgYmJxTGkOHGGsXTK4/wAjgj03Ru7vGQP3H2g6rJe9ahzow/29BFaNXsAsP4hcNQ4SWDV6AqvGgd05/5GCqiFiU2+S+3s74P4DSe4/mOV+3eDBBPcfDKjEIY65X/twCMH9hzjm/l7GLpT7kf46lOT+Qx1wf68YuL+PmfiH2Qrex4f7DxNQ8MOAwTmcVPDDBRS8F6Dgfbpz/of4RHN/H4Kv+9QA9/ck7PrQcZoDbdcB3fE0B8UAmx8AzI+e0d87H9gTJT6MKc2Bo9/T2CWD448wonZkEMeHlATA8aKrwJExcHxf02H97FWgrw/H9xNYBfoBEXEUuQocJbAKHAmsAn27c/4jBeV4xKb+JMf3d8DxfUmOP5rleN3g0QTHHw1w/ADHHK99GEBw/ADHHN/P2IVyPNJfx5Acf4wDju8XA8cPNBN/kK3gA304fpCAgg8CBmcwqeCDBRS8H6DgA7tz/of4RP0pl8aP1KCmPxfJaaKtIwk2X1rDZ/JhnK3vPaI7HrBLY0pz4Aj17JLBxseaOTVkY2TjITGwcZXpsKG2slb5sPFQAWUdCqjQcaSyHiegrEMAZa3qzvmPFFRdEJuGkWw8zAEbV5FsPJxlY93gcIKNhwNsPMIxG2sfRhBsPMIxGw81dqFsjPTX8SQbH++AjYfGwMYjzcQ/wVbwkT5sfIKAgp8ADM4oUsFHCSj4UEDBR3bn/A/xiWbjkSQbo2kOdFvHdsdsGwKytD7LXRpTmoMhoDikyonVrSZRGjyRgPTROa4QUewaXYMbrtHdcWRBfrB/khBGhbUzBLDp5Og2UWkOtM8nExvZU7rHE3x7kWkOxrDBpxscQwTfWMfBp+0aKxR8YbfrINIDLvibnqw+GAfc+2ENpTlAxvBUAN0ZW/R4I23o/jyVmB+p+dhJtbe3qvuouq+qnVXdT9Uuqu6valdVu6laqGqRqsWqeqomVS1RtVTVMlXLVa1QtVLV7qr2UPUAVXuqeqCqvVQ9SNXeqh6s6iGqHqpqH1UPU/VwVY9Q9UhV+6raT9WjVO2v6tGqDlD1GFUHqjpI1cGqHqvqkPwNxzhDVT1O1WGqDld1hKrHqzpS1RNUHaXqiaqOVvUkVU9W9RQd8zq+VB2n+13V01Q9XdXxqp6h6gRVz1T1LFXPVvUcVc9VVf8/Mus/Vzxf1QtUvVDVi1S9WNVLVL1U1ctUnaTq5apeoeqVql6l6tWqTlb1GlWnqHqtqlNVvU7V61W9QdUbVb1J1Wmq3qzqdFVvUfVWVW9T9XZV71B1hqp3qnqXqnereo+q96p6n6r3qzpT1QdUfVDVh1R9WNVHVJ2l6qOqzlb1MVXnqPq4qk+o+qSqT6n6tKpzVX1G1WdVfU7V51V9QdUXVX1J1XmqvqzqK6q+quprqs5XdYGqr6v6hqpvqvqWqm+r+o6q76q6UNX3VF2k6vuqLlb1A1U/VPUjVZeo+rGqS1X9RNVlqn6q6nJVP1P1c1W/UHWFql+q+pWqX6v6jarfqrpS1e9UXaXq96quVvUHVX9U9SdV16j6s6q/qPqrqr+p+ruqf6j6p6prVf1L1XWq/q3qP6r+q+p6VbVAJlTNV7WWqpuoWlvVTVWto+pmqtZVdXNV66laX9UGqm6hakNVG6naWNUtVW2i6laqNlV1a1WbqbqNqs1V3VbVFqpup+r2qu6gaktVC1RtpeqOtTbEb7rgGPP+txjrX25sqmodVTdTta6qm6taT9X6qjZQdQtVG6raSNXGqm6pahNVt1K1qapbq9pM1W1Uba7qtqq2UHU7VbdXdQdVWxrdaaXqjqq2VnUnVduourOqu6i6q6ptVd1N1Xaq7q5qe1X3ULWDqnuq2lHVvbQmqbq3qvuouq+qnVXdT9Uuqu6valdVu6laqGqRqsWqeqomVS1RtVTVMlXLVa1QVf8fVWqJ7KHqAar2VFUtLXm9VD1I1d6qHqzqIaoeqmofVQ9T9XBVj1D1SFX7qtpP1aNU7a/q0aoOUPUYVQeqOkjVwaoeq+qQvA2UNlTV41QdpupwVUeoeryqI1U9QdVRqp6o6mhVT1L1ZFVPUXWMqmNVHafqqaqepurpqo5X9QxVJ6h6pqpn5W04QztH1XPzNux6z1P1fFUvUPVCVS9S9WJVL1H1UlUvU3WSqpereoWqV6p6lapXqzpZ1WtUnaLqtapOVfU6Va9X9QZVb1T1JlWnqaq3p9NVvUXVW1W9TdXbVb1D1Rmq3qnqXarereo9qt6r6n2q3q/qTFUfUPVBVR9S9WFVH1F1lqqPqjpb1cdUnaPq46o+oeqTqj6l6tOqzlX1GVWfVfU5VZ9X9QVVX1T1JVXnqfqyqq+o+qqqr6k6X9UFqr6u6huqvqnqW6q+reo7qr6r6kJV31N1karvq7pY1Q9U/VDVj1RdourHqi5V9RNVl6n6qarLVf1M1c9V/ULVFap+qepXqn6t6jeqfqvqSlW/U3WVqt+rulrVH1T9MW/DerxG1Z9V/UXVX1X9TdXfVf1D1T9VXavqX6quU/VvVf9R9V9V//e3/Sr4E6rmq1pL1U1Ura3qpqrWUXUzVeuqurmq9VStr2oDVbdQtaGqjVRtrOqWqjZRdStVm6q6tarNVN1G1eaqbqtqC1W3U3V7VXdQtaWqBaq2UnVHVVurupOqbVTdWdVdVN1V1baq7qZqO1V3V7W9qnuo2kHVPVXtqOpeqnZSdW9V91F1X1U7q7qfql1U3V/Vrqp2U7VQ1SJVi1X1VE2qWqJqqaplqparWqFqpardVe2h6gGq9lT1QFV7qXqQqr1VPVjVQ1Q9VNU+qh6m6uGqHqHqkar2VbWfqkep2l/Vo1XVh8jHqDpQ1UGqDlb1WFWHqFql6lBVj1N1mKrDVR2h6vGqjlT1BFVHqXqiqqNVPUnVk1U9RdUxqo5VdZyqp6p6mqqnqzpe1TNUnaDqmaqeperZqp6j6rmqTlT1PFXPV/UCVS9U9SJVL1b1ElUvVfUyVSepermqV6h6papXqXq1qpNVvUbVKapeq+pUVa9T9XpVb1D1RlVvUnWaqjerOl3VW1S9VdXbVL1dVX3IP0PVO1W9S9W7Vb1H1XtVvU/V+1WdqeoDqj6o6kOqPqzqI6rOUvVRVWer+piqc1R9XNUnVH1S1adUfVrVuao+o+qzqj6n6vOqvqDqi6q+pOo8VV9W9RVVX1X1NVXnq7pA1ddVfUPVN1V9S9W3VX1H1XdVXajqe6ouUvV9VRer+oGqH6r6kapLVP1Y1aWqfqLqMlU/VXW5qp+p+rmqX6i6QtUvVf1K1a9V/UbVb1Vdqep3qq5S9XtVV6v6g6o/qvqTqmtU/VnVX1T9VdXfVP1d1T9U/VPVtar+peo6Vf9W9R9V/1X1f8efauHXecDyVa2l6iaq1lZ1U1XrqLqZqnVV3VzVeqrWV7WBqluo2lDVRqo2VnVLVZuoupWqTVXdWtVmqm6janNVt1W1harbqbq9qjuo2lLVAlVbqbqjqq1V3UnVNqrurOouqu6qaltVd1O1naq7q9pe1T1U7aDqnvkbUrztlcYzD/z3n/9bN3X54/wb8s7oMK9B2qX/6X511z4KuKb1rLpr5QHXpgVc2zS/+msDAq6NDbg2J+Da5wHXOteq/tqfh2z47LT1pOlX37F13/RrawOu/RVwbV3Atb8Drv0TcO3fgGvrA679D+SquZYIuJYfcK1WwLVNAq7VDri2acC1OgHXNgu4Vjfg2uYB1+oFXKsfcK1BwLUtAq41DLjWKOBa44BrWwZcaxJwbauAa00Drm0dcK1ZwLVtAq41D7i2bcC1FgHXtgu4tn3AtR0CrrUMuFYQcK1VwLUdA661Dri2U8C1NgHXdg64tkvAtV0DrrUNuLZbwLV2Add2D7jWPuDaHgHXOgRc2zPgWseAa3sFXOsUcG3vgGv7BFzbN+Ba54Br+wVc6xJwbf+Aa10DrnULuFYYcK0o4FpxwDUv4Foy4FpJwLXSgGtlAdfKA65VBFyrDLjWPeBaj4BrBwRc6xlw7cCAa70Crh0UcK13wLWDA64dEnDt0IBrfQKuHRZw7fCAa0cEXDsy4FrfgGv9Aq4dFXCtf8C1owOuDQi4dkzAtYEB1wYFXBsccO3YgGtDAq5VBVwbGnDtuIBrwwKuDQ+4NiLg2vEB10YGXDsh4NqogGsnBlwbHXDtpIBrJwdcOyXg2piAa2MDro0LuHZqwLXTAq6dHnBtfMC1MwKuTQi4dmbAtbMCrp0dcO2cgGvnBlybGHDtvIBr5wdcuyDg2oUB1y4KuHZxwLVLAq5dGnDtsoBrkwKuXR5w7YqAa1cGXLsq4NrVAdcmB1y7JuDalIBr1wZcmxpw7bqAa9dXcy31lxLNzOfAgUNGjzpp3NihA0eNrhp4ytCqcUPGjhh94k7m8mbmM3Uypk+f9MlOQV6kktgs7Tn8+XO7b2a/EHo+73/Pp54hns9PPb8J9/z/vgLVpcx6Ps96b/28/370mmc9k7qWdjr5v68XddFfrzZM++9Gac/oUpHWVsK6Vpl2LfXuHPurIsf+yt8yr/o+0l8fax93MP+7lk9b6fOsdto9fu9Lf4c9P/3ekd5OPtlOfkA7Cevfa1n/7td26lnk/tSczE+7v3bA/ZtUY2ee9b6gvqyuD9L7SI9vKt65+XN690RaW3l5/42NXTaxPlP3tDafddPaT7e1IC+4fPzKbx88dsBeoxpbz+uS8nvztPcPHFg14lQtvWPNP/z/RXBJAaiVer4297yv4NoTWBdWcOvnZU/slMiGiXG64Kba3SzPXxgK8iKVyhwFO7FlXvXClBLcQZat6UFbkBep5KfenT6uYYthejuJaj7zrHdkNJhm86Z5sM2JhnnZ82dT673p8Qb0e92Uj3V9LqaubZ727nzrWj2r3dR/28UWv3Sb9dgel/Ze+z7bnk3Trm1uXauTdq2edS3f573oODbMy56nddKes8eitvXftXzs3Mxq236ujvUO29fUNb/P1DvD/LHbyMv7b27ZPhTkRSt+cxN4PpF6vi73fL6+t735H1vkZc+ddJ/T51LtPH8gST27iXV/UdpzHa32qoOM9P+dn2ZDnvVcjuvQpnbMpBe/mLG1z9aV1H/bxS++Uzaj8Z3eD3Wsa+n9uVnAc+mQk4qpdK3a1Go/dU+61tWzfElY/75J2r9v7mPXJtb9peZTP2O+tv8/8yT9+U2sa/V8/Er971R/5gfYn5pDDdKuAXNoi1T/buFzMXWtoY9NqWuNrHZT/20XvzmUshmdQ+n90NC6lt6fKdv81tjUfWHjZY9J6jm/MUn9d02Pib0W/t82JvXTrtljkh7z6fel+5W+6UyP7brWu/z4IH2diHvjN9R8ut74pfP0/zvA+O9Z5P7/mw8wtjX/XTXilKHqJPXUoQNHnDh26LChpww8edzosSOGnjg2NdM3S3sqvbWCvEglP/V8Pe55XzLZPO2/69kNms9NfJ5LVPO/863PoHsTAe+t73Mt9c4tzWe6vSk/UoqWPhqnDj1lbCrKU33YNK095rRlK+553zFomvbfqffap0J5QBupkq6MdrHHtpbVrn2qBLSfqM4Ov/FOjeVWaf+W6o//D8Q4dWwKjTwA", - "debug_symbols": "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utege40ktyS39Us61i/p2N3RHbs7uvFeG++18V4b77XxXjvoXgPGCRgnYJyAcQLGCRgnYJygew2612hyG3Jbv6Rj/ZKO3R3dsbujG++18V4b77XxXhvvtZPuNWGchHESxkkYJ2GchHESxkm616R7zfVLOtcv6Vy/pHP9ks7dHd25u6Mb77XxXhvvtfFeG++1k+41YZyEcRLGSRgnYZyEcRLGSbrXpHvN9Us61y/pXL+kc/2Szt0d3bm7oxvvtfFeG++18V4b77WT7jVhnIRxEsZJGCdhnIRxEsZJuteke80gtyC39Us61y/p3N3Rnbs7uvFeG++18V4b77XxXjvpXhPGSRgnYZyEcRLGSRgnYZyke0261yxyK3Jbv6Rz/ZLO3R3dubujG++18V4b77XxXhvvtZPuNWGchHESxkkYJ2GchHESxkm616R7zSG3Ibf1SzrXL+nc3dGduzu68V4b77XxXhvvtfFeu+heC8YpGKdgnIJxCsYpGKdgnKJ7LbrXWr+ka/2SrvVLutYv6drd0V27O7rxXhvvtfFeG++18V676F4LxikYp2CcgnEKxikYp2Cconstutdav6Rr/ZKu9Uu61i/p2t3RXbs7uvFeG++18V4b77XxXrvoXgvGKRinYJyCcQrGKRinYJyiey261wpyC3Jbv6Rr/ZKu3R3dtbujG++18V4b77XxXhvvtYvutWCcgnEKxikYp2CcgnEKxim616J7rSK3Irf1S7rWL+na3dFduzu68V4b77XxXhvvtfFeu+heC8YpGKdgnIJxCsYpGKdgnKJ7LbrXwi9p/JLGL2n8kt7d0d27O7rxXhvvtfFeG++18V676V4bxmkYp2GchnEaxmkYp2GcpnttutfGL2n8ksYvafyS3t3R3bs7uvFeG++18V4b77XxXrvpXhvGaRinYZyGcRrGaRinYZyme22618YvafySxi9p/JLe3dHduzu68V4b77XxXhvvtfFeu+leG8ZpGKdhnIZxGsZpGKdhnKZ7bbrXxi9p/JLGL2n8kt7d0d27O7rxXhvvtfFeG++18V676V4bxmkYp2GchnEaxmkYp2GcpnttutfGL2n8ksYvafyS3t3R3bs7uvFeG++18V4b77XxXrvpXhvGaRinYZyGcRrGGRhnYJyhex2618EvGfySwS8Z/JLZ3dE9uzu68V4b77XxXhvvtfFee+he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f2WJf2XJ501Y8nkTJn67id9u4reb+O0mfrul9O0pPJjCgyk8mMKDKTyYwoMpPJjSt6f07RmSb0i++FeW+FeWfN6EJZ83YeK3m/jtJn67id9u4rdbSt+ewoMpPJjCgyk8mMKDKTyYwoMpfXtK354l+Zbki39liX9lyedNWPJ5EyZ+u4nfbuK3m/jtJn67pfTtKTyYwoMpPJjCgyk8mMKDKTyY0ren9O05ku9IvvhXlvhXlnzehCWfN2Hit5v47SZ+u4nfbuK3W0nfXsKDJTxYwoMlPFjCgyU8WMKDJX17Sd9e+FdW+FdW+FdW+FdWfN6EFZ83YeK3m/jtJn67id9u4rdbSd9ewoMlPFjCgyU8WMKDJTxYwoMlfXtJ3174V1b4V1b4V1b4V1Z83oQVnzdh4reb+O0mfruJ327it1tJ317CgyU8WMKDJTxYwoMlPFjCgyV9e0nfXiH5huSLf2WFf2XF501Y8XkTJn67id9u4reb+O0mfruV9O0lPFjCgyU8WMKDJTxYwoMlPFjSt5f07VWSb0m++FdW+FdWfN6EFZ83YeK3m/jtJn67id9u4rdbSd9ewoMlPFjCgyU8WMKDJTxYwoMlfXtJ314j+Y7kK/5Vi3/VfN6ENZ83YeK3m/jtJn67id9u4rdbS9/ewoMtPNjCgy082MKDLTzYwoMtfXtL397iX7X4Vy3+VYt/1XzehDWfN2Hit5v47SZ+u4nfbuK3W0vf3sKDLTzYwoMtPNjCgy082MKDLX17S9/e4l+1+Fct/lWLf9V83oQ1nzdh4reb+O0mfruJ327it1tL397Cgy082MKDLTzYwoMtPNjCgy19e0vf3uJftfhXLf5Vi3/VfN6ENZ83YeK3m/jtJn67id9u4rdbS9/ewoMtPNjCgy082MKDLTzYwoMtfXtL397iX7X4Vy3+VYt/1XzehDWfN2Hit5v47SZ+u4nfbuK3W0vf3sKDLTzYwoMtPNjCgy082MKDI337SN8+4l+N+Fcj/tWIfzV83oQNnzdh4reb+O0mfruJ327it9tI3z7CgyM8OMKDIzw4woMjPDjCgyN9+0jfPuJfjfhXI/7ViH81fN6EDZ83YeK3m/jtJn67id9u4rfbSN8+woMjPDjCgyM8OMKDIzw4woMjfftI3z7iX434VyP+1Yh/NXzehA2fN2Hit5v47SZ+u4nfbuK320jfPsKD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vcW3t/j2Ft/e4tu7tW9v5cFWHmzlwVYebOXBVh5s5cHWvr21b2/4q274q274q274q27uTXRzb6LFt7f49hbf3uLbW3x7t/btrTzYyoOtPNjKg6082MqDrTzY2re39u1dmm9pvvBX3fBX3dyb6ObeRItvb/HtLb69xbe3+PZu7dtbebCVB1t5sJUHW3mwlQdbebC1b2/t23s039F84a+64a+6uTfRzb2JFt/e4ttbfHuLb2/x7d3at7fyYCsPtvJgKw+28mArD7byYGvf3tq399N8n+YLf9UNf9XNvYke7k20+PYW397i21t8e4tv79G+fZQHR3lwlAdHeXCUB0d5cJQHR/v20b594K964K964K964K96uDfRw72JFt/e4ttbfHuLb2/x7T3at4/y4CgPjvLgKA+O8uAoD47y4GjfPtq3D/xVD/xVD/xVD/xVD/cmerg30eLbW3x7i29v8e0tvr1H+/ZRHhzlwVEeHOXBUR4c5cFRHhzt20f79inNtzRf+Kse+Kse7k30cG+ixbe3+PYW397i21t8e4/27aM8OMqDozw4yoOjPDjKg6M8ONq3j/btM5rvar7wVz3wVz3cm+jh3kSLb2/x7S2+vcW3t/j2Hu3bR3lwlAdHeXCUB0d5cJQHR3lwtG8f7dtX/NWKv1rxVyv+ark30cu9iRbf3uLbW3x7i29v8e292rev8uAqD67y4CoPrvLgKg+u8uBq377at6/4qxV/teKvVvzVcm+il3sTLb69xbe3+PYW397i23u1b1/lwVUeXOXBVR5c5cFVHlzlwdW+fbVvX/FXK/5qxV+t+Kvl3kQv9yZafHuLb2/x7S2+vcW392rfvsqDqzy4yoOrPLjKg6s8uMqDq337at++4q9W/NWKv1rxV8u9iV7uTbT49hbf3uLbW3x7i2/v1b59lQdXeXCVB1d5cJUHV3lwlQdX+/bVvn3FX634qxV/teKvlnsTvdybaPHtLb69xbe3+PYW396rffsqD67y4CoPrvLgUx58yoNPefBp3/60b3/ir574qyf+6om/etyb6Me9iRbf3uLbW3x7i29v8e39tG9/yoNPefApDz7lwac8+JQHn/Lg0779ad/+xF898VdP/NUTf/W4N9GPexMtvr3Ft7f49hbf3uLb+2nf/pQHn/LgUx58yoNPefApDz7lwad9+9O+/Ym/euKvnvirJ/7qcW+iH/cmWnx7i29v8e0tvr3Ft/fTvv0pDz7lwac8+JQHn/LgUx58yoNP+/anffsTf/XEXz3xV0/81ePeRD/uTbT49hbf3uLbW3x7i2/vp337Ux58yoNPefApDz7lwac8+JQHn/btT/v2J/7qib964q+e+KvHvYl+3Jto8e0tvr3Ft7f49hbfPh/79vnIg/ORB+cjD85HHpyPPDgfeXA+8uB87NvnY98+H/zVfPBX88FfzQd/NR/3Jubj3sSIbx/x7SO+fcS3j/j2+di3z0cenI88OB95cD7y4HxXfa/6XvVl3z4f+/b54K/mg7+aD/5qPvir+bg3MR/3JkZ8+4hvH/HtI759xLfPl5pvar6p+abmm5pvqm+qb6pvab6l+ZbmW5ov/NV88FfzcW9iPu5NjPj2Ed8+4ttHfPuIb5+vNd/WfFvzbc23Nd9W31bfUd/RfEfzHc13NF/4q/ngr+bj3sR83JsY8e0jvn3Et4/49hHfPt9qvqv5rua7mu9qvqu+T32f+j7N92m+T/N9mi/81XzwV/Nxb2I+7k2M+PYR3z7i20d8+4hvn8O+/f/rVj2qVzXzPUd9j/oe9WXf/v91qi7VrXpUr+r/vuvmcG9ixLeP+PYR3z7i20d8+xz27XPIg3PIg3PIg3PIg3NCfUN9Q33Zt89h3z4H/moO/NUc+Ks58FdzuDcxh3sTI759xLeP+PYR3z7i2+ek5puab2q+pfmW5lvqW+pb6luab2m+pfmW5gt/NQf+ag73JuZwb2LEt4/49hHfPuLbR3z7nNZ8W/MdzXc039F8R31HfUd9R/MdzXc039F84a/mwF/N4d7EHO5NjPj2Ed8+4ttHfPuIb5+zmu/TfJ/m+zTfp/k+9X3q+9T3ab5P84W/mgt/NRf+ai781VzuTczl3sSIbx/x7SO+fcS3j/j2uezb55IH55IH55IH55IH5x71Pep71Jd9+1z27XPhr+bCX82Fv5oLfzWXexNzuTcx4ttHfPuIbx/x7SO+fS779rnkwbnkwbnkwbnkwbmhvqG+ob6h+abmm5pvar7wV3Phr+Zyb2Iu9yZGfPuIbx/x7SO+fcS3zy3NtzTf0nxL8y3Nt9S31LfUtzXf1nxb823NF/5qLvzVXO5NzOXexIhvH/HtI759xLeP+Pa5o/mO5jua72i+o/mO+o76rvqu5rua72q+q/nCX82Fv5rLvYm53JsY8e0jvn3Et4/49hHfPvdpvk/zfZrv03yf5qs8GMqDoTwY7Nsn2LdPwF9NwF9NwF9NwF9NcG9ignsTI759xLeP+PYR3z7i2yfYt08oD4byYCgPhvJgKA+G8mAoDwb79gn27RPwVxPwVxPwVxPwVxPcm5jg3sSIbx/x7SO+fcS3j/j2CfbtE8qDoTwYyoOhPBjKg6E8GMqDkZpvar6p+abmC381AX81wb2JCe5NjPj2Ed8+4ttHfPuIb58ozVd5MJQHQ3kwlAdDeTCUB0N5MFrzbc23Nd/WfOGvJuCvJrg3McG9iRHfPuLbR3z7iG8f8e0To/kqD4byYCgPhvJgKA+G8mAoD8Zqvqv5rua7mi/81QT81QT3Jia4NzHi20d8+4hvH/HtI759gn37pPJgKg+m8mAqD6byYCoPpvJgsm+fZN8+CX81CX81CX81CX81yb2JSe5NjPj2Ed8+4ttHfPuIb59k3z6pPJjKg6k8mMqDqTyYyoOpPJjs2yfZt0/CX03CX03CX03CX01yb2KSexMjvn3Et4/49hHfPuLbJ1PzVR5M5cFUHkzlwVQeTOXBVB7M1HxL8y3NtzRf+KtJ+KtJ7k1Mcm9ixLeP+PYR3z7i20d8+2RrvsqDqTyYyoOpPJjKg6k8mMqDOZrvaL6j+Y7mC381CX81yb2JSe5NjPj2Ed8+4ttHfPuIb59czVd5MJUHU3kwlQdTeTCVB1N5MJ/m+zTfp/k+zRf+ahL+apJ7E5Pcmxjx7SO+fcS3j/j2Ed8+pX17KQ+W8mApD5byYCkPlvJgKQ+W9u2lfXvBX03BX03BX03BX01xb2KKexMjvn3Et4/49hHfPuLbp7RvL+XBUh4s5cFSHizlwVIeLOXB0r69tG8v+Ksp+Ksp+Ksp+Ksp7k1McW9ixLeP+PYR3z7i20d8+5T27aU8WMqDpTxYyoOlPFjKg6U8WNq3l/btVZpvab7wV1PwV1Pcm5ji3sSIbx/x7SO+fcS3j/j2Ke3bS3mwlAdLebCUB0t5sJQHS3mwtG8v7dtrNN/RfOGvpuCvprg3McW9iRHfPuLbR3z7iG8f8e1T2reX8mApD5byYCkPlvJgKQ+W8mBp317at9fTfOGvpuGvpuGvprk3Mc29iRHfPuLbR3z7iG8f8e3T2re38mArD7byYCsPtvJgKw+28mBr397atzf81TT81TT81TT81TT3Jqa5NzHi20d8+4hvH/HtI759Wvv2Vh5s5cFWHmzlwVYebOXBVh5s7dtb+/ZOzTc1X/irafirae5NTHNvYsS3j/j2Ed8+4ttHfPu09u2tPNjKg6082MqDrTzYyoOtPNjat7f27d2ab2u+8FfT8FfT3JuY5t7EiG8f8e0jvn3Et4/49mnt21t5sJUHW3mwlQdbebCVB1t5sLVvb+3bezXf1Xzhr6bhr6a5NzHNvYkR3z7i20d8+4hvH/Ht09q3t/JgKw+28mArD7byYCsPjvLgaN8+2rcP/NUM/NUM/NUM/NUM9yZmuDcx4ttHfPuIbx/x7SO+fUb79lEeHOXBUR4c5cFRHhzlwVEeHO3bR/v2gb+agb+agb+agb+a4d7EDPcmRnz7iG8f8e0jvn3Et89o3z7Kg6M8OMqDozw4yoOjPDjKg6N9+2jfPqn5puYLfzUDfzXDvYkZ7k2M+PYR3z7i20d8+4hvn9G+fZQHR3lwlAdHeXCUB0d5cJQHR/v20b59WvNtzRf+agb+aoZ7EzPcmxjx7SO+fcS3j/j2Ed8+o337KA+O8uAoD47y4CgPjvLgKA+O9u2jffus5ruaL/zVDPzVDPcmZrg3MeLbR3z7iG8f8e0jvn1G+/ZRHlzlwVUeXOXBVR5c5cFVHlzt21f79hV/teKvVvzVir9a7k3Mcm9ixLeP+PYR3z7i20d8+6z27as8uMqDqzy4yoOrPLjKg6s8uNq3r/btK/5qxV+t+KsVf7Xcm5jl3sSIbx/x7SO+fcS3j/j2We3bV3lwlQdXeXCVB1d5cJUHV3lwtW9f7dtX/NWKv1rxVyv+ark3Mcu9iRHfPuLbR3z7iG8f8e2z2rev8uAqD67y4CoPrvLgKg+u8uBq377at6/4qxV/teKvVvzVcm9ilnsTI759xLeP+PYR3z7i22e1b1/lwVUeXOXBVR5c5cFVHlzlwdW+fbVvX/FXK/5qxV+t+Kvl3sQs9yZGfPuIbx/x7SO+fcS3z9O+/SkPPuXBpzz4lAef8uBTHnzKg0/79qd9+xN/9cRfPfFXT/zV497EPO5NjPj2Ed8+4ttHfPuIb5+nfftTHnzKg0958CkPPuXBpzz4lAef9u1P+/Yn/uqJv3rir574q8e9iXncmxjx7SO+fcS3j/j2Ed8+T/v2pzz4lAef8uBTHnzKg0958CkPPu3bn/btT/zVE3/1xF898VePexPzuDcx4ttHfPuIbx/x7SO+fZ727U958CkPPuXBpzz4lAef8uBTHnzatz/t25/4qyf+6om/euKvHvcm5nFvYsS3j/j2Ed8+4ttHfPs87duf8uBTHnzKg0958CkPPuXBpzz4tG9/2rc/8VdP/NWDv9oP/mo/7k3sx72JFd++4ttXfPuKb1/x7fuxb9+PPLgfeXA/8uB+5MH9jvoe9T3qy759P/bt+8Ff7Qd/tR/81X7wV/txb2I/7k2s+PYV377i21d8+4pv3499+37kwf3Ig/uRB/cjD+4X6hvqG+rLvn0/9u37heabmi/81X7wV/txb2I/7k2s+PYV377i21d8+4pv368039J8S/Mtzbc031LfUt9S39J8S/Ntzbc1X/ir/eCv9uPexH7cm1jx7Su+fcW3r/j2Fd++32i+o/mO5jua72i+o76jvqO+o/mu5rua72q+8Ff7wV/tx72J/bg3seLbV3z7im9f8e0rvn2/p/k+zfdpvk/zfZrvU9+nvuTBPezb97Bv3wN/tQf+ag/81R74q/+v//uu+//6v++6Fd++4ttXfPuKb1/x7f9fh+pUXapb9ahW36O+V33Zt+9h374H/moP/NUe+Ks98Fd7uDexh3sTK759xbev+PYV377i2/ewb99DHtxDHtxDHtxDHtwT6pvqm+qbmm9qvqn5puYLf7UH/moP9yb2cG9ixbev+PYV377i21d8+57SfEvzLc23NN/SfFt9W31bfVvzbc23Nd/WfOGv9sBf7eHexB7uTaz49hXfvuLbV3z7im/fM5rvaL6j+Y7mu5rvqu+q76rvar6r+a7mu5ov/NUe+Ks93JvYw72JFd++4ttXfPuKb1/x7Xue5vs0X/LgXvLgXvLgXvLgXvLgXvLgXvbte9m374W/2gt/tRf+ai/81V7uTezl3sSKb1/x7Su+fcW3r/j2vezb95IH95IH95IH95IH9171vep71Zd9+1727Xvhr/bCX+2Fv9oLf7WXexN7uTex4ttXfPuKb1/x7Su+fW9ovqn5puabmm9qvqm+qb6pvqn5puabmm9pvvBXe+Gv9nJvYi/3JlZ8+4pvX/HtK759xbfvbc23Nd/WfFvzbc231bfVt9W3Nd/WfEfzHc0X/mov/NVe7k3s5d7Eim9f8e0rvn3Ft6/49r2r+a7mu5rvar6r+a76rvqu+q7m+zTfp/k+zRf+ai/81V7uTezl3sSKb1/x7Su+fcW3r/j2DfbtG8qDoTwYyoOhPBjKg6E8GMqDwb59g337BvzVBvzVBvzVBvzVBvcmNrg3seLbV3z7im9f8e0rvn2DffuG8mAoD4byYCgPhvJgKA+G8mCwb99g374Bf7UBf7UBf7UBf7XBvYkN7k2s+PYV377i21d8+4pv30jNV3kwlAdDeTCUB0N5MJQHQ3kwSvMtzbc039J84a824K82uDexwb2JFd++4ttXfPuKb1/x7Rut+SoPhvJgKA+G8mAoD4byYCgPxmi+o/mO5juaL/zVBvzVBvcmNrg3seLbV3z7im9f8e0rvn1jNV/lwVAeDOXBUB4M5cFQHgzlwXia79N8n+b7NF/4qw34q03uTWxyb2LFt6/49hXfvuLbV3z7Jvv2TeXBVB5M5cFUHkzlwVQeTOXBZN++yb59E/5qE/5qE/5qE/5qk3sTm9ybWPHtK759xbev+PYV377Jvn1TeTCVB1N5MJUHU3kwlQdTeTDZt2+yb9+Ev9oMzRf+ahP+apN7E5vcm1jx7Su+fcW3r/j2Fd++mZqv8mAqD6byYCoPpvJgKg+m8mCW5luab2m+rfnCX23CX21yb2KTexMrvn3Ft6/49hXfvuLbN0fzVR5M5cFUHkzlwVQeTOXBVB7M0XxH813NdzVf+KtN+KtN7k1scm9ixbev+PYV377i21d8++bTfJUHU3kwlQdTeTCVB1N5MJUHU/v20r694K+24K+24K+24K+2uDexxb2JFd++4ttXfPuKb1/x7Vvat5fyYCkPlvJgKQ+W8mApD5byYGnfXtq3F/zVFvzVFvzVFvzVFvcmtrg3seLbV3z7im9f8e0rvn1L+/ZSHizlwVIeLOXBUh4s5cFSHizt20v79krNNzVf+Kst+Kst7k1scW9ixbev+PYV377i21d8+5b27aU8WMqDpTxYyoOlPFjKg6U8WNq3l/bt1Zpva77wV1vwV1vcm9ji3sSKb1/x7Su+fcW3r/j2Le3bS3mwlAdLebCUB0t5sJQHS3mwtG8v7dtrNd/VfOGvtuCvtrg3scW9iRXfvuLbV3z7im9f8e1b2reX8mApD5byYCsPtvJgKw+28mBr397atzf81Tb81Tb81Tb81Tb3Jra5N7Hi21d8+4pvX/HtK759W/v2Vh5s5cFWHmzlwVYebOXBVh5s7dtb+/aGv9qGv9qGv9qGv9rm3sQ29yZWfPuKb1/x7Su+fcW3b2vf3sqDrTzYyoOtPNjKg6082MqDrX17a9/eqfmm5gt/tQ1/tc29iW3uTaz49hXfvuLbV3z7im/f1r69lQdbebCVB1t5sJUHW3mwlQdb+/bWvr1b8x3NF/5qG/5qm3sT29ybWPHtK759xbev+PYV376tfXsrD7byYCsPtvJgKw+28mArD7b27a19ez/N92m+8Ffb8Ffb3JvY5t7Eim9f8e0rvn3Ft6/49h3t20d5cJQHR3lwlAdHeXCUB0d5cLRvH+3bB/5qB/5qB/5qB/5qh3sTO9ybWPHtK759xbev+PYV376jffsoD47y4CgPjvLgKA+O8uAoD4727aN9+8Bf7cBf7cBf7cBf7XBvYod7Eyu+fcW3r/j2Fd++4tt3tG8f5cFRHhzlwVEeHOXBUR4c5cHRvn20b5/SfEvzhb/agb/a4d7EDvcmVnz7im9f8e0rvn3Ft+9o3z7Kg6M8OMqDozw4yoOjPDjKg6N9+2jfPqP5juYLf7UDf7XDvYkd7k2s+PYV377i21d8+4pv39G+fZQHR3lwlAdHeXCUB0d5cJQHR/v20b59nub7NF/4qx34qx3uTexyb2LFt6/49hXfvuLbV3z7rvbtqzy4yoOrPLjKg6s8uMqDqzy42rev9u0r/mrFX634qxV/tdyb2OXexIpvX/HtK759xbev+PZd7dtXeXCVB1d5cJUHV3lwlQdXeXC1b1/t21f81Yq/WvFXK/5quTexy72JFd++4ttXfPuKb1/x7bvat6/y4CoPrvLgKg+u8uAqD67y4Grfvtq3r/irFX+14q9W/NVyb2KXexMrvn3Ft6/49hXfvuLbd7VvX+XBVR5c5cFVHlzlwVUeXOXB1b59tW9f8Vcr/mrFX634q+XexC73JlZ8+4pvX/HtK759xbfvat++yoOrPLjKg6s8uMqDqzy4yoOrfftq3/7EXz3xV0/81RN/9bg3sY97Eyu+fcW3r/j2Fd++4tv3ad/+lAef8uBTHnzKg0958CkPPuXBp3370779ib964q+e+Ksn/upxb2If9yZWfPuKb1/x7Su+fcW379O+/SkPPuXBpzz4lAef8uBTHnzKg0/79qd9+xN/9cRfPfFXT/zV497EPu5NrPj2Fd++4ttXfPuKb9+nfftTHnzKg0958CkPPuXBpzz4lAef9u1P+/Yn/uqJv3rir574q8e9iX3cm1jx7Su+fcW3r/j2Fd++T/v2pzz4lAef8uBTHnzKg0958CkPPu3bn/btT/zVE3/1xF898VePexP7uDex4ttXfPuKb1/x7Su+fZ/27U958CkPPuXBRx58H3nwfeTB95EH38e+/X3s298Hf/U++Kv3wV+9D/7qfdybeB/3Jp749ie+/Ylvf+Lbn/j297Fvfx958H3kwfeRB99HHnzfVd+rvld92be/j337++Cv3gd/9T74q/fBX72PexPv497EE9/+xLc/8e1PfPsT3/4+9u3vIw++LzTf1HxT8031TfVN9U3NNzXf1HxT84W/eh/81fu4N/E+7k088e1PfPsT3/7Etz/x7e8rzbc039Z8W/NtzbfVt9W31bc139Z8W/NtzRf+6n3wV+/j3sT7uDfxxLc/8e1PfPsT3/7Et79vNN/VfFfzXc13Nd9V31XfVd/VfFfzXc33ab7wV++Dv3of9ybex72JJ779iW9/4tuf+PYnvv0d9u3vkAffIQ++Qx58hzz4Dnnw/+tWPaqZ72Hf/g781TvwV+/AX/1/Har/+657h3sTT3z7E9/+xLc/8e1PfPs77NvfIQ++Qx58hzz4Dnnwnau+V32v+rJvf4d9+zvwV+/AX70Df/UO/NU73Jt4h3sTT3z7E9/+xLc/8e1PfPs7qfmm5puab2q+qfmm+qb6pvqW5luab2m+pfnCX70Df/UO9ybe4d7EE9/+xLc/8e1PfPsT3/5Oa76t+bbm25pva76tvq2+o76j+Y7mO5rvaL7wV+/AX73DvYl3uDfxxLc/8e1PfPsT3/7Et7+zmu9qvqv5rua7mu+q71Pfp75P832a79N8n+YLf/UO/NU73Jt4h3sTT3z7E9/+xLc/8e1PfPu77NvfJQ++Sx58lzz4Lnnw3aO+R32P+rJvf5d9+7vwV+/CX70Lf/Uu/NW73Jt4l3sTT3z7E9/+xLc/8e1PfPu77NvfJQ++Sx58lzz4Lnnw3VDfUN9QX/bt77Jvfxf+6l34q3fhr96Fv3qXexPvcm/iiW9/4tuf+PYnvv2Jb383Nd/UfFPzLc23NN9S31LfUt/SfEvzLc23NF/4q3fhr97l3sS73Jt44tuf+PYnvv2Jb3/i299tzbc139F8R/MdzXfUd9R31Hc039F8R/MdzRf+6l34q3e5N/Eu9yae+PYnvv2Jb3/i25/49ndX832a79N8n+b7NN+nvk99n/o+zfdpvvBXL+CvXsBfvYC/esG9iRfcm3ji25/49ie+/Ylvf+LbX7Bvf6E8GMqDoTwYyoOhPBjKg6E8GOzbX7BvfwF/9QL+6gX81Qv4qxfcm3jBvYknvv2Jb3/i25/49ie+/QX79hfKg6E8GMqDoTwYyoOhPBjKgxGab2q+qfmm5gt/9QL+6gX3Jl5wb+KJb3/i25/49ie+/Ylvf1Gar/JgKA+G8mAoD4byYCgPhvJgtObbmm9rvq35wl+9gL96wb2JF9ybeOLbn/j2J779iW9/4ttfjOarPBjKg6E8GMqDoTwYyoOhPBir+a7mu5rvar7wVy/gr15wb+IF9yae+PYnvv2Jb3/i25/49hdP81UeDOXBUB4M5cFQHkzlwVQeTPbtL9m3v4S/egl/9RL+6iX81UvuTbzk3sQT3/7Etz/x7U98+xPf/pJ9+0vlwVQeTOXBVB5M5cFUHkzlwWTf/pJ9+0v4q5fwVy/hr17CX73k3sRL7k088e1PfPsT3/7Etz/x7S/Zt79UHkzlwVQeTOXBVB5M5cFUHszUfFPzTc03NV/4q5fwVy+5N/GSexNPfPsT3/7Etz/x7U98+8vSfJUHU3kwlQdTeTCVB1N5MJUHszXf1nxb823NF/7qJfzVS+5NvOTexBPf/sS3P/HtT3z7E9/+cjRf5cFUHkzlwVQeTOXBVB5M5cFczXc139V8V/OFv3oJf/WSexMvuTfxxLc/8e1PfPsT3/7Et7/Uvr2UB0t5sJQHS3mwlAdLebCUB0v79tK+veCvXsFfvYK/egV/9Yp7E6+4N/HEtz/x7U98+xPf/sS3v9K+vZQHS3mwlAdLebCUB0t5sJQHS/v20r694K9ewV+9gr96BX/1insTr7g38cS3P/HtT3z7E9/+xLe/0r69lAdLebCUB0t5sJQHS3mwlAdL+/bSvr1K8y3NF/7qFfzVK+5NvOLexBPf/sS3P/HtT3z7E9/+Svv2Uh4s5cFSHizlwVIeLOXBUh4s7dtL+/YazXc0X/irV/BXr7g38Yp7E098+xPf/sS3P/HtT3z7K+3bS3mwlAdLebCUB0t5sJQHS3mwtG8v7dvrab5P84W/egV/9Yp7E6+4N/HEtz/x7U98+xPf/sS3v9a+vZUHW3mwlQdbebCVB1t5sJUHW/v21r694a9ew1+9hr96DX/1mnsTr7k38cS3P/HtT3z7E9/+xLe/1r69lQdbebCVB1t5sJUHW3mwlQdb+/bWvr3hr17DX72Gv3oNf/WaexOvuTfxxLc/8e1PfPsT3/7Et7/Wvr2VB1t5sJUHW3mwlQdbebCVB1v79ta+vUvzLc0X/uo1/NVr7k285t7EE9/+xLc/8e1PfPsT3/5a+/ZWHmzlwVYebOXBVh5s5cFWHmzt21v79h7NdzRf+KvX8FevuTfxmnsTT3z7E9/+xLc/8e1PfPtr7dtbebCVB1t5sJUHW3mwlQdbebC1b2/t2/tpvvBXb+Cv3sBfveHexBvuTTzx7U98+xPf/sS3P/Htb7RvH+XBUR4c5cFRHhzlwVEeHOXB0b59tG8f+Ks38Fdv4K/ewF+94d7EG+5NPPHtT3z7E9/+xLc/8e1vtG8f5cFRHhzlwVEeHOXBUR4c5cHRvn20b5/UfFPzhb96A3/1hnsTb7g38cS3P/HtT3z7E9/+xLe/0b59lAdHeXCUB0d5cJQHR3lwlAdH+/bRvn1a823NF/7qDfzVG+5NvOHexBPf/sS3P/HtT3z7E9/+Rvv2UR4c5cFRHhzlwVEeHOXBUR4c7dtH+/ZZzXc1X/irN/BXb7g38YZ7E098+xPf/sS3P/HtT3z7G+3bR3lwlAdHeXCUB0d5cJQHV3lwtW9f7dtX/NWKv1rxVyv+ark38ZZ7E098+xPf/sS3P/HtT3z7W+3bV3lwlQdXeXCVB1d5cJUHV3lwtW9f7dtX/NWKv1rxVyv+ark38ZZ7E098+xPf/sS3P/HtT3z7W+3bV3lwlQdXeXCVB1d5cJUHV3lwtW9f7dtX/NWKv1rxVyv+ark38ZZ7E098+xPf/sS3P/HtT3z7W+3bV3lwlQdXeXCVB1d5cJUHV3lwtW9f7dtX/NWKv1rxVyv+ark38ZZ7E098+xPf/sS3P/HtT3z7W+3bV3lwlQdXeXCVB1d5cJUHV3lwtW9f7dtX/NWKv1rxVyv+ark38ZZ7E098+xPf/sS3P/HtT3z7W+3bV3nwKQ8+5cGnPPiUB5/y4FMefNq3P+3bn/irJ/7qib964q8e9ybe497EE9/+xLc/8e1PfPsT3/6e9u1PefApDz7lwac8+JQHn/LgUx582rc/7duf+Ksn/uqJv3rirx73Jt7j3sQT3/7Etz/x7U98+xPf/p727U958CkPPuXBpzz4lAef8uBTHnzatz/t25/4qyf+6om/euKvHvcm3uPexBPf/sS3P/HtT3z7E9/+nvbtT3nwKQ8+5cGnPPiUB5/y4FMefNq3P+3bn/irJ/7qib964q8e9ybe497EE9/+xLc/8e1PfPsT3/6e9u1PefApDz7lwac8+JQHn/LgUx582rc/7duf+Ksn/uqJv3rirx73Jt7j3sQT3/7g2+8H3/5PfVRf1aE6VZfqVj2qV7X6HvX9b9/+T31Vh+pUXapb9d933T/133fdP/Xf3/n/6/++r/6pj+qrOlSn6lLdqkf1qlbfUN9Q3//27f/UoTpVl+pWPar/vuv+qf++6/6/Tv2dU/NNzTc139R8U/NNzTc139R8U/Mt9S31LfUtzbc039J8S/P9j7/6p17Vj7n/d2/in1p/59Z8W/Ntzbc139Z8W/Ntzbc139F8R31HfUd9R/MdzXc039F8/+Ov/qkf9X/3Jv6pD3Nf/Z1X813NdzXf1XxX813NdzXfp/k+zfep71Pfp75P832a79N8n+b7H391v/Mff/VPff6b+/nv3sQ/NX9n+PZ/6lLdqkf1qma+53yqj+qrWn2P+h71Pcz3nFG9qpnv+Y+/+qc+qu9/cz//3Zv4p+bvDN/+T92qR/WqZr4nPtVH9VUdqtU31DfUN5jviVWt+abmm0f1VR3M/b97E//U+jun5puab2q+qfmW5luab2m+pfmW5lvqW+pb6luab2m+rfm25ttXdahO5v7fvYl/av2dW/Ntzbc139F8R/MdzXc039F8R/Md9R31HfUdzXc139V8V/PdUJ2qi7n/d2/in1p/59V8V/N9mu/TfJ/m+zTfp/k+zfdpvk99n/o++t6P+d7vqL6qQ3WqLtX939zvf/cm/qn5O199X119X8G3/1Nf1aE6VZfqVj2q1feo71Xfy3zvvapDdaou1a2a77p7+a67+r66+r66+r6Cb/+nDtWpulS36lG9qtU31TfVNzXf1HxT803NN1v1qOa77ibfdVffV1ffV1ffV/Dt/9Sab2m+pfmW5luab2m+rb6tvq2+rfm25tuab2u+PapXNd91d/iuu/q+uvq+uvq+gm//p9Z8R/MdzXc039F8V/Nd9V31XfVdzXc139V8V/PdVc27cB/fdffxXXf1fXX1fXX1fQXf/k+t+T7N92m+yoOhPBjKg6E8GMqDoTwYH/ONr1WP6lXNuxDnU813XRy+60LfV6Hvq9D3FXz7P/WoXtXMN5QHQ3kwlAdDeTCUB0N5MC7zjTuqVzXzjfhUH9V810XwXRf6vgp9X4W+r+Db/6lXtearPBjKg6E8GMqDoTwYyoOhPBip+abmm5pvab51VF/VfNdF8V0X+r4KfV+Fvq/g2/+pNd/WfJUHQ3kwlAdDeTCUB0N5MJQHozXf1nxH8x3Nd67qUM13XQzfdaHvq9D3Vej7Cr79/+vVfFfzVR4M5cFQHgzlwVAeDOXBUB6M1Xyf5vs036f5vlCdqvmui8d3Xej7KvR9Ffq+gm//pz6qr+pQnapLdase1atafQ/zzXNUX9WhOlWXar7r8vBdl/q+Sn1fpb6v4Nv/qa/qUJ2qS3WrHtXqqzyYyoMZzDfjqg7VqbpUt2q+6zL4rkt9X6W+r1LfV/Dt/9Sab2q+yoOpPJjKg6k8mMqDqTyYyoNZmm9pvqX5luZbrXpU812XxXdd6vsq9X2V+r6Cb/+n1nxb81UeTOXBVB5M5cFUHkzlwVQezNF8R/MdzXc03xnVq5rvuly+61LfV6nvq9T3FXz7P7Xmu5qv8mAqD6byYCoPpvJgKg+m8mA+zfdpvk/zfZrvW9W8C/XxXVcf33Wl76vS91Xp+6q0by/t20v79lIeLOXBUh4s5cFSHizlwVIeLO3bS/v2OqN6VfMu1P1U811Xl++60vdV6fuq9H1V2reX9u2lfXspD5byYCkPlvJgKQ+W8mApD5b27aV9e8Wq1nzzU31U811XyXdd6fuq9H1V+r4q7dtL+/bSvr2UB0t5sJQHS3mwlAdLebCUB0v79tK+vUrzbc23j+qrmu+6ar7rSt9Xpe+r0vdVad9e2reX9u2lPFjKg6U8WMqDpTxYyoOlPFjat5f27bWa72q+e1WHar7ravmuK31flb6vSt9XpX17ad9e2reX8mApD5byYCkPlvJgKQ+W8mBp397at/d3VF/VoTpV813XH991re+r1vdV6/uqtW9v7dtb+/ZWHmzlwVYebOXBVh5s5cFWHmzt21v79r5XdahO1aWa77q+fNe1vq9a31et76vWvr21b2/t21t5sJUHW3mwlQdbebCVB1t5sLVvb+3bOzXf1HyzVLdqvus6+a5rfV+1vq9a31etfXtr397at7fyYCsPtvJgKw+28mArD7byYGvf3tq3d2u+rfl2qx7VfNd1813X+r5qfV+1vq9a+/bWvr21b2/lwVYebOXBVh5s5cFWHmzlwda+vbVv79V8V/PdUb2q+a7rx3dd6/uq9X3V+r5q7dtb+/bWvr2VB1t5sJUHR3lwlAdHeXCUB0f79tG+fb5WPapXNe/CHL7r5vBdN/q+Gn1fjb6vRvv20b59tG8f5cFRHhzlwVEeHOXBUR4c5cHRvn20b587qlc178LEp5rvugm+60bfV6Pvq9H31WjfPtq3j/btozw4yoOjPDjKg6M8OMqDozw42reP9u2Tmm9qvvWpPqr5rpviu270fTX6vhp9X4327aN9+2jfPsqDozw4yoOjPDjKg6M8OMqDo337aN8+rfmO5jtH9VXNd90M33Wj76vR99Xo+2q0bx/t20f79lEeHOXBUR4c5cFRHhzlwVEeHO3bR/v2eZrv03zfVR2q+a6bx3fd6Ptq9H01+r4a7dtX+/bVvn2VB1d5cJUHV3lwlQdXeXCVB1f79tW+fcVfrfirFX+14q/28F23h++61ffV6vtq9X212rev9u2rffsqD67y4CoPrvLgKg+u8uAqD6727at9+4q/WvFXK/5qxV9t8F23wXfd6vtq9X21+r5a7dtX+/bVvn2VB1d5cJUHV3lwlQdXeXCVB1f79tW+fcVfrfirFX+14q+2+K7b4rtu9X21+r5afV+t9u2rfftq377Kg6s8uMqDqzy4yoOrPLjKg6t9+2rfvuKvVvzVir9a8Vc7fNft8F23+r5afV+tvq9W+/bVvn21b1/lwVUeXOXBVR5c5cFVHlzlwdW+fbVvX/FXK/5qxV+t+Kt9fNe9j++6p++rp++rp++rp3370779ad/+lAef8uBTHnzKg0958CkPPuXBp3370779ib964q+e+Ksn/updvuve5bvu6fvq6fvq6fvqad/+tG9/2rc/5cGnPPiUB5/y4FMefMqDT3nwad/+tG9/4q+e+Ksn/uqJv3rJd91Lvuuevq+evq+evq+e9u1P+/anfftTHnzKg0958CkPPuXBpzz4lAef9u1P+/Yn/uqJv3rir574q9d8173mu+7p++rp++rp++pp3/60b3/atz/lwac8+JQHn/LgUx58yoNPefBp3/60b3/ir574qyf+6om/est33Y9vv//WpbpVj+pV/aj/93v1Vx/VV3WoVt+nvk99n/o+9X3/9T0/vv2vPqqv6lCdqkt1qx7Vq1p9j/oe9T3qe9T3qO9R36O+R32P+h71vep71feq71Xfq75Xfa/6XvW96nvVN9Q31DfUN9Q31DfUN9Q31DfUN9Q31TfVN9U31TfVN9U31TfVN9U31bfUt9S31LfUt9S31LfUt9S31LfUt9W31bfVt9W31bfVt9W31bfVt9V31HfUd9R31HfUd9R31HfUd9R31HfVd9V31XfVd9V31XfVd9V31XfV96nvU9+nvk99n/o+9X3q+9T3qa9+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r45+r358e9xf/U/fiF/dqkf1qn7U//u9+quP6qs6VKdq9S31LfX93+9V5K9+1P/7vfqrj+qrOlT/r+/vv/1/v1exv7pVj+pV/aj/93v1V//TN8+v/qdv/v6e//u9+qtTdalu1aN6VT/q//1e/dVHtfqu+q76/u/3Kn9/z//9Xv3Vo3pVP+r//V791Uf1//r2rw7V//St71f/07d+f5///V791aN6Vb//6h/f/lcf1Vd1qE7VpbpVj+r/9b2/+lH/7/fqrz6qr+pQnar/17d+dav+X9/51f/ru7/6Uf/v9+qvPqqv6lCdqkt1qx7V6nvVN9T3f79X9X71VR2qU3WpbtWj+p++/fv7/O/36t/6f79X3b/6n779+/v87/fqrw7VqbpUt+pRvaof9f9+r/5q9S31LfX93+9V//4+//u9+qtb9ahe1Y/6f79Xf/U/fef37/B/v1fz+5v87/fqr07V//Sd+NWtev77f+3Ht8/v39v/fq/+rf/3e/VX/6/v72/+v9+rvzpU8y78+Pbf7/CPb/+rR/Wq5l348e1/9VF9VYfqVK2+q76rvsu78OPb/63fp/qovqpDNe/Cj2///bb/+Pa/elSvat6FH9/+V/Mu/Pj23+/wj2//q1N1qW7Vo3pV8y78+Pa/+qhW36O+R30P78KPb/+rR/Wq5l348e1/9VHNu/Dj2/9q3oUf3/77Hf7x7X/1qF7VvAs/vv2vPqqv6lCdqtU31DfUN3gX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+Ta+821859v4zrfxnW/jO9/Gd76N73wb3/k2vvNteNHb8KK34UVv4zvfxne+je98G9/5Nr7zbXzn2/jOt7W/au2vWvurxne+je98G9/5Nr7zbXzn2/jOt/Gdb+M738Z3vo3vfBvf+Ta+821859v4zrfxnW/jO9/Bd76D73wH3/kOvvMdfOc78KJ34EXvwIvewXe+g+98B9/5Dr7zHXznO/jOd/Cd72h/NdpfjfZXg+98B9/5Dr7zHXznO/jOd/Cd7+A738F3voPvfAff+Q6+8x185zv4znfwne/Ai96BF70DL3oH3/kOvvMdfOc7+M538J3v4DvfwXe+o/3VaH812l8NvvMdfOc7+M538J3v4DvfwXe+g+98B9/5Dr7zHXznO/Cid+BF78CL3sF3voPvfAff+Q6+8x185zv4znfwne9ofzXaX432V4PvfAff+Q6+8x185zv4znfwne/gO9/Bd76D73wH3/kOvOgdeNE78KJ38J3v4DvfwXe+g+98B9/5Dr7zHXznO9pfjfZXo/3V4DvfwXe+g+98B9/5Dr7zHXznO/jOd/Cd7+A738V3vgsvehde9C686F1857v4znfxne/iO9/Fd76L73wX3/mu9ler/dVqf7X4znfxne/iO9/Fd76L73wX3/kuvvNdfOe7+M538Z3v4jvfxXe+i+98F9/5Lr7zXXznu/jOd/Gd7+I738V3vovvfBde9C686F140bv4znfxne/iO9/Fd76L73wX3/kuvvNd7a9W+6vV/mrxne/iO9/Fd76L73wX3/kuvvNdfOe7+M538Z3v4jvfxXe+i+98F9/5Lr7zXXjRu/Cid+FF7+I738V3vovvfBff+S6+811857v4zne1v1rtr1b7q8V3vovvfBff+S6+811857v4znfxne/iO9/Fd76L73wXXvQuvOhdeNG7+M538Z3v4jvfxXe+i+98F9/5Lr7zXe2vVvur1f5q8Z3v4jvfh+98H77zffjO9+E734fvfB++8334zvfhO98nXvSJF33iRR++8334zvfhO9+H73wfvvN9+M734Tvfp/3V0/7qaX/18J3vw3e+D9/5Pnzn+/Cd78N3vg/f+T585/vwne/Dd75PvOgTL/rEiz585/vwne/Dd74P3/k+fOf78J3vw3e+T/urp/3V0/7q4Tvfh+98H77zffjO9+E734fvfB++8334zvfhO9+H73wfvvN9+M734Tvfh+98H77zffjO9+E734fvfB++8334zvfhO98nXvSJF33iRR++8334zvfhO9+H73wfvvN9+M734Tvfp/3V0/7qaX/18J3vw3e+D9/5Pnzn+/Cd78N3vg/f+T585/vwne/Dd74P3/k+fOf78J3vw3e+T7zoEy/6xIs+fOf78J3vw3e+D9/5Pnzn+PCd48N3jo/9VXzsr+JjfxUfvnN8+M7x4TvHh+8cH75zfPjO8eE7x4fvHB++c3z4zvHBi8YHLxofvGh8+M7x4TvHh+8cH75zfPjO8eE7x4fvHN9V36u+V33xnePDd44P3zk+fOf48J3jw3eOD985Pnzn+PCd48N3jg9eND540fjgRePDd44P3zk+fOf48J3jw3eOD985Pnzn+FJ9U31LffGd48N3jg/fOT585/jwnePDd44P3zk+fOf48J3jw3eOD140PnjR+OBF48N3jg/fOT585/jwnePDd44P3zk+fOf4Rn1HfUd98Z3jw3eOD985Pnzn+PCd48N3jg/fOT585/jwnePDd44P3zk+fOf48J3jw3eOD985Pnzn+PCd48N3jg/fOT585/jwneODF40PXjQ+eNH48J3jw3eOg+8cB985Dr5zHHznOPjOcdhfxWF/FYf9VRx85zj4znHwnePgO8fBd46D7xwH3zkOvnMcfOc4+M5x8J3j4DvHwXeOg+8cB140DrxoHHjROPjOcfCd4+A7x8F3joPvHAffOQ6+c5xQ31DfUF985zj4znHwnePgO8fBd46D7xwH3zkOvnMcfOc4+M5x4EXjwIvGgReNg+8cB985Dr5zHHznOPjOcfCd4+A7xyn1LfUt9cV3joPvHAffOQ6+cxx85zj4znHwnePgO8fBd46D7xwHXjQOvGgceNE4+M5x8J3j4DvHwXeOg+8cB985Dr5znFHfUd9VX3znOPjOcfCd4+A7x8F3joPvHAffOQ6+cxx85zj4znHgRePAi8aBF42D7xwH3zkOvnMcfOc4+M5x8J3j4jvHZX8Vl/1VXPZXcfGd4+I7x8V3jovvHBffOS6+c1x857j4znHxnePiO8fFd46L7xwX3zkuvnNcfOe4+M5x8Z3j4jvHxXeOi+8cF985LrxoXHjRuPCicfGd4+I7x8V3jovvHBffOS6+c1x857ihvqG+ob74znHxnePiO8fFd46L7xwX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sdpfrfZXq/3V4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvH4jvHwovGwovGwovG4jvH4jvH4jvH4jvH4jvH4jvH4jvHan+12l+t9leL7xyL7xyL7xyL7xyL7xyL7xyL7xyL7xyL7xyL7xyL7xyL7xwP3zkevnM88aJPvOgTL/rwnePhO8fDd46H7xwP3zkevnM8fOd42l897a+e9lcP3zkevnM8fOd4+M7x8J3j4TvHw3eOh+8cD985Hr5zPPGiT7zoEy/68J3j4TvHw3eOh+8cD985Hr5zPHzneNpfPe2vnvZXD985Hr5zPHznePjO8fCd4+E7x8N3jofvHA/fOR6+czzxok+86BMv+vCd4+E7x8N3jofvHA/fOR6+czx853jaXz3tr572Vw/fOR6+czx853j4zvHwnePhO8fDd46H7xwP3zkevnM88aJPvOgTL/rwnePhO8fDd46H7xwP3zkevnM8fOd42l897a+e9lcP3zkevnM8fOd4+M7x8J3j4TvHw3eOh+8cD985Hr5zPHznePjO8fCd4+E7x8N3jofvnB++c374zvnhO+eH75wfvnN+8KL5wYvmBy+aH75zfvjO+eE754fvnB++c374zvnhO+d31Peo71FffOf88J3zw3fOD985P3zn/PCd88N3zg/fOT985/zwnfPDd84P3zk/fOf88J3zgxfND140P3jR/PCd88N3zg/fOT985/zwnfPDd84P3zm/VN9U31RffOf88J3zw3fOD985P3zn/PCd88N3zg/fOT985/zwnfODF80PXjQ/eNH88J3zw3fOD985P3zn/PCd88N3zg/fOb9W31bfVl985/zwnfPDd84P3zk/fOf88J3zw3fOD985P3zn/PCd84MXzQ9eND940fzwnfPDd84P3zk/fOf88J3zw3fOD985v1XfVd+nvvjO+eE754fvnB++c374zvnhO+eH75wfvnN++M558J3zwIvmgRfNAy+aB985D75zHnznPPjOefCd8+A758F3znPU96jvUV985zz4znnwnfPgO+fBd86D75wH3zkPvnMefOc8+M558J3z4DvnwXfOg++cB985D75zHnznPPjOefCd8+A758F3zgMvmgdeNA+8aB585zz4znnwnfPgO+fBd86D75wH3zlP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aA68aA68aA6+cw6+cw6+cw6+cw6+cw6+cw6+c472V6P91Wh/NfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfjOOfCiOfCiOfCiOfjOOfjOOfjOOfjOOfjOOfjOOfjOOdpfjfZXo/3V4Dvn4Dvn4jvn4jvn4jvn4jvn4jvn4jvn4jvn4jvn4jvn4jvn4jvn4jvnwovmwovmwovm4jvn4jvn4jvn4jvn4jvn4jvn4jvnan+12l+t9leL75yL75yL75yL75yL75yL75yL75yL75yL75yL75wLL5oLL5oLL5qL75yL75yL75yL75yL75yL75yL75yr/dVqf7XaXy2+cy6+cy6+cy6+cy6+cy6+cy6+cy6+cy6+cy6+cy68aC68aC68aC6+cy6+cy6+cy6+cy6+cy6+cy6+c672V6v91Wp/tfjOufjOufjOufjOufjOufjOufjOufjOufjOufjOufCiufCiufCiufjOufjOufjOufjOufjOufjOufjOudpfrfZXq/3V4jvn4jvn4jvn4jvn4jvn4jvnw3fOh++cD985H75zPnznfPjO+fCd8+E758N3zofvnA/fOR++cz5853z4zvnwnfOJF33iRZ940YfvnA/fOR++cz5853z4zvnwnfPhO+fT/uppf/W0v3r4zvnwnfPhO+fDd86H75wP3zkfvnM+fOd8+M758J3z4Tvnw3fOh++cD985n3jRJ170iRd9+M758J3z4Tvnw3fOh++cD985H75zPu2vnvZXT/urh++cD985H75zPnznfPjO+fCd8+E758N3zofvnA/fOZ940Sde9IkXffjO+fCd8+E758N3zofvnA/fOR++cz7tr572V0/7q4fvnA/fOR++cz5853z4zvnwnfPhO+fDd86H75wP3zmfeNEnXvSJF334zvnwnfPhO+fDd86H75wP3zkfvnM+7a8e+6v62F/Vh+9cH75zffjO9eE714fvXB++c334zvXhO9eH71wfvnN98KL1wYvWBy9aH75zffjO9eE714fvXB++c334zvXhO9d31feq71VffOf68J3rw3euD9+5Pnzn+vCd68N3rg/fuT585/rwnevDd64P37k+fOf68J3rw3euD9+5Pnzn+vCd68N3rg/fuT585/rgReuDF60PXrQ+fOf68J3rw3euD9+5Pnzn+vCd68N3rq/Ut9S31BffuT585/rwnevDd64P37k+fOf68J3rw3euD9+5Pnzn+vCd68N3rg/fuT585/rgReuDF60PXrQ+fOf68J3rw3euD9+5Pnzn+vCd68N3rm/Vd9V31RffuT585/rwnevDd64P37k+fOf68J3rw3euD9+5Pnzn+uBF64MXrQ9etD585/rwnevgO9fBd66D71wH37kOvnMd9ld12F/VYX9VB9+5Dr5zHXznOvjOdfCd6+A718F3roPvXAffuQ6+cx140TrwonXgRevgO9fBd66D71wH37kOvnMdfOc6+M51rvpe9Q31xXeug+9cB9+5Dr5zHXznOvjOdfCd6+A718F3roPvXAdetA68aB140Tr4znXwnevgO9fBd66D71wH37kOvnOdUt9S31JffOc6+M518J3r4DvXwXeug+9cB9+5Dr5zHXznOvjOdfCd6+A718F3roPvXAffuQ6+cx185zr4znXwnevgO9fBd64DL1oHXrQOvGgdfOc6+M518J3r4DvXwXeug+9cB9+5zqrvqu+qL75zHXznOvjOdfCd6+A718F3roPvXAffuQ6+cx185zr4znXwneviO9fFd64LL1oXXrQuvGhdfOe6+M518Z3r4jvXxXeui+9cF9+57lHfo75HffGd6+I718V3rovvXBffuS6+c11857r4znXxneviO9eFF60LL1oXXrQuvnNdfOe6+M518Z3r4jvXxXeui+9cN9Q31DfUF9+5Lr5zXXznuvjOdfGd6+I718V3rovvXBffuS6+c1140brwonXhReviO9fFd66L71wX37kuvnNdfOe6+M51S31LfVt98Z3r4jvXxXeui+9cF9+5Lr5zXXznuvjOdfGd6+I714UXrQsvWhdetC6+c11857r4znXxneviO9fFd66L71x31XfVd9UX37kuvnNdfOe6+M518Z3r4jvXxXeui+9cF9+5Lr5zXXznuvjOdfGd6+I718V3rovvXIHvXIHvXIHvXIHvXIHvXAEvWgEvWgEvWoHvXIHvXIHvXIHvXIHvXIHvXIHvXHHU96jvUV985wp85wp85wp85wp85wp85wp85wp85wp85wp85wp85wp85wp85wp85wp40Qp40Qp40Qp85wp85wp85wp85wp85wp85wp854pU31TfVF985wp85wp85wp85wp85wp85wp85wp85wp85wp85wp40Qp40Qp40Qp85wp85wp85wp85wp85wp85wp854pW31bfVl985wp85wp85wp85wp85wp85wp85wp85wp85wp85wp40Qp40Qp40Qp85wp85wp85wp85wp85wp85wp854pV31Xfp774zhX4zhX4zhX4zhX4zhX4zhX4zhX4zhX4zpX4zpXwopXwopXwopX4zpX4zpX4zpX4zpX4zpX4zpX4zpXaX6X2V6n9VeI7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V+I7V8KLVsKLVsKLVuI7V+I7V+I7V+I7V+I7V+I7V+I7V2p/ldpfpfZXie9cie9cie9cie9cie9cie9cie9cie9cie9cie9cie9cie9cie9cie9cCS9aCS9aCS9aie9cie9cie9cie9cie9cie9cie9cqf1Van+V2l8lvnMlvnMlvnMlvnMlvnMlvnMlvnMlvnMlvnMlvnMlvGglvGglvGglvnMlvnMlvnMlvnMlvnMlvnMlvnOl9lep/VVqf5X4zpX4zlX4zlX4zlX4zlX4zlX4zlX4zlX4zlX4zlXwolXwolXwolX4zlX4zlX4zlX4zlX4zlX4zlX4zlXaX5X2V6X9VeE7V+E7V+E7V+E7V+E7V+E7V+E7V+E7V+E7V+E7V8GLVsGLVsGLVuE7V+E7V+E7V+E7V+E7V+E7V+E7V2l/VdpflfZXhe9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9che9cBS9aBS9aBS9ahe9che9che9che9che9che9che9cpf1VaX9V2l8VvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvnMVvGgVvGgVvGgVvnMVvnMVvnMVvnMVvnM1vnM1vnO19let/VVrf9X4ztX4ztX4ztX4ztX4ztX4ztX4ztX4ztX4ztX4ztXwotXwotXwotX4ztX4ztX4ztX4ztX4ztX4ztX4ztXaX7X2V639VeM7V+M7V+M7V+M7V+M7V+M7V+M7V+M7V+M7V+M7V8OLVsOLVsOLVuM7V+M7V+M7V+M7V+M7V+M7V+M7V2t/1dpftfZXje9cje9cje9cje9cje9cje9cje9cje9cje9cje9cDS9aDS9aDS9aje9cje9cje9cje9cje9cje9cje9crf1Va3/V2l81vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vnM1vGg1vGg1vGg1vnM1vnMNvnMNvnMNvnMNvnMNvnON9lej/dVofzX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjX4zjXwojXwojXwojX4zjX4zjX4zjX4zjX4zjX4zjX4zjXaX432V6P91eA71+A71+A71+A71+A71+A71+A71+A71+A71+A718CL1sCL1sCL1uA71+A71+A71+A71+A71+A71+A712h/NdpfjfZXg+9cg+9cg+9cg+9cg+9cg+9cg+9cg+9cg+9cg+9cAy9aAy9aAy9ag+9cg+9cg+9cg+9cg+9cg+9cg+9co/3VaH812l8NvnMNvnMNvnMNvnMNvnMNvnMNvnMNvnMNvnMNvnMNvGgNvGgNvGgNvnMNvnMNvnMNvnMNvnMNvnMtvnOt9ler/dVqf7X4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrX4zrXworXworXworX4zrX4zrX4zrX4zrX4zrX4zrX4zrXaX632V6v91eI71+I71+I71+I71+I71+I71+I71+I71+I71+I71+I71+I71+I71+I718KL1sKL1sKL1uI71+I71+I71+I71+I71+I71+I712p/tdpfrfZXi+9ci+9ci+9ci+9ci+9ci+9ci+9ci+9ci+9ci+9cCy9aCy9aCy9ai+9ci+9ci+9ci+9ci+9ci+9ci+9cq/3Van+12l8tvnMtvnMtvnMtvnMtvnMtvnMtvnMtvnMtvnMtvnMtvGiteNEnXvThO9fDd66H71wP37kevnM9fOd6+M71tL962l897a8evnM9fOd6+M718J3r4TvXw3euh+9cD9+5Hr5zPXzneuJFn3jRJ1704TvXw3euh+9cD9+5Hr5zPXznevjO9bS/etpfPe2vHr5zPXznevjO9fCd6+E718N3rofvXA/fuR6+cz1853r4zvXwnevhO9fDd66H71wP37kevnM9fOd6+M718J3r4TvXEy/6xIs+8aIP37kevnM9fOd6+M718J3r4TvXw3eup/3V0/7qaX/18J3r4TvXw3euh+9cD9+5Hr5zPXznevjO9fCd6+E718N3rofvXA/fuR6+cz3xok+86BMv+vCd6+E718N3rofvXA/fuR6+cz1853raXz3tr572Vw/fuR6+cz1853r4zvXwnfvDd+4P37k/fOf+8J37w3fuD160P3jR/uBF+8N37g/fuT985/7wnfvDd+4P37k/fOf+jvoe9T3qi+/cH75zf/jO/eE794fv3B++c3/4zv3hO/eH79wfvnN/8KL9wYv2By/aH75zf/jO/eE794fv3B++c3/4zv3hO/cX6hvqm+qL79wfvnN/+M794Tv3h+/cH75zf/jO/eE794fv3B++c3/wov3Bi/YHL9ofvnN/+M794Tv3h+/cH75zf/jO/eE799fq2+rb6ovv3B++c3/4zv3hO/eH79wfvnN/+M794Tv3h+/cH75zf/jO/eE794fv3B++c3/4zv3hO/eH79wfvnN/+M794Tv3h+/cH7xof/Ci/cGL9ofv3B++c3/4zv3hO/eH79wfvnN/+M79PfV96vvUF9+5P3znPvjOffCd++A798F37oPv3AffuQ++cx985z74zn3wnfvgO/fBd+4DL9oHXrQPvGgffOc++M598J374Dv3wXfug+/cB9+5z1Xfq75XffGd++A798F37oPv3AffuQ++cx985z74zn3wnfvgO/eBF+0DL9oHXrQPvnMffOc++M598J374Dv3wXfug+/cJ9U31TfVF9+5D75zH3znPvjOffCd++A798F37oPv3AffuQ++cx940T7won3gRfvgO/fBd+6D79wH37kPvnMffOc++M59Wn1bfUd98Z374Dv3wXfug+/cB9+5D75zH3znPvjOffCd++A794EX7QMv2gdetA++cx985z74zn3wnfvgO/fBd+6D79znqe9T36e++M598J374Dv3wXfug+/cB9+5L75zX3znvvjOffGd++I798V37ovv3BffuS++c1985774zn3xnfviO/fFd+6L79wXXrQvvGhfeNG++M598Z374jv3xXfui+/cF9+5L75z36u+V32v+uI798V37ovv3BffuS++c1985774zn3xnfviO/fFd+6L79wX37kvvnNffOe+8KJ94UX7wov2xXfui+/cF9+5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3Ivv3Ivv3Ivv3Ivv3Ivv3Ivv3Ivv3Ivv3Ivv3Asv2gsv2gsv2ovv3Ivv3Ivv3Ivv3Ivv3Ivv3Ivv3Kv91Wp/tdpfLb5zL75zL75zL75zL75zL75zL75zL75zL75zL75zL75zL75zL75zL75zL7xoL7xoL7xoL75zL75zL75zL75zL75zP3znfvjO/bS/etpfPe2vHr5zP3znfvjO/fCd++E798N37ofv3A/fuR++cz98537iRZ940Sde9OE798N37ofv3A/fuR++cz985374zv20v3raXz3trx6+cz985374zv3wnfvhO/fDd+6H79wP37kfvnM/fOd+4kWfeNEnXvThO/fDd+6H79wP37kfvnM/fOd++M79tL962l897a8evnM/fOd++M798J374Tv3w3fuh+/cD9+5H75zP3znfuJFn3jRJ1704Tv3w3fuh+/cD9+5H75zP3znfvjO/bS/etpfPe2vHr5zP3znfvjO/fCd++E798N37ofv3A/fuR++cz985374zv3wnfvhO/fDd+6H79wP37kfvnM/fOd++M798J374Tv3Ey/6xIs+8aIP37kfvvN8+M7z4TvPh+88H77zfPjO87G/mo/91Xzsr+bDd54P33k+fOf58J3nw3eeD995Pnzn+fCd58N3ng/feT585/nwnefDd54P33k+eNH54EXngxedD995Pnzn+fCd58N3ng/feT585/nwnecL9Q31DfXFd54P33k+fOf58J3nw3eeD995Pnzn+fCd58N3ng/feT540fngReeDF50P33k+fOf58J3nw3eeD995Pnzn+fCd5yv1LfUt9cV3ng/feT585/nwnefDd54P33k+fOf58J3nw3eeD995PnjR+eBF54MXnQ/feT585/nwnefDd54P33k+fOf58J3nG/Ud9V31xXeeD995Pnzn+fCd58N3ng/feT585/nwnefDd54P33k+eNH54EXngxedD995Pnzn+fCd58N3ng/feT585zn4znPYX81hfzWH/dUcfOc5+M5z8J3n4DvPwXeeg+88B995Dr7zHHznOfjOc/Cd5+A7z8F3noPvPAffeQ6+8xx85zn4znPwnefgO8/Bd54DLzoHXnQOvOgcfOc5+M5z8J3n4DvPwXeeg+88B995TqhvqG+oL77zHHznOfjOc/Cd5+A7z8F3noPvPAffeQ6+8xx85zn4znPwnefgO8/Bd54DLzoHXnQOvOgcfOc5+M5z8J3n4DvPwXeeg+88B995Tqtvq2+rL77zHHznOfjOc/Cd5+A7z8F3noPvPAffeQ6+8xx85znwonPgRefAi87Bd56D7zwH33kOvvMcfOc5+M5z8J3nrPqu+q764jvPwXeeg+88B995Dr7zHHznOfjOc/Cd5+A7z8F3ngMvOgdedC686Fx857n4znPxnefiO8/Fd56L7zwX33ku+6u5n/oe9cV3novvPBffeS6+81x857n4znPxnefiO8/Fd56L7zwXXnQuvOhceNG5+M5z8Z3n4jvPxXeei+88F995Lr7z3FDfUN9QX3znufjOc/Gd5+I7z8V3novvPBffeS6+81x857n4znPxnefiO8/Fd56L7zwX33kuvvNcfOe5+M5z8Z3n4jvPxXeeCy86F150LrzoXHznufjOc/Gd5+I7z8V3novvPBffeW6rb6tvqy++81x857n4znPxnefiO8/Fd56L7zwX33kuvvNcfOe5+M5z8Z3n4jvPxXeeCy86F150LrzoXHznufjOc/Gd5+I7z8V3novvPBffee5T36e+T33xnefiO8/Fd56L7zwX33kC33kC33kC33kC33kC33kCXnQCXnQCXnQC33kC33kC33kC33kC33kC33kC33niqO9R36O++M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T8KIT8KIT8KIT+M4T+M4T+M4T+M4T+M4T+M4T+M4Tob6hvqm++M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T8KIT8KIT8KIT+M4T+M4T+M4T+M4T+M4T+M4T+M4Trb6tvq2++M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T+M4T8KIT8KIT8KIT+M4T+M4T+M4T+M4T+M4T+M4T+M4TT32f+j71xXeewHeexHeexHeexHeexHeexHeexHeexHeexHeexHeexHeexHeexHeehBedhBedhBedxHeexHeexHeexHeexHeexHeexHee1P4qtb9K7a8S33kS33kS33kS33kS33kS33kS33kS33kS33kS33kSXnQSXnQSXnQS33kS33kS33kS33kS33kS33kS33lS+6vU/iq1v0p850l850l850l850l850l850l850l850l850l850l40Ul40Ul40Ul850l850l850l850l850l850l850ntr1L7q9T+KvGdJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ+FFJ+FFJ+FFJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ/GdJ7W/Su2vUvurxHeexHeexHeexHeexHeexHeewneewneewneewneewneewneewneewneewneewneewneewneewneewneewneeghedghedghedwneewneewneewneewneewneewnee0v6qtL8q7a8K33kK33kK33kK33kK33kK33kK33kK33kK33kK33kK33kK33kK33kK33kKXnQKXnQKXnQK33kK33kK33kK33kK33kK33kK33lK+6vS/qq0vyp85yl85yl85yl85yl85yl85yl85yl85yl85yl85yl40Sl40Sl40Sl85yl85yl85yl85yl85yl85yl85yntr0r7q9L+qvCdp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp+BFp+BFp+BFp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp/Cdp7S/Ku2vWvurxneexneexneexneexneexneexneexneexneexneehhedhhedhhedxneexneexneexneexneexneexnee1v6qtb9q7a8a33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33ka33kaXnQaXnQaXnQa33ka33ka33ka3/n/mraDVEuX44rCc1FbjYzMyIy9PRUjjC3LRiAsIUsGY97c/Q7onrU7xbp1C7JR8AcE8c3DO8/DO8/DO8+L/dWL/dWL/dXDO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/DO8/jXnQe96LzuBedh3eeh3eeh3eeh3eeh3eeh3eeh3eeF/urF/urF/urh3eeh3eeh3eeh3eeh3eeh3eeh3eeh3eeh3eeh3eex73oPO5F53EvOg/vPA/vPIN3nsE7z+CdZ/DOM3jnmdhfTeyvJvZXg3eewTvP4J1n8M4zeOcZvPMM3nkG7zyDd57BO89wLzrDvegM96IzeOcZvPMM3nkG7zyDd57BO8/gnWdifzWxv5rYXw3eeQbvPIN3nsE7z+CdZ/DOM3jn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LebCLubC3iu6onf0ie5o5sLeL5q5sLkXrc29aG3uRWufit7RJ7qjb/SLnuh498S7He82c2H3jj7RHX2jX/REMxd2Mxf2ZS5s7kVrcy9am3vR2rejb/SLnmhFMxf2W9Hx7ot3X7z7mAv73egXPdGKZi7sWdHMhT3MhT0nuqOZC3teNHNhD3NhD3Nha0UzF7Z29IlmLmzuRWtzL1qbe9HaUjRzYXtFV/SOPtEdHe863nW8a+bCxjvXwTvXwTvXwTvXwTvXwTvXwTvXwTvXwTvXwTvXwTvXwTvXwTvX4V60DveidbgXrYN3roN3roN3roN3roN3roN3roN3rrPj3R3v7ngX71wH71wH71wH71wH71wH71wH71wH71wH71wH71yHe9E63IvW4V60Dt65Dt65Dt65Dt65Dt65Dt65Dt65Tse7He92vIt3roN3roN3roN3roN3roN3roN3roN3roN3roN3rsO9aB3uRetwL1oH71wH71wH71wH71wH71wH71wH71znxbsv3p14F+9cB+9cB+9cB+9cB+9cB+9cB+9cB+9cB+9cB+9ch3vROtyL1uFetA7euQ7euQ7euQ7euQ7euQ7euQ7euY7jXce7jnfxznXwznXwznXwznXwznXwztV452q8czXeuRrvXI13rsY7V+Odq/HO1XjnarxzNd65Gu9cjXeuxjtX452ruRet5l60mnvRarxzNd65Gu9cjXeuxjtX452r8c7Vsb/q2F917K8a71yNd67GO1fjnavxztV452q8czXeuRrvXI13rsY7V+Odq/HO1Xjnau5Fq7kXreZetBrvXI13rsY7V+Odq/HO1XjnarxzdeyvOvZXHfurxjtX452r8c7VeOdqvHM13rka71yNd67GO1fjnau5F63mXrSae9FqvHM13rka71yNd67GO1fjnavxztWxv+rYX3XsrxrvXI13rsY7V+Odq/HO1XjnarxzNd65Gu9cjXeu5l60mnvRau5Fq/HO1XjnarxzNd65Gu9cjXeuxjtXx/6qY391Y3918c518c518c518c518c518c518c518c518c518c51uRety71oXe5F6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd68b+6sb+6sb+6uKd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6+Kd6/7DO//y29/8z7/+9Y//+m9/+sN//+af/u/XH//j7//1+7/98c//9Y8f//a/f/n5zb/99Y9/+tMf//Nf/vLXP//+D//+97/+4V/+9Offf373m/X54/O/+89n/fbc3/36j+v7V36//XVL+rtffvnld7/8Pw==", - "file_map": { - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::{MAX_MSG_NON_ZERO_COEFFS, T};\nuse lib::configs::default::threshold::{\n DECRYPTED_SHARES_AGGREGATION_BIT_NOISE, DECRYPTED_SHARES_AGGREGATION_CONFIGS, L,\n};\nuse lib::core::threshold::decrypted_shares_aggregation::DecryptedSharesAggregationModular;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n decryption_shares: pub [[Polynomial; L]; T + 1],\n party_ids: pub [Field; T + 1],\n message: pub Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n) {\n let decrypted_shares_aggregation: DecryptedSharesAggregationModular = DecryptedSharesAggregationModular::new(\n DECRYPTED_SHARES_AGGREGATION_CONFIGS,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n );\n\n decrypted_shares_aggregation.execute();\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/decrypted_shares_aggregation_mod/src/main.nr" - }, - "67": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\nuse dep::bignum::BigNum;\nuse dep::bignum::bignum::to_field;\nuse dep::bignum::SecureThreshold8192;\n\n/// Cryptographic parameters for decryption share aggregation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Plaintext modulus (typically denoted as `t`)\n pub plaintext_modulus: Field,\n /// Precomputed value: `-Q^(-1) mod t` where Q is the product of all CRT moduli\n pub q_inverse_mod_t: Field,\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], plaintext_modulus: Field, q_inverse_mod_t: Field) -> Self {\n Configs { qis, plaintext_modulus, q_inverse_mod_t }\n }\n}\n\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using BigNum\n/// for large Q values.\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationBigNum {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n/// Decrypted Shares Aggregation Circuit (Circuit 7) using modular arithmetic\n///\n/// Verifies:\n/// 1. Lagrange interpolation to compute u^{(l)} for each CRT basis\n/// 2. CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n/// 3. Decoding verification: message = -Q^{-1} * (t * u_global)_Q mod t\npub struct DecryptedSharesAggregationModular {\n /// Circuit parameters including crypto constants\n configs: Configs,\n\n /// Decryption shares from t+1 parties (public witnesses)\n decryption_shares: [[Polynomial; L]; T + 1],\n\n /// Party IDs (x-coordinates) for interpolation (public witnesses)\n /// Note: Must be in strictly increasing order for correct Lagrange sign computation\n party_ids: [Field; T + 1],\n\n /// Message polynomial m(x) (public witness)\n message: Polynomial,\n\n /// Global u polynomial (secret witness)\n u_global: Polynomial,\n\n /// CRT quotient polynomials (secret witnesses)\n crt_quotients: [Polynomial; L],\n}\n\nimpl DecryptedSharesAggregationBigNum {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationBigNum {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Verifies decoding using BigNum for large Q values\n fn verify_decoding(self) {\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1 as Field;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_bn = SecureThreshold8192::from(q_modulus);\n\n let q_half_bn = q_bn.udiv(SecureThreshold8192::from(2));\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let u_bn = SecureThreshold8192::from(self.u_global.coefficients[coeff_idx]);\n let t_bn = SecureThreshold8192::from(self.configs.plaintext_modulus);\n let u_bn_mod_q = u_bn.umod(q_bn);\n let t_bn_mod_q = t_bn.umod(q_bn);\n let t_times_u_bn_q = (t_bn_mod_q * u_bn_mod_q).umod(q_bn);\n\n let m = ModU128::new(self.configs.plaintext_modulus);\n\n // Check if centering is needed\n let needs_centering = t_times_u_bn_q > q_half_bn;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_bn - t_times_u_bn_q;\n let centered_positive_mod_t = centered_positive.umod(t_bn);\n let centered_field = to_field(centered_positive_mod_t);\n m.mul_mod(self.configs.q_inverse_mod_t, centered_field)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_bn_t = t_times_u_bn_q.umod(t_bn);\n let t_times_u_field = to_field(t_times_u_bn_t);\n let product = m.mul_mod(self.configs.q_inverse_mod_t, t_times_u_field);\n if product == 0 {\n 0\n } else {\n self.configs.plaintext_modulus - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\nimpl DecryptedSharesAggregationModular {\n pub fn new(\n configs: Configs,\n decryption_shares: [[Polynomial; L]; T + 1],\n party_ids: [Field; T + 1],\n message: Polynomial,\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n ) -> Self {\n DecryptedSharesAggregationModular {\n configs,\n decryption_shares,\n party_ids,\n message,\n u_global,\n crt_quotients,\n }\n }\n\n /// Alternative verification function using efficient modular arithmetic without BigNum.\n ///\n /// Uses `ModU128` for decoding verification instead of BigNum. More efficient when\n /// Q (the product of all CRT moduli) fits within u128 (e.g., 72 bits for insecure parameter sets).\n pub fn execute(self) {\n // Step 1: Compute Lagrange coefficients in-circuit\n let lagrange_coeffs = compute_all_lagrange_coeffs::(self.configs.qis, self.party_ids);\n\n // Step 2: Compute u^{(l)} for each CRT basis via Lagrange interpolation\n let u_crts = compute_crt_components::(\n self.configs.qis,\n self.decryption_shares,\n lagrange_coeffs,\n );\n\n // Step 3: Verify CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global\n verify_crt_reconstruction::(\n self.configs.qis,\n self.u_global,\n self.crt_quotients,\n u_crts,\n );\n // Step 4: Verify decoding\n self.verify_decoding();\n }\n\n /// Alternative decoding verification using the formula:\n /// message = -Q^{-1} * (t * u_global)_Q mod t\n fn verify_decoding(self) {\n let t: Field = self.configs.plaintext_modulus;\n // Compute Q as product of all CRT moduli\n let mut q_modulus = 1;\n for l in 0..L {\n q_modulus *= self.configs.qis[l];\n }\n\n // For centered arithmetic\n let q_half = q_modulus as u128 / 2;\n\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n // Compute (t * u_global) mod Q using BigNum\n let q_mod = ModU128::new(q_modulus);\n let t_mod = ModU128::new(t);\n\n // Compute (t * u_global) mod Q using modular arithmetic functions\n let t_times_u_mod_q = q_mod.mul_mod(t, self.u_global.coefficients[coeff_idx]);\n let needs_centering = (t_times_u_mod_q as u128) > q_half;\n\n let computed_message = if needs_centering {\n // When (t*u) mod Q >= Q/2: treat as negative in centered form\n // Centered value is conceptually negative: (t_times_u_mod_q - Q)\n // -Q^{-1} * (negative) = positive result\n let centered_positive = q_modulus - t_times_u_mod_q;\n let centered_positive_mod_t = t_mod.reduce_mod(centered_positive);\n\n t_mod.mul_mod(self.configs.q_inverse_mod_t, centered_positive_mod_t)\n } else {\n // When (t*u) mod Q < Q/2: stays positive in centered form\n // -Q^{-1} * (positive) = negative result = t - result\n let t_times_u_mod_t = t_mod.reduce_mod(t_times_u_mod_q);\n let product = t_mod.mul_mod(self.configs.q_inverse_mod_t, t_times_u_mod_t);\n if product == 0 {\n 0\n } else {\n t - product\n }\n };\n\n // Verify: only check non-zero coefficients\n if self.message.coefficients[coeff_idx] != 0 {\n assert(computed_message == self.message.coefficients[coeff_idx]);\n }\n }\n }\n}\n\n/// Computes all Lagrange coefficients using optimized modular arithmetic\npub fn compute_all_lagrange_coeffs(\n qis: [Field; L],\n party_ids: [Field; T + 1],\n) -> [[Field; T + 1]; L] {\n let mut lagrange_coeffs = [[0 as Field; T + 1]; L];\n\n // Step 1: Cache |x_i - x_j| factors for all party pairs\n let mut diffs = [[0 as Field; T + 1]; T + 1];\n for i in 0..(T + 1) {\n for j in (i + 1)..(T + 1) {\n let diff = party_ids[j] - party_ids[i];\n diffs[i][j] = diff;\n diffs[j][i] = diff;\n }\n }\n\n // Step 2: Determine signs (same for all parties within a basis)\n let numerator_sign_negative = (T % 2) == 1;\n\n // Step 3: For each CRT basis, compute Lagrange coefficients\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n\n // Compute product of all party IDs: PRODUCT(j=0..T) x_j mod q_l\n let mut product_x = 1 as Field;\n for j in 0..(T + 1) {\n product_x = m.mul_mod(product_x, party_ids[j]);\n }\n\n // For each party i, compute L_i(0) mod q_l\n for party_idx in 0..(T + 1) {\n // Numerator (absolute value): PRODUCT(j!=party_idx) x_j\n let numerator_abs = m.div_mod(product_x, party_ids[party_idx]);\n\n // Denominator (absolute value): PRODUCT(j!=party_idx) |x_party_idx - x_j|\n let mut denominator_abs = 1 as Field;\n for j in 0..(T + 1) {\n if j != party_idx {\n denominator_abs = m.mul_mod(denominator_abs, diffs[party_idx][j]);\n }\n }\n\n // Determine denominator sign\n let num_greater = T - party_idx;\n let denom_sign_negative = (num_greater % 2) == 1;\n\n // Compute unsigned result: |numerator| / |denominator| mod q_l\n let result_abs = m.div_mod(numerator_abs, denominator_abs);\n\n // Apply combined sign\n let should_negate = numerator_sign_negative != denom_sign_negative;\n let result = if should_negate {\n m.reduce_mod(q_l - result_abs)\n } else {\n result_abs\n };\n\n lagrange_coeffs[basis_idx][party_idx] = result;\n }\n }\n\n lagrange_coeffs\n}\n\n/// Computes u^{(l)} for each CRT basis via Lagrange interpolation\npub fn compute_crt_components(\n qis: [Field; L],\n decryption_shares: [[Polynomial; L]; T + 1],\n lagrange_coeffs: [[Field; T + 1]; L],\n) -> [Polynomial; L] {\n let mut u_crts: [Polynomial; L] =\n [Polynomial::new([0; MAX_MSG_NON_ZERO_COEFFS]); L];\n\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n let m = ModU128::new(q_l);\n let mut u_coeffs = [0 as Field; MAX_MSG_NON_ZERO_COEFFS];\n\n // For each coefficient position\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n let mut u_coeff = 0 as Field;\n\n // Sum all contributions: u = SUM(i=0..T) [d_i * L_i(0)] mod q_l\n for party_idx in 0..(T + 1) {\n let d_coeff = decryption_shares[party_idx][basis_idx].coefficients[coeff_idx];\n let l_i_0 = lagrange_coeffs[basis_idx][party_idx];\n\n let term = m.mul_mod(d_coeff, l_i_0);\n u_coeff = m.reduce_mod(u_coeff + term);\n }\n\n u_coeffs[coeff_idx] = u_coeff;\n }\n\n u_crts[basis_idx] = Polynomial::new(u_coeffs);\n }\n\n u_crts\n}\n\n/// Verifies CRT reconstruction: u^{(l)} + r^{(l)} * q_l = u_global for all bases l\npub fn verify_crt_reconstruction(\n qis: [Field; L],\n u_global: Polynomial,\n crt_quotients: [Polynomial; L],\n u_crts: [Polynomial; L],\n) {\n for basis_idx in 0..L {\n let q_l = qis[basis_idx];\n\n // Compute r^{(l)} * q_l\n let r_times_q = crt_quotients[basis_idx].mul_scalar(q_l);\n\n // Compute u^{(l)} + r^{(l)} * q_l\n let reconstructed = u_crts[basis_idx].add(r_times_q);\n\n // Verify: u^{(l)} + r^{(l)} * q_l = u_global\n // Must hold for every coefficient\n for coeff_idx in 0..MAX_MSG_NON_ZERO_COEFFS {\n assert(\n reconstructed.coefficients[coeff_idx] == u_global.coefficients[coeff_idx],\n \"CRT reconstruction verification failed\",\n );\n }\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/decrypted_shares_aggregation.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk b/crates/zk-prover/tests/fixtures/decrypted_shares_aggregation_mod.vk deleted file mode 100644 index b3b83d01c2855ffba802a461022eb61b41a1156f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajgcRw2l1HkdbOr$|Xa%Sz7Q1c-+(WpZewTTk5j#9CXS}{r~O5#w_6fLFrL}FIm zoh>MdqE+LH=Zsoy#i5US-a+s8@An1#0DvC``=J7OY<}zjpyajQxPx}qxQE0t*;XqS zztu3ek2G7Q+1p@eU(Op}0`Lu;?T5<<;sy^E1j+-pIrWiYiS@dW`)15QlL!1CqgZPv25UxLp*`uEB z_V)VC|2R(ZfEk{AvAUilkDc`+{Iat>b@axzRA1d&t=rs_tPUwx2x(24>tE(o)i9CC zw_7i0aYFjWYZU6^rTf<4MVWF4k5vqmb8u(MCPH==yqf;lHtOk!dhoWxw3Y2MY*(zR zytl3Z%+ee}S~RH&7$fcezEh!CnYJNo(3iy(?UTX^8WQQJfRBQaJ3 z@2)6yiI|L->erBMxafut6c_eyaPBfH3oP7WSb@)PcIiUZI zf=k$Li24S>{Frj@HnI5&KN0`ojjx&=1L4L&p5upAbxs#!HoVF;ze){9UIP~$ZQh|{ zN+V$X?L?{WY1==ZsfND7r8iu62y(W0<&j_KgW6ZFgk)&T^;VP^4%zQ@f@fw8WG1pT zwPY5?F74P;Wa#FMQZm&Nk}-rbjM8?t@EK=Ek~93mPx#RBDIkC&68qN z(CRdMranzipu7~c2iXb1O*IX7YQ%Z3JE5Ajn~>&>Nr9orur2+@wDzkQxt?7JXV21H zySjYR+0WLNhrO+BkY^p>R=jNvqYB?yxtXqzT|ASc#_LMU?nq3VgN8sYLsx(}!+Hl@ zY=MJXMFH}kE{RK|sK**-i|->Z)4!Z9pBLn*$|V5BPxe3dl^H3##ytG$s$en0ZlXkg z&X9?4Nh>#G@yK2_&YHLE_+=W}439Qv-s$v76Z={B~p6EAL;7 zCJi)zWN-hqPu2#a2eVhR1ZoZZnN*1kPnI?@OHEmL`r;z3(ez4OJJq z=^?IsW#7LWR+*msK^Vp#v|QCoD?ViI-2$H0)^bpo91FE8@q{FgHHZGhlgkQOJ+J?& zUiEr2Cva8c6q`IGZn17#WWvjzRy?juMs zT6X3(ZR2?VcP~Yy-aJtZ2Y%9MNE5I1Ifa%Ls^w+y!xlZ>=>vFN=u=Xef67r@(f3#Y z6E(H~A!2UFs^V9lgC`8n)}&mQ_n%V&c*HiP!8N9HG@4M?cL_cqe-DGw@ve*c+?0Pc z1Pv8E5RXy?Ai6m&_=L5|-O434*;_%Q%_Jz@hk(+%Dv}Gmj7pb&6#r8xq{Y184;cyt zj8a7BWrCJe*iATLh{J%`V49A9ekt8<|AXS++ogiZ*>(!nqn|e90Z-=&C*m-2QIc?v zG}A|ZnLv|8gwik1rk?|0Oe-r0nq{;`2l(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n L_THRESHOLD, N, PARITY_MATRIX, SHARE_COMPUTATION_BIT_SHARE, SHARE_COMPUTATION_E_SM_BIT_SECRET,\n SHARE_COMPUTATION_E_SM_CONFIGS,\n};\nuse lib::configs::default::{N_PARTIES, T};\nuse lib::core::dkg::share_computation::SmudgingNoiseShareComputation;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_secret_commitment: pub Field,\n e_sm_secret: [Polynomial; L_THRESHOLD],\n y: [[[Field; N_PARTIES + 1]; L_THRESHOLD]; N],\n) -> pub [[Field; L_THRESHOLD]; N_PARTIES] {\n let share_computation_e_sm: SmudgingNoiseShareComputation = SmudgingNoiseShareComputation::new(\n SHARE_COMPUTATION_E_SM_CONFIGS,\n expected_secret_commitment,\n e_sm_secret,\n y,\n PARITY_MATRIX,\n );\n\n share_computation_e_sm.execute()\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/e_sm_share_computation/src/main.nr" - }, - "63": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_share_encryption_commitment_from_shares,\n};\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold secret share verification circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Correct Threshold Secret Key Share Computation (Circuit 2a).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == sk_secret[i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For SK: sk_secret is the trinary coefficients\npub struct SecretKeyShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// (public witness)\n expected_secret_commitment: Field,\n /// Secret key polynomial: Polynomial\n /// trinary coefficients\n /// (secret witness)\n sk_secret: Polynomial,\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = sk_secret[i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n /// (secret witnesses)\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n /// (public constants)\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\n/// Correct Threshold Smudging Noise Share Computation (Circuit 2b).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == e_sm[j][i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For ESM: e_sm[j] is the RNS representation at modulus j\npub struct SmudgingNoiseShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// This is computed from all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n expected_secret_commitment: Field,\n /// Smudging noise polynomial per modulus: [Polynomial; L]\n /// For ESM: each modulus has its own polynomial (RNS representation)\n e_sm_secret: [Polynomial; L],\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = e_sm[j][i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\nimpl SecretKeyShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n sk_secret: Polynomial,\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SecretKeyShareComputation { configs, expected_secret_commitment, sk_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_sk_commitment::(self.sk_secret)\n == self.expected_secret_commitment,\n \"SK commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == sk_secret[i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// sk_secret is the trinary coefficients, so y[i][j][0] is the same for all j.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n let secret_coeff = self.sk_secret.coefficients[coeff_idx];\n\n for mod_idx in 0..L {\n assert(self.y[coeff_idx][mod_idx][0] == secret_coeff);\n }\n }\n }\n}\n\nimpl SmudgingNoiseShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n e_sm_secret: [Polynomial; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SmudgingNoiseShareComputation { configs, expected_secret_commitment, e_sm_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n /// The commitment is computed over all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_e_sm_commitment::(self.e_sm_secret)\n == self.expected_secret_commitment,\n \"ESM commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == e_sm_secret[j][i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// e_sm_secret[j] is the RNS representation at modulus j, so y[i][j][0] varies per modulus.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let secret_coeff = self.e_sm_secret[mod_idx].coefficients[coeff_idx];\n assert(\n self.y[coeff_idx][mod_idx][0] == secret_coeff,\n \"Secret consistency check failed\",\n );\n }\n }\n }\n}\n\n/// Performs range checks on secret key and share values.\n///\n/// This function constrains all values to be within their expected bounds:\n/// - Share values for parties k >= 1 must be in [0, q_j) for each CRT modulus q_j\n///\n/// These bounds are critical for security and correctness of the Threshold scheme.\n///\n/// # Panics\n/// This function will cause the circuit to fail if any value is outside\n/// its expected bounds.\npub fn check_range_bounds(\n qis: [Field; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n // Shares y[i][j][k] for k >= 1 should be in [0, q_j)\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n for coeff_idx in 0..N {\n for party_idx in 1..(N_PARTIES + 1) {\n // Use range_check_standard from Polynomial by creating a single-coefficient polynomial\n Polynomial::new([y[coeff_idx][mod_idx][party_idx]])\n .range_check_standard::(q_j);\n }\n }\n }\n}\n\n/// Verifies Reed-Solomon parity check: `H[j] * y[i][j]^T == 0 mod q_j` for all i, j.\n///\n/// This function verifies that for each coefficient i and CRT basis j, the share\n/// vector `y[i][j]` forms a valid Reed-Solomon codeword by satisfying the parity\n/// check equation with the parity check matrix `H[j]`.\n///\n/// The parity check matrix H[j] has dimensions `(N_PARTIES - T) * (N_PARTIES + 1)`,\n/// and the share vector `y[i][j]` has length `N_PARTIES + 1`. The parity check\n/// ensures that any T+1 shares can correctly reconstruct the secret key via\n/// Lagrange interpolation.\n///\n/// # Panics\n/// The circuit will fail if the parity check doesn't hold for any coefficient,\n/// CRT basis, or parity check row.\npub fn verify_parity_check(\n qis: [Field; L],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n // For each row of H, compute dot product with y and verify == 0\n for row in 0..(N_PARTIES - T) {\n let mut sum: Field = 0;\n\n for col in 0..(N_PARTIES + 1) {\n sum = sum + h[mod_idx][row][col] * y[coeff_idx][mod_idx][col];\n }\n\n // Reduce mod q_j and verify == 0\n let m = ModU128::new(q_j);\n let result = m.reduce_mod(sum);\n assert(result == 0, \"Parity check failed\");\n }\n }\n }\n}\n\n/// Commits to shares for each party and modulus\n/// Returns [[Field; L]; N_PARTIES] where commitments[party_idx][mod_idx]\npub fn commit_to_party_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) -> [[Field; L]; N_PARTIES] {\n let mut commitments: [[Field; L]; N_PARTIES] = [[0; L]; N_PARTIES];\n\n for party_idx in 0..N_PARTIES {\n for mod_idx in 0..L {\n commitments[party_idx][mod_idx] = compute_share_encryption_commitment_from_shares::(\n y,\n party_idx,\n mod_idx,\n );\n }\n }\n\n commitments\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_computation.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/e_sm_share_computation.vk b/crates/zk-prover/tests/fixtures/e_sm_share_computation.vk deleted file mode 100644 index 70efd9e0c24c6f638143cf1acbdbb43c2487db6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg`6CmI1Ay^4Uvsl}?t9LSx$nG;FlX7D_C)mHY0Jv zZk>ZH=ML!eGKUs( zMeoed6V!5AbSJau+Y3&EO~KId2~{r#HrAwr7t4&+li+60;O&MVuBx74cLC5K-dZ20 zBgQR;_t)-`ZQeKmF$w(*!`JZ+>a^qXI%knBOu%#Xd*QpeTE`G&`j@x!Zj);1Rh+s7 zLTS||9&td-VIL^0+yFOmbf?=n+1Se7?->M1ODkcat*@w{q_p&9?Ki8k;$>tNa)vptv(Y%%?bh_pa0I?bq!jes&jVdsuS?3U z7evG^%HQ?vvhaRQqykT;#`@`k^K&jqesV(n7CDSIr=rnPcW|IT5Uv^$*ps!+LCIGk zUio296XV*GE@U0mbVwdPdBds*xi3>&D6D4XQg8yjv)%&xzAYtuo1NjV?(JoEC7WAo zUshc3I-eo)lC!=rOd2j{lbsW8Rnu!Q{#BPk#kzQ~)|jYNQ-?9a&nh5AuZPWZZCA{f zl_RdMe);Fnj_hQN)+BpofZo7<#3jJ!R!kb|iMcz%QhX7oBUTUkix&( zcz}1Irg}lfl*e-L>nKi*I*}|%!m%pIllZ3mUO)t6@I%8P`g#3z@m()jZvzpwdhJ_8da|rr}z2WcMjfTdwHkhz{jfdn^WUPxlnv#MxJ5<>xd0^ zp!`c2(wIhG)6dDY%_uM2KR8Le*HMn%jNT~a>}7{RQKC9tGLr{iQP@R3<}uv_)*&PO z+2Kn2-7!>r1tCTECt^^%s`79?g1a2ChqcdbLs*>WC9!)H%#3=XBZ3}u%&X(^s&LoDzcV+ppCYbu3N z%F9tB9h`J+Li!;3E>Gml)ZW>MLeJ;&Dy5$^uD|8$*&bD`PD^`U;+b1q^qMuCx~8aC zBB!wonCNIm@MqAw(Qf$2@w9f4H$bI_Itm?L7 zqwK3Cv?i+wQohp@a!QJ_ ziYOT{JQ;?uJ(J}|+3A<ccpc&q9oRG8P zHPAvutzTKhI`CSh&Ij|<20u^@u|yjP11n5tD=WEMFT~hcIA~2pEpx5SHKrU(K`=hS zz2C!?0pPYNmuu0h>l+2X#b+Sp5wEt^G`?dy;9s zPb!PaM=<1O^_vU=~8K)_Td#NeXl4|`Hj8@&5tX&Js;434UFIl6cuoKE)g#oTYE$j_uail+q zRH#)1{o?3hCX)4G%pMSFVNha>!_dE%0M#Vq`!P}V-xJiXMob{lfvJuDbkTnSI}9`0 diff --git a/crates/zk-prover/tests/fixtures/pk.json b/crates/zk-prover/tests/fixtures/pk.json deleted file mode 100644 index 589596a065..0000000000 --- a/crates/zk-prover/tests/fixtures/pk.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "15513232712324041253", - "abi": { - "parameters": [ - { - "name": "pk0is", - "type": { - "kind": "array", - "length": 1, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "pk1is", - "type": { - "kind": "array", - "length": 1, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - } - ], - "return_type": { "abi_type": { "kind": "field" }, "visibility": "public" }, - "error_types": {} - }, - "bytecode": "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", - "debug_symbols": "pdjRattIFIfxd/F1Lub8z2hG01dZluKmbjEYJ7jJwlL67mvX5ztOFiTSpDdK4upDkc5PM+Tn5uvuy/P3z/vjt4cfm09//dx8Oe0Ph/33z4eH++3T/uF4/unPX3cbvv38dNrtzj/avPj8fNbj9rQ7Pm0+HZ8Ph7vNP9vD8+//9ONxe/x9fNqezp+Wu83u+PV8PAe/7Q+7y1e/7m5nl+VTa5/j5DrPefr0+nxbPn+UGuePNuX5Ta/O1/L5bVQuoJdyu4JeXxV8pdCtR6H1aSwV6nLBy8Q1eHnxW/Tp7YXqWehjqdCWC9P5XxSmaS7vKTTLQpO/q1BKFsw+WlBdKqzMQy+qOQ+zLT1Nsw8PhOnDE7GeeNNIWP3wTKwm3jYU64k3TcWbE+8cizlfEza1xWc6VsbCL59ex8J7WUqorF5FyeEci3dTa8Npl6G5XoVNt6s4j/pbE9M8GndzvHhl/j+x8s4cVrkXw0ZdTKw801qbsXLUcbsKG39wL1o+EZX+nnvxKiG963aOeruddfkq1ubCZDmdvvi60Mp09ub8Ir1NtnQVXj78UN0+/lDXfpHZuZ197tOrq/j7/N32fn96tQnalHPw/JKy60HXg18P9XqYrod2PfTrYb4eRpxOJjoWIYuSRcqiZRGzqFnkLHqKnriu6Cl6ip6ip+gpeoqeoufR8+g5v2j0PHoePY+eR8+j59Gr0avRq9Gr3Lno1ejV6NXo1ejV6E3Rm6I3RW+K3sSjiN4UvSl6U/Sm6LXotei16LXoteg1nm30WvRa9Fr0evR69Hr0evR69Hr0OsMSvR69Hr05enP05ujN0ZujN0dvjt7M9EVvjt6I3ojeiN6I3ojeiN6I3ojeYJxznhnowkQXRrow04WhLkx1YawLc10Y7EL5RoVyYkktySW9JJgUk2QwY6AxpULKuDHgGHIMOoYdA4+hx+Bj+DFP4JQhZBgyEBmKDEaGIwOSIcmgZDXfHZTRZHAyPBmgDFEGKcOUgcpQZVO+ligDy5Bl0DJsGbgMXQYvw5cBzFq+8ShjzEBmKDOYGc4MaIY0g5phzXq+TCnDzfBmgDPEGeQMcwY6Q53BzuZ8T1NGnkHPsGfgM/QZ/Ax/BkBDoI1cAnINYBHAoDAoDAqDwqAwKAwKg8KgLJcXyhgUBoVBYVAYFAaFQeW6lQvXbeWinGtXLl65euXyletXLmAYFAaFQXkuipQxKAwKg8KgMCgMCoPCoDComustZQwKg8KgMCgMCoPCoDAoDGrKpZwyBoVBYVAYFAaFQWFQGBQG1XKXQBmDwqAwKAwKg8KgMCgMCoPquQGhjEFhUBgUBoVBYVAYFAaFQc25t6GMQWFQGBQGhUFhUBgUBoVBjdw25b6JjRMGHYOOQcegY9Ax6Bh0DDoG3XJLRhmDjkHHoGPQMegYdAw6Bh2DrtztUcagY9Ax6Bh0DDoGPXeRuY3MfeRtI0k5t5K5l8zNZO4mczuJQcegXwy6Ll/o8sWvy17/tN9+Oezib5bfno/3L/6E+fTvI5/wR87H08P97uvzaXfZ6f/+7Lz3/w8=", - "file_map": { - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{L, N};\nuse lib::configs::default::dkg::PK_BIT_PK;\nuse lib::core::dkg::pk::Pk;\nuse lib::math::polynomial::Polynomial;\n\nfn main(pk0is: [Polynomial; L], pk1is: [Polynomial; L]) -> pub Field {\n let pk: Pk = Pk::new(pk0is, pk1is);\n pk.execute()\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/bin/dkg/pk/src/main.nr" - }, - "62": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_dkg_pk_commitment;\nuse crate::math::polynomial::Polynomial;\n\n/// Correct DKG Public Key Circuit (Circuit 0).\npub struct Pk {\n /// Correct DKG public key components\n /// pk0[i] is the first component for modulus i\n pk0: [Polynomial; L],\n /// pk1[i] is the second component for modulus i\n pk1: [Polynomial; L],\n}\n\nimpl Pk {\n pub fn new(pk0: [Polynomial; L], pk1: [Polynomial; L]) -> Self {\n Pk { pk0, pk1 }\n }\n\n /// Main verification function\n /// Returns commitment to correct DKG public key\n pub fn execute(self) -> Field {\n compute_dkg_pk_commitment::(self.pk0, self.pk1)\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/core/dkg/pk.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/helpers.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/Users/omardesogus/Projects/Enclave/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/pk.vk b/crates/zk-prover/tests/fixtures/pk.vk deleted file mode 100644 index 56540013f3b7581917480f321d14eabda662e784..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3680 zcmajido+|=9|!O~H>96=Sf^v z1CG#!$7jM^Qe$N1|A=aP#F+<9yu)7%na(c{{i==x5Rd%hiES$u3JaD5^%BhC$4*TdfIvK4*A+VYy@@ZYtEUY4~0H%Kp$y zqS1o9+%e;k3a5$HrXbJb)rXS#W6^5l`No=Sc}_Io2&oq{X_MN{`h_Y+FL%1#0A84t zZXB9ozr&<^Irg1a_(C9XgtTL-jjrn*Pd+iVeN%jPB5+dv#4`7+yh?S(wBr@5;*v9P zgs`}PJsp^<)B!=?mcYGEz#Yb%Nf}-{+FGMbb<4g4*sldHeE%u)gPvtE`z%;tS|+kz zfJexg;Eo5Xyfvv`JoH4+&xh+He7^o2uh0{+Y{s*;YxDTBvY1j?xc3~ z7H|g50vm70V({-GJzC_9Oz)wkXgLqB;^yB;FRo`0GYV-m}$lyiu+fG_olt)8s zEs?Mj_?M1-k#(7K?=}Zbe*HvVc8qzsV!}LHtT02@7m>cMi?Nl8Jvn6C4ICj2@%Q8a-%6#ima;l~15K_sn!7~&OD<-%RJr}OQ{nve4KueIfdRL4qG0dFg z7~u-;FYMm}+6Lzj)-qe?dcE7f!Sl&l!`a9a3|y1{j>par<_M2UZX zYu767VP;3<#gf(<;Nvlg3B9GV$GGQ3iwhryw_O8{5ZU@v_TRD5Uq7>pc*OZ3;JR() z9v7xU9FNA*rUv&HwO7`&7pkduS`9>YFd(XGUnW{x70vGPz0cp$%hnbg}@5Y&{ zjxm7Wz^tyavcl`PZXKzR2w*xL0WLg$dMBA@_?^U<4Un`B7Igt1Sf;m5TynOh#-(S= zy*~e_54f=Z9D3HJan%UvJLAfID6fHUnC>oq6V4#yWm*o|xhn^E0vGnTg}Aw#Rm+6l?0aBEO!b*(7n [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::H;\nuse lib::configs::default::threshold::{L, N, PK_AGGREGATION_BIT_PK, PK_AGGREGATION_CONFIGS};\nuse lib::core::threshold::pk_aggregation::PkAggregation;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_threshold_pk_commitments: pub [Field; H],\n pk0: [[Polynomial; L]; H],\n pk1: [[Polynomial; L]; H],\n pk0_agg: [Polynomial; L],\n pk1_agg: [Polynomial; L],\n) -> pub Field {\n let pk_aggregation: PkAggregation = PkAggregation::new(\n PK_AGGREGATION_CONFIGS,\n expected_threshold_pk_commitments,\n pk0,\n pk1,\n pk0_agg,\n pk1_agg,\n );\n\n pk_aggregation.execute()\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/pk_aggregation/src/main.nr" - }, - "69": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_pk_aggregation_commitment;\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold public key aggregation circuit.\npub struct Configs {\n /// CRT moduli for each basis: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Public Key Aggregation (Circuit 5).\n///\n/// Verifies that for each CRT basis l and each coefficient i:\n/// - pk0_agg[l][i] = sum_h(pk0[h][l][i]) mod q_l\n/// - pk1_agg[l][i] = sum_h(pk1[h][l][i]) mod q_l\npub struct PkAggregation {\n /// Circuit parameters including CRT moduli\n configs: Configs,\n\n /// Expected commitments to threshold public key (from C1)\n /// We need one commitment from each honest party (H).\n /// (public witness)\n expected_threshold_pk_commitments: [Field; H],\n\n /// Individual public keys from H honest parties\n /// pk0[party_idx][basis_idx] - first component of public key for each party and CRT basis\n /// (committed witnesses)\n pk0: [[Polynomial; L]; H],\n /// pk1[party_idx][basis_idx] - second component of public key for each party and CRT basis\n /// (committed witnesses)\n pk1: [[Polynomial; L]; H],\n\n /// Claimed aggregated public key\n /// pk0_agg[basis_idx] - first component of aggregated public key for each CRT basis\n /// (committed witnesses)\n pk0_agg: [Polynomial; L],\n /// pk1_agg[basis_idx] - second component of aggregated public key for each CRT basis\n /// (committed witnesses)\n pk1_agg: [Polynomial; L],\n}\n\nimpl PkAggregation {\n pub fn new(\n configs: Configs,\n expected_threshold_pk_commitments: [Field; H],\n pk0: [[Polynomial; L]; H],\n pk1: [[Polynomial; L]; H],\n pk0_agg: [Polynomial; L],\n pk1_agg: [Polynomial; L],\n ) -> Self {\n PkAggregation { configs, expected_threshold_pk_commitments, pk0, pk1, pk0_agg, pk1_agg }\n }\n\n /// Verifies that pk hashes to each expected_threshold_pk_commitment\n fn verify_pk_commitments(self) {\n for i in 0..H {\n assert(\n compute_pk_aggregation_commitment::(self.pk0[i], self.pk1[i])\n == self.expected_threshold_pk_commitments[i],\n \"PK commitment mismatch\",\n );\n }\n }\n\n fn verify_pk_for_basis(\n self,\n pk: [[Polynomial; L]; H],\n pk_agg: [Polynomial; L],\n basis_idx: u32,\n ) {\n let q_l = self.configs.qis[basis_idx];\n let mod_q_l = ModU128::new(q_l);\n\n for coeff_idx in 0..N {\n // Sum pk coefficients from all honest parties\n let mut sum_pk: Field = 0;\n for party_idx in 0..H {\n sum_pk = sum_pk + pk[party_idx][basis_idx].coefficients[coeff_idx];\n }\n\n // Reduce mod q_l\n let sum_pk_reduced = mod_q_l.reduce_mod(sum_pk);\n\n // Verify equality\n assert(\n sum_pk_reduced == pk_agg[basis_idx].coefficients[coeff_idx],\n \"pk aggregation mismatch\",\n );\n }\n }\n\n /// Main verification function\n /// Returns commitment to aggregated threshold public key\n pub fn execute(self) -> Field {\n // 0. Verify pk commitments\n self.verify_pk_commitments();\n\n // 1. Verify pk0 & pk1 aggregations for each CRT basis\n for basis_idx in 0..L {\n self.verify_pk_for_basis(self.pk0, self.pk0_agg, basis_idx);\n self.verify_pk_for_basis(self.pk1, self.pk1_agg, basis_idx);\n }\n\n // 2. Commit to aggregated threshold public key\n compute_pk_aggregation_commitment::(self.pk0_agg, self.pk1_agg)\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/pk_aggregation.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/pk_aggregation.vk b/crates/zk-prover/tests/fixtures/pk_aggregation.vk deleted file mode 100644 index 58a10c89eef0602904ff50a5ced0d1cbabd1509e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg`6Cky1HkdkH72<>jA8Eke#XKcw^xP`*-#`z!z1L_>qWV**c=b#dJxH#dy3?E zo=9PfFlIu?HDu1{{SThLzkdFJF97hb3H_@A03yF|Amqv-LbGo&{HJlh|I`&XoPjm? z_$W_txw(gRPx!DM$){FjlU=jOo4EF1U1dDv@wqX~hjCWij~q~btm#6(5v{IN ziFEBaNEukKy6pH_>N8(G8aN;AeRAEGeEDe{X^-;AsB!{hmq}Z&Y}k*Jc#SEx->cmy z)bnn-qw!49NA8uY-`saDiTC~i>{UKZrP|Ig4@<5u^y(6RPoS{URel450@6{j#q*{J zPwn5^1A=ph%+>UnxN*bYzl|KU}0YQT3f5QBUDvtz04uhxe^96 zte}{QN_$>PW~m5udNTTDIX9zOnAw8}4VENwmMWH8v2w=oG7L&(w7j%1g z1bu*LtDSk;bc&$YmDU=wED8`_0?@5+pZNR@*3|@rNMiJE21Xk-0o_eix3zD<$L@?A z>ncpI`;9kwZ|D0<ASl=19Whn$-+6~0?p44!WkPbmd{sm|Z#Q8O zYkg$7VN1d*=m$$9S2NCn7{hR-yF*OxMDA(`r<(V;H|riQV*9Nq)=r{xKh?Y|q33y6 z8qocyr;RQz8Ppr;O1qH4*E_dCid1cdd(F1^TZ`R^#U_$^GRfu#f!TqRDcOsWM_Ux1 zFK{wKqVxHS53(+yUR&t}$aps~xj(vE+gfIcg9gFE`kVXfv_E&R8vW(Q|0R8g*P3+G->B=#}uS?dqysNc--kIckhEos_jn{u{=r zA3A|b@{EX`5fymAK{=AY5{m{A7HX!0-EmkI-<{)!qt$0WURJEV$yX+vVQ-`x7?pU` zQG_<{#&hn`YumaFZePgXZ1{N5WDc+jtM>K_Hxo#3DOyxC;Yiq_2kh7T&VYlzmb73# z9?HcA4}Wz@kvt}+y4B>%kkMUXmdY? zU!_hji$LuLC$S4WgRg{7FF%=?a?Z$>=>fv2OgRs_{Asj^dW(p>0>zg{ioGV88tQbP zUdFwCKJC6G71aTIy|>tPn5)OLoka`bDKna?r~r3eh;aZpyW0vnX1dyIj5ry7YJ37r zNU$ORN~Sv9j9mJ#RXk70$H}NP8{Ua`_fgfg1KufWM})Mk7$t!7$+)aYjVX zhd@IbR1W`ayap)PZfeS__TFHrh5HuCHVSA%RY>oa=F72;Xm+z)pq<}&zmbcvaEQqH zQ+Oe3aGC?nWh4w{w1t~DTTMXSmA5IiD?v$oCHW={D`&Xxm?Bhmh&xZ)_ukLK@Z0(M zdD;c4Yj$pEk(Aj{TR=F<AE<)?L47xX7~-vgxjw+JjTu5w9T nwq1_L7gN>uU+gl5et_pp@?>D#%PIRxQHyq [T; N] {\n /// Returns the length of this array.\n ///\n /// ```noir\n /// fn len(self) -> Field\n /// ```\n ///\n /// example\n ///\n /// ```noir\n /// fn main() {\n /// let array = [42, 42];\n /// assert(array.len() == 2);\n /// }\n /// ```\n #[builtin(array_len)]\n pub fn len(self) -> u32 {}\n\n /// Returns this array as a slice.\n ///\n /// ```noir\n /// let array = [1, 2];\n /// let slice = array.as_slice();\n /// assert_eq(slice, &[1, 2]);\n /// ```\n #[builtin(as_slice)]\n pub fn as_slice(self) -> [T] {}\n\n /// Applies a function to each element of this array, returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.map(|a| a * 2);\n /// assert_eq(b, [2, 4, 6]);\n /// ```\n pub fn map(self, f: fn[Env](T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array along with its index,\n /// returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.mapi(|i, a| i + a * 2);\n /// assert_eq(b, [2, 5, 8]);\n /// ```\n pub fn mapi(self, f: fn[Env](u32, T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(i, self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// let mut i = 0;\n /// a.for_each(|x| {\n /// b[i] = x;\n /// i += 1;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_each(self, f: fn[Env](T) -> ()) {\n for i in 0..self.len() {\n f(self[i]);\n }\n }\n\n /// Applies a function to each element of this array along with its index.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// a.for_eachi(|i, x| {\n /// b[i] = x;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_eachi(self, f: fn[Env](u32, T) -> ()) {\n for i in 0..self.len() {\n f(i, self[i]);\n }\n }\n\n /// Applies a function to each element of the array, returning the final accumulated value. The first\n /// parameter is the initial value.\n ///\n /// This is a left fold, so the given function will be applied to the accumulator and first element of\n /// the array, then the second, and so on. For a given call the expected result would be equivalent to:\n ///\n /// ```rust\n /// let a1 = [1];\n /// let a2 = [1, 2];\n /// let a3 = [1, 2, 3];\n ///\n /// let f = |a, b| a - b;\n /// a1.fold(10, f); //=> f(10, 1)\n /// a2.fold(10, f); //=> f(f(10, 1), 2)\n /// a3.fold(10, f); //=> f(f(f(10, 1), 2), 3)\n ///\n /// assert_eq(a3.fold(10, f), 10 - 1 - 2 - 3);\n /// ```\n pub fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U {\n for elem in self {\n accumulator = f(accumulator, elem);\n }\n accumulator\n }\n\n /// Same as fold, but uses the first element as the starting element.\n ///\n /// Requires the input array to be non-empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [1, 2, 3, 4];\n /// let reduced = arr.reduce(|a, b| a + b);\n /// assert(reduced == 10);\n /// }\n /// ```\n pub fn reduce(self, f: fn[Env](T, T) -> T) -> T {\n let mut accumulator = self[0];\n for i in 1..self.len() {\n accumulator = f(accumulator, self[i]);\n }\n accumulator\n }\n\n /// Returns true if all the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 2];\n /// let all = arr.all(|a| a == 2);\n /// assert(all);\n /// }\n /// ```\n pub fn all(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = true;\n for elem in self {\n ret &= predicate(elem);\n }\n ret\n }\n\n /// Returns true if any of the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 5];\n /// let any = arr.any(|a| a == 5);\n /// assert(any);\n /// }\n /// ```\n pub fn any(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n for elem in self {\n ret |= predicate(elem);\n }\n ret\n }\n\n /// Concatenates this array with another array.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr1 = [1, 2, 3, 4];\n /// let arr2 = [6, 7, 8, 9, 10, 11];\n /// let concatenated_arr = arr1.concat(arr2);\n /// assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n /// }\n /// ```\n pub fn concat(self, array2: [T; M]) -> [T; N + M] {\n let mut result = [crate::mem::zeroed(); N + M];\n for i in 0..N {\n result[i] = self[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n }\n}\n\nimpl [T; N]\nwhere\n T: Ord + Eq,\n{\n /// Returns a new sorted array. The original array remains untouched. Notice that this function will\n /// only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting\n /// logic it uses internally is optimized specifically for these values. If you need a sort function to\n /// sort any type, you should use the `sort_via` function.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32];\n /// let sorted = arr.sort();\n /// assert(sorted == [32, 42]);\n /// }\n /// ```\n pub fn sort(self) -> Self {\n self.sort_via(|a, b| a <= b)\n }\n}\n\nimpl [T; N]\nwhere\n T: Eq,\n{\n /// Returns a new sorted array by sorting it with a custom comparison function.\n /// The original array remains untouched.\n /// The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument.\n ///\n /// Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32]\n /// let sorted_ascending = arr.sort_via(|a, b| a <= b);\n /// assert(sorted_ascending == [32, 42]); // verifies\n ///\n /// let sorted_descending = arr.sort_via(|a, b| a >= b);\n /// assert(sorted_descending == [32, 42]); // does not verify\n /// }\n /// ```\n pub fn sort_via(self, ordering: fn[Env](T, T) -> bool) -> Self {\n // Safety: `sorted` array is checked to be:\n // a. a permutation of `input`'s elements\n // b. satisfying the predicate `ordering`\n let sorted = unsafe { quicksort::quicksort(self, ordering) };\n\n if !is_unconstrained() {\n for i in 0..N - 1 {\n assert(\n ordering(sorted[i], sorted[i + 1]),\n \"Array has not been sorted correctly according to `ordering`.\",\n );\n }\n check_shuffle::check_shuffle(self, sorted);\n }\n sorted\n }\n}\n\nimpl [u8; N] {\n /// Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation -\n /// the given array is interpreted as-is as a string.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let hi = [104, 105].as_str_unchecked();\n /// assert_eq(hi, \"hi\");\n /// }\n /// ```\n #[builtin(array_as_str_unchecked)]\n pub fn as_str_unchecked(self) -> str {}\n}\n\nimpl From> for [u8; N] {\n /// Returns an array of the string bytes.\n fn from(s: str) -> Self {\n s.as_bytes()\n }\n}\n\nmod test {\n #[test]\n fn map_empty() {\n assert_eq([].map(|x| x + 1), []);\n }\n\n global arr_with_100_values: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2, 54,\n 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41, 19, 98,\n 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21, 43, 86, 35,\n 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15, 127, 81, 30, 8,\n 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n global expected_with_100_values: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30, 32,\n 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58, 61, 62,\n 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82, 84, 84, 86,\n 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114, 114, 116, 118,\n 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n fn sort_u32(a: u32, b: u32) -> bool {\n a <= b\n }\n\n #[test]\n fn test_sort() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort();\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort();\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values_comptime() {\n let sorted = arr_with_100_values.sort();\n assert(sorted == expected_with_100_values);\n }\n\n #[test]\n fn test_sort_via() {\n let mut arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_via_100_values() {\n let mut arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn mapi_empty() {\n assert_eq([].mapi(|i, x| i * x + 1), []);\n }\n\n #[test]\n fn for_each_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_each(|_x| assert(false));\n }\n\n #[test]\n fn for_eachi_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_eachi(|_i, _x| assert(false));\n }\n\n #[test]\n fn map_example() {\n let a = [1, 2, 3];\n let b = a.map(|a| a * 2);\n assert_eq(b, [2, 4, 6]);\n }\n\n #[test]\n fn mapi_example() {\n let a = [1, 2, 3];\n let b = a.mapi(|i, a| i + a * 2);\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn for_each_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n let mut i = 0;\n let i_ref = &mut i;\n a.for_each(|x| {\n b_ref[*i_ref] = x * 2;\n *i_ref += 1;\n });\n assert_eq(b, [2, 4, 6]);\n assert_eq(i, 3);\n }\n\n #[test]\n fn for_eachi_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n a.for_eachi(|i, a| { b_ref[i] = i + a * 2; });\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn concat() {\n let arr1 = [1, 2, 3, 4];\n let arr2 = [6, 7, 8, 9, 10, 11];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n }\n\n #[test]\n fn concat_zero_length_with_something() {\n let arr1 = [];\n let arr2 = [1];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_something_with_zero_length() {\n let arr1 = [1];\n let arr2 = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_zero_lengths() {\n let arr1: [Field; 0] = [];\n let arr2: [Field; 0] = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, []);\n }\n}\n", - "path": "std/array/mod.nr" - }, - "18": { - "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, PK_GENERATION_BIT_E_SM, PK_GENERATION_BIT_EEK, PK_GENERATION_BIT_PK, PK_GENERATION_BIT_R1,\n PK_GENERATION_BIT_R2, PK_GENERATION_BIT_SK, PK_GENERATION_CONFIGS,\n};\nuse lib::core::threshold::pk_generation::PkGeneration;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n a: pub [Polynomial; L],\n eek: Polynomial,\n sk: Polynomial,\n e_sm: [Polynomial; L],\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n) -> pub (Field, Field, Field) {\n let pk_generation: PkGeneration = PkGeneration::new(\n PK_GENERATION_CONFIGS,\n a,\n eek,\n sk,\n e_sm,\n r1is,\n r2is,\n pk0is,\n pk1is,\n );\n pk_generation.execute()\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/pk_generation/src/main.nr" - }, - "70": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_threshold_pk_challenge, compute_threshold_pk_commitment,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for threshold public key generation circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Bound for error polynomial (eek) coefficients\n pub eek_bound: Field,\n /// Bound for secret key polynomial (sk) coefficients\n pub sk_bound: Field,\n /// Bound for smudging noise polynomial (e_sm) coefficients\n pub e_sm_bound: Field,\n /// Bounds for r1 polynomials (modulus switching quotients) for each CRT basis\n pub r1_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients) for each CRT basis\n pub r2_bounds: [Field; L],\n}\n\nimpl Configs {\n pub fn new(\n qis: [Field; L],\n eek_bound: Field,\n sk_bound: Field,\n e_sm_bound: Field,\n r1_bounds: [Field; L],\n r2_bounds: [Field; L],\n ) -> Self {\n Configs { qis, eek_bound, sk_bound, e_sm_bound, r1_bounds, r2_bounds }\n }\n}\n\n/// Correct Threshold Public Key Generation Circuit (Circuit 1).\n///\n/// Verifies:\n/// 1. Range checks on all secret witnesses (secret key, error, smudging noise, quotients)\n/// 2. Correct public key generation: pk0_i = -a_i * sk + eek + r2_i * (X^N + 1) + r1_i * q_i\n/// and pk1_i = a_i\n///\n/// Outputs:\n/// - commit(threshold_sk)\n/// - commit(threshold_pk)\n/// - commit(e_sm)\npub struct PkGeneration {\n /// Cryptographic parameters including bounds, moduli, and constants.\n configs: Configs,\n\n /// Common Reference String polynomials (public witnesses)\n /// One polynomial per modulus i\n a: [Polynomial; L],\n\n /// Error polynomial (secret witness)\n /// Small coefficients sampled from error distribution\n eek: Polynomial,\n\n /// Secret key polynomial (secret witness)\n /// Small coefficients sampled from CBD (Centered Binomial Distribution)\n sk: Polynomial,\n\n /// Smudging noise polynomial (secret witness)\n /// Used for threshold decryption security\n e_sm: [Polynomial; L],\n\n /// Quotients from polynomial operations (secret witnesses)\n /// r1[i] are quotients from modulus switching for modulus i (can be negative, degree 2*N-1)\n r1: [Polynomial<2 * N - 1>; L],\n /// r2[i] are quotients from cyclotomic reduction for modulus i (typically positive, degree N-1)\n r2: [Polynomial; L],\n\n /// Threshold public key components (committed witnesses)\n /// pk0[i] is the first component of the public key for modulus i\n pk0: [Polynomial; L],\n /// pk1[i] is the second component of the public key for modulus i (should equal a[i])\n pk1: [Polynomial; L],\n}\n\nimpl PkGeneration {\n pub fn new(\n configs: Configs,\n a: [Polynomial; L],\n eek: Polynomial,\n sk: Polynomial,\n e_sm: [Polynomial; L],\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n ) -> Self {\n PkGeneration { configs, a, eek, sk, e_sm, r1, r2, pk0, pk1 }\n }\n\n /// Flattens all witness data into a single array for Fiat-Shamir challenge generation\n fn payload(\n self,\n sk_commitment: Field,\n pk_commitment: Field,\n e_sm_commitment: Field,\n ) -> Vec {\n let mut inputs = Vec::new();\n\n // Flatten CRS polynomials a (L polynomials of degree N)\n inputs = flatten::<_, _, BIT_PK>(inputs, self.a);\n\n // Flatten error polynomial eek (1 polynomial of degree N)\n inputs = flatten::<_, _, BIT_EEK>(inputs, [self.eek]);\n\n // Use commitments instead of full polynomials\n inputs.push(sk_commitment);\n inputs.push(pk_commitment);\n inputs.push(e_sm_commitment);\n\n // Flatten quotient polynomials (L polynomials each)\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2);\n\n inputs\n }\n\n /// Main execution function\n /// Returns (commit(threshold_sk), commit(threshold_pk), commit(e_sm))\n pub fn execute(self) -> (Field, Field, Field) {\n // Step 1: Perform range checks on all secret witness values\n self.perform_range_checks();\n\n // Step 2: Compute commitments\n let sk_commitment = compute_share_computation_sk_commitment::(self.sk);\n let e_sm_commitment =\n compute_share_computation_e_sm_commitment::(self.e_sm);\n let pk_commitment = compute_threshold_pk_commitment::(self.pk0, self.pk1);\n\n // Step 3: Generate Fiat-Shamir challenges using commitments\n let gammas = self.generate_challenge(sk_commitment, pk_commitment, e_sm_commitment);\n\n // Step 4: Verify public key equations for each modulus\n for i in 0..L {\n let gamma = gammas.get(i);\n self.verify_public_key_for_modulus(i, gamma);\n }\n\n // Step 5: Return all commitments\n (sk_commitment, pk_commitment, e_sm_commitment)\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge\n fn generate_challenge(\n self,\n sk_commitment: Field,\n pk_commitment: Field,\n e_sm_commitment: Field,\n ) -> Vec {\n let inputs = self.payload(sk_commitment, pk_commitment, e_sm_commitment);\n\n compute_threshold_pk_challenge::(inputs)\n }\n\n /// Performs range checks on all secret witness values\n fn perform_range_checks(self) {\n // Check that error polynomial has small coefficients\n self.eek.range_check_2bounds::(self.configs.eek_bound, self.configs.eek_bound);\n\n // Check that secret key polynomial has small coefficients\n self.sk.range_check_2bounds::(self.configs.sk_bound, self.configs.sk_bound);\n\n // Check quotient terms are within expected bounds (per modulus)\n for i in 0..L {\n self.e_sm[i].range_check_2bounds::(\n self.configs.e_sm_bound,\n self.configs.e_sm_bound,\n );\n\n self.r1[i].range_check_2bounds::(\n self.configs.r1_bounds[i],\n self.configs.r1_bounds[i],\n );\n\n self.r2[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n }\n }\n\n /// Verifies the threshold public key generation equations for a specific CRT basis\n fn verify_public_key_for_modulus(self, i: u32, gamma: Field) {\n // Evaluate all polynomials at the random challenge point gamma\n let a_at_gamma = self.a.map(|a_poly| a_poly.eval(gamma));\n\n let eek_at_gamma = self.eek.eval(gamma);\n let sk_at_gamma = self.sk.eval(gamma);\n\n let r1_at_gamma = self.r1.map(|r1_poly| r1_poly.eval(gamma));\n let r2_at_gamma = self.r2.map(|r2_poly| r2_poly.eval(gamma));\n\n let pk0_at_gamma = self.pk0.map(|pk0_poly| pk0_poly.eval(gamma));\n let pk1_at_gamma = self.pk1.map(|pk1_poly| pk1_poly.eval(gamma));\n\n // Evaluate the cyclotomic polynomial X^N + 1 at gamma\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n\n // pk0_i = -a_i * sk + eek + r2_i * (X^N + 1) + r1_i * q_i\n let expected_pk0 = -a_at_gamma[i] * sk_at_gamma\n + eek_at_gamma\n + r2_at_gamma[i] * cyclo_at_gamma\n + r1_at_gamma[i] * self.configs.qis[i];\n\n assert(pk0_at_gamma[i] == expected_pk0, \"Public key equation 1 failed\");\n\n // Equation 2: pk1_i = a_i\n assert(pk1_at_gamma[i] == a_at_gamma[i], \"Public key equation 2 failed\");\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/pk_generation.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/pk_generation.vk b/crates/zk-prover/tests/fixtures/pk_generation.vk deleted file mode 100644 index e38d16b2d449b8408bf985bcdd2c8b451dd28204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg`9Bkm1IO{r$FVhH*bpE0Xw#gvWXaWLj;#4O=c-7bCFkffa_0!2PmW;-iE=de z5#?BpBEu(g%<;)JOo~EM`0V@r3;Mi&dp(|iz#9Pg>7YMVfS}aR9RL)7m|wTH9q?y? zTk9l5U%gbxd-Ii3+*{>y7Q|m=h4>#kHU~Nroa(E$9Fn=yXff$99?7GS9OJ)JUUy44 zQZ=-}&ni3~8v&DwL?U|`={9DZiLnGZjRI4DS>Jg` z8RD_R0kJZG>s_k2jlwXXK`-ClfRryKb*vnw0V~vWLDI29sx26xpmYELsDL?=Sdcn0 z>?g&HR-Cnv@TzW93&2Ge;#VVE548Ohmchn8u6?@r{w}MB%g+I8jk}F{Ljk*#QXgldG#1uWCUqqFC0S~FWh_eQ- z4oi5=4@|m`zztNaiINFG$C}BMRM$*&*qdx_FnTvJ=G@_zcTWQS)O(1y0K|l%Td;HC zU;0hjO|@-uRu`yp7fj?MqH~|s&PbO{U4EOcO@ry}sP?=rUayh4?AdZj{x^{r$8GQzPQ^hZn0zZ!|HXMWE?B zBMqd+E6`*%RFajyAaPDlOl0^<=cw%luszHfgsg1fgsCRCq6y& zHF8MT`iDrfbG+fA=l0{8IrpAv30mxu9dDeB-B|N^MI<#<&3C^W|571$$`Wt67vc@7j^z5V5YRR-j``MC_o!Q(Q{K=`N@!X_@eEsZ|2y?XU(e?F;K{!x~-}9fX$zBjSL<{9HYum~C}_B1t!4!8BO? z@UmG8&|lae`~LWvTc+fQ~GX*uIG*`Ckljjv~E*E+V=%#j-pm4s*pv4$@(m~ zi(T9SGM0F?J^W^WUoAH`rMO}nN9|*d{i0WOrYl~?Krw4BBy!d_G|s_|4cadz&Zg1E zW1s`=!dv%q;PzT|VY57H)>}UKIk;2Bisg+oqZM4(ACfsCNE=NOFr%0BqdIeMiJR{# zdst1$=IFKgy<_{Z9u}A=(5w9c=Yu6P)R=7w@#W}V49ow%>CW|?B8Lwjf^fJJIN_HyeO*QHJ?Uw zj*#;o2r|KpE||ZSd+s#u$3co=`u76I7z-W5KsFXWt{5q|iTPDtB?>K_eZrm*#){gop zYfp2HuRF)S)YiUO%X|IpcY6YvZH(k`duixn{@iG`s|vEt$UBC74W)lkJV{Iu6(gS+CX)rJF;07_ zkdp&OscPMe1I-~upW==~YSt1b$1QoOX4X!fa(ZrwZP(vku zIVq=TY^Hl0&}asx=J(|9av-$X)D)sMcy_4)iwU+Q-a3ASgB+4O;qzb+*=s=*k==Y@LnaNz-g=0M*dpzy9ezTtGR+TnS;^ClKbUSXN0`$wVlcH(h(N ufVt1toLT;`3qHOXhZ#ZEZ}~-{yCEAZlb?%MuF7iYF^mRz%|Xm}D*pqvAu{j) diff --git a/crates/zk-prover/tests/fixtures/share_decryption.json b/crates/zk-prover/tests/fixtures/share_decryption.json deleted file mode 100644 index e9de60cc47..0000000000 --- a/crates/zk-prover/tests/fixtures/share_decryption.json +++ /dev/null @@ -1,145 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "5855950985937366278", - "abi": { - "parameters": [ - { "name": "expected_sk_commitment", "type": { "kind": "field" }, "visibility": "public" }, - { "name": "expected_e_sm_commitment", "type": { "kind": "field" }, "visibility": "public" }, - { - "name": "ct0", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "public" - }, - { - "name": "ct1", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "public" - }, - { - "name": "sk", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "e_sm", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "r1", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 1023, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "r2", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 511, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "d", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - } - ], - "return_type": null, - "error_types": { - "790736725912586495": { "error_kind": "string", "string": "Decryption share computation failed" }, - "7023503018538476324": { "error_kind": "string", "string": "S commitment mismatch" }, - "12469291177396340830": { "error_kind": "string", "string": "call to assert_max_bit_size" }, - "13823868475309396004": { "error_kind": "string", "string": "E commitment mismatch" } - } - }, - "bytecode": "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", - "debug_symbols": "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D/U+3PdL/T7M5y/92OAfH+zzl35s8I8P8X4p34fzfqneh/t+qd+H+fylHxv844N9/tKPDf7x4X3N/b7mfl9zv6+539fc72vu9zXP+5rnfc3zvuZ5X/O8r3ne1zzva573Nc/7mufzaz4fH+/D59d8Pvx9iPdL+T6c90v1Ptz3S/0+fH7Nxz7eh8+v+Zi/D/F+Kd+H836p3of7fqnfh/c1+/ua/X3N/r5mf1+zv6/Z39fs72v29zX7+5r9fc3xvuZ4X3O8rzne1xzva473Ncf7muN9zfG+5nhfc76vOd/XnO9rzvc15/ua833N+b7mfF9zvq8539d83td83td83td83td83td83td83td83td83td83tdc72uu9zXX+5rfBs/b4HkbPG+D523wvA2et8HzNnjeBs/b4HkbPG+D523wvA2et8HzNnjeBs/b4HkbPG+D523wvA2et8HzNnjeBs/b4HkbPG+D523wvA2et8HzNnjeBs/b4HkbPG+D522w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButtsN4G622w3gbrbbDeButt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wbv2+B9G7xvg/dt8L4N3rfB+zZ43wb7bbDfBvtt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D+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcD+d4OMfDOR7O8XCOh3M8nOPhHA/neDjHwzkezvFwjodzPJzj4RwP53g4x8M5Hs7xcI6Hczyc4+EcDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u8HCBhws8XODhAg8XeLjAwwUeLvBwgYcLPFzg4QIPF3i4wMMFHi7wcIGHCzxc4OECDxd4uMDDBR4u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ebLzZOfJzpOdJztPdp7sPNl5svNk58nOk50nO092nuw82Xmy82Tnyc6TnSc7T3ae7DzZebLzZOfJzpOdJztPdp7sPNl5svNk58nOk50nO092nuw82Xmy82Tnyc6TnSc7T3ae7DzZebLzZOfJzpOdJztPdp7s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84POz/s/LDzw84PO8fDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx083MHDHTzcwcMdPNzBwx08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wsMVHq7wcIWHKzxc4eEKD1d4uMLDFR6u8HCFhys8XOHhCg9XeLjCwxUervBwhYcrPFzh4QoPV3i4wsMVHq7wcIWHKzxc4eEKD1d4uOK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1OK+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pV7uS73cl3q5L/VyX+rlvtTLfamX+1Iv96Ve7ku93Jd6uS/1cl/q5b7Uy32pl/tSL/elXu5LvdyXerkv9XJf6uW+1Mt9qZf7Ui/3pd7Dzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sPPDzg87P+z8sHM83MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzcxcNdPNzFw1083MXDXTzc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wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzycfQDifnz8PMmPj66Pob8h9fHobyh9vPobWh+Hv+FN/sdH4294o//xMfQ3pD4e/Q2lj1d/Q+ujzuY6m+tsrrO5zuY6m+tsrrO5zuY6m+tsobOFzhY6W+hsobOFzhY6W+hsobOFzpY6W+psqbOlzpY6W+psqbOlzpY6W+psR2c7OtvR2Y7OdnS2o7Mdne3obEdnOzpb6Wyls5XOVjpb6Wyls5XOVjpb6Wyls12d7epsV2e7OtvV2a7OdnW2q7Ndne3qbK2ztc7WOlvrbK2ztc7WOlvrbK2ztc42OtvobKOzjc42OtvobKOzjc42OptaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlphaYmqJqSWmlpha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrha4mqJqyWulrhaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRaEmpJqCWhloRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRakmpJqiWplqRactSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSakmpJaWWlFpSasnvhvPGHx9dH397260/PqY+Hv0NpY9Xf0Pr47y/4XfM+T7a+xt+55zvY+hvSH08+htKH6/+htbH4W/40ZL3kbP9Djvfx9DfkPp49DeUPl79Da2POpvrbK6zuc7mOpvrbK6zuc7mOpvrbK6zhc4WOlvobKGzhc4WOlvobKGzhc4WOlvqbKmzpc6WOlvqbKmzpc6WOlvqbKmzHZ3t6GxHZzs629HZjs52dLajsx2d7ehspbOVzlY6W+lspbOVzlY6W+lspbOVznZ1tquzXZ3t6mxXZ7s629XZrs52dbars7XO1jpb62yts7XO1jpb62yts7XO1jrb6GxqyVVLrlpy1ZKrlly15KolVy25akmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSakmrJa2WtFrSasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoyasmoJaOWjFoytMQ+aIl90BL7oCX2QUvsg5bYBy2xD1piH7TEPmiJfdAS+6Al9kFL7IOW2ActsQ9aYh+0xD5oiX3QEvugJfZhOpvrbK6zuc7mOpvrbK6zuc7mOpvrbK6zhc4WOlvobKGzhc4WOlvobKGzhc4WOlvqbKmzpc6WOlvqbKmzpc6WOlvqbKmzHZ3t6GxHZzs629HZjs52dLajsx2d7ehspbOVzlY6W+lspbOVzlY6W+lspbOVznZ1tquzXZ3t6mxXZ7s629XZrs52dbars7XO1jpb62yts7XO1jpb62yts7XO1jrb6Gyjs43ONjrb6Gyjs43ONjrb6GxqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaklppaYWmJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqiaslrpa4WuJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSagloZaEWhJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqSaolqZakWpJqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlhy15KglRy05aslRS45actSSo5YcteSoJUctOWrJUUuOWnLUkqOWHLXkqCVHLTlqyVFLjlpy1JKjlpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSWllpRaUmpJqSVyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvJvdqcq8m92pyryb3anKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq8u9+pyry736nKvLvfqcq+/fdTZ1BK5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVeXe3W5V5d7dblXl3t1uVf/3b3+9pc/Ptf6fNfnXp9Hn38Ehc+2Pvv6HOtzrs/rvbnem+u9ud6b671nvfes95713rPee9Z7z3rvWe89671nvfes99Z6b6331npvrffWem+t99Z6b6331npvrffe9d673nvXe+96713vveu9d733rvfe9d673tvrvb3e2+u9vd7b67293tvrvb3e2+u9vd47672z3jvrvbPeO+u9s947672z3jvrvaP3/g5n+Wzrs6/PsT7n+nzW51qf7/rc6/N6r6332nqvrffaeq+t99p6r6332nqvrffaeq+v9/p6r6/3+nqvr/f6eq+v9/p6r6/3+npvrPfGem+s98Z6b6z3rl716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9e9epVr1716lWvXvXqVa9ezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWsXs3q1axezerVrF7N6tWoV/GhXsWHehUf6lV8qFfxoV7Fh3oVH+pVfKhX8aFexcfHeq+t99p6r6332nqvrffaeq+t99p6r6332nqvr/f6eq+v9/p6r6/3+nqvr/f6eq+v9/p6b6z3xnpvrPfGem+s98Z6b6z3xnpvrPfGem+u9+Z6b6735npvrvfmem+u9+Z6b6735nrvWe89671nvfes95713rPee9Z7z3rvWe8967213lvrvbXeW+u9td5b67213lvrvbXeW+u9d733rvfe9d673nvXe+96713vveu9d733rvf2em+v9/Z6b6/39npvr/f2em+v9/Z6b6/3znrvrPfOeu+s985676z3znrvrPfOeu/qla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWtXtnqla1e2eqVrV7Z6pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+eqVr1756pWvXvnqla9e+epVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVaxexepVrF7F6lWsXsXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6lWuXuXqVa5e5epVrl7l6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxendWrs3p1Vq/O6tVZvTqrV2f16qxe1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXtXqVa1e1epVrV7V6lWtXt3Vq7t6dVev7urVXb26q1d39equXt3Vq7t6dVev7urVXb26q1d39equXt3Vq7t6dVev7urVXb26q1d39equXt3Vq7t6dVev7urVXb26q1d39equXt3Vq7t6dVevlm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm+P5dtj+fZYvj2Wb4/l22P59li+PZZvj+XbY/n2WL49lm/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+PZdvz+Xbc/n2XL49l2/P5dtz+fZcvj2Xb8/l23P59ly+/bfP672rV8u35/LtuXx7Lt+ey7fn8u25fHsu357Lt+fy7bl8ey7fnsu35/LtuXx7Lt+ey7fn8u25fHsu357Lt+fy7bl8ey7fnsu35/LtuXx7Lt+ey7fn8u25fHsu357Lt+fy7bl8ey7fnsu35/LtuXx7Lt+ey7fn8u25fHsu357Lt+fy7bl8ey7fnsu35/LtuXx7Lt+ey7fn8u25fHsu357Lt+fy7bl8ey7fnsu35/LtuXx7Lt+ey7fn8u25fHsu357Lt+cfvj3yj8/D5z98+/v8473Rf3z29TnW51yfz/pc6/Ndn3t9/vHetN8//96r99nWZ1+fY33O9fmsz7U+3/W51+f1Xl/v9fVeX+/19V5f7/X1Xl/v9fVeX+/19d5Y74313ljvjfXeWO+N9d5Y74313ljvjfXeXO/N9d5c78313lzvzfXeXO/N9d5c78313rPee9Z7z3rvWe89671nvfes95713rPee9Z7a7231ntrvbfWe2u9t9Z7a7231ntrvbfWe+96713vveu9d733rvfe9d673nvXe+96713v7fXeXu/t9d5e7+313l7v7fXeXu/t9d5e75313lnvnfXeWe+d9d5Z75313lnvnfXe0Xv/8O3vs63Pvj7H+pzr81mfa32+63Ovz+u9q1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXoVq1exehWrV7F6FatXsXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6latXuXqVq1e5epWrV7l6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1dn9eqsXp3Vq7N6dVavzurVWb06q1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXtXpVq1e1elWrV7V6VatXd/Xqrl7d1au7enVXr+7q1V29uqtXd/Xqrl7d1au7enVXr+7q1V29uqtXd/Xqrl7d1as/fHv+/t8U/vDt77Otz74+x/qc6/NZn2t9vutzr8/rvbHeG+u9sd4b672x3hvrvbHeG+u9sd4b67253pvrvbnem+u9ud6b67253pvrvbnem+u9Z733rPee9d6z3nvWe89671nvPeu9Z733rPfWem+t99Z6b6331npvrffWem+t99Z6b6333vXeu95713vveu9d773rvXe996733vXeu97b67293tvrvb3e2+u9vd7b67293tvrvb3eO+u9s947672z3jvrvbPeO+u9s947672j9/7h299nW599fY71Odfnsz7X+nzX516f13ttvdfWe22919Z7bb3X1nttvdfWe229d/WqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969apXr3r1qlevevWqV6969WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavZvVqVq9m9WpWr2b1alavRr06H+rV+VCvzod6dT7Uq/OhXp0P9ep8qFfnQ736/5q6l5XZuuQ8o/eithsZMeMwp+/FCEmWTUEhibJkMEb3btf/7V05eu9iZfL0Ritg9efrVX8+dINu0A26QTfoBt2gG3SDbtBNukk36SbdpJt0k27STbpJ99A9dA/dQ/fQPXQP3UP30D10i27RLbpFt+gW3aJbdItu0W26TbfpNt2m23SbbtNtuk136A7doTt0h+7QHbpDd+gO3aW7dJfu0l26S3fpLt2lu3Qv3Uv30r10L91L99K9dC/dS/fRfXQf3Uf30X10H91H99HFq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8Cr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Gq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18erh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1fv69V+vl7t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3Uv30r10H91H99F9dPHq4NXBq4NXB68OXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eXby6eHXx6uLVz3171c9u9rCXfdnvu3+8+rWDnezDpht0g27QDbpBN+km3aSbdJNu0k26STfpJt1D99A9dA/dQ/fQPXQP3UP30C26RbfoFt2iW3SLbtEtukW36Tbdptt0m27TbbpNt+k23aE7dIfu0B26Q3foDt2hO3SX7tJdukt36S7dpbt0l+7SvXQv3Uv30r10L91L99K9dC/dR/fRfXQf3Uf30X10H91H9327P/ftv3ewk33YxW72sJd92XTx6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Op9vXqfr1fv8/Xqfb5evc/Xq/f5evU+X6/e5+vV+3y9ep+vV+/zoRt0g27QDbpBN+gG3aAbdINu0k26STfpJt2km3STbtJNuofuoXvoHrqH7qF76B66h+6hW3SLbtEtukW36Bbdolt0i27TbbpNt+k23abbdJtu0226Q3foDt2hO3SH7tAdukN36C7dpbt0l+7SXbpLd+ku3aV76V66l+6le+leupfupXvpXrqP7qP76D66j+6j++g+uo8uXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1e/7tv3Zzd72Mu+7PfdP1792sFO9mHTTbpJN+km3aR76B66h+6he+geuofuoXvoHrpFt+gW3aJbdItu0S26RbfoNt2m23SbbtNtuk236Tbdpjt0h+7QHbpDd+gO3aE7dIfu0l26S3fpLt2lu3SX7tJdupfupXvpXrqX7qV76V66l+6l++g+uo/uo/voPrqP7qP76L5v99d9+68d7GQfdrGbPexlXzbdoBt0g27QxavCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavF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Fq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dX7+tVfL5exefrVXy+XsXn61V8vl7F5+tVfL5exefrVXy+XsXnQzfoBt2gG3SDbtANukE36AbdpJt0k27STbpJN+km3aSbdA/dQ/fQPXQP3UP30D10D91Dt+gW3aJbdItu0S26RbfoFt2m23SbbtNtuk236Tbdptt0h+7QHbpDd+gO3aE7dIfu0F26S3fpLt2lu3SX7tJdukv30r10L91L99K9dC/dS/fSvXQf3Uf30X10H91H99F9dB9dvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8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", - "file_map": { - "18": { - "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, THRESHOLD_SHARE_DECRYPTION_BIT_CT, THRESHOLD_SHARE_DECRYPTION_BIT_D,\n THRESHOLD_SHARE_DECRYPTION_BIT_E_SM, THRESHOLD_SHARE_DECRYPTION_BIT_R1,\n THRESHOLD_SHARE_DECRYPTION_BIT_R2, THRESHOLD_SHARE_DECRYPTION_BIT_SK,\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n};\nuse lib::core::threshold::share_decryption::ShareDecryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_sk_commitment: pub Field,\n expected_e_sm_commitment: pub Field,\n ct0: pub [Polynomial; L],\n ct1: pub [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<(2 * N) - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n) {\n let share_decryption: ShareDecryption = ShareDecryption::new(\n THRESHOLD_SHARE_DECRYPTION_CONFIGS,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n );\n share_decryption.execute()\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/share_decryption/src/main.nr" - }, - "71": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_aggregated_shares_commitment, compute_threshold_share_decryption_challenge,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold decryption share circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Bounds for r1 polynomials (modulus switching quotients) for each CRT basis\n pub r1_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients) for each CRT basis\n pub r2_bounds: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L], r1_bounds: [Field; L], r2_bounds: [Field; L]) -> Self {\n Configs { qis, r1_bounds, r2_bounds }\n }\n}\n\n/// Threshold Share Decryption (Circuit 6).\n///\n/// Verifies:\n/// 1. Commitment to sk matches expected (from DKG decryption circuit)\n/// 2. Commitment to e_sm matches expected (from DKG decryption circuit)\n/// 3. Correct computation: d_i = c_0i + c_1i * s_i + e_i + r_2i * (X^N + 1) + r_1i * q_i\npub struct ShareDecryption {\n /// Circuit parameters including bounds and cryptographic constants\n configs: Configs,\n\n /// Expected commitment to aggregated sk shares (from DKG decryption circuit)\n /// (public witness)\n expected_sk_commitment: Field,\n\n /// Expected commitment to aggregated e_sm shares (from DKG decryption circuit)\n /// (public witness)\n expected_e_sm_commitment: Field,\n\n /// Ciphertext components (public witnesses)\n /// ct0 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct0: [Polynomial; L],\n /// ct1 components for each CRT basis (degree N-1 polynomials with N coefficients)\n ct1: [Polynomial; L],\n\n /// Aggregated sum of sk shares (secret witness)\n sk: [Polynomial; L],\n\n /// Aggregated sum of e_sm shares (secret witness, direct input)\n /// e_sm[basis] - sum of e_sm shares for each CRT basis (degree N-1 with N coefficients)\n e_sm: [Polynomial; L],\n\n /// Quotient polynomials for lifting to Z (secret witnesses)\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n\n /// Party's computed decryption share\n /// (public witnesses)\n d: [Polynomial; L],\n}\n\nimpl ShareDecryption {\n pub fn new(\n configs: Configs,\n expected_sk_commitment: Field,\n expected_e_sm_commitment: Field,\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n sk: [Polynomial; L],\n e_sm: [Polynomial; L],\n r1: [Polynomial<2 * N - 1>; L],\n r2: [Polynomial; L],\n d: [Polynomial; L],\n ) -> Self {\n ShareDecryption {\n configs,\n expected_sk_commitment,\n expected_e_sm_commitment,\n ct0,\n ct1,\n sk,\n e_sm,\n r1,\n r2,\n d,\n }\n }\n\n /// Verifies that aggregated secret shares hash to expected_sk_commitment\n fn verify_agg_sk_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.sk)\n == self.expected_sk_commitment,\n \"S commitment mismatch\",\n );\n }\n\n /// Verifies that aggregated noise shares hash to expected_e_sm_commitment\n fn verify_agg_e_sm_commitment(self) {\n assert(\n compute_aggregated_shares_commitment::(self.e_sm)\n == self.expected_e_sm_commitment,\n \"E commitment mismatch\",\n );\n }\n\n /// Flattens all witness data into a single array for Fiat-Shamir challenge generation.\n ///\n /// This function serializes all polynomial coefficients (both public inputs and\n /// secret witnesses) into a 1D array in a deterministic order. The flattened data\n /// is used to generate the Fiat-Shamir challenge via the SAFE sponge API.\n ///\n /// The order of serialization is:\n /// 1. Commitment to aggregated secret shares `sk` (expected_sk_commitment)\n /// 2. Commitment to aggregated noise shares `e_sm` (expected_e_sm_commitment)\n /// 3. Ciphertext components `c_0` for each CRT basis (serialized coefficients)\n /// 4. Ciphertext components `c_1` for each CRT basis (serialized coefficients)\n /// 5. Quotient polynomials `r_1` for each CRT basis (serialized coefficients)\n /// 6. Quotient polynomials `r_2` for each CRT basis (serialized coefficients)\n /// 7. Decryption shares `d` for each CRT basis (serialized coefficients)\n ///\n /// Note: Aggregated secret shares `sk` and noise shares `e_sm` are represented by their\n /// commitments rather than serialized coefficients. This saves constraints while\n /// still binding them to the transcript.\n ///\n /// # Returns\n /// A vector containing commitments and polynomial coefficients in flattened form,\n /// ready for hashing to generate the Fiat-Shamir challenge.\n fn payload(self) -> Vec {\n let mut inputs = Vec::new();\n\n // Use commitments instead of full polynomials (saves constraints)\n inputs.push(self.expected_sk_commitment);\n inputs.push(self.expected_e_sm_commitment);\n\n // Flatten ciphertext components (public inputs)\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1);\n\n // Flatten quotient polynomials (secret witnesses)\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2);\n\n // Flatten decryption shares (public outputs)\n inputs = flatten::<_, _, BIT_D>(inputs, self.d);\n\n inputs\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify sk commitment matches expected\n self.verify_agg_sk_commitment();\n\n // Step 2: Verify e_sm commitment matches expected\n self.verify_agg_e_sm_commitment();\n\n // Step 3: Perform range checks on quotient polynomials\n // Note: sk and e_sm range checks are handled by commitment verification\n // (the DKG decryption circuit already performed range checks on these values)\n self.check_range_bounds();\n\n // Step 4: Generate Fiat-Shamir challenge from the transcript\n let gamma = self.generate_challenge();\n\n // Step 5: Verify decryption share computation for each CRT basis\n for i in 0..L {\n self.verify_decryption_share_computation(i, gamma);\n }\n }\n\n /// Performs range checks on quotient polynomial witnesses.\n ///\n /// This function constrains quotient polynomials to be within their expected bounds\n /// as specified in the `configs`. This is critical for security because it prevents\n /// attacks where malicious provers provide out-of-range values that could break the\n /// security properties of the Threshold scheme.\n ///\n /// Note: Range checks on `sk` and `e_sm` are NOT performed here because:\n /// - Their commitments are verified against expected values from the DKG circuit\n /// - The DKG decryption circuit already performed range checks on these values\n /// - Commitment binding ensures the values match what was previously verified\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any quotient coefficient is\n /// outside its expected bounds.\n fn check_range_bounds(self) {\n // Check quotient polynomials are within bounds\n for basis_idx in 0..L {\n // r_1 quotients can be negative (modulus quotients)\n self.r1[basis_idx].range_check_2bounds::(\n self.configs.r1_bounds[basis_idx],\n self.configs.r1_bounds[basis_idx],\n );\n // r_2 quotients (cyclotomic quotients)\n self.r2[basis_idx].range_check_2bounds::(\n self.configs.r2_bounds[basis_idx],\n self.configs.r2_bounds[basis_idx],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge value using the SAFE cryptographic sponge.\n ///\n /// This function implements the Fiat-Shamir transform for the decryption share circuit:\n /// 1. Flattens all witness data (commitments for sk/e_sm, ciphertexts c_0/c_1, quotients r_1/r_2, decryption shares d) into a single array\n /// 2. Absorbs the flattened data into the SAFE sponge\n /// 3. Squeezes a single challenge value\n ///\n /// The challenge is used to evaluate polynomials for the Schwartz-Zippel lemma,\n /// which allows verification of polynomial equations by checking them at a random\n /// point rather than checking all coefficients.\n ///\n /// # Returns\n /// A single challenge value `gamma` used as the evaluation point for verifying\n /// the decryption share computation formula for all CRT bases.\n fn generate_challenge(self) -> Field {\n let inputs = self.payload();\n\n compute_threshold_share_decryption_challenge::(inputs)\n }\n\n /// Verifies the lifted decryption share computation formula for a specific CRT basis using the Schwartz-Zippel lemma.\n ///\n /// This function verifies that the decryption share for basis `i` satisfies:\n /// `d_i(gamma) = c_0i(gamma) + c_1i(gamma) * s_i(gamma) + e_i(gamma) + r_2i(gamma) * cyclo(gamma) + r_1i(gamma) * q_i`\n ///\n /// Where:\n /// - `c_0i`, `c_1i` are ciphertext components for basis i\n /// - `s_i` is the aggregated secret key shares for basis i\n /// - `e_i` is the aggregated noise shares for basis i\n /// - `r_1i`, `r_2i` are quotient witnesses for basis i\n /// - `cyclo(gamma) = gamma^N + 1` is the cyclotomic polynomial evaluated at gamma\n /// - `q_i` is the CRT modulus for basis i\n ///\n /// The Schwartz-Zippel lemma ensures that if this equation holds at a random point\n /// `gamma`, then the polynomials are identical with high probability.\n ///\n /// # Arguments\n /// * `basis_idx` - The index of the CRT basis to verify (0 <= basis_idx < L)\n /// * `gamma` - The Fiat-Shamir challenge value used as the evaluation point\n ///\n /// # Panics\n /// The circuit will fail if the decryption share computation formula doesn't hold for the specified basis.\n fn verify_decryption_share_computation(self, basis_idx: u32, gamma: Field) {\n // Evaluate ciphertext components at gamma\n let c_0_at_gamma = self.ct0[basis_idx].eval(gamma);\n let c_1_at_gamma = self.ct1[basis_idx].eval(gamma);\n\n // Evaluate aggregated sums at gamma\n let sk_at_gamma = self.sk[basis_idx].eval(gamma);\n let e_sm_at_gamma = self.e_sm[basis_idx].eval(gamma);\n\n // Evaluate quotient polynomials at gamma\n let r_1_at_gamma = self.r1[basis_idx].eval(gamma);\n let r_2_at_gamma = self.r2[basis_idx].eval(gamma);\n\n // Evaluate cyclotomic polynomial X^N + 1 at gamma\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n\n // Compute expected decryption share using the lifted formula:\n // d_i = c_0i + c_1i * sk_i + e_sm_i + r_2i * (X^N + 1) + r_1i * q_i\n let expected_decryption_share = c_0_at_gamma\n + c_1_at_gamma * sk_at_gamma\n + e_sm_at_gamma\n + r_2_at_gamma * cyclo_at_gamma\n + r_1_at_gamma * self.configs.qis[basis_idx];\n\n // Evaluate the party's claimed decryption share at gamma\n let computed_decryption_share = self.d[basis_idx].eval(gamma);\n\n // Enforce equality: computed decryption share must match expected value\n assert(\n computed_decryption_share == expected_decryption_share,\n \"Decryption share computation failed\",\n );\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/share_decryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/share_decryption.vk b/crates/zk-prover/tests/fixtures/share_decryption.vk deleted file mode 100644 index e1ea1bfab34d1f30acc3b615f8a8adfa10ab19a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg`6Ckw0KoAL(`@Ee*u=)N8euYp`Jt0cjBZh@^Nbk+n`tq zHPN2-j*FzMosDHl_Uji*?~$bV%FPm5x2*iO zXfh*m8J1Z0cIJ*W9eUTc^_o+Sft*6{rk=O)BeDrnL{F{g#nrE4iMPSnZpAE~1#0d; zg<2AM%#&7UBYRX;(#t$!0~rPtxdP!CI*?J*2CHy zWM#M`Z!VRlox9T|dL-+)y{D)4*i?G36v1SKur*~krq@m!BVmPJcP?ogl(#ROV+XDo zrHAt^a@*j4#WOF2oAZF9S&m{UF}NayRoC5>PxMVYHh9P^V4dG67$_@X!@8%&qsb+8 zy(-kOpD@5sA3T`H2Qnf#{S!gmsdo=KzDQ{*b@vY5ju`oHI_+Gq?jE8E6JG3v3zoW3 z{;-sZ$)QY#!;F%s2SxUl#eHR2*^;x5c9)|R#fKAE+o0$Ht5B;%ZA*(MoKsj|CI23+(L>P>|FAsjW*_w9N z_x2SM*Is?`7^|2Z=n<^bJIC4(kdrJjbZ%rfMV^NvsBen+I*2eQzO+t<4n8rbN|o~$ z4^3#zEh2?(SRLN5ndP07fDU%XZVcGw{PL5Aptd_cD0~InQg_bcWgAcnJ9s@QpSRk> zg{OXfKkQSALJ?O%@2j`L@*|NsLIFJFpx~Ok%5dV3zI|iC@v>YHjRSh(!CUC;v))b) zGFLtb)2Piew2*FX8M5!dA+ehCtZ~yI>iZYCCo=z*O~Y?eKAl3%Qumy%bv8L?XgmOYPT)1qfkPNe z+rO;m1upHIf5o?2HlN+YA>cjk)v502Y`E6oKp;0+HDDH%8ePEJCi*EC=04|*-}^qf z-`$j4D=Mh_JZv$m;QMh}o5&X)j-zz$S{oGLV zWK9IR8cShTF9!T+@o_F5ro_^FN#Zp0KS5FV#p7X{_*ZtMi`xg)~F72rW|PeGNX7T0;X1)&6?3#Os|F zu2$!tCJNDYk)Ywjdm7)y)td|{w6#kW%p}BN?6Z3-I~PAKEXRqqvyVqpKNdr`eYKhN z`y&$Ti1<&s_kB2fAdZQS1x=))}0Ilm3^`y-;HZBVG(0AqW>{HiuU zWG%#`i|Ad!xXmW{;L63}k_WEY$@*v=;${2^q<>QI8J?@^xCI3mmtr70%4^-Jn8EZ%IXVZ-3A)M_Yr*;WC~_n{hP{XG zucaUjTVaN>jrX7d?kfqIgge{9?VUSOzjp4q=e)ox&8p0F@l2TBb_?Pn1gF5-5@3J*Gxx@3Xl00cB zQ`_i!ceBe~HkfaG`@ASf%m#$>RjyJcSMj9}B_)u?Um_epP;-4&!&D=+{1Rx^UkS#y zDHJFR5N;ZC@CyF=Zar^iG}9faK-Tw*K>I3cn(@ZM&MQX1(;uA6fYul!y+veYaVbhE z#Ycf>WJasZd7w630yKg;CLx1jwZW8H`j&C#5zz{1+`G0Q33&D)c@U>75hyB%B3w%M zi~{OU3rh#QcwY|Wry3bSl?E<;rGPOR)_9=Rm`p;m1T578M|L&)JbmIfu$pFLYKKeB z5&WD?`^aIyc}Wm5TaPs%n~w;i<-d=RzC3uszm$z&X_p-f%)KOdJe2*iNN(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n L, N, SHARE_ENCRYPTION_BIT_CT, SHARE_ENCRYPTION_BIT_E0, SHARE_ENCRYPTION_BIT_E1,\n SHARE_ENCRYPTION_BIT_MSG, SHARE_ENCRYPTION_BIT_P1, SHARE_ENCRYPTION_BIT_P2,\n SHARE_ENCRYPTION_BIT_PK, SHARE_ENCRYPTION_BIT_R1, SHARE_ENCRYPTION_BIT_R2,\n SHARE_ENCRYPTION_BIT_U, SHARE_ENCRYPTION_CONFIGS,\n};\nuse lib::core::dkg::share_encryption::ShareEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_pk_commitment: pub Field,\n expected_message_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: pub [Polynomial; L],\n ct1is: pub [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let share_encryption: ShareEncryption = ShareEncryption::new(\n SHARE_ENCRYPTION_CONFIGS,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n share_encryption.execute();\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/share_encryption/src/main.nr" - }, - "65": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_dkg_pk_commitment;\nuse crate::math::commitments::{\n compute_share_encryption_challenge, compute_share_encryption_commitment_from_message,\n};\nuse crate::math::helpers::flatten;\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for DKG share encryption circuit.\npub struct Configs {\n /// Plaintext modulus t\n pub t: Field,\n /// Q mod t (for scaling message)\n pub q_mod_t: Field,\n /// CRT moduli for each basis: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Scaling factors for each basis: [k0_0, k0_1, ..., k0_{L-1}]\n pub k0is: [Field; L],\n /// Bounds for public key polynomials for each CRT basis\n pub pk_bounds: [Field; L],\n /// Bounds for error polynomials (e0)\n pub e0_bound: Field,\n /// Bounds for error polynomials (e1)\n pub e1_bound: Field,\n /// Bound for secret polynomial u (ternary distribution)\n pub u_bound: Field,\n /// Lower bounds for r1 polynomials (modulus switching quotients)\n pub r1_low_bounds: [Field; L],\n /// Upper bounds for r1 polynomials (modulus switching quotients)\n pub r1_up_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients)\n pub r2_bounds: [Field; L],\n /// Bounds for p1 polynomials (modulus switching quotients)\n pub p1_bounds: [Field; L],\n /// Bounds for p2 polynomials (cyclotomic reduction quotients)\n pub p2_bounds: [Field; L],\n /// Bound for message polynomial (m)\n pub msg_bound: Field,\n}\n\nimpl Configs {\n pub fn new(\n t: Field,\n q_mod_t: Field,\n qis: [Field; L],\n k0is: [Field; L],\n pk_bounds: [Field; L],\n e0_bound: Field,\n e1_bound: Field,\n u_bound: Field,\n r1_low_bounds: [Field; L],\n r1_up_bounds: [Field; L],\n r2_bounds: [Field; L],\n p1_bounds: [Field; L],\n p2_bounds: [Field; L],\n msg_bound: Field,\n ) -> Self {\n Configs {\n t,\n q_mod_t,\n qis,\n k0is,\n pk_bounds,\n e0_bound,\n e1_bound,\n u_bound,\n r1_low_bounds,\n r1_up_bounds,\n r2_bounds,\n p1_bounds,\n p2_bounds,\n msg_bound,\n }\n }\n}\n\n/// DKG Share Encryption Circuit (Circuit 3).\n///\n/// Verifies:\n/// 1. Public key commitment matches expected (from Circuit 0)\n/// 2. Message commitment matches expected (from SK shares circuit)\n/// 3. Correct DKG share encryption: ct0[l] = pk0[l] * u + e0[l] + k1 * k0[l] + r1[l] * q[l] + r2[l] * (X^N + 1)\n/// and ct1[l] = pk1[l] * u + e1 + p2[l] * (X^N + 1) + p1[l] * q[l]\npub struct ShareEncryption {\n /// Circuit parameters\n configs: Configs,\n /// Expected commitment to public key (from Circuit 0)\n /// (public witness)\n expected_pk_commitment: Field,\n /// Expected commitment to message (from SK shares verification circuit)\n /// (public witness)\n expected_message_commitment: Field,\n /// Public key component 0 for each CRT basis (committed witnesses)\n pk0is: [Polynomial; L],\n /// Public key component 1 for each CRT basis (committed witnesses)\n pk1is: [Polynomial; L],\n /// Ciphertext component 0 for each CRT basis (public witnesses)\n ct0is: [Polynomial; L],\n /// Ciphertext component 1 for each CRT basis (public witnesses)\n ct1is: [Polynomial; L],\n /// Random ternary polynomial u (secret witness)\n u: Polynomial,\n /// Error polynomial e0 (secret witness)\n e0: Polynomial,\n /// Per-basis error polynomials e0[l] (secret witnesses)\n e0is: [Polynomial; L],\n /// CRT quotients for e0 (secret witnesses)\n e0_quotients: [Polynomial; L],\n /// Error polynomial e1 (secret witness)\n e1: Polynomial,\n /// Raw message polynomial (secret witness)\n message: Polynomial,\n /// Modulus switching quotient polynomials r1 (secret witnesses, degree 2N-1)\n r1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials r2 (secret witnesses, degree N-1)\n r2is: [Polynomial; L],\n /// Modulus switching quotient polynomials p1 (secret witnesses, degree 2N-1)\n p1is: [Polynomial<(2 * N) - 1>; L],\n /// Cyclotomic reduction quotient polynomials p2 (secret witnesses, degree N-1)\n p2is: [Polynomial; L],\n}\n\nimpl ShareEncryption {\n pub fn new(\n configs: Configs,\n expected_pk_commitment: Field,\n expected_message_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n message: Polynomial,\n r1is: [Polynomial<2 * N - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<2 * N - 1>; L],\n p2is: [Polynomial; L],\n ) -> Self {\n ShareEncryption {\n configs,\n expected_pk_commitment,\n expected_message_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n message,\n r1is,\n r2is,\n p1is,\n p2is,\n }\n }\n\n /// Verifies that the public key hashes to the expected commitment\n fn verify_pk_commitment(self) {\n assert(\n compute_dkg_pk_commitment::(self.pk0is, self.pk1is)\n == self.expected_pk_commitment,\n \"Public key commitment mismatch\",\n );\n }\n\n /// Verifies that the message polynomial hashes to the expected commitment\n fn verify_message_commitment(self) {\n assert(\n compute_share_encryption_commitment_from_message::(self.message)\n == self.expected_message_commitment,\n \"Message commitment mismatch\",\n );\n }\n\n /// Computes the scaled message k1 from the raw message in centered form\n /// k1[i] = (q_mod_t * message[i]) mod t, centered to [-t/2, t/2)\n fn compute_scaled_message(self) -> Polynomial {\n let t = self.configs.t;\n let t_mod = ModU128::new(t);\n let q_mod_t: Field = self.configs.q_mod_t;\n let mut k1_coeffs: [Field; N] = [0; N];\n\n // Integer division for t_half\n let t_half: u128 = (t as u128) / 2;\n\n for i in 0..N {\n let msg_i: Field = self.message.coefficients[i];\n let q_times_m_mod_t = t_mod.mul_mod(q_mod_t, msg_i);\n\n // Check if centering is needed (value > t/2 means negative in centered form)\n let needs_centering = (q_times_m_mod_t as u128) > t_half;\n\n k1_coeffs[i] = if needs_centering {\n // Value is in (t/2, t), negative in centered form\n // Represent as P - magnitude (i.e., 0 - magnitude in Field)\n let magnitude = t - q_times_m_mod_t;\n 0 - magnitude\n } else {\n // Value is in [0, t/2], stays positive\n q_times_m_mod_t\n };\n }\n\n Polynomial { coefficients: k1_coeffs }\n }\n\n /// Flattens all polynomial coefficients into a single array for Fiat-Shamir challenge generation\n fn payload(self, k1: Polynomial) -> Vec {\n let mut inputs = Vec::new();\n\n // Use pk commitment instead of full pk polynomials\n inputs.push(self.expected_pk_commitment);\n\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0is);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1is);\n\n inputs = flatten::<_, _, BIT_E0>(inputs, [self.e0]);\n inputs = flatten::<_, _, BIT_E1>(inputs, [self.e1]);\n inputs = flatten::<_, _, BIT_U>(inputs, [self.u]);\n\n // Use message commitment instead of full message\n inputs.push(self.expected_message_commitment);\n\n // Include computed k1 in payload\n for i in 0..N {\n inputs.push(k1.coefficients[i]);\n }\n\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1is);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2is);\n inputs = flatten::<_, _, BIT_P1>(inputs, self.p1is);\n inputs = flatten::<_, _, BIT_P2>(inputs, self.p2is);\n\n inputs\n }\n\n /// Performs coefficient-wise CRT consistency check for the e0 error polynomial\n fn check_e0_crt_consistency(self) {\n for i in 0..L {\n for j in 0..N {\n assert(\n self.e0.coefficients[j]\n == self.e0is[i].coefficients[j]\n + self.e0_quotients[i].coefficients[j] * self.configs.qis[i],\n );\n }\n }\n }\n\n /// Main verification function\n pub fn execute(self) {\n // Step 1: Verify public key commitment matches expected\n self.verify_pk_commitment();\n\n // Step 2: Verify message commitment matches expected\n self.verify_message_commitment();\n\n // Step 3: Perform range checks\n self.check_range_bounds();\n\n // Step 4: Check CRT consistency for e0\n self.check_e0_crt_consistency();\n\n // Step 5: Compute scaled message k1 from message\n let k1 = self.compute_scaled_message();\n\n // Step 6: Generate Fiat-Shamir challenges\n let gammas = self.generate_challenge(k1);\n\n // Step 7: Verify encryption constraints\n self.verify_evaluations(gammas, k1)\n }\n\n /// Performs range checks on all secret witness polynomial coefficients\n fn check_range_bounds(self) {\n self.u.range_check_2bounds::(self.configs.u_bound, self.configs.u_bound);\n self.e0.range_check_2bounds::(self.configs.e0_bound, self.configs.e0_bound);\n self.e1.range_check_2bounds::(self.configs.e1_bound, self.configs.e1_bound);\n\n // Message should be in [0, t)\n self.message.range_check_standard::(self.configs.msg_bound);\n\n for i in 0..L {\n self.pk0is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n self.pk1is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n\n self.r1is[i].range_check_2bounds::(\n self.configs.r1_up_bounds[i],\n self.configs.r1_low_bounds[i],\n );\n self.r2is[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n\n self.p1is[i].range_check_2bounds::(\n self.configs.p1_bounds[i],\n self.configs.p1_bounds[i],\n );\n self.p2is[i].range_check_2bounds::(\n self.configs.p2_bounds[i],\n self.configs.p2_bounds[i],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge\n fn generate_challenge(self, k1: Polynomial) -> Vec {\n let inputs = self.payload(k1);\n\n compute_share_encryption_challenge::(inputs)\n }\n\n /// Verifies DKG encryption constraints using Fiat-Shamir challenges and the Schwartz-Zippel lemma\n fn verify_evaluations(self, gammas: Vec, k1: Polynomial) {\n let gamma = gammas.get(0);\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n let u_at_gamma = self.u.eval(gamma);\n let e1_at_gamma = self.e1.eval(gamma);\n let k1_at_gamma = k1.eval(gamma);\n\n let mut sum = (0, 0);\n for i in 0..L {\n let pk0is_at_gamma = self.pk0is[i].eval(gamma);\n let r1i_at_gamma = self.r1is[i].eval(gamma);\n let r2i_at_gamma = self.r2is[i].eval(gamma);\n let e0is_at_gamma = self.e0is[i].eval(gamma);\n\n // Verify ct0 equation: ct0[i] = pk0[i]*u + e0[i] + k1*k0[i] + r1[i]*q[i] + r2[i]*cyclo\n let mut ct0_rhs = (pk0is_at_gamma * u_at_gamma) + e0is_at_gamma;\n ct0_rhs += k1_at_gamma * self.configs.k0is[i];\n ct0_rhs += r1i_at_gamma * self.configs.qis[i];\n ct0_rhs += r2i_at_gamma * cyclo_at_gamma;\n let ct0_lhs = self.ct0is[i].eval(gamma);\n\n // Verify ct1 equation: ct1[i] = pk1[i]*u + e1 + p2[i]*cyclo + p1[i]*q[i]\n let pk1is_at_gamma = self.pk1is[i].eval(gamma);\n let p1is_at_gamma = self.p1is[i].eval(gamma);\n let p2is_at_gamma = self.p2is[i].eval(gamma);\n let mut ct1_rhs = (pk1is_at_gamma * u_at_gamma) + e1_at_gamma;\n ct1_rhs += p2is_at_gamma * cyclo_at_gamma;\n ct1_rhs += p1is_at_gamma * self.configs.qis[i];\n let ct1_lhs = self.ct1is[i].eval(gamma);\n\n // Accumulate weighted sums for batch verification\n let gamma_i = if i == 0 { 1 } else { gammas.get(i) };\n sum = (\n sum.0 + ct0_lhs * gamma_i + ct1_lhs * gammas.get(i + L),\n sum.1 + ct0_rhs * gamma_i + ct1_rhs * gammas.get(i + L),\n );\n }\n\n assert(sum.0 == sum.1);\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_encryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/share_encryption.vk b/crates/zk-prover/tests/fixtures/share_encryption.vk deleted file mode 100644 index 929d89b0c4f50c04eac7662bab4ff8b7e7ba6f16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajg=OY^k1IO{imL`ITvqy|ZG-{mj2%2bvm`7CAsoJ%xc3XR0>`^hQadw`nitQ*$ zOSQsdj~I;^GsxSgs z_JJ;qi(_q9BG|`f0=)EiESgMthfB{Ch+mC5T^!{Q51?$B`Y(;;ja1vr93D|eQN7d^ zw#T1VtNUnzWJ_j4`-Hm##q6o>qmW5T@|07hg3&qia6C;RVqN@Ic;nr;Z>vJr<6U== z$QaXK9iuP!q$Bjfw7+qpS95m8UCm#nRpX4&L9^DiUId4GK1s5=P<82SF@FuWr_O#H zSexdXW%p|OeL>P{h2sMf18ZR+AoCi&>5RVWCOxwJ_e0#nSt;ujk$j00V$eacSDZaa zv5BJPlC;v@?1ReI>wlM}p6zXD-qo(ETYw14vGG?ywzEL30vd3S#f$q!P-Gybth~;k zM3tf-2fVRyXbTs{yIwhSmoc@#=%aWo4cu$;pSD0qa#$Lq_6_g!OlzX1EcuN#WQK&unCWPt*yXcgU0YL|<}BnQ z|9?q3PSr5SpJj|4@IcVh*YAn&?j!`-dZPxej6PWd8g;2eokThjZvaVzG{qQpQ6@RKn}z4?@66XI+1 zwdMN}p6Vzo6(gTu<$K(fbVX*?5p+9vslwA)`*c&O;ek*8|4*3}Pt_E~gVMu?S$3R; zCc*NHs3GRUSH;Rkm{22e6zyveK+@*DN)hZpQhT58UiK-S)o4mlFJCHn{i=GqQ~;$z zBJpX{sVv@R^w6&Q2rkNHK})o<2BUfE3VilJY~*B{ygR?O&pJy4t=KAq$@Y!iJEDN*WHMAFQlo}HTAQXyF> zUNuo}|0PKKV2mL7ee~>eVo~Cku=q^xZIBzuv*EH5cr?8ia7cQnSYi=}X6&<)IJLYvy{_fG)KNKBskT805tq@0R>IuTcN86z zW)H;dLEZWu05s?8C)NC$b2!Vpc-$rL4!o`$PFa95yv1ncVE9Z~MoF?Avvk2uqA)sz zR1BK#Gwa$87^E;_A&j4)x#XrOPFt}1->Th4Bf-nv?|(o*9@v%ys~4v z&S-%L4?+~*Xs7Y;%q4dp1CYHNZ%9KnJ@kmjFyS(5@4WA56!e_wZ~k>vBy-9)@JO)Q zKdgYQFl?aTHx*cX4$q^N00~6V_v8VLmubDm(4!WK_dbEwFBrzyEqfbF;10$Z6d4sQ zS70o&X#3%!vTU!0*p^VFj!Ka$`_HBjZp-i$e;H<`yd2c=O^gf3-PuBJo9}3?#c(sd zR3U<&L;{ro@INMP??kMP?3XM}6x^0qq3L_XIk}@WZ$MKaGN?Goyzrm$FTFI(=#wIo z`B4Z}QUc$S(nK9z;F84~;kU8sE@}BqW(SK1)=oa}qhvFA+|b^J9H3$*lOCog8z>HQ zh{fbNCjj*q;0pdVW3@n`RxI|C>agxw6Q4`Ic_h$mQYo!d7LsEUM!R+6u;oV$| z>(*g8MX-;VZ|ArSc`z^#vnAA+h98GJA=wkujeumxvw~|(yq%Qi|CHf~0lp{do_^m8 zL){7ro~V;iTb8#BMN=7cb3mw`{lE3;U!3EL@JP++ek~ajPzUP&f{2KmJF6A>Xtt5k r2uqjIqPi$91)Y59{0)LEVYeMug=#osP0p1Us_(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::dkg::{\n L_THRESHOLD, N, PARITY_MATRIX, SHARE_COMPUTATION_BIT_SHARE, SHARE_COMPUTATION_SK_BIT_SECRET,\n SHARE_COMPUTATION_SK_CONFIGS,\n};\nuse lib::configs::default::{N_PARTIES, T};\nuse lib::core::dkg::share_computation::SecretKeyShareComputation;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n expected_secret_commitment: pub Field,\n sk_secret: Polynomial,\n y: [[[Field; N_PARTIES + 1]; L_THRESHOLD]; N],\n) -> pub [[Field; L_THRESHOLD]; N_PARTIES] {\n let sk_share_computation: SecretKeyShareComputation = SecretKeyShareComputation::new(\n SHARE_COMPUTATION_SK_CONFIGS,\n expected_secret_commitment,\n sk_secret,\n y,\n PARITY_MATRIX,\n );\n\n sk_share_computation.execute()\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/dkg/sk_share_computation/src/main.nr" - }, - "63": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::{\n compute_share_computation_e_sm_commitment, compute_share_computation_sk_commitment,\n compute_share_encryption_commitment_from_shares,\n};\nuse crate::math::modulo::U128::ModU128;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Threshold secret share verification circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n}\n\nimpl Configs {\n pub fn new(qis: [Field; L]) -> Self {\n Configs { qis }\n }\n}\n\n/// Correct Threshold Secret Key Share Computation (Circuit 2a).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == sk_secret[i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For SK: sk_secret is the trinary coefficients\npub struct SecretKeyShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// (public witness)\n expected_secret_commitment: Field,\n /// Secret key polynomial: Polynomial\n /// trinary coefficients\n /// (secret witness)\n sk_secret: Polynomial,\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = sk_secret[i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n /// (secret witnesses)\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n /// (public constants)\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\n/// Correct Threshold Smudging Noise Share Computation (Circuit 2b).\n///\n/// Verifies:\n/// 1. secret commitment: verify secret hashes to expected_secret_commitment\n/// 2. secret consistency: y[i][j][0] == e_sm[j][i] for all i, j\n/// 3. Range check: shares are in [0, q_j)\n/// 4. Parity check: H[j] * y[i][j]^T == 0 mod q_j for all i, j\n///\n/// For ESM: e_sm[j] is the RNS representation at modulus j\npub struct SmudgingNoiseShareComputation {\n configs: Configs,\n /// Expected commitment to secret (from C1)\n /// This is computed from all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n expected_secret_commitment: Field,\n /// Smudging noise polynomial per modulus: [Polynomial; L]\n /// For ESM: each modulus has its own polynomial (RNS representation)\n e_sm_secret: [Polynomial; L],\n /// Shares: y[coeff_idx][mod_idx][0..N_PARTIES+1]\n /// y[i][j][0] = e_sm[j][i] = f(0), y[i][j][k] = f(k) for k = 1..N_PARTIES\n y: [[[Field; N_PARTIES + 1]; L]; N],\n /// Parity check matrices: H[mod_idx][row][col]\n /// Size per modulus: (N_PARTIES - T) * (N_PARTIES + 1)\n /// H * y^T = 0 mod q_j\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n}\n\nimpl SecretKeyShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n sk_secret: Polynomial,\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SecretKeyShareComputation { configs, expected_secret_commitment, sk_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_sk_commitment::(self.sk_secret)\n == self.expected_secret_commitment,\n \"SK commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == sk_secret[i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// sk_secret is the trinary coefficients, so y[i][j][0] is the same for all j.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n let secret_coeff = self.sk_secret.coefficients[coeff_idx];\n\n for mod_idx in 0..L {\n assert(self.y[coeff_idx][mod_idx][0] == secret_coeff);\n }\n }\n }\n}\n\nimpl SmudgingNoiseShareComputation {\n pub fn new(\n configs: Configs,\n expected_secret_commitment: Field,\n e_sm_secret: [Polynomial; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n ) -> Self {\n SmudgingNoiseShareComputation { configs, expected_secret_commitment, e_sm_secret, y, h }\n }\n\n /// Main verification function\n pub fn execute(self) -> [[Field; L]; N_PARTIES] {\n // Step 1: Verify secret commitment matches expected\n self.verify_secret_commitment();\n\n // Step 2: Verify secret consistency\n self.verify_secret_consistency();\n\n // Step 3: Range checks\n check_range_bounds::(self.configs.qis, self.y);\n\n // Step 4: Verify parity check\n verify_parity_check::(self.configs.qis, self.h, self.y);\n\n // Step 5: Commit to shares for each party and modulus\n commit_to_party_shares::(self.y)\n }\n\n /// Verifies that secret hashes to expected_secret_commitment\n /// The commitment is computed over all L RNS polynomials (matching\n /// multiple_polynomial_payload's behavior which hashes all L modulus polynomials)\n fn verify_secret_commitment(self) {\n assert(\n compute_share_computation_e_sm_commitment::(self.e_sm_secret)\n == self.expected_secret_commitment,\n \"ESM commitment mismatch\",\n );\n }\n\n /// Verifies secret consistency: `y[i][j][0] == e_sm_secret[j][i]` for all i, j.\n ///\n /// This function ensures that for each coefficient i and CRT basis j, the share\n /// at party ID 0 equals the corresponding secret coefficient for that modulus.\n /// This is a fundamental property of Shamir secret sharing where the secret is the\n /// evaluation of the sharing polynomial at point 0.\n ///\n /// e_sm_secret[j] is the RNS representation at modulus j, so y[i][j][0] varies per modulus.\n ///\n /// # Panics\n /// The circuit will fail if secret consistency doesn't hold for any\n /// coefficient or CRT basis.\n fn verify_secret_consistency(self) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let secret_coeff = self.e_sm_secret[mod_idx].coefficients[coeff_idx];\n assert(\n self.y[coeff_idx][mod_idx][0] == secret_coeff,\n \"Secret consistency check failed\",\n );\n }\n }\n }\n}\n\n/// Performs range checks on secret key and share values.\n///\n/// This function constrains all values to be within their expected bounds:\n/// - Share values for parties k >= 1 must be in [0, q_j) for each CRT modulus q_j\n///\n/// These bounds are critical for security and correctness of the Threshold scheme.\n///\n/// # Panics\n/// This function will cause the circuit to fail if any value is outside\n/// its expected bounds.\npub fn check_range_bounds(\n qis: [Field; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n // Shares y[i][j][k] for k >= 1 should be in [0, q_j)\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n for coeff_idx in 0..N {\n for party_idx in 1..(N_PARTIES + 1) {\n // Use range_check_standard from Polynomial by creating a single-coefficient polynomial\n Polynomial::new([y[coeff_idx][mod_idx][party_idx]])\n .range_check_standard::(q_j);\n }\n }\n }\n}\n\n/// Verifies Reed-Solomon parity check: `H[j] * y[i][j]^T == 0 mod q_j` for all i, j.\n///\n/// This function verifies that for each coefficient i and CRT basis j, the share\n/// vector `y[i][j]` forms a valid Reed-Solomon codeword by satisfying the parity\n/// check equation with the parity check matrix `H[j]`.\n///\n/// The parity check matrix H[j] has dimensions `(N_PARTIES - T) * (N_PARTIES + 1)`,\n/// and the share vector `y[i][j]` has length `N_PARTIES + 1`. The parity check\n/// ensures that any T+1 shares can correctly reconstruct the secret key via\n/// Lagrange interpolation.\n///\n/// # Panics\n/// The circuit will fail if the parity check doesn't hold for any coefficient,\n/// CRT basis, or parity check row.\npub fn verify_parity_check(\n qis: [Field; L],\n h: [[[Field; N_PARTIES + 1]; N_PARTIES - T]; L],\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) {\n for coeff_idx in 0..N {\n for mod_idx in 0..L {\n let q_j = qis[mod_idx];\n\n // For each row of H, compute dot product with y and verify == 0\n for row in 0..(N_PARTIES - T) {\n let mut sum: Field = 0;\n\n for col in 0..(N_PARTIES + 1) {\n sum = sum + h[mod_idx][row][col] * y[coeff_idx][mod_idx][col];\n }\n\n // Reduce mod q_j and verify == 0\n let m = ModU128::new(q_j);\n let result = m.reduce_mod(sum);\n assert(result == 0, \"Parity check failed\");\n }\n }\n }\n}\n\n/// Commits to shares for each party and modulus\n/// Returns [[Field; L]; N_PARTIES] where commitments[party_idx][mod_idx]\npub fn commit_to_party_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n) -> [[Field; L]; N_PARTIES] {\n let mut commitments: [[Field; L]; N_PARTIES] = [[0; L]; N_PARTIES];\n\n for party_idx in 0..N_PARTIES {\n for mod_idx in 0..L {\n commitments[party_idx][mod_idx] = compute_share_encryption_commitment_from_shares::(\n y,\n party_idx,\n mod_idx,\n );\n }\n }\n\n commitments\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/dkg/share_computation.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "77": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Constrained modular arithmetic operations for u128 values.\n//!\n//! This module provides a `ModU128` struct that implements modular arithmetic operations\n//! with full constraint generation for zero-knowledge proof circuits. All operations\n//! are verified in-circuit to ensure correctness.\nuse super::unconstrained_U128::{\n __compute_mod_reduction, __div_mod, __inv_mod, __neg, __sub_with_underflow,\n};\n\n/// Modular arithmetic context for u128 values.\n///\n/// This struct holds a modulus and provides methods for performing modular arithmetic\n/// operations with full constraint generation. All operations are verified in-circuit.\n///\n/// # Generic Parameters\n///\n/// The operations work with `Field` values, but are designed for u128-sized integers.\n/// The modulus must be a positive value less than 2^128.\npub struct ModU128 {\n /// The modulus for all operations\n pub m: Field,\n}\n\nimpl ModU128 {\n /// Creates a new modular arithmetic context with the given modulus.\n ///\n /// # Arguments\n /// * `m` - The modulus for all operations. Must be positive.\n ///\n /// # Returns\n /// A new `ModU128` instance configured with the specified modulus.\n pub fn new(m: Field) -> Self {\n ModU128 { m }\n }\n\n /// Returns the modulus as a Field value.\n ///\n /// # Returns\n /// The modulus value used by this context.\n pub fn get_mod_field(self) -> Field {\n self.m\n }\n\n /// Reduces a value modulo the modulus.\n ///\n /// Computes `n mod m` and returns the result in the range [0, m).\n /// This operation is fully constrained and verified in-circuit.\n ///\n /// # Arguments\n /// * `n` - The value to reduce\n ///\n /// # Returns\n /// The value `n mod m` in the range [0, m)\n ///\n /// # Panics\n /// The circuit will fail if the reduction is incorrect.\n pub fn reduce_mod(self, n: Field) -> Field {\n // Safety: __compute_mod_reduction is safe to call here because we assert the properties of the output\n let (q, r) = unsafe { __compute_mod_reduction(n, self.m) };\n\n // Ensure remainder is in [0, m)\n assert(r as u128 < self.m as u128);\n // Verify the reduction is correct\n assert(n == q * self.m + r);\n\n r\n }\n\n /// Adds two values with modular reduction.\n ///\n /// Computes `(lhs + rhs) mod m` and returns the result.\n /// Handles overflow correctly by reducing modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs + rhs) mod m`\n pub fn add(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs + rhs)\n }\n\n /// Subtracts two values with modular reduction.\n ///\n /// Computes `(lhs - rhs) mod m` and returns the result.\n /// Handles underflow correctly by adding the modulus when needed.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value (minuend)\n /// * `rhs` - Right-hand side value (subtrahend)\n ///\n /// # Returns\n /// The result of `(lhs - rhs) mod m`\n pub fn sub(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __sub_with_underflow is safe because we verify the subtraction equation below\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, self.m) };\n\n // Verify the subtraction\n if underflow {\n assert(lhs + self.m == rhs + result, \"Subtraction with underflow verification failed\");\n } else {\n assert(lhs == rhs + result, \"Subtraction verification failed\");\n }\n\n result\n }\n\n /// Multiplies two values with modular reduction.\n ///\n /// Computes `(lhs * rhs) mod m` and returns the result.\n /// The product is computed first, then reduced modulo the modulus.\n ///\n /// # Arguments\n /// * `lhs` - Left-hand side value\n /// * `rhs` - Right-hand side value\n ///\n /// # Returns\n /// The result of `(lhs * rhs) mod m`\n pub fn mul_mod(self, lhs: Field, rhs: Field) -> Field {\n self.reduce_mod(lhs * rhs)\n }\n\n /// Computes modular division: `lhs * rhs^(-1) mod m`.\n ///\n /// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n /// The result satisfies: `(result * rhs) mod m = lhs mod m`.\n ///\n /// # Arguments\n /// * `lhs` - The numerator\n /// * `rhs` - The denominator (must be coprime with the modulus)\n ///\n /// # Returns\n /// The result of `(lhs * rhs^(-1)) mod m`\n ///\n /// # Panics\n /// The circuit will fail if `rhs` is not invertible modulo `m` (i.e., if\n /// `gcd(rhs, m) != 1`). For prime moduli, any non-zero `rhs` is invertible.\n pub fn div_mod(self, lhs: Field, rhs: Field) -> Field {\n // Safety: __div_mod is safe because we verify result * rhs = lhs (mod m) below\n let result = unsafe { __div_mod(lhs, rhs, self.m) };\n\n // Verify: (result * rhs) mod m == lhs mod m\n assert(\n self.mul_mod(result, rhs) == self.reduce_mod(lhs),\n \"Division verification failed: result * rhs ≠ lhs (mod m)\",\n );\n\n result\n }\n\n /// Negates a value modulo m.\n ///\n /// Computes the additive inverse: `(-val) mod m = (m - val) mod m`.\n /// Special case: negation of zero is zero.\n ///\n /// # Arguments\n /// * `val` - The value to negate\n ///\n /// # Returns\n /// The result of `(-val) mod m`, which satisfies `(val + result) mod m = 0`\n pub fn neg(self, val: Field) -> Field {\n // Safety: __neg is safe because we verify val + result = 0 (mod m) below\n let result = unsafe { __neg(val, self.m) };\n\n // Verify: val + result = 0 (mod m)\n // Special case: if val = 0, result should be 0\n if val == 0 {\n assert(result == 0, \"Negation of zero should be zero\");\n } else {\n assert(val + result == self.m, \"Negation verification failed\");\n }\n\n result\n }\n\n /// Computes the modular multiplicative inverse using Fermat's Little Theorem.\n ///\n /// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n /// such that `(val * result) mod m = 1`.\n ///\n /// The implementation uses Fermat's Little Theorem: `val^(m-1) = 1 (mod m)`,\n /// so `val^(-1) = val^(m-2) (mod m)`.\n ///\n /// # Arguments\n /// * `val` - The value to invert (must be coprime with the modulus)\n ///\n /// # Returns\n /// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n ///\n /// # Panics\n /// The circuit will fail if `val` is not invertible modulo `m` (i.e., if\n /// `gcd(val, m) != 1`). For prime moduli, any non-zero `val` is invertible.\n pub fn inv_mod(self, val: Field) -> Field {\n // Safety: __inv_mod is safe because we verify val * result = 1 (mod m) below\n let result = unsafe { __inv_mod(val, self.m) };\n\n // Verify: val * result = 1 (mod m)\n assert(self.mul_mod(val, result) == 1, \"Inverse verification failed\");\n\n result\n }\n}\n\n#[test]\nfn test_reduce_mod_already_reduced() {\n let value = 42;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 42);\n}\n\n#[test]\nfn test_reduce_mod_needs_reduction() {\n let value = 250;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 50);\n}\n\n#[test]\nfn test_reduce_mod_exact_multiple() {\n let value = 300;\n let m = ModU128::new(100);\n let result = m.reduce_mod(value);\n assert(result == 0);\n}\n\n#[test]\nfn test_reduce_mod_large_value() {\n let value = 123456789;\n let m = ModU128::new(1000);\n let result = m.reduce_mod(value);\n assert(result == 789);\n}\n\n#[test]\nfn test_add_no_overflow() {\n let a = 30;\n let b = 40;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 70);\n}\n\n#[test]\nfn test_add_with_overflow() {\n let a = 60;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 10); // (60 + 50) mod 100 = 10\n}\n\n#[test]\nfn test_add_exact_modulus() {\n let a = 50;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_add_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.add(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_sub_no_underflow() {\n let a = 50;\n let b = 30;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 20);\n}\n\n#[test]\nfn test_sub_with_underflow() {\n let a = 30;\n let b = 50;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_equal_values() {\n let a = 42;\n let b = 42;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_subtract_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.sub(a, b);\n assert(result == 42);\n}\n#[test]\nfn test_mul_mod_small_values() {\n let a = 6;\n let b = 7;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 42);\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n let a = 12;\n let b = 15;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 80); // 12 * 15 = 180, 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_result_zero() {\n let a = 5;\n let b = 20;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0); // 5 * 20 = 100, 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n let a = 42;\n let b = 0;\n let m = ModU128::new(100);\n let result = m.mul_mod(a, b);\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_large_values() {\n let a = 123;\n let b = 456;\n let m = ModU128::new(1000);\n let result = m.mul_mod(a, b);\n assert(result == 88); // 123 * 456 = 56088, 56088 mod 1000 = 88\n}\n\n#[test]\nfn test_neg_non_zero() {\n let val = 30;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_zero() {\n let val = 0;\n let m = ModU128::new(100);\n let result = m.neg(val);\n assert(result == 0); // Negation of 0 is 0, not m\n}\n\n#[test]\nfn test_neg_large_modulus() {\n let val = 12345;\n let m = ModU128::new(1000000);\n let result = m.neg(val);\n assert(result == 987655); // 1000000 - 12345 = 987655\n}\n\n#[test]\nfn test_inv_mod_simple() {\n let val = 3;\n let m = ModU128::new(11);\n let result = m.inv_mod(val);\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n let val = 7;\n let m = ModU128::new(13);\n let result = m.inv_mod(val);\n // Verify: 7 * result = 1 (mod 13)\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_inv_mod_with_result_verification() {\n let val = 5;\n let m = ModU128::new(17);\n let result = m.inv_mod(val);\n // Verify the inverse property\n let product = m.mul_mod(val, result);\n assert(product == 1);\n}\n\n#[test]\nfn test_inv_mod_coprime_values() {\n let val = 9;\n let m = ModU128::new(23);\n let result = m.inv_mod(val);\n assert(m.mul_mod(val, result) == 1);\n}\n\n#[test]\nfn test_div_mod_simple() {\n let a = 6;\n let b = 2;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n assert(result == 3); // 6 / 2 = 3\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n let a = 7;\n let b = 3;\n let m = ModU128::new(11);\n let result = m.div_mod(a, b);\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == a);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a = 10;\n let b = 3;\n let m = ModU128::new(17);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n assert(m.mul_mod(result, b) == m.reduce_mod(a));\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a = 250;\n let b = 7;\n let m = ModU128::new(97);\n let result = m.div_mod(a, b);\n // Verify: result * b = a (mod m)\n let a_reduced = m.reduce_mod(a); // 250 mod 100 = 50\n assert(m.mul_mod(result, b) == a_reduced);\n}\n\n#[test]\nfn test_reduce_mod_function() {\n let m = ModU128::new(7);\n\n // Test reduce_mod directly first\n assert(m.reduce_mod(38) == 3);\n assert(m.reduce_mod(6) == 6);\n assert(m.reduce_mod(7) == 0);\n assert(m.reduce_mod(14) == 0);\n}\n\n#[test]\nfn test_field_properties_additive_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a + 0 = a\n assert(m.add(a, 0) == a);\n}\n\n#[test]\nfn test_field_properties_multiplicative_identity() {\n let a = 42;\n let m = ModU128::new(100);\n // a * 1 = a\n assert(m.mul_mod(a, 1) == a);\n}\n\n#[test]\nfn test_field_properties_additive_inverse() {\n let a = 42;\n let m = ModU128::new(100);\n let neg_a = m.sub(0, a);\n // a + (-a) = 0\n assert(m.add(a, neg_a) == 0);\n}\n\n#[test]\nfn test_field_properties_commutativity_add() {\n let a = 35;\n let b = 47;\n let m = ModU128::new(100);\n // a + b = b + a\n assert(m.add(a, b) == m.add(b, a));\n}\n\n#[test]\nfn test_field_properties_commutativity_mul() {\n let a = 7;\n let b = 9;\n let m = ModU128::new(100);\n // a * b = b * a\n assert(m.mul_mod(a, b) == m.mul_mod(b, a));\n}\n\n#[test]\nfn test_field_properties_associativity_add() {\n let a = 23;\n let b = 34;\n let c = 45;\n let m = ModU128::new(100);\n // (a + b) + c = a + (b + c)\n let left = m.add(m.add(a, b), c);\n let right = m.add(a, m.add(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_associativity_mul() {\n let a = 3;\n let b = 7;\n let c = 11;\n let m = ModU128::new(100);\n // (a * b) * c = a * (b * c)\n let left = m.mul_mod(m.mul_mod(a, b), c);\n let right = m.mul_mod(a, m.mul_mod(b, c));\n assert(left == right);\n}\n\n#[test]\nfn test_field_properties_distributivity() {\n let a = 5;\n let b = 7;\n let c = 9;\n let m = ModU128::new(100);\n // a * (b + c) = (a * b) + (a * c)\n let left = m.mul_mod(a, m.add(b, c));\n let right = m.add(m.mul_mod(a, b), m.mul_mod(a, c));\n assert(left == right);\n}\n#[test]\nfn test_division_multiplication_inverse() {\n let a = 35;\n let b = 7;\n let m = ModU128::new(97);\n let quotient = m.div_mod(a, b);\n let product = m.mul_mod(quotient, b);\n assert(product == m.reduce_mod(a));\n}\n\n#[test]\nfn test_inverse_of_inverse() {\n let a = 7;\n let m = ModU128::new(11);\n // (a^(-1))^(-1) = a\n let inv_a = m.inv_mod(a);\n let inv_inv_a = m.inv_mod(inv_a);\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_operations_with_prime_modulus() {\n let m = ModU128::new(97); // Prime number\n let a = 42;\n let b = 13;\n\n // Test addition\n let sum = m.add(a, b);\n assert(sum == 55); // 42 + 13 = 55\n\n // Test subtraction\n let diff = m.sub(a, b);\n assert(diff == 29); // 42 - 13 = 29\n\n // Test multiplication\n let prod = m.mul_mod(a, b);\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test inverse: b * b^(-1) = 1 (mod m)\n let inv = m.inv_mod(b);\n assert(m.mul_mod(b, inv) == 1);\n\n // Test division: (a / b) * b = a (mod m)\n let quot = m.div_mod(a, b);\n assert(m.mul_mod(quot, b) == a);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/U128.nr" - }, - "79": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Unconstrained functions for modular u128 arithmetic.\n//!\n//! This module provides unconstrained functions that perform modular arithmetic\n//! computations without generating circuit constraints. These functions are used\n//! internally by the constrained operations in `U128` and should not be called\n//! directly in circuits without proper verification.\n\n/// Computes quotient and remainder for value modulo q (unconstrained).\n///\n/// This function performs integer division and modulo operations to compute\n/// `value = q * quotient + remainder` where `0 <= remainder < q`.\n///\n/// # Arguments\n/// * `value` - The value to reduce\n/// * `q` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where:\n/// - `quotient = value / q`\n/// - `remainder = value % q`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __compute_mod_reduction(value: Field, q: Field) -> (Field, Field) {\n let value_u128 = value as u128;\n let q_u128 = q as u128;\n\n let quotient_u128 = value_u128 / q_u128;\n let remainder_u128 = value_u128 % q_u128;\n\n (quotient_u128 as Field, remainder_u128 as Field)\n}\n\n/// Computes the negation of a value modulo m (unconstrained).\n///\n/// Returns `(m - val) mod m`, with special handling for zero (returns 0).\n///\n/// # Arguments\n/// * `val` - The value to negate\n/// * `m` - The modulus\n///\n/// # Returns\n/// The additive inverse `(-val) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __neg(val: Field, m: Field) -> Field {\n if val == 0 {\n 0\n } else {\n m - val\n }\n}\n\n/// Subtracts two values with underflow handling (unconstrained).\n///\n/// Computes `(lhs - rhs) mod m`, handling the case where `lhs < rhs` by adding\n/// the modulus. Returns both the result and a flag indicating if underflow occurred.\n///\n/// # Preconditions\n/// Inputs must be reduced modulo `m` such that `lhs, rhs in [0, m)`. This ensures\n/// that the computed difference is bounded and cannot overflow `u128`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value (minuend), must be in `[0, m)`\n/// * `rhs` - Right-hand side value (subtrahend), must be in `[0, m)`\n/// * `m` - The modulus, must satisfy `m <= u128::MAX`\n///\n/// # Returns\n/// A tuple `(result, underflow)` where:\n/// - `result = (lhs - rhs) mod m`\n/// - `underflow = true` if `lhs < rhs`, `false` otherwise\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// As long as inputs are reduced modulo `m` (and `m <= u128::MAX`), the subtraction-with-underflow\n/// logic is safe and will not overflow `u128`. This function is used by the constrained `sub` method\n/// in `modulo::U128`, which ensures inputs are properly reduced before calling `__sub_with_underflow`.\n/// See the surrounding `modulo/unconstrained_U128` module documentation for details.\npub unconstrained fn __sub_with_underflow(lhs: Field, rhs: Field, m: Field) -> (Field, bool) {\n let lhs_u128 = lhs as u128;\n let rhs_u128 = rhs as u128;\n let m_u128 = m as u128;\n\n let underflow = lhs_u128 < rhs_u128;\n let result = if underflow {\n // Compute (lhs - rhs + m) mod m safely to avoid u128 overflow\n // Since lhs < rhs, we compute: m - (rhs - lhs)\n // This avoids the potential overflow in lhs + m\n let diff = rhs_u128 - lhs_u128; // This is safe since rhs > lhs\n (m_u128 - diff) as Field\n } else {\n (lhs_u128 - rhs_u128) as Field\n };\n (result, underflow)\n}\n\n/// Multiplies two values and returns both quotient and remainder (unconstrained).\n///\n/// Computes `lhs * rhs = m * quotient + remainder` where `0 <= remainder < m`.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// A tuple `(quotient, remainder)` where `lhs * rhs = m * quotient + remainder`\n///\n/// # Overflow Warning\n/// Field multiplication wraps modulo the field prime (~254 bits). For two u128 values\n/// near 2^128, their product (up to 2^256) exceeds the Field modulus, causing silent\n/// wraparound before the mod reduction. This can produce incorrect results.\n///\n/// # Safe Input Range\n/// To avoid overflow, ensure `lhs * rhs < Field::MODULUS`. For typical use cases:\n/// - Party IDs, polynomial coefficients, and small cryptographic values (< 2^64) are safe\n/// - Arbitrary u128 values may overflow and should be validated by callers\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\n/// Callers must ensure inputs are within the safe range to prevent silent overflow.\npub unconstrained fn __mul_with_quotient(lhs: Field, rhs: Field, m: Field) -> (Field, Field) {\n // WARNING: Field multiplication can overflow for large inputs.\n // For u128 values near 2^128, the product (up to 2^256) exceeds Field modulus (~2^254),\n // causing wraparound. This is safe for typical use cases (party IDs, small coefficients),\n // but callers must validate input ranges for arbitrary u128 values.\n let product = lhs * rhs;\n __compute_mod_reduction(product, m)\n}\n\n/// Computes the modular multiplicative inverse using Fermat's Little Theorem (unconstrained).\n///\n/// For a prime modulus `m` and value `val` coprime to `m`, computes `val^(-1) mod m`\n/// using the identity: val^(-1) = val^(m-2) (mod m) (from Fermat's Little Theorem).\n///\n/// # Arguments\n/// * `val` - The value to invert (must be coprime with the modulus)\n/// * `m` - The modulus (should be prime for this method to work correctly)\n///\n/// # Returns\n/// The modular inverse `val^(-1) mod m` such that `(val * result) mod m = 1`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __inv_mod(val: Field, m: Field) -> Field {\n // by Fermat's Little Theorem: val^(m-1)= 1 mod m\n __pow_mod(val, m - 2, m)\n}\n\n/// Computes modular division: `lhs * rhs^(-1) mod m` (unconstrained).\n///\n/// This is equivalent to multiplying `lhs` by the modular inverse of `rhs`.\n///\n/// # Arguments\n/// * `lhs` - The numerator\n/// * `rhs` - The denominator (must be coprime with the modulus)\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs^(-1)) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __div_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let rhs_inv = __inv_mod(rhs, m);\n __mul_mod(lhs, rhs_inv, m)\n}\n\n/// Computes modular exponentiation: `base^exp mod m` (unconstrained).\n///\n/// Uses the binary exponentiation method (also known as square-and-multiply)\n/// for efficient computation of large powers.\n///\n/// # Arguments\n/// * `base` - The base value\n/// * `exp` - The exponent\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `base^exp mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __pow_mod(base: Field, exp: Field, m: Field) -> Field {\n let mut result = 1 as Field;\n let (_, base_mod) = __compute_mod_reduction(base, m);\n let mut current_base = base_mod;\n let mut e = exp as u128;\n\n while e > 0 {\n if (e % 2) == 1 {\n result = __mul_mod(result, current_base, m);\n }\n current_base = __mul_mod(current_base, current_base, m);\n e = e / 2;\n }\n\n result\n}\n\n/// Multiplies two values with modular reduction (unconstrained).\n///\n/// Computes `(lhs * rhs) mod m` and returns only the remainder.\n///\n/// # Arguments\n/// * `lhs` - Left-hand side value\n/// * `rhs` - Right-hand side value\n/// * `m` - The modulus\n///\n/// # Returns\n/// The result of `(lhs * rhs) mod m`\n///\n/// # Safety\n/// This is an unconstrained function. The result must be verified in constrained code.\npub unconstrained fn __mul_mod(lhs: Field, rhs: Field, m: Field) -> Field {\n let (_, r) = __mul_with_quotient(lhs, rhs, m);\n r\n}\n\n// ------------------------------ TESTS ------------------------------\n// Note: All unsafe blocks in the following tests are safe because we are testing\n// unconstrained functions in a controlled test environment. These functions are\n// designed to be called from unsafe blocks or other unconstrained functions.\n// Each unsafe block is used to call an unconstrained function for testing purposes.\n\n#[test]\nfn test_compute_mod_reduction_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(42, 10) };\n assert(q == 4); // 42 / 10 = 4\n assert(r == 2); // 42 % 10 = 2\n // Verify: 42 = 10 * 4 + 2\n assert(10 * q + r == 42);\n}\n\n#[test]\nfn test_compute_mod_reduction_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(100, 10) };\n assert(q == 10); // 100 / 10 = 10\n assert(r == 0); // 100 % 10 = 0\n assert(10 * q + r == 100);\n}\n\n#[test]\nfn test_compute_mod_reduction_large_value() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(12345, 100) };\n assert(q == 123); // 12345 / 100 = 123\n assert(r == 45); // 12345 % 100 = 45\n assert(100 * q + r == 12345);\n}\n\n#[test]\nfn test_compute_mod_reduction_smaller_than_modulus() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __compute_mod_reduction(7, 10) };\n assert(q == 0); // 7 / 10 = 0\n assert(r == 7); // 7 % 10 = 7\n assert(10 * q + r == 7);\n}\n\n#[test]\nfn test_neg_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(0, 100) };\n assert(result == 0); // Negation of zero is zero\n}\n\n#[test]\nfn test_neg_non_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(30, 100) };\n assert(result == 70); // 100 - 30 = 70\n}\n\n#[test]\nfn test_neg_large_value() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __neg(12345, 100000) };\n assert(result == 87655); // 100000 - 12345 = 87655\n}\n\n#[test]\nfn test_neg_verification() {\n let val: Field = 42;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let neg_val = unsafe { __neg(val, m) };\n // Verify: val + neg_val = 0 (mod m)\n let sum = val + neg_val;\n // Safety: Test function calling unconstrained helper\n let (_, remainder) = unsafe { __compute_mod_reduction(sum, m) };\n assert(remainder == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_no_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(50, 30, 100) };\n assert(underflow == false);\n assert(result == 20); // 50 - 30 = 20\n}\n\n#[test]\nfn test_sub_with_underflow_with_underflow() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(30, 50, 100) };\n assert(underflow == true);\n assert(result == 80); // (30 - 50 + 100) mod 100 = 80\n}\n\n#[test]\nfn test_sub_with_underflow_equal_values() {\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(42, 42, 100) };\n assert(underflow == false);\n assert(result == 0);\n}\n\n#[test]\nfn test_sub_with_underflow_verification() {\n let lhs: Field = 30;\n let rhs: Field = 50;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let (result, underflow) = unsafe { __sub_with_underflow(lhs, rhs, m) };\n\n if underflow {\n // Verify: lhs + m = rhs + result\n assert(lhs + m == rhs + result);\n } else {\n // Verify: lhs = rhs + result\n assert(lhs == rhs + result);\n }\n}\n\n#[test]\nfn test_mul_with_quotient_simple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(6, 7, 10) };\n assert(q == 4); // (6 * 7) / 10 = 42 / 10 = 4\n assert(r == 2); // (6 * 7) % 10 = 42 % 10 = 2\n // Verify: 6 * 7 = 10 * 4 + 2\n assert(6 * 7 == 10 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(12, 15, 100) };\n assert(q == 1); // (12 * 15) / 100 = 180 / 100 = 1\n assert(r == 80); // (12 * 15) % 100 = 180 % 100 = 80\n assert(12 * 15 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(5, 20, 100) };\n assert(q == 1); // (5 * 20) / 100 = 100 / 100 = 1\n assert(r == 0); // (5 * 20) % 100 = 100 % 100 = 0\n assert(5 * 20 == 100 * q + r);\n}\n\n#[test]\nfn test_mul_with_quotient_verification() {\n let lhs: Field = 123;\n let rhs: Field = 456;\n let m: Field = 1000;\n // Safety: Test function calling unconstrained helper\n let (q, r) = unsafe { __mul_with_quotient(lhs, rhs, m) };\n // Verify: lhs * rhs = m * q + r\n assert(lhs * rhs == m * q + r);\n // Verify remainder is in range [0, m)\n assert((r as u128) < (m as u128));\n}\n\n#[test]\nfn test_mul_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(6, 7, 10) };\n assert(result == 2); // (6 * 7) mod 10 = 42 mod 10 = 2\n}\n\n#[test]\nfn test_mul_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(12, 15, 100) };\n assert(result == 80); // (12 * 15) mod 100 = 180 mod 100 = 80\n}\n\n#[test]\nfn test_mul_mod_exact_multiple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(5, 20, 100) };\n assert(result == 0); // (5 * 20) mod 100 = 100 mod 100 = 0\n}\n\n#[test]\nfn test_mul_mod_with_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __mul_mod(42, 0, 100) };\n assert(result == 0);\n}\n\n#[test]\nfn test_mul_mod_commutative() {\n let a: Field = 7;\n let b: Field = 9;\n let m: Field = 100;\n // Safety: Test function calling unconstrained helper\n let mul_a_b = unsafe { __mul_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n let mul_b_a = unsafe { __mul_mod(b, a, m) };\n // Verify: a * b = b * a\n assert(mul_a_b == mul_b_a);\n}\n\n#[test]\nfn test_pow_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 3, 10) };\n assert(result == 8); // 2^3 mod 10 = 8 mod 10 = 8\n}\n\n#[test]\nfn test_pow_mod_with_reduction() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(2, 10, 100) };\n assert(result == 24); // 2^10 = 1024, 1024 mod 100 = 24\n}\n\n#[test]\nfn test_pow_mod_exponent_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 1, 100) };\n assert(result == 7); // 7^1 mod 100 = 7\n}\n\n#[test]\nfn test_pow_mod_exponent_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(7, 0, 100) };\n assert(result == 1); // 7^0 mod 100 = 1\n}\n\n#[test]\nfn test_pow_mod_base_zero() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(0, 5, 100) };\n assert(result == 0); // 0^5 mod 100 = 0\n}\n\n#[test]\nfn test_pow_mod_large_exponent() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(3, 7, 97) };\n // 3^7 = 2187, 2187 mod 97 = 53\n assert(result == 53);\n}\n\n#[test]\nfn test_pow_mod_fermat_little_theorem() {\n // For prime modulus p and value a, a^(p-1) = 1 (mod p)\n let a: Field = 3;\n let p: Field = 11; // Prime\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __pow_mod(a, p - 1, p) };\n assert(result == 1);\n}\n\n#[test]\nfn test_inv_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(3, 11) };\n // 3 * 4 = 12 = 1 (mod 11), so 3^(-1) = 4 (mod 11)\n assert(result == 4);\n // Verify: 3 * result = 1 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(3, result, 11) } == 1);\n}\n\n#[test]\nfn test_inv_mod_larger_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(7, 13) };\n // Verify: 7 * result = 1 (mod 13)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(7, result, 13) } == 1);\n}\n\n#[test]\nfn test_inv_mod_another_prime() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __inv_mod(5, 17) };\n // Verify: 5 * result = 1 (mod 17)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(5, result, 17) } == 1);\n}\n\n#[test]\nfn test_inv_mod_inverse_of_inverse() {\n let a: Field = 7;\n let m: Field = 11;\n // Safety: Test function calling unconstrained helper\n let inv_a = unsafe { __inv_mod(a, m) };\n // Safety: Test function calling unconstrained helper\n let inv_inv_a = unsafe { __inv_mod(inv_a, m) };\n // (a^(-1))^(-1) = a\n assert(inv_inv_a == a);\n}\n\n#[test]\nfn test_div_mod_simple() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(6, 2, 11) };\n assert(result == 3); // 6 / 2 = 3\n // Verify: result * 2 = 6 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 2, 11) } == 6);\n}\n\n#[test]\nfn test_div_mod_with_inverse() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(7, 3, 11) };\n // 3^(-1) mod 11 = 4 (since 3 * 4 = 12 = 1 mod 11)\n // 7 * 4 = 28 = 6 (mod 11)\n assert(result == 6);\n // Verify: result * 3 = 7 (mod 11)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 3, 11) } == 7);\n}\n\n#[test]\nfn test_div_mod_verification() {\n let a: Field = 10;\n let b: Field = 3;\n let m: Field = 17;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a);\n}\n\n#[test]\nfn test_div_mod_larger_values() {\n let a: Field = 250;\n let b: Field = 7;\n let m: Field = 97;\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(a, b, m) };\n // Verify: result * b = a (mod m)\n // Safety: Test function calling unconstrained helper\n let (_, a_reduced) = unsafe { __compute_mod_reduction(a, m) }; // 250 mod 97 = 56\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, b, m) } == a_reduced);\n}\n\n#[test]\nfn test_div_mod_by_one() {\n // Safety: Test function calling unconstrained helper\n let result = unsafe { __div_mod(42, 1, 100) };\n assert(result == 42); // 42 / 1 = 42\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(result, 1, 100) } == 42);\n}\n\n#[test]\nfn test_all_operations_consistency() {\n // Test that all operations work together correctly\n let m: Field = 97; // Prime\n let a: Field = 42;\n let b: Field = 13;\n\n // Test: (a + b) mod m\n let sum = a + b;\n // Safety: Test function calling unconstrained helper\n let (_, sum_reduced) = unsafe { __compute_mod_reduction(sum, m) };\n assert(sum_reduced == 55);\n\n // Test: (a - b) mod m using subtraction\n // Safety: Test function calling unconstrained helper\n let (diff, _) = unsafe { __sub_with_underflow(a, b, m) };\n assert(diff == 29);\n\n // Test: (a * b) mod m\n // Safety: Test function calling unconstrained helper\n let prod = unsafe { __mul_mod(a, b, m) };\n assert(prod == 61); // (42 * 13) mod 97 = 546 mod 97 = 61\n\n // Test: b^(-1) mod m\n // Safety: Test function calling unconstrained helper\n let inv = unsafe { __inv_mod(b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(b, inv, m) } == 1);\n\n // Test: (a / b) mod m\n // Safety: Test function calling unconstrained helper\n let quot = unsafe { __div_mod(a, b, m) };\n // Safety: Test function calling unconstrained helper\n assert(unsafe { __mul_mod(quot, b, m) } == a);\n\n // Test: (-a) mod m\n // Safety: Test function calling unconstrained helper\n let neg = unsafe { __neg(a, m) };\n let sum_neg = a + neg;\n // Safety: Test function calling unconstrained helper\n let (_, sum_neg_reduced) = unsafe { __compute_mod_reduction(sum_neg, m) };\n assert(sum_neg_reduced == 0);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/modulo/unconstrained_U128.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/sk_share_computation.vk b/crates/zk-prover/tests/fixtures/sk_share_computation.vk deleted file mode 100644 index 56f249009a6465135172f73f87432d86ef724d1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajgXCoU30D$2HMG`ww93{kFp{K5mB6eb=_AFZEtZKCc(N>6}_Glr?H zS4YsCz4xpYd%L6I{=xPA`uuRdVVle5@gF-D`n`58C8j=c ztCh!%-Wl>QpWk-rKO<_RCk3#OSa|@nopb-f1VwawEo5!OEZJI)op!Q)7CEaVRngMd z!`zp$gA;Ot?9Ci{;T;J~%ZPEUmc)Jm?!UO&qCoDd*Rvr_?WOG85LBBXJeSqw@)sF* zr~V2*f3J^0gHm_z3PdR4R!s#7@L5|kfP}9s_~YI?6Q|>b;==SAHop_Z@9#8pF#{L+ z3qB;jljNb`6_WUkE<%&N`^w-5u-cxF1M zje2IC3Thdof*-cLy~l^N6M8jD9#ekOlBu9qvI(wTd!Ho!1kmXA)R)0fg;SvwavYil zt0geMr$N#EaXMiWlw=p9^}$d{)`q5d>?Ot&Z>nb;RF`wa3)^9eYC&k3&AZm1L3xZ| zj29WVt3v}3QVC2O`854$J#ow-o@_zS`A_>EK}PcaKkyP&R=ANkhUUyOEBcg z!4XzOl+vu7IcT)Xo3H*l0JgIpeR}T1&cHaFM(q&^eqATWZcu-R6w`?gaxnfuiVho5 z_O-AWn_b>^-uE(aF>@R-OR*)Zna>cI`c29a+c!Nu=?M5T5iCodL7Q?Jm<^dz*Q#!M z7c;Z1U$7<_nrgINPC$Z1TL?QV)M&6|nw3ZMK^B??BN1P)G5k-%4%jj?{9BGlOD27sf_$J|U>sVtQefgN8{grL}6o{o2 zQD#*;ULJW8V$Kx}PLX39nxvCGnIhb*UThhHrIf z{M^^$ukZhcnsG#dU0(Q;#9A= z+Ao@n22P$(hP4;6Lh}HxP@#gO!yk6y!iK*AC>%mgU%!6f6DVh&>H6lvrZ(Yi7nbs= zV(_8$g`P94u@xvry>FANBwbHQ4o&RA1&ZL>XBKI{rViZho6ZVJA;4>rDN<9O(Xdq3 zC-iTG9ebr3&8ZUeQE1Wpx<>y-o6FbpNnz;FE!AzYsc$r-s@bN^HJdy*bxqr z2f#iL+PH@;c5miQ50G7?m8htDL{~56tH%8Cypqa9@l3o(7KEak+#->k4N{g-c@e`s zEjLhM!UwTv6>5vp@JP)1h}oW!Sz%^zMLx$!8+2|g!2yLMDP5u0rGmtuj!`<9w_|{) zNf;uqr0+dYum+8WsQmrQ;zw?eEc0+6W>7A%L5ersG?eOOJUhv{_xE~+g%K_^{S|aJ zrEQEums1A{o}+~rQce0{u8La&rAzmp^X8NF=S*xRynE$gGIZ{j8r}gHIU#q+QQq5Pd;?Zq}FV9s$F&r3JbxpP>vLP`>yn6?l-%zE1 k#A&}8JU92RV?d=&ndQez(SajcP^^`1C38V6951J diff --git a/crates/zk-prover/tests/fixtures/user_data_encryption.json b/crates/zk-prover/tests/fixtures/user_data_encryption.json deleted file mode 100644 index cc8b03d011..0000000000 --- a/crates/zk-prover/tests/fixtures/user_data_encryption.json +++ /dev/null @@ -1,214 +0,0 @@ -{ - "noir_version": "1.0.0-beta.15+83245db91dcf63420ef4bcbbd85b98f397fee663", - "hash": "9408608105749895694", - "abi": { - "parameters": [ - { "name": "pk_commitment", "type": { "kind": "field" }, "visibility": "public" }, - { - "name": "pk0is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "pk1is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "ct0is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "ct1is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "u", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "e0", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "e1", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "e0is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "e0_quotients", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "k1", - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 512, "type": { "kind": "field" } } }] - }, - "visibility": "private" - }, - { - "name": "r1is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 1023, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "r2is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 511, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "p1is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 1023, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - }, - { - "name": "p2is", - "type": { - "kind": "array", - "length": 2, - "type": { - "kind": "struct", - "path": "lib::math::polynomial::Polynomial", - "fields": [{ "name": "coefficients", "type": { "kind": "array", "length": 511, "type": { "kind": "field" } } }] - } - }, - "visibility": "private" - } - ], - "return_type": null, - "error_types": { "12469291177396340830": { "error_kind": "string", "string": "call to assert_max_bit_size" } } - }, - "bytecode": "H4sIAAAAAAAA/6zQZdSW9R+1eenu7u7uhpPu7u7u7u7u7u6WEhEREREREREREREREBEQEekZ1zxrzT1rXtz/fVz7eiGuxT75/o5PhPf+n1/k//Nn7/bd+9y89t57KW689//7Rfw/f6Z/73/6RYgQ///d5u9UZ8CtAutyHK1X+fD48c1aZy90r9rwY/3mV7z1bOHj//vvXxQT/t3/+z+R/vuf//NdxHDeqdwOb/vyf39nxLDvfPk/vDOcX4SIgucr6PnK4PlK8HwNPV8bPCMJnm+g5xuD5xvB8y30fGvwjCx4voOe7wye7wTP94ozz/++C9UziuAZoTjzjFA8dM+wt8PbRoSeEQ2eUQXPSNAzksEzkuAZGXpGNnhGEzyjQM8oBs8ogmdU6BnV4Bld8IwGPaMZPKMJntGhZ3SDZwzBMwb0jGHwjCF4xoSeMQ2eMQXPWNAzlsEzluAZG3rGNnjGEjzjQM84Bs84gmdc6BnX4Blb8IwHPeMZPOMJnvGhZ3yDZxzBMwH0TGDwTCB4JoSeCQ2ecQXPRNAzkcEzkeCZGHomNnjGEzyTQM8kBs8kgmdS6JnU4Blf8EwGPZMZPJMJnsmhZ3KDZwLBMwX0TGHwTCF4poSeKQ2eCQXPVNAzlcEzleCZGnqmNngmEjzTQM80Bs80gmda6JnW4JlY8EwHPdMZPNMJnumhZ3qDZxLBMwP0zGDwzCB4ZoSeGQ2eSQXPTNAzk8Ezk+CZGXpmNngmEzyzQM8sBs8sgmdW6JnV4Jlc8MwGPbMZPLMJntmhZ3aDZwrBMwf0zGHwzCF45oSeOQ2eKQXPXNAzl8Ezl+CZG3rmNnimEjzzQM88Bs88gmde6JnX4Jla8MwHPfMZPPMJnvmhZ36DZxrBswD0LGDwLCB4FoSeBQ2eaQXPQtCzkMGzkOBZGHoWNnimEzyLQM8iBs8igmdR6FnU4Jle8CwGPYsZPIsJnsWhZ3GDZwbBswT0LGHwLCF4loSeJQ2eGQXPUtCzlMGzlOBZGnqWNnhmEjzLQM8yBs8ygmdZ6FnW4JlZ8CwHPcsZPMsJngH0DAyeWQTP8tCzvMGzvOBZAXpWMHhmFTwrQs+KBs+Kgmcl6FnJ4JlN8KwMPSsbPCsLnlWgZxWDZ3bBsyr0rGrwrCp4VoOe1QyeOQTP6tCzusGzuuBZA3rWMHjmFDxrQs+aBs+agmct6FnL4JlL8KwNPWsbPGsLnnWgZx2DZ27Bsy70rGvwrCt41oOe9QyeeQTP+tCzvsGzvuDZAHo2MHjmFTwbQs+GBs+Ggmcj6NnI4JlP8GwMPRsbPBsLnk2gZxODZ37Bsyn0bGrwbCp4NoOezQyeBQTP5tCzucGzueDZAnq2MHgWFDxbQs+WBs+Wgmcr6NnK4FlI8GwNPVsbPFsLnm2gZxuDZ2HBsy30bGvwbCt4toOe7QyeRQTP9tCzvcGzveDZAXp2MHgWFTw7Qs+OBs+Ogmcn6NnJ4FlM8OwMPTsbPDsLnl2gZxeDZ3HBsyv07Grw7Cp4doOe3QyeJQTP7tCzu8Gzu+DZA3r2MHiWFDx7Qs+eBs+egmcv6NnL4FlK8OwNPXsbPHsLnn2gZx+DZ2nBsy/07Gvw7Ct49oOe/QyeZQTP/tCzv8Gzv+A5AHoOMHiWFTwHQs+BBs+Bgucg6DnI4FlO8BwMPQcbPAcLnkOg5xCDZyB4DoWeQw2eQwXPYdBzmMGzvOA5HHoON3gOFzxHQM8RBs8KgudI6DnS4DlS8BwFPUcZPCsKnqOh52iD52jBcwz0HGPwrCR4joWeYw2eYwXPcdBznMGzsuA5HnqON3iOFzwnQM8JBs8qgudE6DnR4DlR8JwEPScZPKsKnpOh52SD52TBcwr0nGLwrCZ4ToWeUw2eUwXPadBzmsGzuuA5HXpON3hOFzxnQM8ZBs8agudM6DnT4DlT8JwFPWcZPGsKnrOh52yD52zBcw70nGPwrCV4zoWecw2ecwXPedBznsGztuA5H3rON3jOFzwXQM8FBs86gudC6LnQ4LlQ8FwEPRcZPOsKnouh52KD52LBcwn0XGLwrCd4LoWeSw2eSwXPZdBzmcGzvuC5HHouN3guFzxXQM8VBs8GgudK6LnS4LlS8FwFPVcZPBsKnquh52qD52rBcw30XGPwbCR4roWeaw2eawXPddBzncGzseC5HnquN3iuFzw3QM8NBs8mgudG6LnR4LlR8NwEPTcZPJsKnpuh52aD52bBcwv03GLwbCZ4boWeWw2eWwXPbdBzm8GzueC5HXpuN3huFzx3QM8dBs8WgudO6LnT4LlT8NwFPXcZPFsKnruh526D527Bcw/03GPwbCV47oWeew2eewXPfdBzn8GzteC5H3ruN3juFzwPQM8DBs82gudB6HnQ4HlQ8Hwfer5v8GwreB6CnocMnocEz8PQ87DBs53geQR6HjF4HhE8j0LPowbP9oLnMeh5zOB5TPD8AHp+YPDsIHgeh57HDZ7HBc8PoeeHBs+OgucJ6HnC4HlC8PwIen5k8OwkeJ6EnicNnicFz4+h58cGz86C5ynoecrgeUrw/AR6fmLw7CJ4noaepw2epwXPT6HnpwbProLnGeh5xuB5RvD8DHp+ZvDsJniehZ5nDZ5nBc/PoefnBs/uguc56HnO4HlO8PwCen5h8OwheJ6HnucNnucFzy+h55cGz56C5wXoecHgeUHw/Ap6fmXw7CV4XoSeFw2eFwXPr6Hn1wbP3oLnJeh5yeB5SfD8Bnp+Y/DsI3hehp6XDZ6XBc9voee3Bs++gucV6HnF4HlF8PwOen5n8OwneF6FnlcNnlcFz++h5/cGz/6C5zXoec3geU3w/AF6/mDwHCB4Xoee1w2e1wXPH6HnjwbPgYLnDeh5w+B5Q/D8CXr+ZPAcJHjehJ43DZ43Bc+foefPBs/Bguct6HnL4HlL8PwFev5i8BwieN6GnrcNnrcFz1+h568Gz6GC5x3oecfgeUfw/A16/mbwHCZ43oWedw2edwXPe9DznsFzuOB5H3reN3jeFzx/h56/GzxHCJ4PoOcDg+cDwfMP6PmHwXOk4PkQej40eD4UPP+Enn8aPEcJno+g5yOD5yPB8zH0fGzwHC14PoGeTwyeTwTPv6DnXwbPMYLnU+j51OD5VPD8G3r+bfAcK3g+g57PDJ7PBM9/oOc/Bs9xgudz6Pnc4Plc8PwXev5r8BwveL6Ani8Mni8Ez5fQ86XBc4Lg+Qp6vjJ4vhI8X0PP1wbPiYLnG+j5xuD5RvB8Cz3fGjwnCZ7voOc7g+c7wfO9Eszzv+9C9ZwseEYowTwjlAjdM+zt8LYRoWdEg+cUwTMS9Ixk8IwkeEaGnpENnlMFzyjQM4rBM4rgGRV6RjV4ThM8o0HPaAbPaIJndOgZ3eA5XfCMAT1jGDxjCJ4xoWdMg+cMwTMW9Ixl8IwleMaGnrENnjMFzzjQM47BM47gGRd6xjV4zhI840HPeAbPeIJnfOgZ3+A5W/BMAD0TGDwTCJ4JoWdCg+ccwTMR9Exk8EwkeCaGnokNnnMFzyTQM4nBM4ngmRR6JjV4zhM8k0HPZAbPZIJncuiZ3OA5X/BMAT1TGDxTCJ4poWdKg+cCwTMV9Exl8EwleKaGnqkNngsFzzTQM43BM43gmRZ6pjV4LhI800HPdAbPdIJneuiZ3uC5WPDMAD0zGDwzCJ4ZoWdGg+cSwTMT9Mxk8MwkeGaGnpkNnksFzyzQM4vBM4vgmRV6ZjV4LhM8s0HPbAbPbIJnduiZ3eC5XPDMAT1zGDxzCJ45oWdOg+cKwTMX9Mxl8MwleOaGnrkNnisFzzzQM4/BM4/gmRd65jV4rhI880HPfAbPfIJnfuiZ3+C5WvAsAD0LGDwLCJ4FoWdBg+cawbMQ9Cxk8CwkeBaGnoUNnmsFzyLQs4jBs4jgWRR6FjV4rhM8i0HPYgbPYoJncehZ3OC5XvAsAT1LGDxLCJ4loWdJg+cGwbMU9Cxl8CwleJaGnqUNnhsFzzLQs4zBs4zgWRZ6ljV4bhI8y0HPcgbPcoJnAD0Dg+dmwbM89Cxv8CwveFaAnhUMnlsEz4rQs6LBs6LgWQl6VjJ4bhU8K0PPygbPyoJnFehZxeC5TfCsCj2rGjyrCp7VoGc1g+d2wbM69Kxu8KwueNaAnjUMnjsEz5rQs6bBs6bgWQt61jJ47hQ8a0PP2gbP2oJnHehZx+C5S/CsCz3rGjzrCp71oGc9g+duwbM+9Kxv8KwveDaAng0MnnsEz4bQs6HBs6Hg2Qh6NjJ47hU8G0PPxgbPxoJnE+jZxOC5T/BsCj2bGjybCp7NoGczg+d+wbM59Gxu8GwueLaAni0MngcEz5bQs6XBs6Xg2Qp6tjJ4HhQ8W0PP1gbP1oJnG+jZxuD5vuDZFnq2NXi2FTzbQc92Bs9Dgmd76Nne4Nle8OwAPTsYPA8Lnh2hZ0eDZ0fBsxP07GTwPCJ4doaenQ2enQXPLtCzi8HzqODZFXp2NXh2FTy7Qc9uBs9jgmd36Nnd4Nld8OwBPXsYPD8QPHtCz54Gz56CZy/o2cvgeVzw7A09exs8ewuefaBnH4Pnh4JnX+jZ1+DZV/DsBz37GTxPCJ79oWd/g2d/wXMA9Bxg8PxI8BwIPQcaPAcKnoOg5yCD50nBczD0HGzwHCx4DoGeQwyeHwueQ6HnUIPnUMFzGPQcZvA8JXgOh57DDZ7DBc8R0HOEwfMTwXMk9Bxp8BwpeI6CnqMMnqcFz9HQc7TBc7TgOQZ6jjF4fip4joWeYw2eYwXPcdBznMHzjOA5HnqON3iOFzwnQM8JBs/PBM+J0HOiwXOi4DkJek4yeJ4VPCdDz8kGz8mC5xToOcXg+bngORV6TjV4ThU8p0HPaQbPc4LndOg53eA5XfCcAT1nGDy/EDxnQs+ZBs+Zgucs6DnL4Hle8JwNPWcbPGcLnnOg5xyD55eC51zoOdfgOVfwnAc95xk8Lwie86HnfIPnfMFzAfRcYPD8SvBcCD0XGjwXCp6LoOcig+dFwXMx9Fxs8FwseC6BnksMnl8Lnkuh51KD51LBcxn0XGbwvCR4Loeeyw2eywXPFdBzhcHzG8FzJfRcafBcKXiugp6rDJ6XBc/V0HO1wXO14LkGeq4xeH4reK6FnmsNnmsFz3XQc53B84rguR56rjd4rhc8N0DPDQbP7wTPjdBzo8Fzo+C5CXpuMnheFTw3Q8/NBs/NgucW6LnF4Pm94LkVem41eG4VPLdBz20Gz2uC53boud3guV3w3AE9dxg8fxA8d0LPnQbPnYLnLui5y+B5XfDcDT13Gzx3C557oOceg+ePgude6LnX4LlX8NwHPfcZPG8Invuh536D537B8wD0PGDw/EnwPAg9Dxo8Dwqe70PP9w2eNwXPQ9DzkMHzkOB5GHoeNnj+LHgegZ5HDJ5HBM+j0POowfOW4HkMeh4zeB4TPD+Anh8YPH8RPI9Dz+MGz+OC54fQ80OD523B8wT0PGHwPCF4fgQ9PzJ4/ip4noSeJw2eJwXPj6HnxwbPO4LnKeh5yuB5SvD8BHp+YvD8TfA8DT1PGzxPC56fQs9PDZ53Bc8z0POMwfOM4PkZ9PzM4HlP8DwLPc8aPM8Knp9Dz88NnvcFz3PQ85zB85zg+QX0/MLg+bvgeR56njd4nhc8v4SeXxo8HwieF6DnBYPnBcHzK+j5lcHzD8HzIvS8aPC8KHh+DT2/Nng+FDwvQc9LBs9Lguc30PMbg+efgudl6HnZ4HlZ8PwWen5r8HwkeF6BnlcMnlcEz++g53cGz8eC51XoedXgeVXw/B56fm/wfCJ4XoOe1wye1wTPH6DnDwbPvwTP69DzusHzuuD5I/T80eD5VPC8AT1vGDxvCJ4/Qc+fDJ5/C543oedNg+dNwfNn6PmzwfOZ4HkLet4yeN4SPH+Bnr8YPP8RPG9Dz9sGz9uC56/Q81eD53PB8w70vGPwvCN4/gY9fzN4/it43oWedw2edwXPe9DznsHzheB5H3reN3jeFzx/h56/GzxfCp4PoOcDg+cDwfMP6PmHwfOV4PkQej40eD4UPP+Enn8aPF8Lno+g5yOD5yPB8zH0fGzwfCN4PoGeTwyeTwTPv6DnXwbPt4LnU+j51OD5VPD8G3r+bfB8J3g+g57PDJ7PBM9/oOc/Bs/3Evzv73wOPZ8bPJ8Lnv9Cz38NnhEEzxfQ84XB84Xg+RJ6vjR4RhQ8X0HPVwbPV4Lna+j52uAZSfB8Az3fGDzfCJ5voedbg2dkwfMd9Hxn8HwneL5Xknn+912onlEEzwglmWeEkqF7hr0d3jYi9Ixo8IwqeEaCnpEMnpEEz8jQM7LBM5rgGQV6RjF4RhE8o0LPqAbP6IJnNOgZzeAZTfCMDj2jGzxjCJ4xoGcMg2cMwTMm9Ixp8IwpeMaCnrEMnrEEz9jQM7bBM5bgGQd6xjF4xhE840LPuAbP2IJnPOgZz+AZT/CMDz3jGzzjCJ4JoGcCg2cCwTMh9Exo8IwreCaCnokMnokEz8TQM7HBM57gmQR6JjF4JhE8k0LPpAbP+IJnMuiZzOCZTPBMDj2TGzwTCJ4poGcKg2cKwTMl9Exp8EwoeKaCnqkMnqkEz9TQM7XBM5HgmQZ6pjF4phE800LPtAbPxIJnOuiZzuCZTvBMDz3TGzyTCJ4ZoGcGg2cGwTMj9Mxo8EwqeGaCnpkMnpkEz8zQM7PBM5ngmQV6ZjF4ZhE8s0LPrAbP5IJnNuiZzeCZTfDMDj2zGzxTCJ45oGcOg2cOwTMn9Mxp8EwpeOaCnrkMnrkEz9zQM7fBM5XgmQd65jF45hE880LPvAbP1IJnPuiZz+CZT/DMDz3zGzzTCJ4FoGcBg2cBwbMg9Cxo8EwreBaCnoUMnoUEz8LQs7DBM53gWQR6FjF4FhE8i0LPogbP9IJnMehZzOBZTPAsDj2LGzwzCJ4loGcJg2cJwbMk9Cxp8MwoeJaCnqUMnqUEz9LQs7TBM5PgWQZ6ljF4lhE8y0LPsgbPzIJnOehZzuBZTvAMoGdg8MwieJaHnuUNnuUFzwrQs4LBM6vgWRF6VjR4VhQ8K0HPSgbPbIJnZehZ2eBZWfCsAj2rGDyzC55VoWdVg2dVwbMa9Kxm8MwheFaHntUNntUFzxrQs4bBM6fgWRN61jR41hQ8a0HPWgbPXIJnbehZ2+BZW/CsAz3rGDxzC551oWddg2ddwbMe9Kxn8MwjeNaHnvUNnvUFzwbQs4HBM6/g2RB6NjR4NhQ8G0HPRgbPfIJnY+jZ2ODZWPBsAj2bGDzzC55NoWdTg2dTwbMZ9Gxm8CwgeDaHns0Nns0FzxbQs4XBs6Dg2RJ6tjR4thQ8W0HPVgbPQoJna+jZ2uDZWvBsAz3bGDwLC55toWdbg2dbwbMd9Gxn8CwieLaHnu0Nnu0Fzw7Qs4PBs6jg2RF6djR4dhQ8O0HPTgbPYoJnZ+jZ2eDZWfDsAj27GDyLC55doWdXg2dXwbMb9Oxm8CwheHaHnt0Nnt0Fzx7Qs4fBs6Tg2RN69jR49hQ8e0HPXgbPUoJnb+jZ2+DZW/DsAz37GDxLC559oWdfg2dfwbMf9Oxn8CwjePaHnv0Nnv0FzwHQc4DBs6zgORB6DjR4DhQ8B0HPQQbPcoLnYOg52OA5WPAcAj2HGDwDwXMo9Bxq8BwqeA6DnsMMnuUFz+HQc7jBc7jgOQJ6jjB4VhA8R0LPkQbPkYLnKOg5yuBZUfAcDT1HGzxHC55joOcYg2clwXMs9Bxr8BwreI6DnuMMnpUFz/HQc7zBc7zgOQF6TjB4VhE8J0LPiQbPiYLnJOg5yeBZVfCcDD0nGzwnC55ToOcUg2c1wXMq9Jxq8JwqeE6DntMMntUFz+nQc7rBc7rgOQN6zjB41hA8Z0LPmQbPmYLnLOg5y+BZU/CcDT1nGzxnC55zoOccg2ctwXMu9Jxr8JwreM6DnvMMnrUFz/nQc77Bc77guQB6LjB41hE8F0LPhQbPhYLnIui5yOBZV/BcDD0XGzwXC55LoOcSg2c9wXMp9Fxq8FwqeC6DnssMnvUFz+XQc7nBc7nguQJ6rjB4NhA8V0LPlQbPlYLnKui5yuDZUPBcDT1XGzxXC55roOcag2cjwXMt9Fxr8FwreK6DnusMno0Fz/XQc73Bc73guQF6bjB4NhE8N0LPjQbPjYLnJui5yeDZVPDcDD03Gzw3C55boOcWg2czwXMr9Nxq8NwqeG6DntsMns0Fz+3Qc7vBc7vguQN67jB4thA8d0LPnQbPnYLnLui5y+DZUvDcDT13Gzx3C557oOceg2crwXMv9Nxr8NwreO6DnvsMnq0Fz/3Qc7/Bc7/geQB6HjB4thE8D0LPgwbPg4Ln+9DzfYNnW8HzEPQ8ZPA8JHgehp6HDZ7tBM8j0POIwfOI4HkUeh41eLYXPI9Bz2MGz2OC5wfQ8wODZwfB8zj0PG7wPC54fgg9PzR4dhQ8T0DPEwbPE4LnR9DzI4NnJ8HzJPQ8afA8KXh+DD0/Nnh2FjxPQc9TBs9Tgucn0PMTg2cXwfM09Dxt8DwteH4KPT81eHYVPM9AzzMGzzOC52fQ8zODZzfB8yz0PGvwPCt4fg49Pzd4dhc8z0HPcwbPc4LnF9DzC4NnD8HzPPQ8b/A8L3h+CT2/NHj2FDwvQM8LBs8LgudX0PMrg2cvwfMi9Lxo8LwoeH4NPb82ePYWPC9Bz0sGz0uC5zfQ8xuDZx/B8zL0vGzwvCx4fgs9vzV49hU8r0DPKwbPK4Lnd9DzO4NnP8HzKvS8avC8Knh+Dz2/N3j2FzyvQc9rBs9rgucP0PMHg+cAwfM69Lxu8LwueP4IPX80eA4UPG9AzxsGzxuC50/Q8yeD5yDB8yb0vGnwvCl4/gw9fzZ4DhY8b0HPWwbPW4LnL9DzF4PnEMHzNvS8bfC8LXj+Cj1/NXgOFTzvQM87Bs87gudv0PM3g+cwwfMu9Lxr8LwreN6DnvcMnsMFz/vQ877B877g+Tv0/N3gOULwfAA9Hxg8Hwief0DPPwyeIwXPh9DzocHzoeD5J/T80+A5SvB8BD0fGTwfCZ6Poedjg+dowfMJ9Hxi8HwieP4FPf8yeI4RPJ9Cz6cGz6eC59/Q82+D51jB8xn0fGbwfCZ4/gM9/zF4jhM8n0PP5wbP54Lnv9DzX4PneMHzBfR8YfB8IXi+hJ4vDZ4TBM9X0POVwfOV4Pkaer42eE4UPN9AzzcGzzeC51vo+dbgOUnwfAc93xk83wme75Vinv99F6rnZMEzQinmGaFU6J5hb4e3jQg9Ixo8pwiekaBnJINnJMEzMvSMbPCcKnhGgZ5RDJ5RBM+o0DOqwXOa4BkNekYzeEYTPKNDz+gGz+mCZwzoGcPgGUPwjAk9Yxo8ZwiesaBnLINnLMEzNvSMbfCcKXjGgZ5xDJ5xBM+40DOuwXOW4BkPesYzeMYTPONDz/gGz9mCZwLomcDgmUDwTAg9Exo85wieiaBnIoNnIsEzMfRMbPCcK3gmgZ5JDJ5JBM+k0DOpwXOe4JkMeiYzeCYTPJNDz+QGz/mCZwromcLgmULwTAk9Uxo8FwieqaBnKoNnKsEzNfRMbfBcKHimgZ5pDJ5pBM+00DOtwXOR4JkOeqYzeKYTPNNDz/QGz8WCZwbomcHgmUHwzAg9Mxo8lwiemaBnJoNnJsEzM/TMbPBcKnhmgZ5ZDJ5ZBM+s0DOrwXOZ4JkNemYzeGYTPLNDz+wGz+WCZw7omcPgmUPwzAk9cxo8VwieuaBnLoNnLsEzN/TMbfBcKXjmgZ55DJ55BM+80DOvwXOV4JkPeuYzeOYTPPNDz/wGz9WCZwHoWcDgWUDwLAg9Cxo81wiehaBnIYNnIcGzMPQsbPBcK3gWgZ5FDJ5FBM+i0LOowXOd4FkMehYzeBYTPItDz+IGz/WCZwnoWcLgWULwLAk9Sxo8NwiepaBnKYNnKcGzNPQsbfDcKHiWgZ5lDJ5lBM+y0LOswXOT4FkOepYzeJYTPAPoGRg8Nwue5aFneYNnecGzAvSsYPDcInhWhJ4VDZ4VBc9K0LOSwXOr4FkZelY2eFYWPKtAzyoGz22CZ1XoWdXgWVXwrAY9qxk8twue1aFndYNndcGzBvSsYfDcIXjWhJ41DZ41Bc9a0LOWwXOn4FkbetY2eNYWPOtAzzoGz12CZ13oWdfgWVfwrAc96xk8dwue9aFnfYNnfcGzAfRsYPDcI3g2hJ4NDZ4NBc9G0LORwXOv4NkYejY2eDYWPJtAzyYGz32CZ1Po2dTg2VTwbAY9mxk89wuezaFnc4Nnc8GzBfRsYfA8IHi2hJ4tDZ4tBc9W0LOVwfOg4NkaerY2eLYWPNtAzzYGz/cFz7bQs63Bs63g2Q56tjN4HhI820PP9gbP9oJnB+jZweB5WPDsCD07Gjw7Cp6doGcng+cRwbMz9Oxs8OwseHaBnl0MnkcFz67Qs6vBs6vg2Q16djN4HhM8u0PP7gbP7oJnD+jZw+D5geDZE3r2NHj2FDx7Qc9eBs/jgmdv6Nnb4Nlb8OwDPfsYPD8UPPtCz74Gz76CZz/o2c/geULw7A89+xs8+wueA6DnAIPnR4LnQOg50OA5UPAcBD0HGTxPCp6Doedgg+dgwXMI9Bxi8PxY8BwKPYcaPIcKnsOg5zCD5ynBczj0HG7wHC54joCeIwyenwieI6HnSIPnSMFzFPQcZfA8LXiOhp6jDZ6jBc8x0HOMwfNTwXMs9Bxr8BwreI6DnuMMnmcEz/HQc7zBc7zgOQF6TjB4fiZ4ToSeEw2eEwXPSdBzksHzrOA5GXpONnhOFjynQM8pBs/PBc+p0HOqwXOq4DkNek4zeJ4TPKdDz+kGz+mC5wzoOcPg+YXgORN6zjR4zhQ8Z0HPWQbP84LnbOg52+A5W/CcAz3nGDy/FDznQs+5Bs+5guc86DnP4HlB8JwPPecbPOcLngug5wKD51eC50LoudDguVDwXAQ9Fxk8Lwqei6HnYoPnYsFzCfRcYvD8WvBcCj2XGjyXCp7LoOcyg+clwXM59Fxu8FwueK6AnisMnt8Iniuh50qD50rBcxX0XGXwvCx4roaeqw2eqwXPNdBzjcHzW8FzLfRca/BcK3iug57rDJ5XBM/10HO9wXO94LkBem4weH4neG6EnhsNnhsFz03Qc5PB86rguRl6bjZ4bhY8t0DPLQbP7wXPrdBzq8Fzq+C5DXpuM3heEzy3Q8/tBs/tgucO6LnD4PmD4LkTeu40eO4UPHdBz10Gz+uC527oudvguVvw3AM99xg8fxQ890LPvQbPvYLnPui5z+B5Q/DcDz33Gzz3C54HoOcBg+dPgudB6HnQ4HlQ8Hwfer5v8LwpeB6CnocMnocEz8PQ87DB82fB8wj0PGLwPCJ4HoWeRw2etwTPY9DzmMHzmOD5AfT8wOD5i+B5HHoeN3geFzw/hJ4fGjxvC54noOcJg+cJwfMj6PmRwfNXwfMk9Dxp8DwpeH4MPT82eN4RPE9Bz1MGz1OC5yfQ8xOD52+C52noedrgeVrw/BR6fmrwvCt4noGeZwyeZwTPz6DnZwbPe4LnWeh51uB5VvD8HHp+bvC8L3ieg57nDJ7nBM8voOcXBs/fBc/z0PO8wfO84Pkl9PzS4PlA8LwAPS8YPC8Inl9Bz68Mnn8Inheh50WD50XB82vo+bXB86HgeQl6XjJ4XhI8v4Ge3xg8/xQ8L0PPywbPy4Lnt9DzW4PnI8HzCvS8YvC8Inh+Bz2/M3g+FjyvQs+rBs+rguf30PN7g+cTwfMa9Lxm8LwmeP4APX8weP4leF6HntcNntcFzx+h548Gz6eC5w3oecPgeUPw/Al6/mTw/FvwvAk9bxo8bwqeP0PPnw2ezwTPW9DzlsHzluD5C/T8xeD5j+B5G3reNnjeFjx/hZ6/GjyfC553oOcdg+cdwfM36PmbwfNfwfMu9Lxr8LwreN6DnvcMni8Ez/vQ877B877g+Tv0/N3g+VLwfAA9Hxg8Hwief0DPPwyerwTPh9DzocHzoeD5J/T80+D5WvB8BD0fGTwfCZ6Poedjg+cbwfMJ9Hxi8HwieP4FPf8yeL4VPJ9Cz6cGz6eC59/Q82+D5zvB8xn0fGbwfCZ4/gM9/zF4vpfwf3/nc+j53OD5XPD8F3r+a/CMIHi++N/fmTjsO//7Lmo471Ruh7d9+b+/M3vYd778H94Zzi9CRMHzFfR8ZfB8JXi+hp6vDZ6RBM830PONwfON4PkWer41eEYWPN9Bz3cGz3eC53ulmed/34XqGUXwjFCaeUYoHbpn2NvhbSNCz4gGz6iCZyToGcngGUnwjAw9Ixs8owmeUaBnFINnFMEzKvSMavCMLnhGg57RDJ7RBM/o0DO6wTOG4BkDesYweMYQPGNCz5gGz5iCZyzoGcvgGUvwjA09Yxs8YwmecaBnHINnHMEzLvSMa/CMLXjGg57xDJ7xBM/40DO+wTOO4JkAeiYweCYQPBNCz4QGz7iCZyLomcjgmUjwTAw9Exs84wmeSaBnEoNnEsEzKfRMavCML3gmg57JDJ7JBM/k0DO5wTOB4JkCeqYweKYQPFNCz5QGz4SCZyromcrgmUrwTA09Uxs8EwmeaaBnGoNnGsEzLfRMa/BMLHimg57pDJ7pBM/00DO9wTOJ4JkBemYweGYQPDNCz4wGz6SCZybomcngmUnwzAw9Mxs8kwmeWaBnFoNnFsEzK/TMavBMLnhmg57ZDJ7ZBM/s0DO7wTOF4JkDeuYweOYQPHNCz5wGz5SCZy7omcvgmUvwzA09cxs8UwmeeaBnHoNnHsEzL/TMa/BMLXjmg575DJ75BM/80DO/wTON4FkAehYweBYQPAtCz4IGz7SCZyHoWcjgWUjwLAw9Cxs80wmeRaBnEYNnEcGzKPQsavBML3gWg57FDJ7FBM/i0LO4wTOD4FkCepYweJYQPEtCz5IGz4yCZynoWcrgWUrwLA09Sxs8MwmeZaBnGYNnGcGzLPQsa/DMLHiWg57lDJ7lBM8AegYGzyyCZ3noWd7gWV7wrAA9Kxg8swqeFaFnRYNnRcGzEvSsZPDMJnhWhp6VDZ6VBc8q0LOKwTO74FkVelY1eFYVPKtBz2oGzxyCZ3XoWd3gWV3wrAE9axg8cwqeNaFnTYNnTcGzFvSsZfDMJXjWhp61DZ61Bc860LOOwTO34FkXetY1eNYVPOtBz3oGzzyCZ33oWd/gWV/wbAA9Gxg88wqeDaFnQ4NnQ8GzEfRsZPDMJ3g2hp6NDZ6NBc8m0LOJwTO/4NkUejY1eDYVPJtBz2YGzwKCZ3Po2dzg2VzwbAE9Wxg8CwqeLaFnS4NnS8GzFfRsZfAsJHi2hp6tDZ6tBc820LONwbOw4NkWerY1eLYVPNtBz3YGzyKCZ3vo2d7g2V7w7AA9Oxg8iwqeHaFnR4NnR8GzE/TsZPAsJnh2hp6dDZ6dBc8u0LOLwbO44NkVenY1eHYVPLtBz24GzxKCZ3fo2d3g2V3w7AE9exg8SwqePaFnT4NnT8GzF/TsZfAsJXj2hp69DZ69Bc8+0LOPwbO04NkXevY1ePYVPPtBz34GzzKCZ3/o2d/g2V/wHAA9Bxg8ywqeA6HnQIPnQMFzEPQcZPAsJ3gOhp6DDZ6DBc8h0HOIwTMQPIdCz6EGz6GC5zDoOczgWV7wHA49hxs8hwueI6DnCINnBcFzJPQcafAcKXiOgp6jDJ4VBc/R0HO0wXO04DkGeo4xeFYSPMdCz7EGz7GC5zjoOc7gWVnwHA89xxs8xwueE6DnBINnFcFzIvScaPCcKHhOgp6TDJ5VBc/J0HOywXOy4DkFek4xeFYTPKdCz6kGz6mC5zToOc3gWV3wnA49pxs8pwueM6DnDINnDcFzJvScafCcKXjOgp6zDJ41Bc/Z0HO2wXO24DkHes4xeNYSPOdCz7kGz7mC5zzoOc/gWVvwnA895xs85wueC6DnAoNnHcFzIfRcaPBcKHgugp6LDJ51Bc/F0HOxwXOx4LkEei4xeNYTPJdCz6UGz6WC5zLouczgWV/wXA49lxs8lwueK6DnCoNnA8FzJfRcafBcKXiugp6rDJ4NBc/V0HO1wXO14LkGeq4xeDYSPNdCz7UGz7WC5zrouc7g2VjwXA891xs81wueG6DnBoNnE8FzI/TcaPDcKHhugp6bDJ5NBc/N0HOzwXOz4LkFem4xeDYTPLdCz60Gz62C5zbouc3g2Vzw3A49txs8twueO6DnDoNnC8FzJ/TcafDcKXjugp67DJ4tBc/d0HO3wXO34LkHeu4xeLYSPPdCz70Gz72C5z7ouc/g2Vrw3A899xs89wueB6DnAYNnG8HzIPQ8aPA8KHi+Dz3fN3i2FTwPQc9DBs9Dgudh6HnY4NlO8DwCPY8YPI8Inkeh51GDZ3vB8xj0PGbwPCZ4fgA9PzB4dhA8j0PP4wbP44Lnh9DzQ4NnR8HzBPQ8YfA8IXh+BD0/Mnh2EjxPQs+TBs+TgufH0PNjg2dnwfMU9Dxl8DwleH4CPT8xeHYRPE9Dz9MGz9OC56fQ81ODZ1fB8wz0PGPwPCN4fgY9PzN4dhM8z0LPswbPs4Ln59Dzc4Nnd8HzHPQ8Z/A8J3h+AT2/MHj2EDzPQ8/zBs/zgueX0PNLg2dPwfMC9Lxg8LwgeH4FPb8yePYSPC9Cz4sGz4uC59fQ82uDZ2/B8xL0vGTwvCR4fgM9vzF49hE8L0PPywbPy4Lnt9DzW4NnX8HzCvS8YvC8Inh+Bz2/M3j2EzyvQs+rBs+rguf30PN7g2d/wfMa9Lxm8LwmeP4APX8weA4QPK9Dz+sGz+uC54/Q80eD50DB8wb0vGHwvCF4/gQ9fzJ4DhI8b0LPmwbPm4Lnz9DzZ4PnYMHzFvS8ZfC8JXj+Aj1/MXgOETxvQ8/bBs/bguev0PNXg+dQwfMO9Lxj8LwjeP4GPX8zeA4TPO9Cz7sGz7uC5z3oec/gOVzwvA897xs87wuev0PP3w2eIwTPB9DzgcHzgeD5B/T8w+A5UvB8CD0fGjwfCp5/Qs8/DZ6jBM9H0PORwfOR4PkYej42eI4WPJ9AzycGzyeC51/Q8y+D5xjB8yn0fGrwfCp4/g09/zZ4jhU8n0HPZwbPZ4LnP9DzH4PnOMHzOfR8bvB8Lnj+Cz3/NXiOFzxfQM8XBs8XgudL6PnS4DlB8HwFPV8ZPF8Jnq+h52uD50TB8w30fGPwfCN4voWebw2ekwTPd9DzncHzneD5Xhnm+d93oXpOFjwjlGGeEcqE7hn2dnjbiNAzosFziuAZCXpGMnhGEjwjQ8/IBs+pgmcU6BnF4BlF8IwKPaMaPKcJntGgZzSDZzTBMzr0jG7wnC54xoCeMQyeMQTPmNAzpsFzhuAZC3rGMnjGEjxjQ8/YBs+Zgmcc6BnH4BlH8IwLPeMaPGcJnvGgZzyDZzzBMz70jG/wnC14JoCeCQyeCQTPhNAzocFzjuCZCHomMngmEjwTQ8/EBs+5gmcS6JnE4JlE8EwKPZMaPOcJnsmgZzKDZzLBMzn0TG7wnC94poCeKQyeKQTPlNAzpcFzgeCZCnqmMnimEjxTQ8/UBs+Fgmca6JnG4JlG8EwLPdMaPBcJnumgZzqDZzrBMz30TG/wXCx4ZoCeGQyeGQTPjNAzo8FzieCZCXpmMnhmEjwzQ8/MBs+lgmcW6JnF4JlF8MwKPbMaPJcJntmgZzaDZzbBMzv0zG7wXC545oCeOQyeOQTPnNAzp8FzheCZC3rmMnjmEjxzQ8/cBs+Vgmce6JnH4JlH8MwLPfMaPFcJnvmgZz6DZz7BMz/0zG/wXC14FoCeBQyeBQTPgtCzoMFzjeBZCHoWMngWEjwLQ8/CBs+1gmcR6FnE4FlE8CwKPYsaPNcJnsWgZzGDZzHBszj0LG7wXC94loCeJQyeJQTPktCzpMFzg+BZCnqWMniWEjxLQ8/SBs+NgmcZ6FnG4FlG8CwLPcsaPDcJnuWgZzmDZznBM4CegcFzs+BZHnqWN3iWFzwrQM8KBs8tgmdF6FnR4FlR8KwEPSsZPLcKnpWhZ2WDZ2XBswr0rGLw3CZ4VoWeVQ2eVQXPatCzmsFzu+BZHXpWN3hWFzxrQM8aBs8dgmdN6FnT4FlT8KwFPWsZPHcKnrWhZ22DZ23Bsw70rGPw3CV41oWedQ2edQXPetCznsFzt+BZH3rWN3jWFzwbQM8GBs89gmdD6NnQ4NlQ8GwEPRsZPPcKno2hZ2ODZ2PBswn0bGLw3Cd4NoWeTQ2eTQXPZtCzmcFzv+DZHHo2N3g2FzxbQM8WBs8DgmdL6NnS4NlS8GwFPVsZPA8Knq2hZ2uDZ2vBsw30bGPwfF/wbAs92xo82wqe7aBnO4PnIcGzPfRsb/BsL3h2gJ4dDJ6HBc+O0LOjwbOj4NkJenYyeB4RPDtDz84Gz86CZxfo2cXgeVTw7Ao9uxo8uwqe3aBnN4PnMcGzO/TsbvDsLnj2gJ49DJ4fCJ49oWdPg2dPwbMX9Oxl8DwuePaGnr0Nnr0Fzz7Qs4/B80PBsy/07Gvw7Ct49oOe/QyeJwTP/tCzv8Gzv+A5AHoOMHh+JHgOhJ4DDZ4DBc9B0HOQwfOk4DkYeg42eA4WPIdAzyEGz48Fz6HQc6jBc6jgOQx6DjN4nhI8h0PP4QbP4YLnCOg5wuD5ieA5EnqONHiOFDxHQc9RBs/Tgudo6Dna4Dla8BwDPccYPD8VPMdCz7EGz7GC5zjoOc7geUbwHA89xxs8xwueE6DnBIPnZ4LnROg50eA5UfCcBD0nGTzPCp6Toedkg+dkwXMK9Jxi8Pxc8JwKPacaPKcKntOg5zSD5znBczr0nG7wnC54zoCeMwyeXwieM6HnTIPnTMFzFvScZfA8L3jOhp6zDZ6zBc850HOOwfNLwXMu9Jxr8JwreM6DnvMMnhcEz/nQc77Bc77guQB6LjB4fiV4LoSeCw2eCwXPRdBzkcHzouC5GHouNnguFjyXQM8lBs+vBc+l0HOpwXOp4LkMei4zeF4SPJdDz+UGz+WC5wroucLg+Y3guRJ6rjR4rhQ8V0HPVQbPy4Lnaui52uC5WvBcAz3XGDy/FTzXQs+1Bs+1guc66LnO4HlF8FwPPdcbPNcLnhug5waD53eC50boudHguVHw3AQ9Nxk8rwqem6HnZoPnZsFzC/TcYvD8XvDcCj23Gjy3Cp7boOc2g+c1wXM79Nxu8NwueO6AnjsMnj8Injuh506D507Bcxf03GXwvC547oaeuw2euwXPPdBzj8HzR8FzL/Tca/DcK3jug577DJ43BM/90HO/wXO/4HkAeh4weP4keB6EngcNngcFz/eh5/sGz5uC5yHoecjgeUjwPAw9Dxs8fxY8j0DPIwbPI4LnUeh51OB5S/A8Bj2PGTyPCZ4fQM8PDJ6/CJ7Hoedxg+dxwfND6PmhwfO24HkCep4weJ4QPD+Cnh8ZPH8VPE9Cz5MGz5OC58fQ82OD5x3B8xT0PGXwPCV4fgI9PzF4/iZ4noaepw2epwXPT6HnpwbPu4LnGeh5xuB5RvD8DHp+ZvC8J3iehZ5nDZ5nBc/PoefnBs/7guc56HnO4HlO8PwCen5h8Pxd8DwPPc8bPM8Lnl9Czy8Nng8EzwvQ84LB84Lg+RX0/Mrg+YfgeRF6XjR4XhQ8v4aeXxs8Hwqel6DnJYPnJcHzG+j5jcHzT8HzMvS8bPC8LHh+Cz2/NXg+EjyvQM8rBs8rgud30PM7g+djwfMq9Lxq8LwqeH4PPb83eD4RPK9Bz2sGz2uC5w/Q8weD51+C53Xoed3geV3w/BF6/mjwfCp43oCeNwyeNwTPn6DnTwbPvwXPm9DzpsHzpuD5M/T82eD5TPC8BT1vGTxvCZ6/QM9fDJ7/CJ63oedtg+dtwfNX6PmrwfO54HkHet4xeN4RPH+Dnr8ZPP8VPO9Cz7sGz7uC5z3oec/g+ULwvA897xs87wuev0PP3w2eLwXPB9DzgcHzgeD5B/T8w+D5SvB8CD0fGjwfCp5/Qs8/DZ6vBc9H0PORwfOR4PkYej42eL4RPJ9AzycGzyeC51/Q8y+D51vB8yn0fGrwfCp4/g09/zZ4vhM8n0HPZwbPZ4LnP9DzH4Pne4n+93c+h57PDZ7PBc9/oee/Bs8IgucL6PnC4PlC8HwJPV8aPCMKnq+g5yuD5yvB8zX0fG3wjCR4voGebwyebwTPt9DzrcEzsuD5Dnq+M3i+EzzfK8s8//suVM8ogmeEsswzQtnQPcPeDm8bEXpGNHhGFTwjQc9IBs9Igmdk6BnZ4BlN8IwCPaMYPKMInlGhZ1SDZ3TBMxr0jGbwjCZ4Roee0Q2eMQTPGNAzhsEzhuAZE3rGNHjGFDxjQc9YBs9Ygmds6Bnb4BlL8IwDPeMYPOMInnGhZ1yDZ2zBMx70jGfwjCd4xoee8Q2ecQTPBNAzgcEzgeCZEHomNHjGFTwTQc9EBs9Egmdi6JnY4BlP8EwCPZMYPJMInkmhZ1KDZ3zBMxn0TGbwTCZ4JoeeyQ2eCQTPFNAzhcEzheCZEnqmNHgmFDxTQc9UBs9Ugmdq6Jna4JlI8EwDPdMYPNMInmmhZ1qDZ2LBMx30TGfwTCd4poee6Q2eSQTPDNAzg8Ezg+CZEXpmNHgmFTwzQc9MBs9Mgmdm6JnZ4JlM8MwCPbMYPLMInlmhZ1aDZ3LBMxv0zGbwzCZ4Zoee2Q2eKQTPHNAzh8Ezh+CZE3rmNHimFDxzQc9cBs9cgmdu6Jnb4JlK8MwDPfMYPPMInnmhZ16DZ2rBMx/0zGfwzCd45oee+Q2eaQTPAtCzgMGzgOBZEHoWNHimFTwLQc9CBs9Cgmdh6FnY4JlO8CwCPYsYPIsInkWhZ1GDZ3rBsxj0LGbwLCZ4FoeexQ2eGQTPEtCzhMGzhOBZEnqWNHhmFDxLQc9SBs9Sgmdp6Fna4JlJ8CwDPcsYPMsInmWhZ1mDZ2bBsxz0LGfwLCd4BtAzMHhmETzLQ8/yBs/ygmcF6FnB4JlV8KwIPSsaPCsKnpWgZyWDZzbBszL0rGzwrCx4VoGeVQye2QXPqtCzqsGzquBZDXpWM3jmEDyrQ8/qBs/qgmcN6FnD4JlT8KwJPWsaPGsKnrWgZy2DZy7Bszb0rG3wrC141oGedQyeuQXPutCzrsGzruBZD3rWM3jmETzrQ8/6Bs/6gmcD6NnA4JlX8GwIPRsaPBsKno2gZyODZz7BszH0bGzwbCx4NoGeTQye+QXPptCzqcGzqeDZDHo2M3gWEDybQ8/mBs/mgmcL6NnC4FlQ8GwJPVsaPFsKnq2gZyuDZyHBszX0bG3wbC14toGebQyehQXPttCzrcGzreDZDnq2M3gWETzbQ8/2Bs/2gmcH6NnB4FlU8OwIPTsaPDsKnp2gZyeDZzHBszP07Gzw7Cx4doGeXQyexQXPrtCzq8Gzq+DZDXp2M3iWEDy7Q8/uBs/ugmcP6NnD4FlS8OwJPXsaPHsKnr2gZy+DZynBszf07G3w7C149oGefQyepQXPvtCzr8Gzr+DZD3r2M3iWETz7Q8/+Bs/+gucA6DnA4FlW8BwIPQcaPAcKnoOg5yCDZznBczD0HGzwHCx4DoGeQwyegeA5FHoONXgOFTyHQc9hBs/ygudw6Dnc4Dlc8BwBPUcYPCsIniOh50iD50jBcxT0HGXwrCh4joaeow2eowXPMdBzjMGzkuA5FnqONXiOFTzHQc9xBs/Kgud46Dne4Dle8JwAPScYPKsInhOh50SD50TBcxL0nGTwrCp4Toaekw2ekwXPKdBzisGzmuA5FXpONXhOFTynQc9pBs/qgud06Dnd4Dld8JwBPWcYPGsInjOh50yD50zBcxb0nGXwrCl4zoaesw2eswXPOdBzjsGzluA5F3rONXjOFTznQc95Bs/agud86Dnf4Dlf8FwAPRcYPOsInguh50KD50LBcxH0XGTwrCt4Loaeiw2eiwXPJdBzicGznuC5FHouNXguFTyXQc9lBs/6gudy6Lnc4Llc8FwBPVcYPBsIniuh50qD50rBcxX0XGXwbCh4roaeqw2eqwXPNdBzjcGzkeC5FnquNXiuFTzXQc91Bs/Ggud66Lne4Lle8NwAPTcYPJsInhuh50aD50bBcxP03GTwbCp4boaemw2emwXPLdBzi8GzmeC5FXpuNXhuFTy3Qc9tBs/mgud26Lnd4Lld8NwBPXcYPFsInjuh506D507Bcxf03GXwbCl47oaeuw2euwXPPdBzj8GzleC5F3ruNXjuFTz3Qc99Bs/Wgud+6Lnf4Llf8DwAPQ8YPNsIngeh50GD50HB833o+b7Bs63geQh6HjJ4HhI8D0PPwwbPdoLnEeh5xOB5RPA8Cj2PGjzbC57HoOcxg+cxwfMD6PmBwbOD4Hkceh43eB4XPD+Enh8aPDsKnieg5wmD5wnB8yPo+ZHBs5PgeRJ6njR4nhQ8P4aeHxs8Owuep6DnKYPnKcHzE+j5icGzi+B5GnqeNnieFjw/hZ6fGjy7Cp5noOcZg+cZwfMz6PmZwbOb4HkWep41eJ4VPD+Hnp8bPLsLnueg5zmD5znB8wvo+YXBs4fgeR56njd4nhc8v4SeXxo8ewqeF6DnBYPnBcHzK+j5lcGzl+B5EXpeNHheFDy/hp5fGzx7C56XoOclg+clwfMb6PmNwbOP4HkZel42eF4WPL+Fnt8aPPsKnleg5xWD5xXB8zvo+Z3Bs5/geRV6XjV4XhU8v4ee3xs8+wue16DnNYPnNcHzB+j5g8FzgOB5HXpeN3heFzx/hJ4/GjwHCp43oOcNg+cNwfMn6PmTwXOQ4HkTet40eN4UPH+Gnj8bPAcLnreg5y2D5y3B8xfo+YvBc4jgeRt63jZ43hY8f4Wevxo8hwqed6DnHYPnHcHzN+j5m8FzmOB5F3reNXjeFTzvQc97Bs/hgud96Hnf4Hlf8Pwdev5u8BwheD6Ang8Mng8Ezz+g5x8Gz5GC50Po+dDg+VDw/BN6/mnwHCV4PoKejwyejwTPx9DzscFztOD5BHo+MXg+ETz/gp5/GTzHCJ5PoedTg+dTwfNv6Pm3wXOs4PkMej4zeD4TPP+Bnv8YPMcJns+h53OD53PB81/o+a/Bc7zg+QJ6vjB4vhA8X0LPlwbPCYLnK+j5yuD5SvB8DT1fGzwnCp5voOcbg+cbwfMt9Hxr8JwkeL6Dnu8Mnu8Ez/fKMc//vgvVc7LgGaEc84xQLnTPsLfD20aEnhENnlMEz0jQM5LBM5LgGRl6RjZ4ThU8o0DPKAbPKIJnVOgZ1eA5TfCMBj2jGTyjCZ7RoWd0g+d0wTMG9Ixh8IwheMaEnjENnjMEz1jQM5bBM5bgGRt6xjZ4zhQ840DPOAbPOIJnXOgZ1+A5S/CMBz3jGTzjCZ7xoWd8g+dswTMB9Exg8EwgeCaEngkNnnMEz0TQM5HBM5HgmRh6JjZ4zhU8k0DPJAbPJIJnUuiZ1OA5T/BMBj2TGTyTCZ7JoWdyg+d8wTMF9Exh8EwheKaEnikNngsEz1TQM5XBM5XgmRp6pjZ4LhQ800DPNAbPNIJnWuiZ1uC5SPBMBz3TGTzTCZ7poWd6g+diwTMD9Mxg8MwgeGaEnhkNnksEz0zQM5PBM5PgmRl6ZjZ4LhU8s0DPLAbPLIJnVuiZ1eC5TPDMBj2zGTyzCZ7ZoWd2g+dywTMH9Mxh8MwheOaEnjkNnisEz1zQM5fBM5fgmRt65jZ4rhQ880DPPAbPPIJnXuiZ1+C5SvDMBz3zGTzzCZ75oWd+g+dqwbMA9Cxg8CwgeBaEngUNnmsEz0LQs5DBs5DgWRh6FjZ4rhU8i0DPIgbPIoJnUehZ1OC5TvAsBj2LGTyLCZ7FoWdxg+d6wbME9Cxh8CwheJaEniUNnhsEz1LQs5TBs5TgWRp6ljZ4bhQ8y0DPMgbPMoJnWehZ1uC5SfAsBz3LGTzLCZ4B9AwMnpsFz/LQs7zBs7zgWQF6VjB4bhE8K0LPigbPioJnJehZyeC5VfCsDD0rGzwrC55VoGcVg+c2wbMq9Kxq8KwqeFaDntUMntsFz+rQs7rBs7rgWQN61jB47hA8a0LPmgbPmoJnLehZy+C5U/CsDT1rGzxrC551oGcdg+cuwbMu9Kxr8KwreNaDnvUMnrsFz/rQs77Bs77g2QB6NjB47hE8G0LPhgbPhoJnI+jZyOC5V/BsDD0bGzwbC55NoGcTg+c+wbMp9Gxq8GwqeDaDns0MnvsFz+bQs7nBs7ng2QJ6tjB4HhA8W0LPlgbPloJnK+jZyuB5UPBsDT1bGzxbC55toGcbg+f7gmdb6NnW4NlW8GwHPdsZPA8Jnu2hZ3uDZ3vBswP07GDwPCx4doSeHQ2eHQXPTtCzk8HziODZGXp2Nnh2Fjy7QM8uBs+jgmdX6NnV4NlV8OwGPbsZPI8Jnt2hZ3eDZ3fBswf07GHw/EDw7Ak9exo8ewqevaBnL4PnccGzN/TsbfDsLXj2gZ59DJ4fCp59oWdfg2dfwbMf9Oxn8DwhePaHnv0Nnv0FzwHQc4DB8yPBcyD0HGjwHCh4DoKegwyeJwXPwdBzsMFzsOA5BHoOMXh+LHgOhZ5DDZ5DBc9h0HOYwfOU4Dkceg43eA4XPEdAzxEGz08Ez5HQc6TBc6TgOQp6jjJ4nhY8R0PP0QbP0YLnGOg5xuD5qeA5FnqONXiOFTzHQc9xBs8zgud46Dne4Dle8JwAPScYPD8TPCdCz4kGz4mC5yToOcngeVbwnAw9Jxs8JwueU6DnFIPn54LnVOg51eA5VfCcBj2nGTzPCZ7Toed0g+d0wXMG9Jxh8PxC8JwJPWcaPGcKnrOg5yyD53nBczb0nG3wnC14zoGecwyeXwqec6HnXIPnXMFzHvScZ/C8IHjOh57zDZ7zBc8F0HOBwfMrwXMh9Fxo8FwoeC6CnosMnhcFz8XQc7HBc7HguQR6LjF4fi14LoWeSw2eSwXPZdBzmcHzkuC5HHouN3guFzxXQM8VBs9vBM+V0HOlwXOl4LkKeq4yeF4WPFdDz9UGz9WC5xroucbg+a3guRZ6rjV4rhU810HPdQbPK4Lneui53uC5XvDcAD03GDy/Ezw3Qs+NBs+Ngucm6LnJ4HlV8NwMPTcbPDcLnlug5xaD5/eC51boudXguVXw3AY9txk8rwme26HndoPndsFzB/TcYfD8QfDcCT13Gjx3Cp67oOcug+d1wXM39Nxt8NwteO6BnnsMnj8Knnuh516D517Bcx/03GfwvCF47oee+w2e+wXPA9DzgMHzJ8HzIPQ8aPA8KHi+Dz3fN3jeFDwPQc9DBs9Dgudh6HnY4Pmz4HkEeh4xeB4RPI9Cz6MGz1uC5zHoeczgeUzw/AB6fmDw/EXwPA49jxs8jwueH0LPDw2etwXPE9DzhMHzhOD5EfT8yOD5q+B5EnqeNHieFDw/hp4fGzzvCJ6noOcpg+cpwfMT6PmJwfM3wfM09Dxt8DwteH4KPT81eN4VPM9AzzMGzzOC52fQ8zOD5z3B8yz0PGvwPCt4fg49Pzd43hc8z0HPcwbPc4LnF9DzC4Pn74Lneeh53uB5XvD8Enp+afB8IHhegJ4XDJ4XBM+voOdXBs8/BM+L0POiwfOi4Pk19Pza4PlQ8LwEPS8ZPC8Jnt9Az28Mnn8Knpeh52WD52XB81vo+a3B85HgeQV6XjF4XhE8v4Oe3xk8HwueV6HnVYPnVcHze+j5vcHzieB5DXpeM3heEzx/gJ4/GDz/EjyvQ8/rBs/rgueP0PNHg+dTwfMG9Lxh8LwheP4EPX8yeP4teN6EnjcNnjcFz5+h588Gz2eC5y3oecvgeUvw/AV6/mLw/EfwvA09bxs8bwuev0LPXw2ezwXPO9DzjsHzjuD5G/T8zeD5r+B5F3reNXjeFTzvQc97Bs8Xgud96Hnf4Hlf8Pwdev5u8HwpeD6Ang8Mng8Ezz+g5x8Gz1eC50Po+dDg+VDw/BN6/mnwfC14PoKejwyejwTPx9DzscHzjeD5BHo+MXg+ETz/gp5/GTzfCp5PoedTg+dTwfNv6Pm3wfOd4PkMej4zeD4TPP+Bnv8YPN9L/L+/8zn0fG7wfC54/gs9/zV4RhA8X0DPFwbPF4LnS+j50uAZUfB8BT1fGTxfCZ6voedrg2ckwfMN9Hxj8HwjeL6Fnm8NnpEFz3fQ853B853g+V7APP/7LlTPKIJnhIB5RghC9wx7O7xtxIB5RgxC94wqeEYKmGekIHTPsLfD20YOmGfkIHTPaIJnlIB5RglC9wx7O7xt1IB5Rg1C94wueEYLmGe0IHTPsLfD20YPmGf0IHTPGIJnjIB5xghC9wx7O7xtzIB5xgxC94wpeMYKmGesIHTPsLfD28YOmGfsIHTPWIJnnIB5xglC9wx7O7xt3IB5xg1C94wteMYLmGe8IHTPsLfD28YPmGf8IHTPOIJngoB5JghC9wx7O7xtwoB5JgxC94wreCYKmGeiIHTPsLfD2yYOmGfiIHTPeIJnkoB5JglC9wx7O7xt0oB5Jg1C94wveCYLmGeyIHTPsLfD2yYPmGfyIHTPBIJnioB5pghC9wx7O7xtyoB5pgxC90woeKYKmGeqIHTPsLfD26YOmGfqIHTPRIJnmoB5pglC9wx7O7xt2oB5pg1C90wseKYLmGe6IHTPsLfD26YPmGf6IHTPJIJnhoB5ZghC9wx7O7xtxoB5ZgxC90wqeGYKmGemIHTPsLfD22YOmGfmIHTPZIJnloB5ZglC9wx7O7xt1oB5Zg1C90wueGYLmGe2IHTPsLfD22YPmGf2IHTPFIJnjoB55ghC9wx7O7xtzoB55gxC90wpeOYKmGeuIHTPsLfD2+YOmGfuIHTPVIJnnoB55glC9wx7O7xt3oB55g1C90wteOYLmGe+IHTPsLfD2+YPmGf+IHTPNIJngYB5FghC9wx7O7xtwYB5FgxC90wreBYKmGehIHTPsLfD2xYOmGfhIHTPdIJnkYB5FglC9wx7O7xt0YB5Fg1C90wveBYLmGexIHTPsLfD2xYPmGfxIHTPDIJniYB5lghC9wx7O7xtyYB5lgxC98woeJYKmGepIHTPsLfD25YOmGfpIHTPTIJnmYB5lglC9wx7O7xt2YB5lg1C98wseJYLmGe5IHTPsLfD2wYB8wyC0D2zCJ7lA+ZZPgjdM+zt8LYVAuZZIQjdM6vgWTFgnhWD0D3D3g5vWylgnpWC0D2zCZ6VA+ZZOQjdM+zt8LZVAuZZJQjdM7vgWTVgnlWD0D3D3g5vWy1gntWC0D1zCJ7VA+ZZPQjdM+zt8LY1AuZZIwjdM6fgWTNgnjWD0D3D3g5vWytgnrWC0D1zCZ61A+ZZOwjdM+zt8LZ1AuZZJwjdM7fgWTdgnnWD0D3D3g5vWy9gnvWC0D3zCJ71A+ZZPwjdM+zt8LYNAubZIAjdM6/g2TBgng2D0D3D3g5v2yhgno2C0D3zCZ6NA+bZOAjdM+zt8LZNAubZJAjdM7/g2TRgnk2D0D3D3g5v2yxgns2C0D0LCJ7NA+bZPAjdM+zt8LYtAubZIgjds6Dg2TJgni2D0D3D3g5v2ypgnq2C0D0LCZ6tA+bZOgjdM+zt8LZtAubZJgjds7Dg2TZgnm2D0D3D3g5v2y5gnu2C0D2LCJ7tA+bZPgjdM+zt8LYdAubZIQjds6jg2TFgnh2D0D3D3g5v2ylgnp2C0D2LCZ6dA+bZOQjdM+zt8LZdAubZJQjds7jg2TVgnl2D0D3D3g5v2y1gnt2C0D1LCJ7dA+bZPQjdM+zt8LY9AubZIwjds6Tg2TNgnj2D0D3D3g5v2ytgnr2C0D1LCZ69A+bZOwjdM+zt8LZ9AubZJwjds7Tg2Tdgnn2D0D3D3g5v2y9gnv2C0D3LCJ79A+bZPwjdM+zt8LYDAuY5IAjds6zgOTBgngOD0D3D3g5vOyhgnoOC0D3LCZ6DA+Y5OAjdM+zt8LZDAuY5JAjdMxA8hwbMc2gQumfY2+FthwXMc1gQumd5wXN4wDyHB6F7hr0d3nZEwDxHBKF7VhA8RwbMc2QQumfY2+FtRwXMc1QQumdFwXN0wDxHB6F7hr0d3nZMwDzHBKF7VhI8xwbMc2wQumfY2+FtxwXMc1wQumdlwXN8wDzHB6F7hr0d3nZCwDwnBKF7VhE8JwbMc2IQumfY2+FtJwXMc1IQumdVwXNywDwnB6F7hr0d3nZKwDynBKF7VhM8pwbMc2oQumfY2+FtpwXMc1oQumd1wXN6wDynB6F7hr0d3nZGwDxnBKF71hA8ZwbMc2YQumfY2+FtZwXMc1YQumdNwXN2wDxnB6F7hr0d3nZOwDznBKF71hI85wbMc24QumfY2+Ft5wXMc14QumdtwXN+wDznB6F7hr0d3nZBwDwXBKF71hE8FwbMc2EQumfY2+FtFwXMc1EQumddwXNxwDwXB6F7hr0d3nZJwDyXBKF71hM8lwbMc2kQumfY2+FtlwXMc1kQumd9wXN5wDyXB6F7hr0d3nZFwDxXBKF7NhA8VwbMc2UQumfY2+FtVwXMc1UQumdDwXN1wDxXB6F7hr0d3nZNwDzXBKF7NhI81wbMc20QumfY2+Ft1wXMc10QumdjwXN9wDzXB6F7hr0d3nZDwDw3BKF7NhE8NwbMc2MQumfY2+FtNwXMc1MQumdTwXNzwDw3B6F7hr0d3nZLwDy3BKF7NhM8twbMc2sQumfY2+FttwXMc1sQumdzwXN7wDy3B6F7hr0d3nZHwDx3BKF7thA8dwbMc2cQumfY2+FtdwXMc1cQumdLwXN3wDx3B6F7hr0d3nZPwDz3BKF7thI89wbMc28QumfY2+Ft9wXMc18QumdrwXN/wDz3B6F7hr0d3vZAwDwPBKF7thE8DwbM82AQumfY2+Ft3w+Y5/tB6J5tBc9DAfM8FITuGfZ2eNvDAfM8HITu2U7wPBIwzyNB6J5hb4e3PRowz6NB6J7tBc9jAfM8FoTuGfZ2eNsPAub5QRC6ZwfB83jAPI8HoXuGvR3e9sOAeX4YhO7ZUfA8ETDPE0HonmFvh7f9KGCeHwWhe3YSPE8GzPNkELpn2NvhbT8OmOfHQeienQXPUwHzPBWE7hn2dnjbTwLm+UkQumcXwfN0wDxPB6F7hr0d3vbTgHl+GoTu2VXwPBMwzzNB6J5hb4e3/Sxgnp8FoXt2EzzPBszzbBC6Z9jb4W0/D5jn50Hont0Fz3MB8zwXhO4Z9nZ42y8C5vlFELpnD8HzfMA8zwehe4a9Hd72y4B5fhmE7tlT8LwQMM8LQeieYW+Ht/0qYJ5fBaF79hI8LwbM82IQumfY2+Ftvw6Y59dB6J69Bc9LAfO8FITuGfZ2eNtvAub5TRC6Zx/B83LAPC8HoXuGvR3e9tuAeX4bhO7ZV/C8EjDPK0HonmFvh7f9LmCe3wWhe/YTPK8GzPNqELpn2Nvhbb8PmOf3Qeie/QXPawHzvBaE7hn2dnjbHwLm+UMQuucAwfN6wDyvB6F7hr0d3vbHgHn+GITuOVDwvBEwzxtB6J5hb4e3/Slgnj8FoXsOEjxvBszzZhC6Z9jb4W1/Dpjnz0HonoMFz1sB87wVhO4Z9nZ4218C5vlLELrnEMHzdsA8bwehe4a9Hd7214B5/hqE7jlU8LwTMM87QeieYW+Ht/0tYJ6/BaF7DhM87wbM824QumfY2+Ft7wXM814QuudwwfN+wDzvB6F7hr0d3vb3gHn+HoTuOULwfBAwzwdB6J5hb4e3/SNgnn8EoXuOFDwfBszzYRC6Z9jb4W3/DJjnn0HonqMEz0cB83wUhO4Z9nZ428cB83wchO45WvB8EjDPJ0HonmFvh7f9K2CefwWhe44RPJ8GzPNpELpn2Nvhbf8OmOffQeieYwXPZwHzfBaE7hn2dnjbfwLm+U8Quuc4wfN5wDyfB6F7hr0d3vbfgHn+G4TuOV7wfBEwzxdB6J5hb4e3fRkwz5dB6J4TBM9XAfN8FYTuGfZ2eNvXAfN8HYTuOVHwfBMwzzdB6J5hb4e3fRswz7dB6J6TBM93AfN8F4TuGfZ2eNv3yjPP/74L1XOy4BmhPPOMUD50z7C3w9tGhJ4RDZ5TBM9I0DOSwTOS4BkZekY2eE4VPKNAzygGzyiCZ1ToGdXgOU3wjAY9oxk8owme0aFndIPndMEzBvSMYfCMIXjGhJ4xDZ4zBM9Y0DOWwTOW4BkbesY2eM4UPONAzzgGzziCZ1zoGdfgOUvwjAc94xk84wme8aFnfIPnbMEzAfRMYPBMIHgmhJ4JDZ5zBM9E0DORwTOR4JkYeiY2eM4VPJNAzyQGzySCZ1LomdTgOU/wTAY9kxk8kwmeyaFncoPnfMEzBfRMYfBMIXimhJ4pDZ4LBM9U0DOVwTOV4JkaeqY2eC4UPNNAzzQGzzSCZ1romdbguUjwTAc90xk80wme6aFneoPnYsEzA/TMYPDMIHhmhJ4ZDZ5LBM9M0DOTwTOT4JkZemY2eC4VPLNAzywGzyyCZ1bomdXguUzwzAY9sxk8swme2aFndoPncsEzB/TMYfDMIXjmhJ45DZ4rBM9c0DOXwTOX4JkbeuY2eK4UPPNAzzwGzzyCZ17omdfguUrwzAc98xk88wme+aFnfoPnasGzAPQsYPAsIHgWhJ4FDZ5rBM9C0LOQwbOQ4FkYehY2eK4VPItAzyIGzyKCZ1HoWdTguU7wLAY9ixk8iwmexaFncYPnesGzBPQsYfAsIXiWhJ4lDZ4bBM9S0LOUwbOU4FkaepY2eG4UPMtAzzIGzzKCZ1noWdbguUnwLAc9yxk8ywmeAfQMDJ6bBc/y0LO8wbO84FkBelYweG4RPCtCz4oGz4qCZyXoWcnguVXwrAw9Kxs8KwueVaBnFYPnNsGzKvSsavCsKnhWg57VDJ7bBc/q0LO6wbO64FkDetYweO4QPGtCz5oGz5qCZy3oWcvguVPwrA09axs8awuedaBnHYPnLsGzLvSsa/CsK3jWg571DJ67Bc/60LO+wbO+4NkAejYweO4RPBtCz4YGz4aCZyPo2cjguVfwbAw9Gxs8GwueTaBnE4PnPsGzKfRsavBsKng2g57NDJ77Bc/m0LO5wbO54NkCerYweB4QPFtCz5YGz5aCZyvo2crgeVDwbA09Wxs8WwuebaBnG4Pn+4JnW+jZ1uDZVvBsBz3bGTwPCZ7toWd7g2d7wbMD9Oxg8DwseHaEnh0Nnh0Fz07Qs5PB84jg2Rl6djZ4dhY8u0DPLgbPo4JnV+jZ1eDZVfDsBj27GTyPCZ7doWd3g2d3wbMH9Oxh8PxA8OwJPXsaPHsKnr2gZy+D53HBszf07G3w7C149oGefQyeHwqefaFnX4NnX8GzH/TsZ/A8IXj2h579DZ79Bc8B0HOAwfMjwXMg9Bxo8BwoeA6CnoMMnicFz8HQc7DBc7DgOQR6DjF4fix4DoWeQw2eQwXPYdBzmMHzlOA5HHoON3gOFzxHQM8RBs9PBM+R0HOkwXOk4DkKeo4yeJ4WPEdDz9EGz9GC5xjoOcbg+angORZ6jjV4jhU8x0HPcQbPM4LneOg53uA5XvCcAD0nGDw/EzwnQs+JBs+Jguck6DnJ4HlW8JwMPScbPCcLnlOg5xSD5+eC51ToOdXgOVXwnAY9pxk8zwme06HndIPndMFzBvScYfD8QvCcCT1nGjxnCp6zoOcsg+d5wXM29Jxt8JwteM6BnnMMnl8KnnOh51yD51zBcx70nGfwvCB4zoee8w2e8wXPBdBzgcHzK8FzIfRcaPBcKHgugp6LDJ4XBc/F0HOxwXOx4LkEei4xeH4teC6FnksNnksFz2XQc5nB85LguRx6Ljd4Lhc8V0DPFQbPbwTPldBzpcFzpeC5CnquMnheFjxXQ8/VBs/Vguca6LnG4Pmt4LkWeq41eK4VPNdBz3UGzyuC53roud7guV7w3AA9Nxg8vxM8N0LPjQbPjYLnJui5yeB5VfDcDD03Gzw3C55boOcWg+f3gudW6LnV4LlV8NwGPbcZPK8Jntuh53aD53bBcwf03GHw/EHw3Ak9dxo8dwqeu6DnLoPndcFzN/TcbfDcLXjugZ57DJ4/Cp57oedeg+dewXMf9Nxn8LwheO6HnvsNnvsFzwPQ84DB8yfB8yD0PGjwPCh4vg893zd43hQ8D0HPQwbPQ4LnYeh52OD5s+B5BHoeMXgeETyPQs+jBs9bgucx6HnM4HlM8PwAen5g8PxF8DwOPY8bPI8Lnh9Czw8NnrcFzxPQ84TB84Tg+RH0/Mjg+avgeRJ6njR4nhQ8P4aeHxs87wiep6DnKYPnKcHzE+j5icHzN8HzNPQ8bfA8LXh+Cj0/NXjeFTzPQM8zBs8zgudn0PMzg+c9wfMs9Dxr8DwreH4OPT83eN4XPM9Bz3MGz3OC5xfQ8wuD5++C53noed7geV7w/BJ6fmnwfCB4XoCeFwyeFwTPr6DnVwbPPwTPi9DzosHzouD5NfT82uD5UPC8BD0vGTwvCZ7fQM9vDJ5/Cp6Xoedlg+dlwfNb6PmtwfOR4HkFel4xeF4RPL+Dnt8ZPB8Lnleh51WD51XB83vo+b3B84ngeQ16XjN4XhM8f4CePxg8/xI8r0PP6wbP64Lnj9DzR4PnU8HzBvS8YfC8IXj+BD1/Mnj+LXjehJ43DZ43Bc+foefPBs9nguct6HnL4HlL8PwFev5i8PxH8LwNPW8bPG8Lnr9Cz18Nns8FzzvQ847B847g+Rv0/M3g+a/geRd63jV43hU870HPewbPF4Lnfeh53+B5X/D8HXr+bvB8KXg+gJ4PDJ4PBM8/oOcfBs9XgudD6PnQ4PlQ8PwTev5p8HwteD6Cno8Mno8Ez8fQ87HB843g+QR6PjF4PhE8/4Kefxk83wqeT6HnU4PnU8Hzb+j5t8HzneD5DHo+M3g+Ezz/gZ7/GDzfS/K/v/M59Hxu8HwueP4LPf81eEYQPF9AzxcGzxeC50vo+dLgGVHwfAU9Xxk8Xwmer6Hna4NnJMHzDfR8Y/B8I3i+hZ5vDZ6RBc930POdwfOd4PleBeb533ehekYRPCNUYJ4RKoTuGfZ2eNuI0DOiwTOq4BkJekYyeEYSPCNDz8gGz2iCZxToGcXgGUXwjAo9oxo8owue0aBnNINnNMEzOvSMbvCMIXjGgJ4xDJ4xBM+Y0DOmwTOm4BkLesYyeMYSPGNDz9gGz1iCZxzoGcfgGUfwjAs94xo8Ywue8aBnPINnPMEzPvSMb/CMI3gmgJ4JDJ4JBM+E0DOhwTOu4JkIeiYyeCYSPBNDz8QGz3iCZxLomcTgmUTwTAo9kxo84wueyaBnMoNnMsEzOfRMbvBMIHimgJ4pDJ4pBM+U0DOlwTOh4JkKeqYyeKYSPFNDz9QGz0SCZxromcbgmUbwTAs90xo8Ewue6aBnOoNnOsEzPfRMb/BMInhmgJ4ZDJ4ZBM+M0DOjwTOp4JkJemYyeGYSPDNDz8wGz2SCZxbomcXgmUXwzAo9sxo8kwue2aBnNoNnNsEzO/TMbvBMIXjmgJ45DJ45BM+c0DOnwTOl4JkLeuYyeOYSPHNDz9wGz1SCZx7omcfgmUfwzAs98xo8Uwue+aBnPoNnPsEzP/TMb/BMI3gWgJ4FDJ4FBM+C0LOgwTOt4FkIehYyeBYSPAtDz8IGz3SCZxHoWcTgWUTwLAo9ixo80wuexaBnMYNnMcGzOPQsbvDMIHiWgJ4lDJ4lBM+S0LOkwTOj4FkKepYyeJYSPEtDz9IGz0yCZxnoWcbgWUbwLAs9yxo8Mwue5aBnOYNnOcEzgJ6BwTOL4FkeepY3eJYXPCtAzwoGz6yCZ0XoWdHgWVHwrAQ9Kxk8swmelaFnZYNnZcGzCvSsYvDMLnhWhZ5VDZ5VBc9q0LOawTOH4FkdelY3eFYXPGtAzxoGz5yCZ03oWdPgWVPwrAU9axk8cwmetaFnbYNnbcGzDvSsY/DMLXjWhZ51DZ51Bc960LOewTOP4FkfetY3eNYXPBtAzwYGz7yCZ0Po2dDg2VDwbAQ9Gxk88wmejaFnY4NnY8GzCfRsYvDML3g2hZ5NDZ5NBc9m0LOZwbOA4NkcejY3eDYXPFtAzxYGz4KCZ0vo2dLg2VLwbAU9Wxk8CwmeraFna4Nna8GzDfRsY/AsLHi2hZ5tDZ5tBc920LOdwbOI4NkeerY3eLYXPDtAzw4Gz6KCZ0fo2dHg2VHw7AQ9Oxk8iwmenaFnZ4NnZ8GzC/TsYvAsLnh2hZ5dDZ5dBc9u0LObwbOE4NkdenY3eHYXPHtAzx4Gz5KCZ0/o2dPg2VPw7AU9exk8SwmevaFnb4Nnb8GzD/TsY/AsLXj2hZ59DZ59Bc9+0LOfwbOM4NkfevY3ePYXPAdAzwEGz7KC50DoOdDgOVDwHAQ9Bxk8ywmeg6HnYIPnYMFzCPQcYvAMBM+h0HOowXOo4DkMeg4zeJYXPIdDz+EGz+GC5wjoOcLgWUHwHAk9Rxo8Rwqeo6DnKINnRcFzNPQcbfAcLXiOgZ5jDJ6VBM+x0HOswXOs4DkOeo4zeFYWPMdDz/EGz/GC5wToOcHgWUXwnAg9Jxo8Jwqek6DnJINnVcFzMvScbPCcLHhOgZ5TDJ7VBM+p0HOqwXOq4DkNek4zeFYXPKdDz+kGz+mC5wzoOcPgWUPwnAk9Zxo8Zwqes6DnLINnTcFzNvScbfCcLXjOgZ5zDJ61BM+50HOuwXOu4DkPes4zeNYWPOdDz/kGz/mC5wLoucDgWUfwXAg9Fxo8Fwqei6DnIoNnXcFzMfRcbPBcLHgugZ5LDJ71BM+l0HOpwXOp4LkMei4zeNYXPJdDz+UGz+WC5wroucLg2UDwXAk9Vxo8Vwqeq6DnKoNnQ8FzNfRcbfBcLXiugZ5rDJ6NBM+10HOtwXOt4LkOeq4zeDYWPNdDz/UGz/WC5wboucHg2UTw3Ag9Nxo8Nwqem6DnJoNnU8FzM/TcbPDcLHhugZ5bDJ7NBM+t0HOrwXOr4LkNem4zeDYXPLdDz+0Gz+2C5w7oucPg2ULw3Ak9dxo8dwqeu6DnLoNnS8FzN/TcbfDcLXjugZ57DJ6tBM+90HOvwXOv4LkPeu4zeLYWPPdDz/0Gz/2C5wHoecDg2UbwPAg9Dxo8Dwqe70PP9w2ebQXPQ9DzkMHzkOB5GHoeNni2EzyPQM8jBs8jgudR6HnU4Nle8DwGPY8ZPI8Jnh9Azw8Mnh0Ez+PQ87jB87jg+SH0/NDg2VHwPAE9Txg8TwieH0HPjwyenQTPk9DzpMHzpOD5MfT82ODZWfA8BT1PGTxPCZ6fQM9PDJ5dBM/T0PO0wfO04Pkp9PzU4NlV8DwDPc8YPM8Inp9Bz88Mnt0Ez7PQ86zB86zg+Tn0/Nzg2V3wPAc9zxk8zwmeX0DPLwyePQTP89DzvMHzvOD5JfT80uDZU/C8AD0vGDwvCJ5fQc+vDJ69BM+L0POiwfOi4Pk19Pza4Nlb8LwEPS8ZPC8Jnt9Az28Mnn0Ez8vQ87LB87Lg+S30/Nbg2VfwvAI9rxg8rwie30HP7wye/QTPq9DzqsHzquD5PfT83uDZX/C8Bj2vGTyvCZ4/QM8fDJ4DBM/r0PO6wfO64Pkj9PzR4DlQ8LwBPW8YPG8Inj9Bz58MnoMEz5vQ86bB86bg+TP0/NngOVjwvAU9bxk8bwmev0DPXwyeQwTP29DztsHztuD5K/T81eA5VPC8Az3vGDzvCJ6/Qc/fDJ7DBM+70POuwfOu4HkPet4zeA4XPO9Dz/sGz/uC5+/Q83eD5wjB8wH0fGDwfCB4/gE9/zB4jhQ8H0LPhwbPh4Lnn9DzT4PnKMHzEfR8ZPB8JHg+hp6PDZ6jBc8n0POJwfOJ4PkX9PzL4DlG8HwKPZ8aPJ8Knn9Dz78NnmMFz2fQ85nB85ng+Q/0/MfgOU7wfA49nxs8nwue/0LPfw2e4wXPF9DzhcHzheD5Enq+NHhOEDxfQc9XBs9Xgudr6Pna4DlR8HwDPd8YPN8Inm+h51uD5yTB8x30fGfwfCd4vleRef73XaiekwXPCBWZZ4SKoXuGvR3eNiL0jGjwnCJ4RoKekQyekQTPyNAzssFzquAZBXpGMXhGETyjQs+oBs9pgmc06BnN4BlN8IwOPaMbPKcLnjGgZwyDZwzBMyb0jGnwnCF4xoKesQyesQTP2NAztsFzpuAZB3rGMXjGETzjQs+4Bs9Zgmc86BnP4BlP8IwPPeMbPGcLngmgZwKDZwLBMyH0TGjwnCN4JoKeiQyeiQTPxNAzscFzruCZBHomMXgmETyTQs+kBs95gmcy6JnM4JlM8EwOPZMbPOcLnimgZwqDZwrBMyX0TGnwXCB4poKeqQyeqQTP1NAztcFzoeCZBnqmMXimETzTQs+0Bs9Fgmc66JnO4JlO8EwPPdMbPBcLnhmgZwaDZwbBMyP0zGjwXCJ4ZoKemQyemQTPzNAzs8FzqeCZBXpmMXhmETyzQs+sBs9lgmc26JnN4JlN8MwOPbMbPJcLnjmgZw6DZw7BMyf0zGnwXCF45oKeuQyeuQTP3NAzt8FzpeCZB3rmMXjmETzzQs+8Bs9Vgmc+6JnP4JlP8MwPPfMbPFcLngWgZwGDZwHBsyD0LGjwXCN4FoKehQyehQTPwtCzsMFzreBZBHoWMXgWETyLQs+iBs91gmcx6FnM4FlM8CwOPYsbPNcLniWgZwmDZwnBsyT0LGnw3CB4loKepQyepQTP0tCztMFzo+BZBnqWMXiWETzLQs+yBs9Ngmc56FnO4FlO8AygZ2Dw3Cx4loee5Q2e5QXPCtCzgsFzi+BZEXpWNHhWFDwrQc9KBs+tgmdl6FnZ4FlZ8KwCPasYPLcJnlWhZ1WDZ1XBsxr0rGbw3C54Voee1Q2e1QXPGtCzhsFzh+BZE3rWNHjWFDxrQc9aBs+dgmdt6Fnb4Flb8KwDPesYPHcJnnWhZ12DZ13Bsx70rGfw3C141oee9Q2e9QXPBtCzgcFzj+DZEHo2NHg2FDwbQc9GBs+9gmdj6NnY4NlY8GwCPZsYPPcJnk2hZ1ODZ1PBsxn0bGbw3C94NoeezQ2ezQXPFtCzhcHzgODZEnq2NHi2FDxbQc9WBs+Dgmdr6Nna4Nla8GwDPdsYPN8XPNtCz7YGz7aCZzvo2c7geUjwbA892xs82wueHaBnB4PnYcGzI/TsaPDsKHh2gp6dDJ5HBM/O0LOzwbOz4NkFenYxeB4VPLtCz64Gz66CZzfo2c3geUzw7A49uxs8uwuePaBnD4PnB4JnT+jZ0+DZU/DsBT17GTyPC569oWdvg2dvwbMP9Oxj8PxQ8OwLPfsaPPsKnv2gZz+D5wnBsz/07G/w7C94DoCeAwyeHwmeA6HnQIPnQMFzEPQcZPA8KXgOhp6DDZ6DBc8h0HOIwfNjwXMo9Bxq8BwqeA6DnsMMnqcEz+HQc7jBc7jgOQJ6jjB4fiJ4joSeIw2eIwXPUdBzlMHztOA5GnqONniOFjzHQM8xBs9PBc+x0HOswXOs4DkOeo4zeJ4RPMdDz/EGz/GC5wToOcHg+ZngORF6TjR4ThQ8J0HPSQbPs4LnZOg52eA5WfCcAj2nGDw/FzynQs+pBs+pguc06DnN4HlO8JwOPacbPKcLnjOg5wyD5xeC50zoOdPgOVPwnAU9Zxk8zwues6HnbIPnbMFzDvScY/D8UvCcCz3nGjznCp7zoOc8g+cFwXM+9Jxv8JwveC6AngsMnl8Jnguh50KD50LBcxH0XGTwvCh4Loaeiw2eiwXPJdBzicHza8FzKfRcavBcKngug57LDJ6XBM/l0HO5wXO54LkCeq4weH4jeK6EnisNnisFz1XQc5XB87LguRp6rjZ4rhY810DPNQbPbwXPtdBzrcFzreC5DnquM3heETzXQ8/1Bs/1gucG6LnB4Pmd4LkRem40eG4UPDdBz00Gz6uC52boudnguVnw3AI9txg8vxc8t0LPrQbPrYLnNui5zeB5TfDcDj23Gzy3C547oOcOg+cPgudO6LnT4LlT8NwFPXcZPK8Lnruh526D527Bcw/03GPw/FHw3As99xo89wqe+6DnPoPnDcFzP/Tcb/DcL3gegJ4HDJ4/CZ4HoedBg+dBwfN96Pm+wfOm4HkIeh4yeB4SPA9Dz8MGz58FzyPQ84jB84jgeRR6HjV43hI8j0HPYwbPY4LnB9DzA4PnL4Lnceh53OB5XPD8EHp+aPC8LXiegJ4nDJ4nBM+PoOdHBs9fBc+T0POkwfOk4Pkx9PzY4HlH8DwFPU8ZPE8Jnp9Az08Mnr8Jnqeh52mD52nB81Po+anB867geQZ6njF4nhE8P4Oenxk87wmeZ6HnWYPnWcHzc+j5ucHzvuB5DnqeM3ieEzy/gJ5fGDx/FzzPQ8/zBs/zgueX0PNLg+cDwfMC9Lxg8LwgeH4FPb8yeP4heF6EnhcNnhcFz6+h59cGz4eC5yXoecngeUnw/AZ6fmPw/FPwvAw9Lxs8Lwue30LPbw2ejwTPK9DzisHziuD5HfT8zuD5WPC8Cj2vGjyvCp7fQ8/vDZ5PBM9r0POawfOa4PkD9PzB4PmX4Hkdel43eF4XPH+Enj8aPJ8Knjeg5w2D5w3B8yfo+ZPB82/B8yb0vGnwvCl4/gw9fzZ4PhM8b0HPWwbPW4LnL9DzF4PnP4Lnbeh52+B5W/D8FXr+avB8LnjegZ53DJ53BM/foOdvBs9/Bc+70POuwfOu4HkPet4zeL4QPO9Dz/sGz/uC5+/Q83eD50vB8wH0fGDwfCB4/gE9/zB4vhI8H0LPhwbPh4Lnn9DzT4Pna8HzEfR8ZPB8JHg+hp6PDZ5vBM8n0POJwfOJ4PkX9PzL4PlW8HwKPZ8aPJ8Knn9Dz78Nnu8Ez2fQ85nB85ng+Q/0/Mfg+V7S//2dz6Hnc4Pnc8HzX+j5r8EzQtr//Z0v/vd3Fgz7zv++ixbOO5Xb4W1f/u/v7Bj2nS//h3eG84sQUfB8BT1fGTxfCZ6voedrg2ckwfMN9Hxj8HwjeL6Fnm8NnpEFz3fQ853B853g+V4l5vnfd6F6RhE8I1RinhEqhe4Z9nZ424jQM6LBM6rgGQl6RjJ4RhI8I0PPyAbPaIJnFOgZxeAZRfCMCj2jGjyjC57RoGc0g2c0wTM69Ixu8IwheMaAnjEMnjEEz5jQM6bBM6bgGQt6xjJ4xhI8Y0PP2AbPWIJnHOgZx+AZR/CMCz3jGjxjC57xoGc8g2c8wTM+9Ixv8IwjeCaAngkMngkEz4TQM6HBM67gmQh6JjJ4JhI8E0PPxAbPeIJnEuiZxOCZRPBMCj2TGjzjC57JoGcyg2cywTM59Exu8EwgeKaAnikMnikEz5TQM6XBM6HgmQp6pjJ4phI8U0PP1AbPRIJnGuiZxuCZRvBMCz3TGjwTC57poGc6g2c6wTM99Exv8EwieGaAnhkMnhkEz4zQM6PBM6ngmQl6ZjJ4ZhI8M0PPzAbPZIJnFuiZxeCZRfDMCj2zGjyTC57ZoGc2g2c2wTM79Mxu8EwheOaAnjkMnjkEz5zQM6fBM6XgmQt65jJ45hI8c0PP3AbPVIJnHuiZx+CZR/DMCz3zGjxTC575oGc+g2c+wTM/9Mxv8EwjeBaAngUMngUEz4LQs6DBM63gWQh6FjJ4FhI8C0PPwgbPdIJnEehZxOBZRPAsCj2LGjzTC57FoGcxg2cxwbM49Cxu8MwgeJaAniUMniUEz5LQs6TBM6PgWQp6ljJ4lhI8S0PP0gbPTIJnGehZxuBZRvAsCz3LGjwzC57loGc5g2c5wTOAnoHBM4vgWR56ljd4lhc8K0DPCgbPrIJnRehZ0eBZUfCsBD0rGTyzCZ6VoWdlg2dlwbMK9Kxi8MwueFaFnlUNnlUFz2rQs5rBM4fgWR16Vjd4Vhc8a0DPGgbPnIJnTehZ0+BZU/CsBT1rGTxzCZ61oWdtg2dtwbMO9Kxj8MwteNaFnnUNnnUFz3rQs57BM4/gWR961jd41hc8G0DPBgbPvIJnQ+jZ0ODZUPBsBD0bGTzzCZ6NoWdjg2djwbMJ9Gxi8MwveDaFnk0Nnk0Fz2bQs5nBs4Dg2Rx6Njd4Nhc8W0DPFgbPgoJnS+jZ0uDZUvBsBT1bGTwLCZ6toWdrg2drwbMN9Gxj8CwseLaFnm0Nnm0Fz3bQs53Bs4jg2R56tjd4thc8O0DPDgbPooJnR+jZ0eDZUfDsBD07GTyLCZ6doWdng2dnwbML9Oxi8CwueHaFnl0Nnl0Fz27Qs5vBs4Tg2R16djd4dhc8e0DPHgbPkoJnT+jZ0+DZU/DsBT17GTxLCZ69oWdvg2dvwbMP9Oxj8CwtePaFnn0Nnn0Fz37Qs5/Bs4zg2R969jd49hc8B0DPAQbPsoLnQOg50OA5UPAcBD0HGTzLCZ6Doedgg+dgwXMI9Bxi8AwEz6HQc6jBc6jgOQx6DjN4lhc8h0PP4QbP4YLnCOg5wuBZQfAcCT1HGjxHCp6joOcog2dFwXM09Bxt8BwteI6BnmMMnpUEz7HQc6zBc6zgOQ56jjN4VhY8x0PP8QbP8YLnBOg5weBZRfCcCD0nGjwnCp6ToOckg2dVwXMy9Jxs8JwseE6BnlMMntUEz6nQc6rBc6rgOQ16TjN4Vhc8p0PP6QbP6YLnDOg5w+BZQ/CcCT1nGjxnCp6zoOcsg2dNwXM29Jxt8JwteM6BnnMMnrUEz7nQc67Bc67gOQ96zjN41hY850PP+QbP+YLnAui5wOBZR/BcCD0XGjwXCp6LoOcig2ddwXMx9Fxs8FwseC6BnksMnvUEz6XQc6nBc6nguQx6LjN41hc8l0PP5QbP5YLnCui5wuDZQPBcCT1XGjxXCp6roOcqg2dDwXM19Fxt8FwteK6BnmsMno0Ez7XQc63Bc63guQ56rjN4NhY810PP9QbP9YLnBui5weDZRPDcCD03Gjw3Cp6boOcmg2dTwXMz9Nxs8NwseG6BnlsMns0Ez63Qc6vBc6vguQ16bjN4Nhc8t0PP7QbP7YLnDui5w+DZQvDcCT13Gjx3Cp67oOcug2dLwXM39Nxt8NwteO6BnnsMnq0Ez73Qc6/Bc6/guQ967jN4thY890PP/QbP/YLnAeh5wODZRvA8CD0PGjwPCp7vQ8/3DZ5tBc9D0POQwfOQ4HkYeh42eLYTPI9AzyMGzyOC51HoedTg2V7wPAY9jxk8jwmeH0DPDwyeHQTP49DzuMHzuOD5IfT80ODZUfA8AT1PGDxPCJ4fQc+PDJ6dBM+T0POkwfOk4Pkx9PzY4NlZ8DwFPU8ZPE8Jnp9Az08Mnl0Ez9PQ87TB87Tg+Sn0/NTg2VXwPAM9zxg8zwien0HPzwye3QTPs9DzrMHzrOD5OfT83ODZXfA8Bz3PGTzPCZ5fQM8vDJ49BM/z0PO8wfO84Pkl9PzS4NlT8LwAPS8YPC8Inl9Bz68Mnr0Ez4vQ86LB86Lg+TX0/Nrg2VvwvAQ9Lxk8Lwme30DPbwyefQTPy9DzssHzsuD5LfT81uDZV/C8Aj2vGDyvCJ7fQc/vDJ79BM+r0POqwfOq4Pk99Pze4Nlf8LwGPa8ZPK8Jnj9Azx8MngMEz+vQ87rB87rg+SP0/NHgOVDwvAE9bxg8bwieP0HPnwyegwTPm9DzpsHzpuD5M/T82eA5WPC8BT1vGTxvCZ6/QM9fDJ5DBM/b0PO2wfO24Pkr9PzV4DlU8LwDPe8YPO8Inr9Bz98MnsMEz7vQ867B867geQ963jN4Dhc870PP+wbP+4Ln79Dzd4PnCMHzAfR8YPB8IHj+AT3/MHiOFDwfQs+HBs+Hguef0PNPg+cowfMR9Hxk8HwkeD6Gno8NnqMFzyfQ84nB84ng+Rf0/MvgOUbwfAo9nxo8nwqef0PPvw2eYwXPZ9DzmcHzmeD5D/T8x+A5TvB8Dj2fGzyfC57/Qs9/DZ7jBc8X0POFwfOF4PkSer40eE4QPF9Bz1cGz1eC52vo+drgOVHwfAM93xg83wieb6HnW4PnJMHzHfR8Z/B8J3i+V5l5/vddqJ6TBc8IlZlnhMqhe4a9Hd42IvSMaPCcInhGgp6RDJ6RBM/I0DOywXOq4BkFekYxeEYRPKNCz6gGz2mCZzToGc3gGU3wjA49oxs8pwueMaBnDINnDMEzJvSMafCcIXjGgp6xDJ6xBM/Y0DO2wXOm4BkHesYxeMYRPONCz7gGz1mCZzzoGc/gGU/wjA894xs8ZwueCaBnAoNnAsEzIfRMaPCcI3gmgp6JDJ6JBM/E0DOxwXOu4JkEeiYxeCYRPJNCz6QGz3mCZzLomczgmUzwTA49kxs85wueKaBnCoNnCsEzJfRMafBcIHimgp6pDJ6pBM/U0DO1wXOh4JkGeqYxeKYRPNNCz7QGz0WCZzromc7gmU7wTA890xs8FwueGaBnBoNnBsEzI/TMaPBcInhmgp6ZDJ6ZBM/M0DOzwXOp4JkFemYxeGYRPLNCz6wGz2WCZzbomc3gmU3wzA49sxs8lwueOaBnDoNnDsEzJ/TMafBcIXjmgp65DJ65BM/c0DO3wXOl4JkHeuYxeOYRPPNCz7wGz1WCZz7omc/gmU/wzA898xs8VwueBaBnAYNnAcGzIPQsaPBcI3gWgp6FDJ6FBM/C0LOwwXOt4FkEehYxeBYRPItCz6IGz3WCZzHoWczgWUzwLA49ixs81wueJaBnCYNnCcGzJPQsafDcIHiWgp6lDJ6lBM/S0LO0wXOj4FkGepYxeJYRPMtCz7IGz02CZznoWc7gWU7wDKBnYPDcLHiWh57lDZ7lBc8K0LOCwXOL4FkRelY0eFYUPCtBz0oGz62CZ2XoWdngWVnwrAI9qxg8twmeVaFnVYNnVcGzGvSsZvDcLnhWh57VDZ7VBc8a0LOGwXOH4FkTetY0eNYUPGtBz1oGz52CZ23oWdvgWVvwrAM96xg8dwmedaFnXYNnXcGzHvSsZ/DcLXjWh571DZ71Bc8G0LOBwXOP4NkQejY0eDYUPBtBz0YGz72CZ2Po2djg2VjwbAI9mxg89wmeTaFnU4NnU8GzGfRsZvDcL3g2h57NDZ7NBc8W0LOFwfOA4NkSerY0eLYUPFtBz1YGz4OCZ2vo2drg2VrwbAM92xg83xc820LPtgbPtoJnO+jZzuB5SPBsDz3bGzzbC54doGcHg+dhwbMj9Oxo8OwoeHaCnp0MnkcEz87Qs7PBs7Pg2QV6djF4HhU8u0LPrgbProJnN+jZzeB5TPDsDj27Gzy7C549oGcPg+cHgmdP6NnT4NlT8OwFPXsZPI8Lnr2hZ2+DZ2/Bsw/07GPw/FDw7As9+xo8+wqe/aBnP4PnCcGzP/Tsb/DsL3gOgJ4DDJ4fCZ4DoedAg+dAwXMQ9Bxk8DwpeA6GnoMNnoMFzyHQc4jB82PBcyj0HGrwHCp4DoOewwyepwTP4dBzuMFzuOA5AnqOMHh+IniOhJ4jDZ4jBc9R0HOUwfO04Dkaeo42eI4WPMdAzzEGz08Fz7HQc6zBc6zgOQ56jjN4nhE8x0PP8QbP8YLnBOg5weD5meA5EXpONHhOFDwnQc9JBs+zgudk6DnZ4DlZ8JwCPacYPD8XPKdCz6kGz6mC5zToOc3geU7wnA49pxs8pwueM6DnDIPnF4LnTOg50+A5U/CcBT1nGTzPC56zoedsg+dswXMO9Jxj8PxS8JwLPecaPOcKnvOg5zyD5wXBcz70nG/wnC94LoCeCwyeXwmeC6HnQoPnQsFzEfRcZPC8KHguhp6LDZ6LBc8l0HOJwfNrwXMp9Fxq8FwqeC6DnssMnpcEz+XQc7nBc7nguQJ6rjB4fiN4roSeKw2eKwXPVdBzlcHzsuC5GnquNniuFjzXQM81Bs9vBc+10HOtwXOt4LkOeq4zeF4RPNdDz/UGz/WC5wboucHg+Z3guRF6bjR4bhQ8N0HPTQbPq4LnZui52eC5WfDcAj23GDy/Fzy3Qs+tBs+tguc26LnN4HlN8NwOPbcbPLcLnjug5w6D5w+C507oudPguVPw3AU9dxk8rwueu6HnboPnbsFzD/TcY/D8UfDcCz33Gjz3Cp77oOc+g+cNwXM/9Nxv8NwveB6AngcMnj8Jngeh50GD50HB833o+b7B86bgeQh6HjJ4HhI8D0PPwwbPnwXPI9DziMHziOB5FHoeNXjeEjyPQc9jBs9jgucH0PMDg+cvgudx6Hnc4Hlc8PwQen5o8LwteJ6AnicMnicEz4+g50cGz18Fz5PQ86TB86Tg+TH0/NjgeUfwPAU9Txk8Twmen0DPTwyevwmep6HnaYPnacHzU+j5qcHzruB5BnqeMXieETw/g56fGTzvCZ5noedZg+dZwfNz6Pm5wfO+4HkOep4zeJ4TPL+Anl8YPH8XPM9Dz/MGz/OC55fQ80uD5wPB8wL0vGDwvCB4fgU9vzJ4/iF4XoSeFw2eFwXPr6Hn1wbPh4LnJeh5yeB5SfD8Bnp+Y/D8U/C8DD0vGzwvC57fQs9vDZ6PBM8r0POKwfOK4Pkd9PzO4PlY8LwKPa8aPK8Knt9Dz+8Nnk8Ez2vQ85rB85rg+QP0/MHg+ZfgeR16Xjd4Xhc8f4SePxo8nwqeN6DnDYPnDcHzJ+j5k8Hzb8HzJvS8afC8KXj+DD1/Nng+EzxvQc9bBs9bgucv0PMXg+c/gudt6Hnb4Hlb8PwVev5q8HwueN6BnncMnncEz9+g528Gz38Fz7vQ867B867geQ963jN4vhA870PP+wbP+4Ln79Dzd4PnS8HzAfR8YPB8IHj+AT3/MHi+EjwfQs+HBs+Hguef0PNPg+drwfMR9Hxk8HwkeD6Gno8Nnm8EzyfQ84nB84ng+Rf0/Mvg+VbwfAo9nxo8nwqef0PPvw2e7wTPZ9DzmcHzmeD5D/T8x+D5Xrr//Z3Poedzg+dzwfNf6PmvwTOC4PkCer4weL4QPF9Cz5cGz4iC5yvo+crg+UrwfA09Xxs8Iwmeb6DnG4PnG8HzLfR8a/CMLHi+g57vDJ7vBM/3qjDP/74L1TOK4BmhCvOMUCV0z7C3w9tGhJ4RDZ5RBc9I0DOSwTOS4BkZekY2eEYTPKNAzygGzyiCZ1ToGdXgGV3wjAY9oxk8owme0aFndINnDMEzBvSMYfCMIXjGhJ4xDZ4xBc9Y0DOWwTOW4BkbesY2eMYSPONAzzgGzziCZ1zoGdfgGVvwjAc94xk84wme8aFnfINnHMEzAfRMYPBMIHgmhJ4JDZ5xBc9E0DORwTOR4JkYeiY2eMYTPJNAzyQGzySCZ1LomdTgGV/wTAY9kxk8kwmeyaFncoNnAsEzBfRMYfBMIXimhJ4pDZ4JBc9U0DOVwTOV4JkaeqY2eCYSPNNAzzQGzzSCZ1romdbgmVjwTAc90xk80wme6aFneoNnEsEzA/TMYPDMIHhmhJ4ZDZ5JBc9M0DOTwTOT4JkZemY2eCYTPLNAzywGzyyCZ1bomdXgmVzwzAY9sxk8swme2aFndoNnCsEzB/TMYfDMIXjmhJ45DZ4pBc9c0DOXwTOX4JkbeuY2eKYSPPNAzzwGzzyCZ17omdfgmVrwzAc98xk88wme+aFnfoNnGsGzAPQsYPAsIHgWhJ4FDZ5pBc9C0LOQwbOQ4FkYehY2eKYTPItAzyIGzyKCZ1HoWdTgmV7wLAY9ixk8iwmexaFncYNnBsGzBPQsYfAsIXiWhJ4lDZ4ZBc9S0LOUwbOU4FkaepY2eGYSPMtAzzIGzzKCZ1noWdbgmVnwLAc9yxk8ywmeAfQMDJ5ZBM/y0LO8wbO84FkBelYweGYVPCtCz4oGz4qCZyXoWcngmU3wrAw9Kxs8KwueVaBnFYNndsGzKvSsavCsKnhWg57VDJ45BM/q0LO6wbO64FkDetYweOYUPGtCz5oGz5qCZy3oWcvgmUvwrA09axs8awuedaBnHYNnbsGzLvSsa/CsK3jWg571DJ55BM/60LO+wbO+4NkAejYweOYVPBtCz4YGz4aCZyPo2cjgmU/wbAw9Gxs8GwueTaBnE4NnfsGzKfRsavBsKng2g57NDJ4FBM/m0LO5wbO54NkCerYweBYUPFtCz5YGz5aCZyvo2crgWUjwbA09Wxs8WwuebaBnG4NnYcGzLfRsa/BsK3i2g57tDJ5FBM/20LO9wbO94NkBenYweBYVPDtCz44Gz46CZyfo2cngWUzw7Aw9Oxs8OwueXaBnF4NnccGzK/TsavDsKnh2g57dDJ4lBM/u0LO7wbO74NkDevYweJYUPHtCz54Gz56CZy/o2cvgWUrw7A09exs8ewuefaBnH4NnacGzL/Tsa/DsK3j2g579DJ5lBM/+0LO/wbO/4DkAeg4weJYVPAdCz4EGz4GC5yDoOcjgWU7wHAw9Bxs8BwueQ6DnEINnIHgOhZ5DDZ5DBc9h0HOYwbO84Dkceg43eA4XPEdAzxEGzwqC50joOdLgOVLwHAU9Rxk8Kwqeo6HnaIPnaMFzDPQcY/CsJHiOhZ5jDZ5jBc9x0HOcwbOy4Dkeeo43eI4XPCdAzwkGzyqC50ToOdHgOVHwnAQ9Jxk8qwqek6HnZIPnZMFzCvScYvCsJnhOhZ5TDZ5TBc9p0HOawbO64Dkdek43eE4XPGdAzxkGzxqC50zoOdPgOVPwnAU9Zxk8awqes6HnbIPnbMFzDvScY/CsJXjOhZ5zDZ5zBc950HOewbO24Dkfes43eM4XPBdAzwUGzzqC50LoudDguVDwXAQ9Fxk86wqei6HnYoPnYsFzCfRcYvCsJ3guhZ5LDZ5LBc9l0HOZwbO+4Lkcei43eC4XPFdAzxUGzwaC50roudLguVLwXAU9Vxk8Gwqeq6HnaoPnasFzDfRcY/BsJHiuhZ5rDZ5rBc910HOdwbOx4Lkeeq43eK4XPDdAzw0GzyaC50boudHguVHw3AQ9Nxk8mwqem6HnZoPnZsFzC/TcYvBsJnhuhZ5bDZ5bBc9t0HObwbO54Lkdem43eG4XPHdAzx0GzxaC507oudPguVPw3AU9dxk8Wwqeu6HnboPnbsFzD/TcY/BsJXjuhZ57DZ57Bc990HOfwbO14Lkfeu43eO4XPA9AzwMGzzaC50HoedDgeVDwfB96vm/wbCt4HoKehwyehwTPw9DzsMGzneB5BHoeMXgeETyPQs+jBs/2gucx6HnM4HlM8PwAen5g8OwgeB6HnscNnscFzw+h54cGz46C5wnoecLgeULw/Ah6fmTw7CR4noSeJw2eJwXPj6HnxwbPzoLnKeh5yuB5SvD8BHp+YvDsIniehp6nDZ6nBc9PoeenBs+ugucZ6HnG4HlG8PwMen5m8OwmeJ6FnmcNnmcFz8+h5+cGz+6C5znoec7geU7w/AJ6fmHw7CF4noee5w2e5wXPL6HnlwbPnoLnBeh5weB5QfD8Cnp+ZfDsJXhehJ4XDZ4XBc+voefXBs/egucl6HnJ4HlJ8PwGen5j8OwjeF6GnpcNnpcFz2+h57cGz76C5xXoecXgeUXw/A56fmfw7Cd4XoWeVw2eVwXP76Hn9wbP/oLnNeh5zeB5TfD8AXr+YPAcIHheh57XDZ7XBc8foeePBs+BgucN6HnD4HlD8PwJev5k8BwkeN6EnjcNnjcFz5+h588Gz8GC5y3oecvgeUvw/AV6/mLwHCJ43oaetw2etwXPX6HnrwbPoYLnHeh5x+B5R/D8DXr+ZvAcJnjehZ53DZ53Bc970POewXO44Hkfet43eN4XPH+Hnr8bPEcIng+g5wOD5wPB8w/o+YfBc6Tg+RB6PjR4PhQ8/4Sefxo8Rwmej6DnI4PnI8HzMfR8bPAcLXg+gZ5PDJ5PBM+/oOdfBs8xgudT6PnU4PlU8Pwbev5t8BwreD6Dns8Mns8Ez3+g5z8Gz3GC53Po+dzg+Vzw/Bd6/mvwHC94voCeLwyeLwTPl9DzpcFzguD5Cnq+Mni+EjxfQ8/XBs+Jgucb6PnG4PlG8HwLPd8aPCcJnu+g5zuD5zvB872qzPO/70L1nCx4RqjKPCNUDd0z7O3wthGhZ0SD5xTBMxL0jGTwjCR4RoaekQ2eUwXPKNAzisEziuAZFXpGNXhOEzyjQc9oBs9ogmd06Bnd4Dld8IwBPWMYPGMInjGhZ0yD5wzBMxb0jGXwjCV4xoaesQ2eMwXPONAzjsEzjuAZF3rGNXjOEjzjQc94Bs94gmd86Bnf4Dlb8EwAPRMYPBMIngmhZ0KD5xzBMxH0TGTwTCR4JoaeiQ2ecwXPJNAzicEzieCZFHomNXjOEzyTQc9kBs9kgmdy6Jnc4Dlf8EwBPVMYPFMInimhZ0qD5wLBMxX0TGXwTCV4poaeqQ2eCwXPNNAzjcEzjeCZFnqmNXguEjzTQc90Bs90gmd66Jne4LlY8MwAPTMYPDMInhmhZ0aD5xLBMxP0zGTwzCR4ZoaemQ2eSwXPLNAzi8Ezi+CZFXpmNXguEzyzQc9sBs9sgmd26Jnd4Llc8MwBPXMYPHMInjmhZ06D5wrBMxf0zGXwzCV45oaeuQ2eKwXPPNAzj8Ezj+CZF3rmNXiuEjzzQc98Bs98gmd+6Jnf4Lla8CwAPQsYPAsIngWhZ0GD5xrBsxD0LGTwLCR4FoaehQ2eawXPItCziMGziOBZFHoWNXiuEzyLQc9iBs9igmdx6Fnc4Lle8CwBPUsYPEsIniWhZ0mD5wbBsxT0LGXwLCV4loaepQ2eGwXPMtCzjMGzjOBZFnqWNXhuEjzLQc9yBs9ygmcAPQOD52bBszz0LG/wLC94VoCeFQyeWwTPitCzosGzouBZCXpWMnhuFTwrQ8/KBs/KgmcV6FnF4LlN8KwKPasaPKsKntWgZzWD53bBszr0rG7wrC541oCeNQyeOwTPmtCzpsGzpuBZC3rWMnjuFDxrQ8/aBs/agmcd6FnH4LlL8KwLPesaPOsKnvWgZz2D527Bsz70rG/wrC94NoCeDQyeewTPhtCzocGzoeDZCHo2MnjuFTwbQ8/GBs/GgmcT6NnE4LlP8GwKPZsaPJsKns2gZzOD537Bszn0bG7wbC54toCeLQyeBwTPltCzpcGzpeDZCnq2MngeFDxbQ8/WBs/Wgmcb6NnG4Pm+4NkWerY1eLYVPNtBz3YGz0OCZ3vo2d7g2V7w7AA9Oxg8DwueHaFnR4NnR8GzE/TsZPA8Inh2hp6dDZ6dBc8u0LOLwfOo4NkVenY1eHYVPLtBz24Gz2OCZ3fo2d3g2V3w7AE9exg8PxA8e0LPngbPnoJnL+jZy+B5XPDsDT17Gzx7C559oGcfg+eHgmdf6NnX4NlX8OwHPfsZPE8Inv2hZ3+DZ3/BcwD0HGDw/EjwHAg9Bxo8Bwqeg6DnIIPnScFzMPQcbPAcLHgOgZ5DDJ4fC55DoedQg+dQwXMY9Bxm8DwleA6HnsMNnsMFzxHQc4TB8xPBcyT0HGnwHCl4joKeowyepwXP0dBztMFztOA5BnqOMXh+KniOhZ5jDZ5jBc9x0HOcwfOM4Dkeeo43eI4XPCdAzwkGz88Ez4nQc6LBc6LgOQl6TjJ4nhU8J0PPyQbPyYLnFOg5xeD5ueA5FXpONXhOFTynQc9pBs9zgud06Dnd4Dld8JwBPWcYPL8QPGdCz5kGz5mC5yzoOcvgeV7wnA09Zxs8Zwuec6DnHIPnl4LnXOg51+A5V/CcBz3nGTwvCJ7zoed8g+d8wXMB9Fxg8PxK8FwIPRcaPBcKnoug5yKD50XBczH0XGzwXCx4LoGeSwyeXwueS6HnUoPnUsFzGfRcZvC8JHguh57LDZ7LBc8V0HOFwfMbwXMl9Fxp8FwpeK6CnqsMnpcFz9XQc7XBc7XguQZ6rjF4fit4roWeaw2eawXPddBzncHziuC5HnquN3iuFzw3QM8NBs/vBM+N0HOjwXOj4LkJem4yeF4VPDdDz80Gz82C5xboucXg+b3guRV6bjV4bhU8t0HPbQbPa4Lndui53eC5XfDcAT13GDx/EDx3Qs+dBs+dgucu6LnL4Hld8NwNPXcbPHcLnnug5x6D54+C517oudfguVfw3Ac99xk8bwie+6HnfoPnfsHzAPQ8YPD8SfA8CD0PGjwPCp7vQ8/3DZ43Bc9D0POQwfOQ4HkYeh42eP4seB6BnkcMnkcEz6PQ86jB85bgeQx6HjN4HhM8P4CeHxg8fxE8j0PP4wbP44Lnh9DzQ4PnbcHzBPQ8YfA8IXh+BD0/Mnj+KniehJ4nDZ4nBc+PoefHBs87gucp6HnK4HlK8PwEen5i8PxN8DwNPU8bPE8Lnp9Cz08NnncFzzPQ84zB84zg+Rn0/MzgeU/wPAs9zxo8zwqen0PPzw2e9wXPc9DznMHznOD5BfT8wuD5u+B5HnqeN3ieFzy/hJ5fGjwfCJ4XoOcFg+cFwfMr6PmVwfMPwfMi9Lxo8LwoeH4NPb82eD4UPC9Bz0sGz0uC5zfQ8xuD55+C52XoedngeVnw/BZ6fmvwfCR4XoGeVwyeVwTP76DndwbPx4LnVeh51eB5VfD8Hnp+b/B8Inheg57XDJ7XBM8foOcPBs+/BM/r0PO6wfO64Pkj9PzR4PlU8LwBPW8YPG8Inj9Bz58Mnn8Lnjeh502D503B82fo+bPB85ngeQt63jJ43hI8f4Gevxg8/xE8b0PP2wbP24Lnr9DzV4Pnc8HzDvS8Y/C8I3j+Bj1/M3j+K3jehZ53DZ53Bc970POewfOF4Hkfet43eN4XPH+Hnr8bPF8Kng+g5wOD5wPB8w/o+YfB85Xg+RB6PjR4PhQ8/4Sefxo8Xwuej6DnI4PnI8HzMfR8bPB8I3g+gZ5PDJ5PBM+/oOdfBs+3gudT6PnU4PlU8Pwbev5t8HwneD6Dns8Mns8Ez3+g5z8Gz/+G6f/Hdz6Hns8Nns8Fz3+h578GzwhC04v/7Z3R3r3r917Yd/73XeZw3qncDm/78n97Z7x3b3/+/7zz5f/wznB+ESIKTa+g5yuD5yvB8zX0fG3wjCQ0vYGebwyebwTPt9DzrcEzstD0Dnq+M3i+Ezzfq8Y8//suVM8oQlOEaswzQrXQPcPeDm8bEXpGNHhGFZoiQc9IBs9Igmdk6BnZ4BlNaIoCPaMYPKMInlGhZ1SDZ3ShKRr0jGbwjCZ4Roee0Q2eMYSmGNAzhsEzhuAZE3rGNHjGFJpiQc9YBs9Ygmds6Bnb4BlLaIoDPeMYPOMInnGhZ1yDZ2yhKR70jGfwjCd4xoee8Q2ecYSmBNAzgcEzgeCZEHomNHjGFZoSQc9EBs9Egmdi6JnY4BlPaEoCPZMYPJMInkmhZ1KDZ3yhKRn0TGbwTCZ4JoeeyQ2eCYSmFNAzhcEzheCZEnqmNHgmFJpSQc9UBs9Ugmdq6Jna4JlIaEoDPdMYPNMInmmhZ1qDZ2KhKR30TGfwTCd4poee6Q2eSYSmDNAzg8Ezg+CZEXpmNHgmFZoyQc9MBs9Mgmdm6JnZ4JlMaMoCPbMYPLMInlmhZ1aDZ3KhKRv0zGbwzCZ4Zoee2Q2eKYSmHNAzh8Ezh+CZE3rmNHimFJpyQc9cBs9cgmdu6Jnb4JlKaMoDPfMYPPMInnmhZ16DZ2qhKR/0zGfwzCd45oee+Q2eaYSmAtCzgMGzgOBZEHoWNHimFZoKQc9CBs9Cgmdh6FnY4JlOaCoCPYsYPIsInkWhZ1GDZ3qhqRj0LGbwLCZ4FoeexQ2eGYSmEtCzhMGzhOBZEnqWNHhmFJpKQc9SBs9Sgmdp6Fna4JlJaCoDPcsYPMsInmWhZ1mDZ2ahqRz0LGfwLCd4BtAzMHhmEZrKQ8/yBs/ygmcF6FnB4JlVaKoIPSsaPCsKnpWgZyWDZzahqTL0rGzwrCx4VoGeVQye2YWmqtCzqsGzquBZDXpWM3jmEJqqQ8/qBs/qgmcN6FnD4JlTaKoJPWsaPGsKnrWgZy2DZy6hqTb0rG3wrC141oGedQyeuYWmutCzrsGzruBZD3rWM3jmEZrqQ8/6Bs/6gmcD6NnA4JlXaGoIPRsaPBsKno2gZyODZz6hqTH0bGzwbCx4NoGeTQye+YWmptCzqcGzqeDZDHo2M3gWEJqaQ8/mBs/mgmcL6NnC4FlQaGoJPVsaPFsKnq2gZyuDZyGhqTX0bG3wbC14toGebQyehYWmttCzrcGzreDZDnq2M3gWEZraQ8/2Bs/2gmcH6NnB4FlUaOoIPTsaPDsKnp2gZyeDZzGhqTP07Gzw7Cx4doGeXQyexYWmrtCzq8Gzq+DZDXp2M3iWEJq6Q8/uBs/ugmcP6NnD4FlSaOoJPXsaPHsKnr2gZy+DZymhqTf07G3w7C149oGefQyepYWmvtCzr8Gzr+DZD3r2M3iWEZr6Q8/+Bs/+gucA6DnA4FlWaBoIPQcaPAcKnoOg5yCDZzmhaTD0HGzwHCx4DoGeQwyegdA0FHoONXgOFTyHQc9hBs/yQtNw6Dnc4Dlc8BwBPUcYPCsITSOh50iD50jBcxT0HGXwrCg0jYaeow2eowXPMdBzjMGzktA0FnqONXiOFTzHQc9xBs/KQtN46Dne4Dle8JwAPScYPKsITROh50SD50TBcxL0nGTwrCo0TYaekw2ekwXPKdBzisGzmtA0FXpONXhOFTynQc9pBs/qQtN06Dnd4Dld8JwBPWcYPGsITTOh50yD50zBcxb0nGXwrCk0zYaesw2eswXPOdBzjsGzltA0F3rONXjOFTznQc95Bs/aQtN86Dnf4Dlf8FwAPRcYPOsITQuh50KD50LBcxH0XGTwrCs0LYaeiw2eiwXPJdBzicGzntC0FHouNXguFTyXQc9lBs/6QtNy6Lnc4Llc8FwBPVcYPBsITSuh50qD50rBcxX0XGXwbCg0rYaeqw2eqwXPNdBzjcGzkdC0FnquNXiuFTzXQc91Bs/GQtN66Lne4Lle8NwAPTcYPJsITRuh50aD50bBcxP03GTwbCo0bYaemw2emwXPLdBzi8GzmdC0FXpuNXhuFTy3Qc9tBs/mQtN26Lnd4Lld8NwBPXcYPFsITTuh506D507Bcxf03GXwbCk07Yaeuw2euwXPPdBzj8GzldC0F3ruNXjuFTz3Qc99Bs/WQtN+6Lnf4Llf8DwAPQ8YPNsITQeh50GD50HB833o+b7Bs63QdAh6HjJ4HhI8D0PPwwbPdkLTEeh5xOB5RPA8Cj2PGjzbC03HoOcxg+cxwfMD6PmBwbOD0HQceh43eB4XPD+Enh8aPDsKTSeg5wmD5wnB8yPo+ZHBs5PQdBJ6njR4nhQ8P4aeHxs8OwtNp6DnKYPnKcHzE+j5icGzi9B0GnqeNnieFjw/hZ6fGjy7Ck1noOcZg+cZwfMz6PmZwbOb0HQWep41eJ4VPD+Hnp8bPLsLTeeg5zmD5znB8wvo+YXBs4fQdB56njd4nhc8v4SeXxo8ewpNF6DnBYPnBcHzK+j5lcGzl9B0EXpeNHheFDy/hp5fGzx7C02XoOclg+clwfMb6PmNwbOP0HQZel42eF4WPL+Fnt8aPPsKTVeg5xWD5xXB8zvo+Z3Bs5/QdBV6XjV4XhU8v4ee3xs8+wtN16DnNYPnNcHzB+j5g8FzgNB0HXpeN3heFzx/hJ4/GjwHCk03oOcNg+cNwfMn6PmTwXOQ0HQTet40eN4UPH+Gnj8bPAcLTbeg5y2D5y3B8xfo+YvBc4jQdBt63jZ43hY8f4Wevxo8hwpNd6DnHYPnHcHzN+j5m8FzmNB0F3reNXjeFTzvQc97Bs/hQtN96Hnf4Hlf8Pwdev5u8BwhND2Ang8Mng8Ezz+g5x8Gz5FC00Po+dDg+VDw/BN6/mnwHCU0PYKejwyejwTPx9DzscFztND0BHo+MXg+ETz/gp5/GTzHCE1PoedTg+dTwfNv6Pm3wXOs0PQMej4zeD4TPP+Bnv8YPMcJTc+h53OD53PB81/o+a/Bc7zQ9AJ6vjB4vhA8X0LPlwbPCULTK+j5yuD5SvB8DT1fGzwnCk1voOcbg+cbwfMt9Hxr8JwkNL2Dnu8Mnu8Ez/eqM8//vgvVc7LQFKE684xQPXTPsLfD20aEnhENnlOEpkjQM5LBM5LgGRl6RjZ4ThWaokDPKAbPKIJnVOgZ1eA5TWiKBj2jGTyjCZ7RoWd0g+d0oSkG9Ixh8IwheMaEnjENnjOEpljQM5bBM5bgGRt6xjZ4zhSa4kDPOAbPOIJnXOgZ1+A5S2iKBz3jGTzjCZ7xoWd8g+dsoSkB9Exg8EwgeCaEngkNnnOEpkTQM5HBM5HgmRh6JjZ4zhWakkDPJAbPJIJnUuiZ1OA5T2hKBj2TGTyTCZ7JoWdyg+d8oSkF9Exh8EwheKaEnikNnguEplTQM5XBM5XgmRp6pjZ4LhSa0kDPNAbPNIJnWuiZ1uC5SGhKBz3TGTzTCZ7poWd6g+dioSkD9Mxg8MwgeGaEnhkNnkuEpkzQM5PBM5PgmRl6ZjZ4LhWaskDPLAbPLIJnVuiZ1eC5TGjKBj2zGTyzCZ7ZoWd2g+dyoSkH9Mxh8MwheOaEnjkNniuEplzQM5fBM5fgmRt65jZ4rhSa8kDPPAbPPIJnXuiZ1+C5SmjKBz3zGTzzCZ75oWd+g+dqoakA9Cxg8CwgeBaEngUNnmuEpkLQs5DBs5DgWRh6FjZ4rhWaikDPIgbPIoJnUehZ1OC5TmgqBj2LGTyLCZ7FoWdxg+d6oakE9Cxh8CwheJaEniUNnhuEplLQs5TBs5TgWRp6ljZ4bhSaykDPMgbPMoJnWehZ1uC5SWgqBz3LGTzLCZ4B9AwMnpuFpvLQs7zBs7zgWQF6VjB4bhGaKkLPigbPioJnJehZyeC5VWiqDD0rGzwrC55VoGcVg+c2oakq9Kxq8KwqeFaDntUMntuFpurQs7rBs7rgWQN61jB47hCaakLPmgbPmoJnLehZy+C5U2iqDT1rGzxrC551oGcdg+cuoaku9Kxr8KwreNaDnvUMnruFpvrQs77Bs77g2QB6NjB47hGaGkLPhgbPhoJnI+jZyOC5V2hqDD0bGzwbC55NoGcTg+c+oakp9Gxq8GwqeDaDns0MnvuFpubQs7nBs7ng2QJ6tjB4HhCaWkLPlgbPloJnK+jZyuB5UGhqDT1bGzxbC55toGcbg+f7QlNb6NnW4NlW8GwHPdsZPA8JTe2hZ3uDZ3vBswP07GDwPCw0dYSeHQ2eHQXPTtCzk8HziNDUGXp2Nnh2Fjy7QM8uBs+jQlNX6NnV4NlV8OwGPbsZPI8JTd2hZ3eDZ3fBswf07GHw/EBo6gk9exo8ewqevaBnL4PncaGpN/TsbfDsLXj2gZ59DJ4fCk19oWdfg2dfwbMf9Oxn8DwhNPWHnv0Nnv0FzwHQc4DB8yOhaSD0HGjwHCh4DoKegwyeJ4WmwdBzsMFzsOA5BHoOMXh+LDQNhZ5DDZ5DBc9h0HOYwfOU0DQceg43eA4XPEdAzxEGz0+EppHQc6TBc6TgOQp6jjJ4nhaaRkPP0QbP0YLnGOg5xuD5qdA0FnqONXiOFTzHQc9xBs8zQtN46Dne4Dle8JwAPScYPD8TmiZCz4kGz4mC5yToOcngeVZomgw9Jxs8JwueU6DnFIPn50LTVOg51eA5VfCcBj2nGTzPCU3Toed0g+d0wXMG9Jxh8PxCaJoJPWcaPGcKnrOg5yyD53mhaTb0nG3wnC14zoGecwyeXwpNc6HnXIPnXMFzHvScZ/C8IDTNh57zDZ7zBc8F0HOBwfMroWkh9Fxo8FwoeC6CnosMnheFpsXQc7HBc7HguQR6LjF4fi00LYWeSw2eSwXPZdBzmcHzktC0HHouN3guFzxXQM8VBs9vhKaV0HOlwXOl4LkKeq4yeF4WmlZDz9UGz9WC5xroucbg+a3QtBZ6rjV4rhU810HPdQbPK0LTeui53uC5XvDcAD03GDy/E5o2Qs+NBs+Ngucm6LnJ4HlVaNoMPTcbPDcLnlug5xaD5/dC01boudXguVXw3AY9txk8rwlN26HndoPndsFzB/TcYfD8QWjaCT13Gjx3Cp67oOcug+d1oWk39Nxt8NwteO6BnnsMnj8KTXuh516D517Bcx/03GfwvCE07Yee+w2e+wXPA9DzgMHzJ6HpIPQ8aPA8KHi+Dz3fN3jeFJoOQc9DBs9Dgudh6HnY4Pmz0HQEeh4xeB4RPI9Cz6MGz1tC0zHoeczgeUzw/AB6fmDw/EVoOg49jxs8jwueH0LPDw2et4WmE9DzhMHzhOD5EfT8yOD5q9B0EnqeNHieFDw/hp4fGzzvCE2noOcpg+cpwfMT6PmJwfM3oek09Dxt8DwteH4KPT81eN4Vms5AzzMGzzOC52fQ8zOD5z2h6Sz0PGvwPCt4fg49Pzd43heazkHPcwbPc4LnF9DzC4Pn70LTeeh53uB5XvD8Enp+afB8IDRdgJ4XDJ4XBM+voOdXBs8/hKaL0POiwfOi4Pk19Pza4PlQaLoEPS8ZPC8Jnt9Az28Mnn8KTZeh52WD52XB81vo+a3B85HQdAV6XjF4XhE8v4Oe3xk8HwtNV6HnVYPnVcHze+j5vcHzidB0DXpeM3heEzx/gJ4/GDz/EpquQ8/rBs/rgueP0PNHg+dToekG9Lxh8LwheP4EPX8yeP4tNN2EnjcNnjcFz5+h588Gz2dC0y3oecvgeUvw/AV6/mLw/Edoug09bxs8bwuev0LPXw2ez4WmO9DzjsHzjuD5G/T8zeD5r9B0F3reNXjeFTzvQc97Bs8XQtN96Hnf4Hlf8Pwdev5u8HwpND2Ang8Mng8Ezz+g5x8Gz1dC00Po+dDg+VDw/BN6/mnwfC00PYKejwyejwTPx9DzscHzjdD0BHo+MXg+ETz/gp5/GTzfCk1PoedTg+dTwfNv6Pm3wfOd0PQMej4zeD4TPP+Bnv8YPP/7h9L/j+98Dj2fGzyfC57/Qs9/DZ4RBM8X0POFwfOF4PkSer40eEYUPF9Bz1cGz1eC52vo+drgGUnwfAM93xg83wieb6HnW4NnZMHzHfR8Z/B8J3i+V4N5/vddqJ5RBM8INZhnhBqhe4a9Hd42IvSMaPCMKnhGgp6RDJ6RBM/I0DOywTOa4BkFekYxeEYRPKNCz6gGz+iCZzToGc3gGU3wjA49oxs8YwieMaBnDINnDMEzJvSMafCMKXjGgp6xDJ6xBM/Y0DO2wTOW4BkHesYxeMYRPONCz7gGz9iCZzzoGc/gGU/wjA894xs84wieCaBnAoNnAsEzIfRMaPCMK3gmgp6JDJ6JBM/E0DOxwTOe4JkEeiYxeCYRPJNCz6QGz/iCZzLomczgmUzwTA49kxs8EwieKaBnCoNnCsEzJfRMafBMKHimgp6pDJ6pBM/U0DO1wTOR4JkGeqYxeKYRPNNCz7QGz8SCZzromc7gmU7wTA890xs8kwieGaBnBoNnBsEzI/TMaPBMKnhmgp6ZDJ6ZBM/M0DOzwTOZ4JkFemYxeGYRPLNCz6wGz+SCZzbomc3gmU3wzA49sxs8UwieOaBnDoNnDsEzJ/TMafBMKXjmgp65DJ65BM/c0DO3wTOV4JkHeuYxeOYRPPNCz7wGz9SCZz7omc/gmU/wzA898xs80wieBaBnAYNnAcGzIPQsaPBMK3gWgp6FDJ6FBM/C0LOwwTOd4FkEehYxeBYRPItCz6IGz/SCZzHoWczgWUzwLA49ixs8MwieJaBnCYNnCcGzJPQsafDMKHiWgp6lDJ6lBM/S0LO0wTOT4FkGepYxeJYRPMtCz7IGz8yCZznoWc7gWU7wDKBnYPDMIniWh57lDZ7lBc8K0LOCwTOr4FkRelY0eFYUPCtBz0oGz2yCZ2XoWdngWVnwrAI9qxg8swueVaFnVYNnVcGzGvSsZvDMIXhWh57VDZ7VBc8a0LOGwTOn4FkTetY0eNYUPGtBz1oGz1yCZ23oWdvgWVvwrAM96xg8cwuedaFnXYNnXcGzHvSsZ/DMI3jWh571DZ71Bc8G0LOBwTOv4NkQejY0eDYUPBtBz0YGz3yCZ2Po2djg2VjwbAI9mxg88wueTaFnU4NnU8GzGfRsZvAsIHg2h57NDZ7NBc8W0LOFwbOg4NkSerY0eLYUPFtBz1YGz0KCZ2vo2drg2VrwbAM92xg8CwuebaFnW4NnW8GzHfRsZ/AsIni2h57tDZ7tBc8O0LODwbOo4NkRenY0eHYUPDtBz04Gz2KCZ2fo2dng2Vnw7AI9uxg8iwueXaFnV4NnV8GzG/TsZvAsIXh2h57dDZ7dBc8e0LOHwbOk4NkTevY0ePYUPHtBz14Gz1KCZ2/o2dvg2Vvw7AM9+xg8SwuefaFnX4NnX8GzH/TsZ/AsI3j2h579DZ79Bc8B0HOAwbOs4DkQeg40eA4UPAdBz0EGz3KC52DoOdjgOVjwHAI9hxg8A8FzKPQcavAcKngOg57DDJ7lBc/h0HO4wXO44DkCeo4weFYQPEdCz5EGz5GC5yjoOcrgWVHwHA09Rxs8RwueY6DnGINnJcFzLPQca/AcK3iOg57jDJ6VBc/x0HO8wXO84DkBek4weFYRPCdCz4kGz4mC5yToOcngWVXwnAw9Jxs8JwueU6DnFINnNcFzKvScavCcKnhOg57TDJ7VBc/p0HO6wXO64DkDes4weNYQPGdCz5kGz5mC5yzoOcvgWVPwnA09Zxs8Zwuec6DnHINnLcFzLvSca/CcK3jOg57zDJ61Bc/50HO+wXO+4LkAei4weNYRPBdCz4UGz4WC5yLoucjgWVfwXAw9Fxs8FwueS6DnEoNnPcFzKfRcavBcKngug57LDJ71Bc/l0HO5wXO54LkCeq4weDYQPFdCz5UGz5WC5yroucrg2VDwXA09Vxs8Vwuea6DnGoNnI8FzLfRca/BcK3iug57rDJ6NBc/10HO9wXO94LkBem4weDYRPDdCz40Gz42C5yboucng2VTw3Aw9Nxs8NwueW6DnFoNnM8FzK/TcavDcKnhug57bDJ7NBc/t0HO7wXO74LkDeu4weLYQPHdCz50Gz52C5y7oucvg2VLw3A09dxs8dwuee6DnHoNnK8FzL/Tca/DcK3jug577DJ6tBc/90HO/wXO/4HkAeh4weLYRPA9Cz4MGz4OC5/vQ832DZ1vB8xD0PGTwPCR4Hoaehw2e7QTPI9DziMHziOB5FHoeNXi2FzyPQc9jBs9jgucH0PMDg2cHwfM49Dxu8DwueH4IPT80eHYUPE9AzxMGzxOC50fQ8yODZyfB8yT0PGnwPCl4fgw9PzZ4dhY8T0HPUwbPU4LnJ9DzE4NnF8HzNPQ8bfA8LXh+Cj0/NXh2FTzPQM8zBs8zgudn0PMzg2c3wfMs9Dxr8DwreH4OPT83eHYXPM9Bz3MGz3OC5xfQ8wuDZw/B8zz0PG/wPC94fgk9vzR49hQ8L0DPCwbPC4LnV9DzK4NnL8HzIvS8aPC8KHh+DT2/Nnj2FjwvQc9LBs9Lguc30PMbg2cfwfMy9Lxs8LwseH4LPb81ePYVPK9AzysGzyuC53fQ8zuDZz/B8yr0vGrwvCp4fg89vzd49hc8r0HPawbPa4LnD9DzB4PnAMHzOvS8bvC8Lnj+CD1/NHgOFDxvQM8bBs8bgudP0PMng+cgwfMm9Lxp8LwpeP4MPX82eA4WPG9Bz1sGz1uC5y/Q8xeD5xDB8zb0vG3wvC14/go9fzV4DhU870DPOwbPO4Lnb9DzN4PnMMHzLvS8a/C8K3jeg573DJ7DBc/70PO+wfO+4Pk79Pzd4DlC8HwAPR8YPB8Inn9Azz8MniMFz4fQ86HB86Hg+Sf0/NPgOUrwfAQ9Hxk8Hwmej6HnY4PnaMHzCfR8YvB8Inj+BT3/MniOETyfQs+nBs+nguff0PNvg+dYwfMZ9Hxm8HwmeP4DPf8xeI4TPJ9Dz+cGz+eC57/Q81+D53jB8wX0fGHwfCF4voSeLw2eEwTPV9DzlcHzleD5Gnq+NnhOFDzfQM83Bs83gudb6PnW4DlJ8HwHPd8ZPN8Jnu/VZJ7/fReq52TBM0JN5hmhZuieYW+Ht40IPSMaPKcInpGgZySDZyTBMzL0jGzwnCp4RoGeUQyeUQTPqNAzqsFzmuAZDXpGM3hGEzyjQ8/oBs/pgmcM6BnD4BlD8IwJPWMaPGcInrGgZyyDZyzBMzb0jG3wnCl4xoGecQyecQTPuNAzrsFzluAZD3rGM3jGEzzjQ8/4Bs/ZgmcC6JnA4JlA8EwIPRMaPOcInomgZyKDZyLBMzH0TGzwnCt4JoGeSQyeSQTPpNAzqcFznuCZDHomM3gmEzyTQ8/kBs/5gmcK6JnC4JlC8EwJPVMaPBcInqmgZyqDZyrBMzX0TG3wXCh4poGeaQyeaQTPtNAzrcFzkeCZDnqmM3imEzzTQ8/0Bs/FgmcG6JnB4JlB8MwIPTMaPJcInpmgZyaDZybBMzP0zGzwXCp4ZoGeWQyeWQTPrNAzq8FzmeCZDXpmM3hmEzyzQ8/sBs/lgmcO6JnD4JlD8MwJPXMaPFcInrmgZy6DZy7BMzf0zG3wXCl45oGeeQyeeQTPvNAzr8FzleCZD3rmM3jmEzzzQ8/8Bs/VgmcB6FnA4FlA8CwIPQsaPNcInoWgZyGDZyHBszD0LGzwXCt4FoGeRQyeRQTPotCzqMFzneBZDHoWM3gWEzyLQ8/iBs/1gmcJ6FnC4FlC8CwJPUsaPDcInqWgZymDZynBszT0LG3w3Ch4loGeZQyeZQTPstCzrMFzk+BZDnqWM3iWEzwD6BkYPDcLnuWhZ3mDZ3nBswL0rGDw3CJ4VoSeFQ2eFQXPStCzksFzq+BZGXpWNnhWFjyrQM8qBs9tgmdV6FnV4FlV8KwGPasZPLcLntWhZ3WDZ3XBswb0rGHw3CF41oSeNQ2eNQXPWtCzlsFzp+BZG3rWNnjWFjzrQM86Bs9dgmdd6FnX4FlX8KwHPesZPHcLnvWhZ32DZ33BswH0bGDw3CN4NoSeDQ2eDQXPRtCzkcFzr+DZGHo2Nng2FjybQM8mBs99gmdT6NnU4NlU8GwGPZsZPPcLns2hZ3ODZ3PBswX0bGHwPCB4toSeLQ2eLQXPVtCzlcHzoODZGnq2Nni2FjzbQM82Bs/3Bc+20LOtwbOt4NkOerYzeB4SPNtDz/YGz/aCZwfo2cHgeVjw7Ag9Oxo8OwqenaBnJ4PnEcGzM/TsbPDsLHh2gZ5dDJ5HBc+u0LOrwbOr4NkNenYzeB4TPLtDz+4Gz+6CZw/o2cPg+YHg2RN69jR49hQ8e0HPXgbP44Jnb+jZ2+DZW/DsAz37GDw/FDz7Qs++Bs++gmc/6NnP4HlC8OwPPfsbPPsLngOg5wCD50eC50DoOdDgOVDwHAQ9Bxk8Twqeg6HnYIPnYMFzCPQcYvD8WPAcCj2HGjyHCp7DoOcwg+cpwXM49Bxu8BwueI6AniMMnp8IniOh50iD50jBcxT0HGXwPC14joaeow2eowXPMdBzjMHzU8FzLPQca/AcK3iOg57jDJ5nBM/x0HO8wXO84DkBek4weH4meE6EnhMNnhMFz0nQc5LB86zgORl6TjZ4ThY8p0DPKQbPzwXPqdBzqsFzquA5DXpOM3ieEzynQ8/pBs/pgucM6DnD4PmF4DkTes40eM4UPGdBz1kGz/OC52zoOdvgOVvwnAM95xg8vxQ850LPuQbPuYLnPOg5z+B5QfCcDz3nGzznC54LoOcCg+dXgudC6LnQ4LlQ8FwEPRcZPC8Knouh52KD52LBcwn0XGLw/FrwXAo9lxo8lwqey6DnMoPnJcFzOfRcbvBcLniugJ4rDJ7fCJ4roedKg+dKwXMV9Fxl8LwseK6GnqsNnqsFzzXQc43B81vBcy30XGvwXCt4roOe6wyeVwTP9dBzvcFzveC5AXpuMHh+J3huhJ4bDZ4bBc9N0HOTwfOq4LkZem42eG4WPLdAzy0Gz+8Fz63Qc6vBc6vguQ16bjN4XhM8t0PP7QbP7YLnDui5w+D5g+C5E3ruNHjuFDx3Qc9dBs/rgudu6Lnb4Llb8NwDPfcYPH8UPPdCz70Gz72C5z7ouc/geUPw3A899xs89wueB6Dngf+LFboKo4LqtjAs3d296e7u7u7u7u7u7i4REREREenubhERke7urvN4958r9/gc63rONb/nNXheFjzXQc91Bs91gud66Lne4HlF8NwAPTcYPDcInhuh50aD51XBcxP03GTw3CR4boaemw2e1wTPLdBzi8Fzi+C5FXpuNXheFzy3Qc9tBs9tgud26Lnd4HlD8NwBPXcYPHcInjuh506D503Bcxf03GXw3CV47oaeuw2etwTPPdBzj8Fzj+C5F3ruNXjeFjz3Qc99Bs99gud+6Lnf4HlH8DwAPQ8YPA8Ingeh50GD513B8xD0PGTwPCR4Hoaehw2e9wTPI9DziMHziOB5FHoeNXjeFzyPQc9jBs9jgudx6Hnc4PlA8DwBPU8YPE8Inieh50mD50PB8xT0PGXwPCV4noaepw2ejwTPM9DzjMHzjOD5G/T8zeD5WPA8Cz3PGjzPCp6/Q8/fDZ5PBM9z0POcwfOc4PkH9PzD4PlU8DwPPc8bPM8Lnn9Czz8Nns8EzwvQ84LB84Lg+Rf0/Mvg+VzwvAg9Lxo8Lwqef0PPvw2eLwTPS9DzksHzkuB5GXpeNni+FDyvQM8rBs8rgudV6HnV4PlK8LwGPa8ZPK8Jnteh53WD52vB8wb0vGHwvCF43oSeNw2ebwTPW9DzlsHzluB5G3reNni+FTzvQM87Bs87gudd6HnX4PlO8LwHPe8ZPO8Jnveh532D53vB8wH0fGDwfCB4PoSeDw2eHwTPR9DzkcHzkeD5GHo+Nnh+FDyfQM8nBs8ngudT6PnU4PlJ8HwGPZ8ZPJ8Jns+h53OD52fB8wX0fGHwfCF4voSeLw2eXwTPV9DzlcHzleD5Gnq+Nnj+sxAIsvMN9Hxj8HwjeL6Fnm8NniFCB9/5Dnq+M3i+EzzfQ8/3Bs+QgucH6PnB4PlB8PwIPT8aPEMJnp+g5yeD5yfB8zP0/GzwDC14foGeXwyeXwTPryoxz3/2/qtnGMEzRCXmGaLSf/f839v/NhsSeoY0eIYVPENBz1AGz1CCZ2joGdrgGU7wDAM9wxg8wwieYaFnWINneMEzHPQMZ/AMJ3iGh57hDZ4RBM8I0DOCwTOC4BkRekY0eEYUPCNBz0gGz0iCZ2ToGdngGUnwjAI9oxg8owieUaFnVINnZMEzGvSMZvCMJnhGh57RDZ5RBM8Y0DOGwTOG4BkTesY0eEYVPGNBz1gGz1iCZ2zoGdvgGU3wjAM94xg84wiecaFnXINndMEzHvSMZ/CMJ3jGh57xDZ4xBM8E0DOBwTOB4JkQeiY0eMYUPBNBz0QGz0SCZ2LomdjgGUvwTAI9kxg8kwieSaFnUoNnbMEzGfRMZvBMJngGoGfA4BlH8EwOPZMbPJMLnimgZwqDZ1zBMyX0TGnwTCl4poKeqQye8QTP1NAztcEzteCZBnqmMXjGFzzTQs+0Bs+0gmc66JnO4JlA8EwPPdMbPNMLnhmgZwaDZ0LBMyP0zGjwzCh4ZoKemQyeiQTPzNAzs8Ezs+CZBXpmMXgmFjyzQs+sBs+sgmc26JnN4JlE8MwOPbMbPLMLnjmgZw6DZ1LBMyf0zGnwzCl45oKeuQyeyQTP3NAzt8Ezt+CZB3rmMXgGBM+80DOvwTOv4JkPeuYzeCYXPPNDz/wGz/yCZwHoWcDgmULwLAg9Cxo8CwqehaBnIYNnSsGzMPQsbPAsLHgWgZ5FDJ6pBM+i0LOowbOo4FkMehYzeKYWPItDz+IGz+KCZwnoWcLgmUbwLAk9Sxo8SwqepaBnKYNnWsGzNPQsbfAsLXiWgZ5lDJ7pBM+y0LOswbOs4FkOepYzeKYXPMtDz/IGz/KCZwXoWcHgmUHwrAg9Kxo8KwqelaBnJYNnRsGzMvSsbPCsLHhWgZ5VDJ6ZBM+q0LOqwbOq4FkNelYzeGYWPKtDz+oGz+qCZw3oWcPgmUXwrAk9axo8awqetaBnLYNnVsGzNvSsbfCsLXjWgZ51DJ7ZBM+60LOuwbOu4FkPetYzeGYXPOtDz/oGz/qCZwPo2cDgmUPwbAg9Gxo8GwqejaBnI4NnTsGzMfRsbPBsLHg2gZ5NDJ65BM+m0LOpwbOp4NkMejYzeOYWPJtDz+YGz+aCZwvo2cLgmUfwbAk9Wxo8WwqeraBnK4NnXsGzNfRsbfBsLXi2gZ5tDJ75BM+20LOtwbOt4NkOerYzeOYXPNtDz/YGz/aCZwfo2cHgWUDw7Ag9Oxo8OwqenaBnJ4NnQcGzM/TsbPDsLHh2gZ5dDJ6FBM+u0LOrwbOr4NkNenYzeBYWPLtDz+4Gz+6CZw/o2cPgWUTw7Ak9exo8ewqevaBnL4NnUcGzN/TsbfDsLXj2gZ59DJ7FBM++0LOvwbOv4NkPevYzeBYXPPtDz/4Gz/6C5wDoOcDgWULwHAg9Bxo8Bwqeg6DnIINnScFzMPQcbPAcLHgOgZ5DDJ6lBM+h0HOowXOo4DkMeg4zeJYWPIdDz+EGz+GC5wjoOcLgWUbwHAk9Rxo8Rwqeo6DnKINnWcFzNPQcbfAcLXiOgZ5jDJ7lBM+x0HOswXOs4DkOeo4zeJYXPMdDz/EGz/GC5wToOcHgWUHwnAg9Jxo8Jwqek6DnJINnRcFzMvScbPCcLHhOgZ5TDJ6VBM+p0HOqwXOq4DkNek4zeFYWPKdDz+kGz+mC5wzoOcPgWUXwnAk9Zxo8Zwqes6DnLINnVcFzNvScbfCcLXjOgZ5zDJ7VBM+50HOuwXOu4DkPes4zeFYXPOdDz/kGz/mC5wLoucDgWUPwXAg9Fxo8Fwqei6DnIoNnTcFzMfRcbPBcLHh+DT2/NnjWEjyXQM8lBs8lguc30PMbg2dtwXMp9Fxq8FwqeH4LPb81eNYRPJdBz2UGz2WC53fQ8zuDZ13Bczn0XG7wXC54fg89vzd41hM8V0DPFQbPFYLnD9DzB4NnfcFzJfRcafBcKXj+CD1/NHg2EDxXQc9VBs9VgudP0PMng2dDwXM19Fxt8FwteP4MPX82eDYSPNdAzzUGzzWC5y/Q8xeDZ2PBcy30XGvwXCt4/go9fzV4NhE810HPdQbPdYLneui53uDZVPDcAD03GDw3CJ4boedGg2czwXMT9Nxk8NwkeG6GnpsNns0Fzy3Qc4vBc4vguRV6bjV4thA8t0HPbQbPbYLndui53eDZUvDcAT13GDx3CJ47oedOg2crwXMX9Nxl8NwleO6GnrsNnq0Fzz3Qc4/Bc4/guRd67jV4thE890HPfQbPfYLnfui53+DZVvA8AD0PGDwPCJ4HoedBg2c7wfMQ9Dxk8DwkeB6GnocNnu0FzyPQ84jB84jgeRR6HjV4dhA8j0HPYwbPY4Lnceh53ODZUfA8AT1PGDxPCJ4noedJg2cnwfMU9Dxl8DwleJ6GnqcNnp0FzzPQ84zB84zg+Rv0/M3g2UXwPAs9zxo8zwqev0PP3w2eXQXPc9DznMHznOD5B/T8w+DZTfA8Dz3PGzzPC55/Qs8/DZ7dBc8L0POCwfOC4PkX9PzL4NlD8LwIPS8aPC8Knn9Dz78Nnj0Fz0vQ85LB85LgeRl6XjZ49hI8r0DPKwbPK4LnVeh51eDZW/C8Bj2vGTyvCZ7Xoed1g2cfwfMG9Lxh8LwheN6EnjcNnn0Fz1vQ85bB85bgeRt63jZ49hM870DPOwbPO4LnXeh51+DZX/C8Bz3vGTzvCZ73oed9g+cAwfMB9Hxg8HwgeD6Eng8NngMFz0fQ85HB85Hg+Rh6PjZ4DhI8n0DPJwbPJ4LnU+j51OA5WPB8Bj2fGTyfCZ7Poedzg+cQwfMF9Hxh8HwheL6Eni8NnkMFz1fQ85XB85Xg+Rp6vjZ4DhM830DPNwbPN4LnW+j51uA5XPB8Bz3fGTzfCZ7voed7g+cIwfMD9Pxg8PwgeH6Enh8NniMFz0/Q85PB85Pg+Rl6fjZ4jhI8v0DPLwbPL4LnV5WZ5z97/9VztOAZojLzDFH5v3v+7+1/mw0JPUMaPMcInqGgZyiDZyjBMzT0DG3wHCt4hoGeYQyeYQTPsNAzrMFznOAZDnqGM3iGEzzDQ8/wBs/xgmcE6BnB4BlB8IwIPSMaPCcInpGgZySDZyTBMzL0jGzwnCh4RoGeUQyeUQTPqNAzqsFzkuAZDXpGM3hGEzyjQ8/oBs/JgmcM6BnD4BlD8IwJPWMaPKcInrGgZyyDZyzBMzb0jG3wnCp4xoGecQyecQTPuNAzrsFzmuAZD3rGM3jGEzzjQ8/4Bs/pgmcC6JnA4JlA8EwIPRMaPGcInomgZyKDZyLBMzH0TGzwnCl4JoGeSQyeSQTPpNAzqcFzluCZDHomM3gmEzwD0DNg8JwteCaHnskNnskFzxTQM4XBc47gmRJ6pjR4phQ8U0HPVAbPuYJnauiZ2uCZWvBMAz3TGDznCZ5poWdag2dawTMd9Exn8JwveKaHnukNnukFzwzQM4PBc4HgmRF6ZjR4ZhQ8M0HPTAbPhYJnZuiZ2eCZWfDMAj2zGDwXCZ5ZoWdWg2dWwTMb9Mxm8FwseGaHntkNntkFzxzQM4fB82vBMyf0zGnwzCl45oKeuQyeSwTP3NAzt8Ezt+CZB3rmMXh+I3jmhZ55DZ55Bc980DOfwXOp4JkfeuY3eOYXPAtAzwIGz28Fz4LQs6DBs6DgWQh6FjJ4LhM8C0PPwgbPwoJnEehZxOD5neBZFHoWNXgWFTyLQc9iBs/lgmdx6Fnc4Flc8CwBPUsYPL8XPEtCz5IGz5KCZynoWcrguULwLA09Sxs8SwueZaBnGYPnD4JnWehZ1uBZVvAsBz3LGTxXCp7loWd5g2d5wbMC9Kxg8PxR8KwIPSsaPCsKnpWgZyWD5yrBszL0rGzwrCx4VoGeVQyePwmeVaFnVYNnVcGzGvSsZvBcLXhWh57VDZ7VBc8a0LOGwfNnwbMm9Kxp8KwpeNaCnrUMnmsEz9rQs7bBs7bgWQd61jF4/iJ41oWedQ2edQXPetCznsFzreBZH3rWN3jWFzwbQM8GBs9fBc+G0LOhwbOh4NkIejYyeK4TPBtDz8YGz8aCZxPo2cTguV7wbAo9mxo8mwqezaBnM4PnBsGzOfRsbvBsLni2gJ4tDJ4bBc+W0LOlwbOl4NkKerYyeG4SPFtDz9YGz9aCZxvo2cbguVnwbAs92xo82wqe7aBnO4PnFsGzPfRsb/BsL3h2gJ4dDJ5bBc+O0LOjwbOj4NkJenYyeG4TPDtDz84Gz86CZxfo2cXguV3w7Ao9uxo8uwqe3aBnN4PnDsGzO/TsbvDsLnj2gJ49DJ47Bc+e0LOnwbOn4NkLevYyeO4SPHtDz94Gz96CZx/o2cfguVvw7As9+xo8+wqe/aBnP4PnHsGzP/Tsb/DsL3gOgJ4DDJ57Bc+B0HOgwXOg4DkIeg4yeO4TPAdDz8EGz8GC5xDoOcTguV/wHAo9hxo8hwqew6DnMIPnAcFzOPQcbvAcLniOgJ4jDJ4HBc+R0HOkwXOk4DkKeo4yeB4SPEdDz9EGz9GC5xjoOcbgeVjwHAs9xxo8xwqe46DnOIPnEcFzPPQcb/AcL3hOgJ4TDJ5HBc+J0HOiwXOi4DkJek4yeB4TPCdDz8kGz8mC5xToOcXgeVzwnAo9pxo8pwqe06DnNIPnCcFzOvScbvCcLnjOgJ4zDJ4nBc+Z0HOmwXOm4DkLes4yeJ4SPGdDz9kGz9mC5xzoOcfgeVrwnAs95xo85wqe86DnPIPnGcFzPvScb/CcL3gugJ4LDJ6/CZ4LoedCg+dCwXMR9Fxk8DwreC6GnosNnosFz6+h59cGz98FzyXQc4nBc4ng+Q30/MbgeU7wXAo9lxo8lwqe30LPbw2efwiey6DnMoPnMsHzO+j5ncHzvOC5HHouN3guFzy/h57fGzz/FDxXQM8VBs8VgucP0PMHg+cFwXMl9Fxp8FwpeP4IPX80eP4leK6CnqsMnqsEz5+g508Gz4uC52roudrguVrw/Bl6/mzw/FvwXAM91xg81wiev0DPXwyelwTPtdBzrcFzreD5K/T81eB5WfBcBz3XGTzXCZ7roed6g+cVwXMD9Nxg8NwgeG6EnhsNnlcFz03Qc5PBc5PguRl6bjZ4XhM8t0DPLQbPLYLnVui51eB5XfDcBj23GTy3CZ7boed2g+cNwXMH9Nxh8NwheO6EnjsNnjcFz13Qc5fBc5fguRt67jZ43hI890DPPQbPPYLnXui51+B5W/DcBz33GTz3CZ77oed+g+cdwfMA9Dxg8DwgeB6EngcNnncFz0PQ85DB85DgeRh6HjZ43hM8j0DPIwbPI4LnUeh51OB5X/A8Bj2PGTyPCZ7Hoedxg+cDwfME9Dxh8DwheJ6EnicNng8Fz1PQ85TB85TgeRp6njZ4PhI8z0DPMwbPM4Lnb9DzN4PnY8HzLPQ8a/A8K3j+Dj1/N3g+ETzPQc9zBs9zgucf0PMPg+dTwfM89Dxv8DwveP4JPf80eD4TPC9AzwsGzwuC51/Q8y+D53PB8yL0vGjwvCh4/g09/zZ4vhA8L0HPSwbPS4LnZeh52eD5UvC8Aj2vGDyvCJ5XoedVg+crwfMa9Lxm8LwmeF6HntcNnq8FzxvQ84bB84bgeRN63jR4vhE8b0HPWwbPW4Lnbeh52+D5VvC8Az3vGDzvCJ53oeddg+c7wfMe9Lxn8LwneN6HnvcNnu8FzwfQ84HB84Hg+RB6PjR4fhA8H0HPRwbPR4LnY+j52OD5UfB8Aj2fGDyfCJ5PoedTg+cnwfMZ9Hxm8HwmeD6Hns8Nnp8FzxfQ84XB84Xg+RJ6vjR4fhE8X0HPVwbPV4Lna+j52uD5VZjgO99AzzcGzzeC51vo+dbgGULwfAc93xk83wme76Hne4NnSMHzA/T8YPD8IHh+hJ4fDZ6hBM9P0POTwfOT4PkZen42eIYWPL9Azy8Gzy+C51dVmOc/e//VM4zgGaIK8wxR5b97/u/tf5sNCT1DGjzDCp6hoGcog2cowTM09Axt8AwneIaBnmEMnmEEz7DQM6zBM7zgGQ56hjN4hhM8w0PP8AbPCIJnBOgZweAZQfCMCD0jGjwjCp6RoGckg2ckwTMy9Ixs8IwkeEaBnlEMnlEEz6jQM6rBM7LgGQ16RjN4RhM8o0PP6AbPKIJnDOgZw+AZQ/CMCT1jGjyjCp6xoGcsg2cswTM29Ixt8IwmeMaBnnEMnnEEz7jQM67BM7rgGQ96xjN4xhM840PP+AbPGIJnAuiZwOCZQPBMCD0TGjxjCp6JoGcig2ciwTMx9Exs8IwleCaBnkkMnkkEz6TQM6nBM7bgmQx6JjN4JhM8A9AzYPCMI3gmh57JDZ7JBc8U0DOFwTOu4JkSeqY0eKYUPFNBz1QGz3iCZ2romdrgmVrwTAM90xg84wueaaFnWoNnWsEzHfRMZ/BMIHimh57pDZ7pBc8M0DODwTOh4JkRemY0eGYUPDNBz0wGz0SCZ2bomdngmVnwzAI9sxg8EwueWaFnVoNnVsEzG/TMZvBMInhmh57ZDZ7ZBc8c0DOHwTOp4JkTeuY0eOYUPHNBz1wGz2SCZ27omdvgmVvwzAM98xg8A4JnXuiZ1+CZV/DMBz3zGTyTC575oWd+g2d+wbMA9Cxg8EwheBaEngUNngUFz0LQs5DBM6XgWRh6FjZ4FhY8i0DPIgbPVIJnUehZ1OBZVPAsBj2LGTxTC57FoWdxg2dxwbME9Cxh8EwjeJaEniUNniUFz1LQs5TBM63gWRp6ljZ4lhY8y0DPMgbPdIJnWehZ1uBZVvAsBz3LGTzTC57loWd5g2d5wbMC9Kxg8MwgeFaEnhUNnhUFz0rQs5LBM6PgWRl6VjZ4VhY8q0DPKgbPTIJnVehZ1eBZVfCsBj2rGTwzC57VoWd1g2d1wbMG9Kxh8MwieNaEnjUNnjUFz1rQs5bBM6vgWRt61jZ41hY860DPOgbPbIJnXehZ1+BZV/CsBz3rGTyzC571oWd9g2d9wbMB9Gxg8MwheDaEng0Nng0Fz0bQs5HBM6fg2Rh6NjZ4NhY8m0DPJgbPXIJnU+jZ1ODZVPBsBj2bGTxzC57NoWdzg2dzwbMF9Gxh8MwjeLaEni0Nni0Fz1bQs5XBM6/g2Rp6tjZ4thY820DPNgbPfIJnW+jZ1uDZVvBsBz3bGTzzC57toWd7g2d7wbMD9Oxg8CwgeHaEnh0Nnh0Fz07Qs5PBs6Dg2Rl6djZ4dhY8u0DPLgbPQoJnV+jZ1eDZVfDsBj27GTwLC57doWd3g2d3wbMH9Oxh8CwiePaEnj0Nnj0Fz17Qs5fBs6jg2Rt69jZ49hY8+0DPPgbPYoJnX+jZ1+DZV/DsBz37GTyLC579oWd/g2d/wXMA9Bxg8CwheA6EngMNngMFz0HQc5DBs6TgORh6DjZ4DhY8h0DPIQbPUoLnUOg51OA5VPAcBj2HGTxLC57Doedwg+dwwXME9Bxh8CwjeI6EniMNniMFz1HQc5TBs6zgORp6jjZ4jhY8x0DPMQbPcoLnWOg51uA5VvAcBz3HGTzLC57joed4g+d4wXMC9Jxg8KwgeE6EnhMNnhMFz0nQc5LBs6LgORl6TjZ4ThY8p0DPKQbPSoLnVOg51eA5VfCcBj2nGTwrC57Toed0g+d0wXMG9Jxh8KwieM6EnjMNnjMFz1nQc5bBs6rgORt6zjZ4zhY850DPOQbPaoLnXOg51+A5V/CcBz3nGTyrC57zoed8g+d8wXMB9Fxg8KwheC6EngsNngsFz0XQc5HBs6bguRh6LjZ4LhY8v4aeXxs8awmeS6DnEoPnEsHzG+j5jcGztuC5FHouNXguFTy/hZ7fGjzrCJ7LoOcyg+cywfM76PmdwbOu4Lkcei43eC4XPL+Hnt8bPOsJniug5wqD5wrB8wfo+YPBs77guRJ6rjR4rhQ8f4SePxo8Gwieq6DnKoPnKsHzJ+j5k8GzoeC5GnquNniuFjx/hp4/GzwbCZ5roOcag+cawfMX6PmLwbOx4LkWeq41eK4VPH+Fnr8aPJsInuug5zqD5zrBcz30XG/wbCp4boCeGwyeGwTPjdBzo8GzmeC5CXpuMnhuEjw3Q8/NBs/mgucW6LnF4LlF8NwKPbcaPFsIntug5zaD5zbBczv03G7wbCl47oCeOwyeOwTPndBzp8GzleC5C3ruMnjuEjx3Q8/dBs/Wguce6LnH4LlH8NwLPfcaPNsInvug5z6D5z7Bcz/03G/wbCt4HoCeBwyeBwTPg9DzoMGzneB5CHoeMngeEjwPQ8/DBs/2gucR6HnE4HlE8DwKPY8aPDsInseg5zGD5zHB8zj0PG7w7Ch4noCeJwyeJwTPk9DzpMGzk+B5CnqeMnieEjxPQ8/TBs/OgucZ6HnG4HlG8PwNev5m8OwieJ6FnmcNnmcFz9+h5+8Gz66C5znoec7geU7w/AN6/mHw7CZ4noee5w2e5wXPP6HnnwbP7oLnBeh5weB5QfD8C3r+ZfDsIXhehJ4XDZ4XBc+/oeffBs+egucl6HnJ4HlJ8LwMPS8bPHsJnleg5xWD5xXB8yr0vGrw7C14XoOe1wye1wTP69DzusGzj+B5A3reMHjeEDxvQs+bBs++guct6HnL4HlL8LwNPW8bPPsJnneg5x2D5x3B8y70vGvw7C943oOe9wye9wTP+9DzvsFzgOD5AHo+MHg+EDwfQs+HBs+Bgucj6PnI4PlI8HwMPR8bPAcJnk+g5xOD5xPB8yn0fGrwHCx4PoOezwyezwTP59DzucFziOD5Anq+MHi+EDxfQs+XBs+hgucr6PnK4PlK8HwNPV8bPIcJnm+g5xuD5xvB8y30fGvwHC54voOe7wye7wTP99DzvcFzhOD5AXp+MHh+EDw/Qs+PBs+Rgucn6PnJ4PlJ8PwMPT8bPEcJnl+g5xeD5xfB86uqzPOfvf/qOVrwDFGVeYao+t89//f2v82GhJ4hDZ5jBM9Q0DOUwTOU4BkaeoY2eI4VPMNAzzAGzzCCZ1joGdbgOU7wDAc9wxk8wwme4aFneIPneMEzAvSMYPCMIHhGhJ4RDZ4TBM9I0DOSwTOS4BkZekY2eE4UPKNAzygGzyiCZ1ToGdXgOUnwjAY9oxk8owme0aFndIPnZMEzBvSMYfCMIXjGhJ4xDZ5TBM9Y0DOWwTOW4BkbesY2eE4VPONAzzgGzziCZ1zoGdfgOU3wjAc94xk84wme8aFnfIPndMEzAfRMYPBMIHgmhJ4JDZ4zBM9E0DORwTOR4JkYeiY2eM4UPJNAzyQGzySCZ1LomdTgOUvwTAY9kxk8kwmeAegZMHjOFjyTQ8/kBs/kgmcK6JnC4DlH8EwJPVMaPFMKnqmgZyqD51zBMzX0TG3wTC14poGeaQye8wTPtNAzrcEzreCZDnqmM3jOFzzTQ8/0Bs/0gmcG6JnB4LlA8MwIPTMaPDMKnpmgZyaD50LBMzP0zGzwzCx4ZoGeWQyeiwTPrNAzq8Ezq+CZDXpmM3guFjyzQ8/sBs/sgmcO6JnD4Pm14JkTeuY0eOYUPHNBz1wGzyWCZ27omdvgmVvwzAM98xg8vxE880LPvAbPvIJnPuiZz+C5VPDMDz3zGzzzC54FoGcBg+e3gmdB6FnQ4FlQ8CwEPQsZPJcJnoWhZ2GDZ2HBswj0LGLw/E7wLAo9ixo8iwqexaBnMYPncsGzOPQsbvAsLniWgJ4lDJ7fC54loWdJg2dJwbMU9Cxl8FwheJaGnqUNnqUFzzLQs4zB8wfBsyz0LGvwLCt4loOe5QyeKwXP8tCzvMGzvOBZAXpWMHj+KHhWhJ4VDZ4VBc9K0LOSwXOV4FkZelY2eFYWPKtAzyoGz58Ez6rQs6rBs6rgWQ16VjN4rhY8q0PP6gbP6oJnDehZw+D5s+BZE3rWNHjWFDxrQc9aBs81gmdt6Fnb4Flb8KwDPesYPH8RPOtCz7oGz7qCZz3oWc/guVbwrA896xs86wueDaBnA4Pnr4JnQ+jZ0ODZUPBsBD0bGTzXCZ6NoWdjg2djwbMJ9Gxi8FwveDaFnk0Nnk0Fz2bQs5nBc4Pg2Rx6Njd4Nhc8W0DPFgbPjYJnS+jZ0uDZUvBsBT1bGTw3CZ6toWdrg2drwbMN9Gxj8NwseLaFnm0Nnm0Fz3bQs53Bc4vg2R56tjd4thc8O0DPDgbPrYJnR+jZ0eDZUfDsBD07GTy3CZ6doWdng2dnwbML9Oxi8NwueHaFnl0Nnl0Fz27Qs5vBc4fg2R16djd4dhc8e0DPHgbPnYJnT+jZ0+DZU/DsBT17GTx3CZ69oWdvg2dvwbMP9Oxj8NwtePaFnn0Nnn0Fz37Qs5/Bc4/g2R969jd49hc8B0DPAQbPvYLnQOg50OA5UPAcBD0HGTz3CZ6Doedgg+dgwXMI9Bxi8NwveA6FnkMNnkMFz2HQc5jB84DgORx6Djd4Dhc8R0DPEQbPg4LnSOg50uA5UvAcBT1HGTwPCZ6joedog+dowXMM9Bxj8DwseI6FnmMNnmMFz3HQc5zB84jgOR56jjd4jhc8J0DPCQbPo4LnROg50eA5UfCcBD0nGTyPCZ6Toedkg+dkwXMK9Jxi8DwueE6FnlMNnlMFz2nQc5rB84TgOR16Tjd4Thc8Z0DPGQbPk4LnTOg50+A5U/CcBT1nGTxPCZ6zoedsg+dswXMO9Jxj8DwteM6FnnMNnnMFz3nQc57B84zgOR96zjd4zhc8F0DPBQbP3wTPhdBzocFzoeC5CHouMnieFTwXQ8/FBs/FgufX0PNrg+fvgucS6LnE4LlE8PwGen5j8DwneC6FnksNnksFz2+h57cGzz8Ez2XQc5nBc5ng+R30/M7geV7wXA49lxs8lwue30PP7w2efwqeK6DnCoPnCsHzB+j5g8HzguC5EnquNHiuFDx/hJ4/Gjz/EjxXQc9VBs9VgudP0PMng+dFwXM19Fxt8FwteP4MPX82eP4teK6BnmsMnmsEz1+g5y8Gz0uC51roudbguVbw/BV6/mrwvCx4roOe6wye6wTP9dBzvcHziuC5AXpuMHhuEDw3Qs+NBs+rgucm6LnJ4LlJ8NwMPTcbPK8Jnlug5xaD5xbBcyv03GrwvC54boOe2wye2wTP7dBzu8HzhuC5A3ruMHjuEDx3Qs+dBs+bgucu6LnL4LlL8NwNPXcbPG8Jnnug5x6D5x7Bcy/03GvwvC147oOe+wye+wTP/dBzv8HzjuB5AHoeMHgeEDwPQs+DBs+7guch6HnI4HlI8DwMPQ8bPO8Jnkeg5xGD5xHB8yj0PGrwvC94HoOexwyexwTP49DzuMHzgeB5AnqeMHieEDxPQs+TBs+Hgucp6HnK4HlK8DwNPU8bPB8Jnmeg5xmD5xnB8zfo+ZvB87HgeRZ6njV4nhU8f4eevxs8nwie56DnOYPnOcHzD+j5h8HzqeB5HnqeN3ieFzz/hJ5/GjyfCZ4XoOcFg+cFwfMv6PmXwfO54HkRel40eF4UPP+Gnn8bPF8Inpeg5yWD5yXB8zL0vGzwfCl4XoGeVwyeVwTPq9DzqsHzleB5DXpeM3heEzyvQ8/rBs/XgucN6HnD4HlD8LwJPW8aPN8Inreg5y2D5y3B8zb0vG3wfCt43oGedwyedwTPu9DzrsHzneB5D3reM3jeEzzvQ8/7Bs/3gucD6PnA4PlA8HwIPR8aPD8Ino+g5yOD5yPB8zH0fGzw/Ch4PoGeTwyeTwTPp9DzqcHzk+D5DHo+M3g+EzyfQ8/nBs/PgucL6PnC4PlC8HwJPV8aPL8Inq+g5yuD5yvB8zX0fG3w/Cps8J1voOcbg+cbwfMt9Hxr8AwRCL7zXdVg/w2R+X87/9mL+C+dyu1/m30fdGfI+v/b+T6Izn95IUIGgu/8AD0/GDw/CJ4foedHg2eoQPCdn6DnJ4PnJ8HzM/T8bPAMHQi+8wv0/GLw/CJ4flWNef6z9189wwSC7wxRjXmGqPbfPf/39r/NhoSeIQ2eYQPBd4aCnqEMnqEEz9DQM7TBM1wg+M4w0DOMwTOM4BkWeoY1eIYPBN8ZDnqGM3iGEzzDQ8/wBs8IgeA7I0DPCAbPCIJnROgZ0eAZMRB8ZyToGcngGUnwjAw9Ixs8IwWC74wCPaMYPKMInlGhZ1SDZ+RA8J3RoGc0g2c0wTM69Ixu8IwSCL4zBvSMYfCMIXjGhJ4xDZ5RA8F3xoKesQyesQTP2NAztsEzWiD4zjjQM47BM47gGRd6xjV4Rg8E3xkPesYzeMYTPONDz/gGzxiB4DsTQM8EBs8EgmdC6JnQ4BkzEHxnIuiZyOCZSPBMDD0TGzxjBYLvTAI9kxg8kwieSaFnUoNn7EDwncmgZzKDZzLBMwA9AwbPOIHgO5NDz+QGz+SCZwromcLgGTcQfGdK6JnS4JlS8EwFPVMZPOMFgu9MDT1TGzxTC55poGcag2f8QPCdaaFnWoNnWsEzHfRMZ/BMEAi+Mz30TG/wTC94ZoCeGQyeCQPBd2aEnhkNnhkFz0zQM5PBM1Eg+M7M0DOzwTOz4JkFemYxeCYOBN+ZFXpmNXhmFTyzQc9sBs8kgeA7s0PP7AbP7IJnDuiZw+CZNBB8Z07omdPgmVPwzAU9cxk8kwWC78wNPXMbPHMLnnmgZx6DZyAQfGde6JnX4JlX8MwHPfMZPJMHgu/MDz3zGzzzC54FoGcBg2eKQPCdBaFnQYNnQcGzEPQsZPBMGQi+szD0LGzwLCx4FoGeRQyeqQLBdxaFnkUNnkUFz2LQs5jBM3Ug+M7i0LO4wbO44FkCepYweKYJBN9ZEnqWNHiWFDxLQc9SBs+0geA7S0PP0gbP0oJnGehZxuCZLhB8Z1noWdbgWVbwLAc9yxk80weC7ywPPcsbPMsLnhWgZwWDZ4ZA8J0VoWdFg2dFwbMS9Kxk8MwYCL6zMvSsbPCsLHhWgZ5VDJ6ZAsF3VoWeVQ2eVQXPatCzmsEzcyD4zurQs7rBs7rgWQN61jB4ZgkE31kTetY0eNYUPGtBz1oGz6yB4DtrQ8/aBs/agmcd6FnH4JktEHxnXehZ1+BZV/CsBz3rGTyzB4LvrA896xs8//f2v802qMY8/9n7r545AsF3NqzGPBtW+++eDQXPRtCzkcEzZyD4zsbQs7HBs7Hg2QR6NjF45goE39kUejY1eDYVPJtBz2YGz9yB4DubQ8/mBs/mgmcL6NnC4JknEHxnS+jZ0uDZUvBsBT1bGTzzBoLvbA09Wxs8WwuebaBnG4NnvkDwnW2hZ1uDZ1vBsx30bGfwzB8IvrM99Gxv8GwveHaAnh0MngUCwXd2hJ4dDZ4dBc9O0LOTwbNgIPjOztCzs8Gzs+DZBXp2MXgWCgTf2RV6djV4dhU8u0HPbgbPwoHgO7tDz+4Gz+6CZw/o2cPgWSQQfGdP6NnT4NlT8OwFPXsZPIsGgu/sDT17Gzx7C559oGcfg2exQPCdfaFnX4NnX8GzH/TsZ/AsHgi+sz/07G/w7C94DoCeAwyeJQLBdw6EngMNngMFz0HQc5DBs2Qg+M7B0HOwwXOw4DkEeg4xeJYKBN85FHoONXgOFTyHQc9hBs/SgeA7h0PP4QbP4YLnCOg5wuBZJhB850joOdLgOVLwHAU9Rxk8ywaC7xwNPUcbPEcLnmOg5xiDZ7lA8J1joedYg+dYwXMc9Bxn8CwfCL5zPPQcb/AcL3hOgJ4TDJ4VAsF3ToSeEw2eEwXPSdBzksGzYiD4zsnQc7LBc7LgOQV6TjF4VgoE3zkVek41eE4VPKdBz2kGz8qB4DunQ8/pBs/pgucM6DnD4FklEHznTOg50+A5U/CcBT1nGTyrBoLvnA09Zxs8Zwuec6DnHINntUDwnXOh51yD51zBcx70nGfwrB4IvnM+9Jxv8JwveC6AngsMnjUCwXcuhJ4LDZ4LBc9F0HORwbNmIPjOxdBzscFzseD5NfT82uBZKxB85xLoucTguUTw/AZ6fmPwrB0IvnMp9Fxq8FwqeH4LPb81eNYJBN+5DHouM3guEzy/g57fGTzrBoLvXA49lxs8lwue30PP7w2e9QLBd66AnisMnisEzx+g5w8Gz/qB4DtXQs+VBs+VgueP0PNHg2eDQPCdq6DnKoPnKsHzJ+j5k8GzYSD4ztXQc7XBc7Xg+TP0/Nng2SgQfOca6LnG4LlG8PwFev5i8GwcCL5zLfRca/BcK3j+Cj1/NXg2CQTfuQ56rjN4rhM810PP9QbPpoHgOzdAzw0Gzw2C50boudHg2SwQfOcm6LnJ4LlJ8NwMPTcbPJsHgu/cAj23GDy3CJ5boedWg2eLQPCd26DnNoPnNsFzO/TcbvBsGQi+cwf03GHw3CF47oSeOw2erQLBd+6CnrsMnrsEz93Qc7fBs3Ug+M490HOPwXOP4LkXeu41eLYJBN+5D3ruM3juEzz3Q8/9Bs+2geA7D0DPAwbPA4LnQeh50ODZLhB85yHoecjgeUjwPAw9Dxs82weC7zwCPY8YPI8Inkeh51GDZ4dA8J3HoOcxg+cxwfM49Dxu8OwYCL7zBPQ8YfA8IXiehJ4nDZ6dAsF3noKepwyepwTP09DztMGzcyD4zjPQ84zB84zg+Rv0/M3g2SUQfOdZ6HnW4HlW8Pwdev5u8OwaCL7zHPQ8Z/A8J3j+AT3/MHh2CwTfeR56njd4nhc8/4Sefxo8uweC77wAPS8YPC8Inn9Bz78Mnj0CwXdehJ4XDZ4XBc+/oeffBs+egeA7L0HPSwbPS4LnZeh52eDZKxB85xXoecXgeUXwvAo9rxo8eweC77wGPa8ZPK8Jnteh53WDZ59A8J03oOcNg+cNwfMm9Lxp8OwbCL7zFvS8ZfC8JXjehp63DZ79AsF33oGedwyedwTPu9DzrsGzfyD4znvQ857B857geR963jd4DggE3/kAej4weD4QPB9Cz4cGz4GB4DsfQc9HBs9Hgudj6PnY4DkoEHznE+j5xOD5RPB8Cj2fGjwHB4LvfAY9nxk8nwmez6Hnc4PnkEDwnS+g5wuD5wvB8yX0fGnwHBoIvvMV9Hxl8HwleL6Gnq8NnsMCwXe+gZ5vDJ5vBM+30POtwXN4IPjOd9DzncHzneD5Hnq+N3iOCATf+QF6fjB4fhA8P0LPjwbPkYHgOz9Bz08Gz0+C52fo+dngOSoQfOcX6PnF4PlF8PyqOvP8Z++/eo4OBN8ZojrzDFH9v3v+7+1/mw0JPUMaPMcEgu8MBT1DGTxDCZ6hoWdog+fYQPCdYaBnGINnGMEzLPQMa/AcFwi+Mxz0DGfwDCd4hoee4Q2e4wPBd0aAnhEMnhEEz4jQM6LBc0Ig+M5I0DOSwTOS4BkZekY2eE4MBN8ZBXpGMXhGETyjQs+oBs9JgeA7o0HPaAbPaIJndOgZ3eA5ORB8ZwzoGcPgGUPwjAk9Yxo8pwSC74wFPWMZPGMJnrGhZ2yD59RA8J1xoGccg2ccwTMu9Ixr8JwWCL4zHvSMZ/CMJ3jGh57xDZ7TA8F3JoCeCQyeCQTPhNAzocFzRiD4zkTQM5HBM5HgmRh6JjZ4zgwE35kEeiYxeCYRPJNCz6QGz1mB4DuTQc9kBs9kgmcAegYMnrMDwXcmh57JDZ7JBc8U0DOFwXNOIPjOlNAzpcEzpeCZCnqmMnjODQTfmRp6pjZ4phY800DPNAbPeYHgO9NCz7QGz7SCZzromc7gOT8QfGd66Jne4Jle8MwAPTMYPBcEgu/MCD0zGjwzCp6ZoGcmg+fCQPCdmaFnZoNnZsEzC/TMYvBcFAi+Myv0zGrwzCp4ZoOe2QyeiwPBd2aHntkNntkFzxzQM4fB8+tA8J05oWdOg2dOwTMX9Mxl8FwSCL4zN/TMbfDMLXjmgZ55DJ7fBILvzAs98xo88wqe+aBnPoPn0kDwnfmhZ36DZ37BswD0LGDw/DYQfGdB6FnQ4FlQ8CwEPQsZPJcFgu8sDD0LGzwLC55FoGcRg+d3geA7i0LPogbPooJnMehZzOC5PBB8Z3HoWdzgWVzwLAE9Sxg8vw8E31kSepY0eJYUPEtBz1IGzxWB4DtLQ8/SBs/SgmcZ6FnG4PlDIPjOstCzrMGzrOBZDnqWM3iuDATfWR56ljd4lhc8K0DPCgbPHwPBd1aEnhUNnhUFz0rQs5LBc1Ug+M7K0LOywbOy4FkFelYxeP4UCL6zKvSsavCsKnhWg57VDJ6rA8F3Voee1Q2e1QXPGtCzhsHz50DwnTWhZ02DZ03Bsxb0rGXwXBMIvrM29Kxt8KwteNaBnnUMnr8Egu+sCz3rGjzrCp71oGc9g+faQPCd9aFnfYNnfcGzAfRsYPD8NRB8Z0Po2dDg2VDwbAQ9Gxk81wWC72wMPRsbPBsLnk2gZxOD5/pA8J1NoWdTg2dTwbMZ9Gxm8NwQCL6zOfRsbvBsLni2gJ4tDJ4bA8F3toSeLQ2eLQXPVtCzlcFzUyD4ztbQs7XBs7Xg2QZ6tjF4bg4E39kWerY1eLYVPNtBz3YGzy2B4DvbQ8/2Bs/2gmcH6NnB4Lk1EHxnR+jZ0eDZUfDsBD07GTy3BYLv7Aw9Oxs8OwueXaBnF4Pn9kDwnV2hZ1eDZ1fBsxv07Gbw3BEIvrM79Oxu8OwuePaAnj0MnjsDwXf2hJ49DZ49Bc9e0LOXwXNXIPjO3tCzt8Gzt+DZB3r2MXjuDgTf2Rd69jV49hU8+0HPfgbPPYHgO/tDz/4Gz/6C5wDoOcDguTcQfOdA6DnQ4DlQ8BwEPQcZPPcFgu8cDD0HGzwHC55DoOcQg+f+QPCdQ6HnUIPnUMFzGPQcZvA8EAi+czj0HG7wHC54joCeIwyeBwPBd46EniMNniMFz1HQc5TB81Ag+M7R0HO0wXO04DkGeo4xeB4OBN85FnqONXiOFTzHQc9xBs8jgeA7x0PP8QbP8YLnBOg5weB5NBB850ToOdHgOVHwnAQ9Jxk8jwWC75wMPScbPCcLnlOg5xSD5/FA8J1ToedUg+dUwXMa9Jxm8DwRCL5zOvScbvCcLnjOgJ4zDJ4nA8F3zoSeMw2eMwXPWdBzlsHzVCD4ztnQc7bBc7bgOQd6zjF4ng4E3zkXes41eM4VPOdBz3kGzzOB4DvnQ8/5Bs/5gucC6LnA4PlbIPjOhdBzocFzoeC5CHouMnieDQTfuRh6LjZ4LhY8v4aeXxs8fw8E37kEei4xeC4RPL+Bnt8YPM8Fgu9cCj2XGjyXCp7fQs9vDZ5/BILvXAY9lxk8lwme30HP7wye5wPBdy6HnssNnssFz++h5/cGzz8DwXeugJ4rDJ4rBM8foOcPBs8LgeA7V0LPlQbPlYLnj9DzR4PnX4HgO1dBz1UGz1WC50/Q8yeD58VA8J2roedqg+dqwfNn6PmzwfPvQPCda6DnGoPnGsHzF+j5i8HzUiD4zrXQc63Bc63g+Sv0/NXgeTkQfOc66LnO4LlO8FwPPdcbPK8Egu/cAD03GDw3CJ4boedGg+fVQPCdm6DnJoPnJsFzM/TcbPC8Fgi+cwv03GLw3CJ4boWeWw2e1wPBd26DntsMntsEz+3Qc7vB80Yg+M4d0HOHwXOH4LkTeu40eN4MBN+5C3ruMnjuEjx3Q8/dBs9bgeA790DPPQbPPYLnXui51+B5OxB85z7ouc/guU/w3A899xs87wSC7zwAPQ8YPA8Ingeh50GD591A8J2HoOchg+chwfMw9Dxs8LwXCL7zCPQ8YvA8IngehZ5HDZ73A8F3HoOexwyexwTP49DzuMHzQSD4zhPQ84TB84TgeRJ6njR4PgwE33kKep4yeJ4SPE9Dz9MGz0eB4DvPQM8zBs8zgudv0PM3g+fjQPCdZ6HnWYPnWcHzd+j5u8HzSSD4znPQ85zB85zg+Qf0/MPg+TQQfOd56Hne4Hle8PwTev5p8HwWCL7zAvS8YPC8IHj+BT3/Mng+DwTfeRF6XjR4XhQ8/4aefxs8XwSC77wEPS8ZPC8Jnpeh52WD58tA8J1XoOcVg+cVwfMq9Lxq8HwVCL7zGvS8ZvC8Jnheh57XDZ6vA8F33oCeNwyeNwTPm9DzpsHzTSD4zlvQ85bB85bgeRt63jZ4vg0E33kHet4xeN4RPO9Cz7sGz3eB4DvvQc97Bs97gud96Hnf4Pk+EHznA+j5wOD5QPB8CD0fGjw/BILvfAQ9Hxk8Hwmej6HnY4Pnx0DwnU+g5xOD5xPB8yn0fGrw/BQIvvMZ9Hxm8HwmeD6Hns8Nnp8DwXe+gJ4vDJ4vBM+X0POlwfNLIPjOV9DzlcHzleD5Gnq+Nnh+lTz4zjfQ843B843g+RZ6vjV4hhA830HPdwbPd4Lne+j53uAZUvD8AD0/GDw/CJ4foedHg2cowfMT9Pxk8PwkeH6Gnp8NnqEFzy/Q84vB84vg+VUN5vnP3n/1DCN4hqjBPEPU+O+e/3v732ZDQs+QBs+wgmco6BnK4BlK8AwNPUMbPMMJnmGgZxiDZxjBMyz0DGvwDC94hoOe4Qye4QTP8NAzvMEzguAZAXpGMHhGEDwjQs+IBs+Igmck6BnJ4BlJ8IwMPSMbPCMJnlGgZxSDZxTBMyr0jGrwjCx4RoOe0Qye0QTP6NAzusEziuAZA3rGMHjGEDxjQs+YBs+ogmcs6BnL4BlL8IwNPWMbPKMJnnGgZxyDZxzBMy70jGvwjC54xoOe8Qye8QTP+NAzvsEzhuCZAHomMHgmEDwTQs+EBs+Ygmci6JnI4JlI8EwMPRMbPGMJnkmgZxKDZxLBMyn0TGrwjC14JoOeyQyeyQTPAPQMGDzjCJ7JoWdyg2dywTMF9Exh8IwreKaEnikNnikFz1TQM5XBM57gmRp6pjZ4phY800DPNAbP+IJnWuiZ1uCZVvBMBz3TGTwTCJ7poWd6g2d6wTMD9Mxg8EwoeGaEnhkNnhkFz0zQM5PBM5HgmRl6ZjZ4ZhY8s0DPLAbPxIJnVuiZ1eCZVfDMBj2zGTyTCJ7ZoWd2g2d2wTMH9Mxh8EwqeOaEnjkNnjkFz1zQM5fBM5ngmRt65jZ45hY880DPPAbPgOCZF3rmNXjmFTzzQc98Bs/kgmd+6Jnf4Jlf8CwAPQsYPFMIngWhZ0GDZ0HBsxD0LGTwTCl4FoaehQ2ehQXPItCziMEzleBZFHoWNXgWFTyLQc9iBs/Ugmdx6Fnc4Flc8CwBPUsYPNMIniWhZ0mDZ0nBsxT0LGXwTCt4loaepQ2epQXPMtCzjMEzneBZFnqWNXiWFTzLQc9yBs/0gmd56Fne4Fle8KwAPSsYPDMInhWhZ0WDZ0XBsxL0rGTwzCh4VoaelQ2elQXPKtCzisEzk+BZFXpWNXhWFTyrQc9qBs/Mgmd16Fnd4Fld8KwBPWsYPLMInjWhZ02DZ03Bsxb0rGXwzCp41oaetQ2etQXPOtCzjsEzm+BZF3rWNXjWFTzrQc96Bs/sgmd96Fnf4Flf8GwAPRsYPHMIng2hZ0ODZ0PBsxH0bGTwzCl4NoaejQ2ejQXPJtCzicEzl+DZFHo2NXg2FTybQc9mBs/cgmdz6Nnc4Nlc8GwBPVsYPPMIni2hZ0uDZ0vBsxX0bGXwzCt4toaerQ2erQXPNtCzjcEzn+DZFnq2NXi2FTzbQc92Bs/8gmd76Nne4Nle8OwAPTsYPAsInh2hZ0eDZ0fBsxP07GTwLCh4doaenQ2enQXPLtCzi8GzkODZFXp2NXh2FTy7Qc9uBs/Cgmd36Nnd4Nld8OwBPXsYPIsInj2hZ0+DZ0/Bsxf07GXwLCp49oaevQ2evQXPPtCzj8GzmODZF3r2NXj2FTz7Qc9+Bs/igmd/6Nnf4Nlf8BwAPQcYPEsIngOh50CD50DBcxD0HGTwLCl4Doaegw2egwXPIdBziMGzlOA5FHoONXgOFTyHQc9hBs/Sgudw6Dnc4Dlc8BwBPUcYPMsIniOh50iD50jBcxT0HGXwLCt4joaeow2eowXPMdBzjMGznOA5FnqONXiOFTzHQc9xBs/ygud46Dne4Dle8JwAPScYPCsInhOh50SD50TBcxL0nGTwrCh4Toaekw2ekwXPKdBzisGzkuA5FXpONXhOFTynQc9pBs/Kgud06Dnd4Dld8JwBPWcYPKsInjOh50yD50zBcxb0nGXwrCp4zoaesw2eswXPOdBzjsGzmuA5F3rONXjOFTznQc95Bs/qgud86Dnf4Dlf8FwAPRcYPGsInguh50KD50LBcxH0XGTwrCl4Loaeiw2eiwXPr6Hn1wbPWoLnEui5xOC5RPD8Bnp+Y/CsLXguhZ5LDZ5LBc9voee3Bs86gucy6LnM4LlM8PwOen5n8KwreC6HnssNnssFz++h5/cGz3qC5wroucLguULw/AF6/mDwrC94roSeKw2eKwXPH6HnjwbPBoLnKui5yuC5SvD8CXr+ZPBsKHiuhp6rDZ6rBc+foefPBs9Gguca6LnG4LlG8PwFev5i8GwseK6FnmsNnmsFz1+h568GzyaC5zrouc7guU7wXA891xs8mwqeG6DnBoPnBsFzI/TcaPBsJnhugp6bDJ6bBM/N0HOzwbO54LkFem4xeG4RPLdCz60GzxaC5zbouc3guU3w3A49txs8WwqeO6DnDoPnDsFzJ/TcafBsJXjugp67DJ67BM/d0HO3wbO14LkHeu4xeO4RPPdCz70GzzaC5z7ouc/guU/w3A899xs82wqeB6DnAYPnAcHzIPQ8aPBsJ3gegp6HDJ6HBM/D0POwwbO94HkEeh4xeB4RPI9Cz6MGzw6C5zHoeczgeUzwPA49jxs8OwqeJ6DnCYPnCcHzJPQ8afDsJHiegp6nDJ6nBM/T0PO0wbOz4HkGep4xeJ4RPH+Dnr8ZPLsInmeh51mD51nB83fo+bvBs6vgeQ56njN4nhM8/4Cefxg8uwme56HneYPnecHzT+j5p8Gzu+B5AXpeMHheEDz/gp5/GTx7CJ4XoedFg+dFwfNv6Pm3wbOn4HkJel4yeF4SPC9Dz8sGz16C5xXoecXgeUXwvAo9rxo8ewue16DnNYPnNcHzOvS8bvDsI3jegJ43DJ43BM+b0POmwbOv4HkLet4yeN4SPG9Dz9sGz36C5x3oecfgeUfwvAs97xo8+wue96DnPYPnPcHzPvS8b/AcIHg+gJ4PDJ4PBM+H0POhwXOg4PkIej4yeD4SPB9Dz8cGz0GC5xPo+cTg+UTwfAo9nxo8Bwuez6DnM4PnM8HzOfR8bvAcIni+gJ4vDJ4vBM+X0POlwXOo4PkKer4yeL4SPF9Dz9cGz2GC5xvo+cbg+UbwfAs93xo8hwue76DnO4PnO8HzPfR8b/AcIXh+gJ4fDJ4fBM+P0POjwXOk4PkJen4yeH4SPD9Dz88Gz1GC5xfo+cXg+UXw/Kom8/xn7796jhY8Q9RkniFq/nfP/739b7MhoWdIg+cYwTMU9Axl8AwleIaGnqENnmMFzzDQM4zBM4zgGRZ6hjV4jhM8w0HPcAbPcIJneOgZ3uA5XvCMAD0jGDwjCJ4RoWdEg+cEwTMS9Ixk8IwkeEaGnpENnhMFzyjQM4rBM4rgGRV6RjV4ThI8o0HPaAbPaIJndOgZ3eA5WfCMAT1jGDxjCJ4xoWdMg+cUwTMW9Ixl8IwleMaGnrENnlMFzzjQM47BM47gGRd6xjV4ThM840HPeAbPeIJnfOgZ3+A5XfBMAD0TGDwTCJ4JoWdCg+cMwTMR9Exk8EwkeCaGnokNnjMFzyTQM4nBM4ngmRR6JjV4zhI8k0HPZAbPZIJnAHoGDJ6zBc/k0DO5wTO54JkCeqYweM4RPFNCz5QGz5SCZyromcrgOVfwTA09Uxs8UwueaaBnGoPnPMEzLfRMa/BMK3img57pDJ7zBc/00DO9wTO94JkBemYweC4QPDNCz4wGz4yCZybomcnguVDwzAw9Mxs8MwueWaBnFoPnIsEzK/TMavDMKnhmg57ZDJ6LBc/s0DO7wTO74JkDeuYweH4teOaEnjkNnjkFz1zQM5fBc4ngmRt65jZ45hY880DPPAbPbwTPvNAzr8Ezr+CZD3rmM3guFTzzQ8/8Bs/8gmcB6FnA4Pmt4FkQehY0eBYUPAtBz0IGz2WCZ2HoWdjgWVjwLAI9ixg8vxM8i0LPogbPooJnMehZzOC5XPAsDj2LGzyLC54loGcJg+f3gmdJ6FnS4FlS8CwFPUsZPFcInqWhZ2mDZ2nBswz0LGPw/EHwLAs9yxo8ywqe5aBnOYPnSsGzPPQsb/AsL3hWgJ4VDJ4/Cp4VoWdFg2dFwbMS9Kxk8FwleFaGnpUNnpUFzyrQs4rB8yfBsyr0rGrwrCp4VoOe1QyeqwXP6tCzusGzuuBZA3rWMHj+LHjWhJ41DZ41Bc9a0LOWwXON4FkbetY2eNYWPOtAzzoGz18Ez7rQs67Bs67gWQ961jN4rhU860PP+gbP+oJnA+jZwOD5q+DZEHo2NHg2FDwbQc9GBs91gmdj6NnY4NlY8GwCPZsYPNcLnk2hZ1ODZ1PBsxn0bGbw3CB4NoeezQ2ezQXPFtCzhcFzo+DZEnq2NHi2FDxbQc9WBs9Ngmdr6Nna4Nla8GwDPdsYPDcLnm2hZ1uDZ1vBsx30bGfw3CJ4toee7Q2e7QXPDtCzg8Fzq+DZEXp2NHh2FDw7Qc9OBs9tgmdn6NnZ4NlZ8OwCPbsYPLcLnl2hZ1eDZ1fBsxv07Gbw3CF4doee3Q2e3QXPHtCzh8Fzp+DZE3r2NHj2FDx7Qc9eBs9dgmdv6Nnb4Nlb8OwDPfsYPHcLnn2hZ1+DZ1/Bsx/07Gfw3CN49oee/Q2e/QXPAdBzgMFzr+A5EHoONHgOFDwHQc9BBs99gudg6DnY4DlY8BwCPYcYPPcLnkOh51CD51DBcxj0HGbwPCB4Doeeww2ewwXPEdBzhMHzoOA5EnqONHiOFDxHQc9RBs9Dgudo6Dna4Dla8BwDPccYPA8LnmOh51iD51jBcxz0HGfwPCJ4joee4w2e4wXPCdBzgsHzqOA5EXpONHhOFDwnQc9JBs9jgudk6DnZ4DlZ8JwCPacYPI8LnlOh51SD51TBcxr0nGbwPCF4Toee0w2e0wXPGdBzhsHzpOA5E3rONHjOFDxnQc9ZBs9Tguds6Dnb4Dlb8JwDPecYPE8LnnOh51yD51zBcx70nGfwPCN4zoee8w2e8wXPBdBzgcHzN8FzIfRcaPBcKHgugp6LDJ5nBc/F0HOxwXOx4Pk19Pza4Pm74LkEei4xeC4RPL+Bnt8YPM8Jnkuh51KD51LB81vo+a3B8w/Bcxn0XGbwXCZ4fgc9vzN4nhc8l0PP5QbP5YLn99Dze4Pnn4LnCui5wuC5QvD8AXr+YPC8IHiuhJ4rDZ4rBc8foeePBs+/BM9V0HOVwXOV4PkT9PzJ4HlR8FwNPVcbPFcLnj9Dz58Nnn8Lnmug5xqD5xrB8xfo+YvB85LguRZ6rjV4rhU8f4Wevxo8Lwue66DnOoPnOsFzPfRcb/C8InhugJ4bDJ4bBM+N0HOjwfOq4LkJem4yeG4SPDdDz80Gz2uC5xboucXguUXw3Ao9txo8rwue26DnNoPnNsFzO/TcbvC8IXjugJ47DJ47BM+d0HOnwfOm4LkLeu4yeO4SPHdDz90Gz1uC5x7oucfguUfw3As99xo8bwue+6DnPoPnPsFzP/Tcb/C8I3gegJ4HDJ4HBM+D0POgwfOu4HkIeh4yeB4SPA9Dz8MGz3uC5xHoecTgeUTwPAo9jxo87wuex6DnMYPnMcHzOPQ8bvB8IHiegJ4nDJ4nBM+T0POkwfOh4HkKep4yeJ4SPE9Dz9MGz0eC5xnoecbgeUbw/A16/mbwfCx4noWeZw2eZwXP36Hn7wbPJ4LnOeh5zuB5TvD8A3r+YfB8Knieh57nDZ7nBc8/oeefBs9ngucF6HnB4HlB8PwLev5l8HwueF6EnhcNnhcFz7+h598GzxeC5yXoecngeUnwvAw9Lxs8XwqeV6DnFYPnFcHzKvS8avB8JXheg57XDJ7XBM/r0PO6wfO14HkDet4weN4QPG9Cz5sGzzeC5y3oecvgeUvwvA09bxs83wqed6DnHYPnHcHzLvS8a/B8J3jeg573DJ73BM/70PO+wfO94PkAej4weD4QPB9Cz4cGzw+C5yPo+cjg+UjwfAw9Hxs8PwqeT6DnE4PnE8HzKfR8avD8JHg+g57PDJ7PBM/n0PO5wfOz4PkCer4weL4QPF9Cz5cGzy+C5yvo+crg+UrwfA09Xxs8v0oRfOcb6PnG4PlG8HwLPd8aPEMInu+g5zuD5zvB8z30fG/wDCl4foCeHwyeHwTPj9Dzo8EzlOD5CXp+Mnh+Ejw/Q8/PBs/QgucX6PnF4PlF8PyqFvP8Z++/eoYRPEPUYp4hav13z/+9/W+zIaFnSINnWMEzFPQMZfAMJXiGhp6hDZ7hBM8w0DOMwTOM4BkWeoY1eIYXPMNBz3AGz3CCZ3joGd7gGUHwjAA9Ixg8IwieEaFnRINnRMEzEvSMZPCMJHhGhp6RDZ6RBM8o0DOKwTOK4BkVekY1eEYWPKNBz2gGz2iCZ3ToGd3gGUXwjAE9Yxg8YwieMaFnTINnVMEzFvSMZfCMJXjGhp6xDZ7RBM840DOOwTOO4BkXesY1eEYXPONBz3gGz3iCZ3zoGd/gGUPwTAA9Exg8EwieCaFnQoNnTMEzEfRMZPBMJHgmhp6JDZ6xBM8k0DOJwTOJ4JkUeiY1eMYWPJNBz2QGz2SCZwB6BgyecQTP5NAzucEzueCZAnqmMHjGFTxTQs+UBs+Ugmcq6JnK4BlP8EwNPVMbPFMLnmmgZxqDZ3zBMy30TGvwTCt4poOe6QyeCQTP9NAzvcEzveCZAXpmMHgmFDwzQs+MBs+Mgmcm6JnJ4JlI8MwMPTMbPDMLnlmgZxaDZ2LBMyv0zGrwzCp4ZoOe2QyeSQTP7NAzu8Ezu+CZA3rmMHgmFTxzQs+cBs+cgmcu6JnL4JlM8MwNPXMbPHMLnnmgZx6DZ0DwzAs98xo88wqe+aBnPoNncsEzP/TMb/DML3gWgJ4FDJ4pBM+C0LOgwbOg4FkIehYyeKYUPAtDz8IGz8KCZxHoWcTgmUrwLAo9ixo8iwqexaBnMYNnasGzOPQsbvAsLniWgJ4lDJ5pBM+S0LOkwbOk4FkKepYyeKYVPEtDz9IGz9KCZxnoWcbgmU7wLAs9yxo8ywqe5aBnOYNnesGzPPQsb/AsL3hWgJ4VDJ4ZBM+K0LOiwbOi4FkJelYyeGYUPCtDz8oGz8qCZxXoWcXgmUnwrAo9qxo8qwqe1aBnNYNnZsGzOvSsbvCsLnjWgJ41DJ5ZBM+a0LOmwbOm4FkLetYyeGYVPGtDz9oGz9qCZx3oWcfgmU3wrAs96xo86wqe9aBnPYNndsGzPvSsb/CsL3g2gJ4NDJ45BM+G0LOhwbOh4NkIejYyeOYUPBtDz8YGz8aCZxPo2cTgmUvwbAo9mxo8mwqezaBnM4NnbsGzOfRsbvBsLni2gJ4tDJ55BM+W0LOlwbOl4NkKerYyeOYVPFtDz9YGz9aCZxvo2cbgmU/wbAs92xo82wqe7aBnO4NnfsGzPfRsb/BsL3h2gJ4dDJ4FBM+O0LOjwbOj4NkJenYyeBYUPDtDz84Gz86CZxfo2cXgWUjw7Ao9uxo8uwqe3aBnN4NnYcGzO/TsbvDsLnj2gJ49DJ5FBM+e0LOnwbOn4NkLevYyeBYVPHtDz94Gz96CZx/o2cfgWUzw7As9+xo8+wqe/aBnP4NnccGzP/Tsb/DsL3gOgJ4DDJ4lBM+B0HOgwXOg4DkIeg4yeJYUPAdDz8EGz8GC5xDoOcTgWUrwHAo9hxo8hwqew6DnMINnacFzOPQcbvAcLniOgJ4jDJ5lBM+R0HOkwXOk4DkKeo4yeJYVPEdDz9EGz9GC5xjoOcbgWU7wHAs9xxo8xwqe46DnOINnecFzPPQcb/AcL3hOgJ4TDJ4VBM+J0HOiwXOi4DkJek4yeFYUPCdDz8kGz8mC5xToOcXgWUnwnAo9pxo8pwqe06DnNINnZcFzOvScbvCcLnjOgJ4zDJ5VBM+Z0HOmwXOm4DkLes4yeFYVPGdDz9kGz9mC5xzoOcfgWU3wnAs95xo85wqe86DnPINndcFzPvScb/CcL3gugJ4LDJ41BM+F0HOhwXOh4LkIei4yeNYUPBdDz8UGz8WC59fQ82uDZy3Bcwn0XGLwXCJ4fgM9vzF41hY8l0LPpQbPpYLnt9DzW4NnHcFzGfRcZvBcJnh+Bz2/M3jWFTyXQ8/lBs/lguf30PN7g2c9wXMF9Fxh8FwheP4APX8weNYXPFdCz5UGz5WC54/Q80eDZwPBcxX0XGXwXCV4/gQ9fzJ4NhQ8V0PP1QbP1YLnz9DzZ4NnI8FzDfRcY/BcI3j+Aj1/MXg2FjzXQs+1Bs+1guev0PNXg2cTwXMd9Fxn8FwneK6HnusNnk0Fzw3Qc4PBc4PguRF6bjR4NhM8N0HPTQbPTYLnZui52eDZXPDcAj23GDy3CJ5boedWg2cLwXMb9Nxm8NwmeG6HntsNni0Fzx3Qc4fBc4fguRN67jR4thI8d0HPXQbPXYLnbui52+DZWvDcAz33GDz3CJ57oedeg2cbwXMf9Nxn8NwneO6HnvsNnm0FzwPQ84DB84DgeRB6HjR4thM8D0HPQwbPQ4LnYeh52ODZXvA8Aj2PGDyPCJ5HoedRg2cHwfMY9Dxm8DwmeB6HnscNnh0FzxPQ84TB84TgeRJ6njR4dhI8T0HPUwbPU4Lnaeh52uDZWfA8Az3PGDzPCJ6/Qc/fDJ5dBM+z0POswfOs4Pk79Pzd4NlV8DwHPc8ZPM8Jnn9Azz8Mnt0Ez/PQ87zB87zg+Sf0/NPg2V3wvAA9Lxg8Lwief0HPvwyePQTPi9DzosHzouD5N/T82+DZU/C8BD0vGTwvCZ6Xoedlg2cvwfMK9Lxi8LwieF6FnlcNnr0Fz2vQ85rB85rgeR16Xjd49hE8b0DPGwbPG4LnTeh50+DZV/C8BT1vGTxvCZ63oedtg2c/wfMO9Lxj8LwjeN6FnncNnv0Fz3vQ857B857geR963jd4DhA8H0DPBwbPB4LnQ+j50OA5UPB8BD0fGTwfCZ6Poedjg+cgwfMJ9Hxi8HwieD6Fnk8NnoMFz2fQ85nB85ng+Rx6Pjd4DhE8X0DPFwbPF4LnS+j50uA5VPB8BT1fGTxfCZ6voedrg+cwwfMN9Hxj8HwjeL6Fnm8NnsMFz3fQ853B853g+R56vjd4jhA8P0DPDwbPD4LnR+j50eA5UvD8BD0/GTw/CZ6foedng+cowfML9Pxi8PwieH5Vm3n+s/dfPUcLniFqM88Qtf+75//e/rfZkNAzpMFzjOAZCnqGMniGEjxDQ8/QBs+xgmcY6BnG4BlG8AwLPcMaPMcJnuGgZziDZzjBMzz0DG/wHC94RoCeEQyeEQTPiNAzosFzguAZCXpGMnhGEjwjQ8/IBs+JgmcU6BnF4BlF8IwKPaMaPCcJntGgZzSDZzTBMzr0jG7wnCx4xoCeMQyeMQTPmNAzpsFziuAZC3rGMnjGEjxjQ8/YBs+pgmcc6BnH4BlH8IwLPeMaPKcJnvGgZzyDZzzBMz70jG/wnC54JoCeCQyeCQTPhNAzocFzhuCZCHomMngmEjwTQ8/EBs+ZgmcS6JnE4JlE8EwKPZMaPGcJnsmgZzKDZzLBMwA9AwbP2YJncuiZ3OCZXPBMAT1TGDznCJ4poWdKg2dKwTMV9Exl8JwreKaGnqkNnqkFzzTQM43Bc57gmRZ6pjV4phU800HPdAbP+YJneuiZ3uCZXvDMAD0zGDwXCJ4ZoWdGg2dGwTMT9Mxk8FwoeGaGnpkNnpkFzyzQM4vBc5HgmRV6ZjV4ZhU8s0HPbAbPxYJnduiZ3eCZXfDMAT1zGDy/FjxzQs+cBs+cgmcu6JnL4LlE8MwNPXMbPHMLnnmgZx6D5zeCZ17omdfgmVfwzAc98xk8lwqe+aFnfoNnfsGzAPQsYPD8VvAsCD0LGjwLCp6FoGchg+cywbMw9Cxs8CwseBaBnkUMnt8JnkWhZ1GDZ1HBsxj0LGbwXC54FoeexQ2exQXPEtCzhMHze8GzJPQsafAsKXiWgp6lDJ4rBM/S0LO0wbO04FkGepYxeP4geJaFnmUNnmUFz3LQs5zBc6XgWR56ljd4lhc8K0DPCgbPHwXPitCzosGzouBZCXpWMniuEjwrQ8/KBs/KgmcV6FnF4PmT4FkVelY1eFYVPKtBz2oGz9WCZ3XoWd3gWV3wrAE9axg8fxY8a0LPmgbPmoJnLehZy+C5RvCsDT1rGzxrC551oGcdg+cvgmdd6FnX4FlX8KwHPesZPNcKnvWhZ32DZ33BswH0bGDw/FXwbAg9Gxo8GwqejaBnI4PnOsGzMfRsbPBsLHg2gZ5NDJ7rBc+m0LOpwbOp4NkMejYzeG4QPJtDz+YGz+aCZwvo2cLguVHwbAk9Wxo8WwqeraBnK4PnJsGzNfRsbfBsLXi2gZ5tDJ6bBc+20LOtwbOt4NkOerYzeG4RPNtDz/YGz/aCZwfo2cHguVXw7Ag9Oxo8OwqenaBnJ4PnNsGzM/TsbPDsLHh2gZ5dDJ7bBc+u0LOrwbOr4NkNenYzeO4QPLtDz+4Gz+6CZw/o2cPguVPw7Ak9exo8ewqevaBnL4PnLsGzN/TsbfDsLXj2gZ59DJ67Bc++0LOvwbOv4NkPevYzeO4RPPtDz/4Gz/6C5wDoOcDguVfwHAg9Bxo8Bwqeg6DnIIPnPsFzMPQcbPAcLHgOgZ5DDJ77Bc+h0HOowXOo4DkMeg4zeB4QPIdDz+EGz+GC5wjoOcLgeVDwHAk9Rxo8Rwqeo6DnKIPnIcFzNPQcbfAcLXiOgZ5jDJ6HBc+x0HOswXOs4DkOeo4zeB4RPMdDz/EGz/GC5wToOcHgeVTwnAg9Jxo8Jwqek6DnJIPnMcFzMvScbPCcLHhOgZ5TDJ7HBc+p0HOqwXOq4DkNek4zeJ4QPKdDz+kGz+mC5wzoOcPgeVLwnAk9Zxo8Zwqes6DnLIPnKcFzNvScbfCcLXjOgZ5zDJ6nBc+50HOuwXOu4DkPes4zeJ4RPOdDz/kGz/mC5wLoucDg+ZvguRB6LjR4LhQ8F0HPRQbPs4LnYui52OC5WPD8Gnp+bfD8XfBcAj2XGDyXCJ7fQM9vDJ7nBM+l0HOpwXOp4Pkt9PzW4PmH4LkMei4zeC4TPL+Dnt8ZPM8Lnsuh53KD53LB83vo+b3B80/BcwX0XGHwXCF4/gA9fzB4XhA8V0LPlQbPlYLnj9DzR4PnX4LnKui5yuC5SvD8CXr+ZPC8KHiuhp6rDZ6rBc+foefPBs+/Bc810HONwXON4PkL9PzF4HlJ8FwLPdcaPNcKnr9Cz18NnpcFz3XQc53Bc53guR56rjd4XhE8N0DPDQbPDYLnRui50eB5VfDcBD03GTw3CZ6boedmg+c1wXML9Nxi8NwieG6FnlsNntcFz23Qc5vBc5vguR16bjd43hA8d0DPHQbPHYLnTui50+B5U/DcBT13GTx3CZ67oedug+ctwXMP9Nxj8NwjeO6FnnsNnrcFz33Qc5/Bc5/guR967jd43hE8D0DPAwbPA4LnQeh50OB5V/A8BD0PGTwPCZ6Hoedhg+c9wfMI9Dxi8DwieB6FnkcNnvcFz2PQ85jB85jgeRx6Hjd4PhA8T0DPEwbPE4LnSeh50uD5UPA8BT1PGTxPCZ6noedpg+cjwfMM9Dxj8DwjeP4GPX8zeD4WPM9Cz7MGz7OC5+/Q83eD5xPB8xz0PGfwPCd4/gE9/zB4PhU8z0PP8wbP84Lnn9DzT4PnM8HzAvS8YPC8IHj+BT3/Mng+FzwvQs+LBs+Lguff0PNvg+cLwfMS9Lxk8LwkeF6GnpcNni8FzyvQ84rB84rgeRV6XjV4vhI8r0HPawbPa4Lndeh53eD5WvC8AT1vGDxvCJ43oedNg+cbwfMW9Lxl8LwleN6GnrcNnm8FzzvQ847B847geRd63jV4vhM870HPewbPe4Lnfeh53+D5XvB8AD0fGDwfCJ4PoedDg+cHwfMR9Hxk8HwkeD6Gno8Nnh8FzyfQ84nB84ng+RR6PjV4fhI8n0HPZwbPZ4Lnc+j53OD5WfB8AT1fGDxfCJ4voedLg+cXwfMV9Hxl8HwleL6Gnq8Nnl+lDL7zDfR8Y/B8I3i+hZ5vDZ4hBM930POdwfOd4Pkeer43eIYUPD9Azw8Gzw+C50fo+dHgGUrw/AQ9Pxk8Pwmen6HnZ4NnaMHzC/T8YvD8Inh+VYd5/rP3Xz3DCJ4h6jDPEHX+u+f/3v632ZDQM6TBM6zgGQp6hjJ4hhI8Q0PP0AbPcIJnGOgZxuAZRvAMCz3DGjzDC57hoGc4g2c4wTM89Axv8IwgeEaAnhEMnhEEz4jQM6LBM6LgGQl6RjJ4RhI8I0PPyAbPSIJnFOgZxeAZRfCMCj2jGjwjC57RoGc0g2c0wTM69Ixu8IwieMaAnjEMnjEEz5jQM6bBM6rgGQt6xjJ4xhI8Y0PP2AbPaIJnHOgZx+AZR/CMCz3jGjyjC57xoGc8g2c8wTM+9Ixv8IwheCaAngkMngkEz4TQM6HBM6bgmQh6JjJ4JhI8E0PPxAbPWIJnEuiZxOCZRPBMCj2TGjxjC57JoGcyg2cywTMAPQMGzziCZ3LomdzgmVzwTAE9Uxg84wqeKaFnSoNnSsEzFfRMZfCMJ3imhp6pDZ6pBc800DONwTO+4JkWeqY1eKYVPNNBz3QGzwSCZ3romd7gmV7wzAA9Mxg8EwqeGaFnRoNnRsEzE/TMZPBMJHhmhp6ZDZ6ZBc8s0DOLwTOx4JkVemY1eGYVPLNBz2wGzySCZ3bomd3gmV3wzAE9cxg8kwqeOaFnToNnTsEzF/TMZfBMJnjmhp65DZ65Bc880DOPwTMgeOaFnnkNnnkFz3zQM5/BM7ngmR965jd45hc8C0DPAgbPFIJnQehZ0OBZUPAsBD0LGTxTCp6FoWdhg2dhwbMI9Cxi8EwleBaFnkUNnkUFz2LQs5jBM7XgWRx6Fjd4Fhc8S0DPEgbPNIJnSehZ0uBZUvAsBT1LGTzTCp6loWdpg2dpwbMM9Cxj8EwneJaFnmUNnmUFz3LQs5zBM73gWR56ljd4lhc8K0DPCgbPDIJnRehZ0eBZUfCsBD0rGTwzCp6VoWdlg2dlwbMK9Kxi8MwkeFaFnlUNnlUFz2rQs5rBM7PgWR16Vjd4Vhc8a0DPGgbPLIJnTehZ0+BZU/CsBT1rGTyzCp61oWdtg2dtwbMO9Kxj8MwmeNaFnnUNnnUFz3rQs57BM7vgWR961jd41hc8G0DPBgbPHIJnQ+jZ0ODZUPBsBD0bGTxzCp6NoWdjg2djwbMJ9Gxi8MwleDaFnk0Nnk0Fz2bQs5nBM7fg2Rx6Njd4Nhc8W0DPFgbPPIJnS+jZ0uDZUvBsBT1bGTzzCp6toWdrg2drwbMN9Gxj8MwneLaFnm0Nnm0Fz3bQs53BM7/g2R56tjd4thc8O0DPDgbPAoJnR+jZ0eDZUfDsBD07GTwLCp6doWdng2dnwbML9Oxi8CwkeHaFnl0Nnl0Fz27Qs5vBs7Dg2R16djd4dhc8e0DPHgbPIoJnT+jZ0+DZU/DsBT17GTyLCp69oWdvg2dvwbMP9Oxj8CwmePaFnn0Nnn0Fz37Qs5/Bs7jg2R969jd49hc8B0DPAQbPEoLnQOg50OA5UPAcBD0HGTxLCp6Doedgg+dgwXMI9Bxi8CwleA6FnkMNnkMFz2HQc5jBs7TgORx6Djd4Dhc8R0DPEQbPMoLnSOg50uA5UvAcBT1HGTzLCp6joedog+dowXMM9Bxj8CwneI6FnmMNnmMFz3HQc5zBs7zgOR56jjd4jhc8J0DPCQbPCoLnROg50eA5UfCcBD0nGTwrCp6Toedkg+dkwXMK9Jxi8KwkeE6FnlMNnlMFz2nQc5rBs7LgOR16Tjd4Thc8Z0DPGQbPKoLnTOg50+A5U/CcBT1nGTyrCp6zoedsg+dswXMO9Jxj8KwmeM6FnnMNnnMFz3nQc57Bs7rgOR96zjd4zhc8F0DPBQbPGoLnQui50OC5UPBcBD0XGTxrCp6Loedig+diwfNr6Pm1wbOW4LkEei4xeC4RPL+Bnt8YPGsLnkuh51KD51LB81vo+a3Bs47guQx6LjN4LhM8v4Oe3xk86wqey6HncoPncsHze+j5vcGznuC5AnquMHiuEDx/gJ4/GDzrC54roedKg+dKwfNH6PmjwbOB4LkKeq4yeK4SPH+Cnj8ZPBsKnquh52qD52rB82fo+bPBs5HguQZ6rjF4rhE8f4Gevxg8Gwuea6HnWoPnWsHzV+j5q8GzieC5DnquM3iuEzzXQ8/1Bs+mgucG6LnB4LlB8NwIPTcaPJsJnpug5yaD5ybBczP03GzwbC54boGeWwyeWwTPrdBzq8GzheC5DXpuM3huEzy3Q8/tBs+WgucO6LnD4LlD8NwJPXcaPFsJnrug5y6D5y7Bczf03G3wbC147oGeewyeewTPvdBzr8GzjeC5D3ruM3juEzz3Q8/9Bs+2gucB6HnA4HlA8DwIPQ8aPNsJnoeg5yGD5yHB8zD0PGzwbC94HoGeRwyeRwTPo9DzqMGzg+B5DHoeM3geEzyPQ8/jBs+OgucJ6HnC4HlC8DwJPU8aPDsJnqeg5ymD5ynB8zT0PG3w7Cx4noGeZwyeZwTP36DnbwbPLoLnWeh51uB5VvD8HXr+bvDsKnieg57nDJ7nBM8/oOcfBs9ugud56Hne4Hle8PwTev5p8OwueF6AnhcMnhcEz7+g518Gzx6C50XoedHgeVHw/Bt6/m3w7Cl4XoKelwyelwTPy9DzssGzl+B5BXpeMXheETyvQs+rBs/eguc16HnN4HlN8LwOPa8bPPsInjeg5w2D5w3B8yb0vGnw7Ct43oKetwyetwTP29DztsGzn+B5B3reMXjeETzvQs+7Bs/+guc96HnP4HlP8LwPPe8bPAcIng+g5wOD5wPB8yH0fGjwHCh4PoKejwyejwTPx9DzscFzkOD5BHo+MXg+ETyfQs+nBs/Bgucz6PnM4PlM8HwOPZ8bPIcIni+g5wuD5wvB8yX0fGnwHCp4voKerwyerwTP19DztcFzmOD5Bnq+MXi+ETzfQs+3Bs/hguc76PnO4PlO8HwPPd8bPEcInh+g5weD5wfB8yP0/GjwHCl4foKenwyenwTPz9Dzs8FzlOD5BXp+MXh+ETy/qss8/9n7r56jBc8QdZlniLr/3fN/b//bbEjoGdLgOUbwDAU9Qxk8QwmeoaFnaIPnWMEzDPQMY/AMI3iGhZ5hDZ7jBM9w0DOcwTOc4BkeeoY3eI4XPCNAzwgGzwiCZ0ToGdHgOUHwjAQ9Ixk8IwmekaFnZIPnRMEzCvSMYvCMInhGhZ5RDZ6TBM9o0DOawTOa4BkdekY3eE4WPGNAzxgGzxiCZ0zoGdPgOUXwjAU9Yxk8YwmesaFnbIPnVMEzDvSMY/CMI3jGhZ5xDZ7TBM940DOewTOe4BkfesY3eE4XPBNAzwQGzwSCZ0LomdDgOUPwTAQ9Exk8EwmeiaFnYoPnTMEzCfRMYvBMIngmhZ5JDZ6zBM9k0DOZwTOZ4BmAngGD52zBMzn0TG7wTC54poCeKQyecwTPlNAzpcEzpeCZCnqmMnjOFTxTQ8/UBs/Ugmca6JnG4DlP8EwLPdMaPNMKnumgZzqD53zBMz30TG/wTC94ZoCeGQyeCwTPjNAzo8Ezo+CZCXpmMnguFDwzQ8/MBs/MgmcW6JnF4LlI8MwKPbMaPLMKntmgZzaD52LBMzv0zG7wzC545oCeOQyeXwueOaFnToNnTsEzF/TMZfBcInjmhp65DZ65Bc880DOPwfMbwTMv9Mxr8MwreOaDnvkMnksFz/zQM7/BM7/gWQB6FjB4fit4FoSeBQ2eBQXPQtCzkMFzmeBZGHoWNngWFjyLQM8iBs/vBM+i0LOowbOo4FkMehYzeC4XPItDz+IGz+KCZwnoWcLg+b3gWRJ6ljR4lhQ8S0HPUgbPFYJnaehZ2uBZWvAsAz3LGDx/EDzLQs+yBs+ygmc56FnO4LlS8CwPPcsbPMsLnhWgZwWD54+CZ0XoWdHgWVHwrAQ9Kxk8VwmelaFnZYNnZcGzCvSsYvD8SfCsCj2rGjyrCp7VoGc1g+dqwbM69Kxu8KwueNaAnjUMnj8LnjWhZ02DZ03Bsxb0rGXwXCN41oaetQ2etQXPOtCzjsHzF8GzLvSsa/CsK3jWg571DJ5rBc/60LO+wbO+4NkAejYweP4qeDaEng0Nng0Fz0bQs5HBc53g2Rh6NjZ4NhY8m0DPJgbP9YJnU+jZ1ODZVPBsBj2bGTw3CJ7NoWdzg2dzwbMF9Gxh8NwoeLaEni0Nni0Fz1bQs5XBc5Pg2Rp6tjZ4thY820DPNgbPzYJnW+jZ1uDZVvBsBz3bGTy3CJ7toWd7g2d7wbMD9Oxg8NwqeHaEnh0Nnh0Fz07Qs5PBc5vg2Rl6djZ4dhY8u0DPLgbP7YJnV+jZ1eDZVfDsBj27GTx3CJ7doWd3g2d3wbMH9Oxh8NwpePaEnj0Nnj0Fz17Qs5fBc5fg2Rt69jZ49hY8+0DPPgbP3YJnX+jZ1+DZV/DsBz37GTz3CJ79oWd/g2d/wXMA9Bxg8NwreA6EngMNngMFz0HQc5DBc5/gORh6DjZ4DhY8h0DPIQbP/YLnUOg51OA5VPAcBj2HGTwPCJ7Doedwg+dwwXME9Bxh8DwoeI6EniMNniMFz1HQc5TB85DgORp6jjZ4jhY8x0DPMQbPw4LnWOg51uA5VvAcBz3HGTyPCJ7joed4g+d4wXMC9Jxg8DwqeE6EnhMNnhMFz0nQc5LB85jgORl6TjZ4ThY8p0DPKQbP44LnVOg51eA5VfCcBj2nGTxPCJ7Toed0g+d0wXMG9Jxh8DwpeM6EnjMNnjMFz1nQc5bB85TgORt6zjZ4zhY850DPOQbP04LnXOg51+A5V/CcBz3nGTzPCJ7zoed8g+d8wXMB9Fxg8PxN8FwIPRcaPBcKnoug5yKD51nBczH0XGzwXCx4fg09vzZ4/i54LoGeSwyeSwTPb6DnNwbPc4LnUui51OC5VPD8Fnp+a/D8Q/BcBj2XGTyXCZ7fQc/vDJ7nBc/l0HO5wXO54Pk99Pze4Pmn4LkCeq4weK4QPH+Anj8YPC8Iniuh50qD50rB80fo+aPB8y/BcxX0XGXwXCV4/gQ9fzJ4XhQ8V0PP1QbP1YLnz9DzZ4Pn34LnGui5xuC5RvD8BXr+YvC8JHiuhZ5rDZ5rBc9foeevBs/Lguc66LnO4LlO8FwPPdcbPK8Inhug5waD5wbBcyP03GjwvCp4boKemwyemwTPzdBzs8HzmuC5BXpuMXhuETy3Qs+tBs/rguc26LnN4LlN8NwOPbcbPG8Injug5w6D5w7Bcyf03GnwvCl47oKeuwyeuwTP3dBzt8HzluC5B3ruMXjuETz3Qs+9Bs/bguc+6LnP4LlP8NwPPfcbPO8Ingeg5wGD5wHB8yD0PGjwvCt4HoKehwyehwTPw9DzsMHznuB5BHoeMXgeETyPQs+jBs/7gucx6HnM4HlM8DwOPY8bPB8Inieg5wmD5wnB8yT0PGnwfCh4noKepwyepwTP09DztMHzkeB5BnqeMXieETx/g56/GTwfC55noedZg+dZwfN36Pm7wfOJ4HkOep4zeJ4TPP+Ann8YPJ8Knueh53mD53nB80/o+afB85ngeQF6XjB4XhA8/4Kefxk8nwueF6HnRYPnRcHzb+j5t8HzheB5CXpeMnheEjwvQ8/LBs+XgucV6HnF4HlF8LwKPa8aPF8Jnteg5zWD5zXB8zr0vG7wfC143oCeNwyeNwTPm9DzpsHzjeB5C3reMnjeEjxvQ8/bBs+3gucd6HnH4HlH8LwLPe8aPN8Jnveg5z2D5z3B8z70vG/wfC94PoCeDwyeDwTPh9DzocHzg+D5CHo+Mng+EjwfQ8/HBs+PgucT6PnE4PlE8HwKPZ8aPD8Jns+g5zOD5zPB8zn0fG7w/Cx4voCeLwyeLwTPl9DzpcHzi+D5Cnq+Mni+EjxfQ8/XDs+0wXe+Ca4z3Jcv3b76385/9lL9S6dy+99m3wbXGe3L56v/r/NtEJ3/8kJ8lS74znfQ853B853g+R56vjd4hhA8P0DPDwbPD4LnR+j50eAZUvD8BD0/GTw/CZ6foedng2cowfML9Pxi8PwieH5Vj3n+s/dfPUMLniHqMc8Q9f675//e/rfZkNAzpMEzjOAZCnqGMniGEjxDQ8/QBs+wgmcY6BnG4BlG8AwLPcMaPMMJnuGgZziDZzjBMzz0DG/wDC94RoCeEQyeEQTPiNAzosEzguAZCXpGMnhGEjwjQ8/IBs+IgmcU6BnF4BlF8IwKPaMaPCMJntGgZzSDZzTBMzr0jG7wjCx4xoCeMQyeMQTPmNAzpsEziuAZC3rGMnjGEjxjQ8/YBs+ogmcc6BnH4BlH8IwLPeMaPKMJnvGgZzyDZzzBMz70jG/wjC54JoCeCQyeCQTPhNAzocEzhuCZCHomMngmEjwTQ8/EBs+YgmcS6JnE4JlE8EwKPZMaPGMJnsmgZzKDZzLBMwA9AwbP2IJncuiZ3OCZXPBMAT1TGDzjCJ4poWdKg2dKwTMV9Exl8IwreKaGnqkNnqkFzzTQM43BM57gmRZ6pjV4phU800HPdAbP+IJneuiZ3uCZXvDMAD0zGDwTCJ4ZoWdGg2dGwTMT9Mxk8EwoeGaGnpkNnpkFzyzQM4vBM5HgmRV6ZjV4ZhU8s0HPbAbPxIJnduiZ3eCZXfDMAT1zGDyTCJ45oWdOg2dOwTMX9Mxl8EwqeOaGnrkNnrkFzzzQM4/BM5ngmRd65jV45hU880HPfAbPgOCZH3rmN3jmFzwLQM8CBs/kgmdB6FnQ4FlQ8CwEPQsZPFMInoWhZ2GDZ2HBswj0LGLwTCl4FoWeRQ2eRQXPYtCzmMEzleBZHHoWN3gWFzxLQM8SBs/UgmdJ6FnS4FlS8CwFPUsZPNMInqWhZ2mDZ2nBswz0LGPwTCt4loWeZQ2eZQXPctCznMEzneBZHnqWN3iWFzwrQM8KBs/0gmdF6FnR4FlR8KwEPSsZPDMInpWhZ2WDZ2XBswr0rGLwzCh4VoWeVQ2eVQXPatCzmsEzk+BZHXpWN3hWFzxrQM8aBs/MgmdN6FnT4FlT8KwFPWsZPLMInrWhZ22DZ23Bsw70rGPwzCp41oWedQ2edQXPetCznsEzm+BZH3rWN3jWFzwbQM8GBs/sgmdD6NnQ4NlQ8GwEPRsZPHMIno2hZ2ODZ2PBswn0bGLwzCl4NoWeTQ2eTQXPZtCzmcEzl+DZHHo2N3g2FzxbQM8WBs/cgmdL6NnS4NlS8GwFPVsZPPMInq2hZ2uDZ2vBsw30bGPwzCt4toWebQ2ebQXPdtCzncEzn+DZHnq2N3i2Fzw7QM8OBs/8gmdH6NnR4NlR8OwEPTsZPAsInp2hZ2eDZ2fBswv07GLwLCh4doWeXQ2eXQXPbtCzm8GzkODZHXp2N3h2Fzx7QM8eBs/CgmdP6NnT4NlT8OwFPXsZPIsInr2hZ2+DZ2/Bsw/07GPwLCp49oWefQ2efQXPftCzn8GzmODZH3r2N3j2FzwHQM8BBs/igudA6DnQ4DlQ8BwEPQcZPEsInoOh52CD52DBcwj0HGLwLCl4DoWeQw2eQwXPYdBzmMGzlOA5HHoON3gOFzxHQM8RBs/SgudI6DnS4DlS8BwFPUcZPMsInqOh52iD52jBcwz0HGPwLCt4joWeYw2eYwXPcdBznMGznOA5HnqON3iOFzwnQM8JBs/ygudE6DnR4DlR8JwEPScZPCsInpOh52SD52TBcwr0nGLwrCh4ToWeUw2eUwXPadBzmsGzkuA5HXpON3hOFzxnQM8ZBs/KgudM6DnT4DlT8JwFPWcZPKsInrOh52yD52zBcw70nGPwrCp4zoWecw2ecwXPedBznsGzmuA5H3rON3jOFzwXQM8FBs/qgudC6LnQ4LlQ8FwEPRcZPGsInouh52KD52LB82vo+bXBs6bguQR6LjF4LhE8v4Ge3xg8awmeS6HnUoPnUsHzW+j5rcGztuC5DHouM3guEzy/g57fGTzrCJ7Loedyg+dywfN76Pm9wbOu4LkCeq4weK4QPH+Anj8YPOsJniuh50qD50rB80fo+aPBs77guQp6rjJ4rhI8f4KePxk8Gwieq6HnaoPnasHzZ+j5s8GzoeC5BnquMXiuETx/gZ6/GDwbCZ5roedag+dawfNX6PmrwbOx4LkOeq4zeK4TPNdDz/UGzyaC5wboucHguUHw3Ag9Nxo8mwqem6DnJoPnJsFzM/TcbPBsJnhugZ5bDJ5bBM+t0HOrwbO54LkNem4zeG4TPLdDz+0GzxaC5w7oucPguUPw3Ak9dxo8Wwqeu6DnLoPnLsFzN/TcbfBsJXjugZ57DJ57BM+90HOvwbO14LkPeu4zeO4TPPdDz/0GzzaC5wHoecDgeUDwPAg9Dxo82wqeh6DnIYPnIcHzMPQ8bPBsJ3gegZ5HDJ5HBM+j0POowbO94HkMeh4zeB4TPI9Dz+MGzw6C5wnoecLgeULwPAk9Txo8Owqep6DnKYPnKcHzNPQ8bfDsJHiegZ5nDJ5nBM/foOdvBs/OgudZ6HnW4HlW8Pwdev5u8OwieJ6DnucMnucEzz+g5x8Gz66C53noed7geV7w/BN6/mnw7CZ4XoCeFwyeFwTPv6DnXwbP7oLnReh50eB5UfD8G3r+bfDsIXhegp6XDJ6XBM/L0POywbOn4HkFel4xeF4RPK9Cz6sGz16C5zXoec3geU3wvA49rxs8ewueN6DnDYPnDcHzJvS8afDsI3jegp63DJ63BM/b0PO2wbOv4HkHet4xeN4RPO9Cz7sGz36C5z3oec/geU/wvA897xs8+wueD6DnA4PnA8HzIfR8aPAcIHg+gp6PDJ6PBM/H0POxwXOg4PkEej4xeD4RPJ9Cz6cGz0GC5zPo+czg+UzwfA49nxs8BwueL6DnC4PnC8HzJfR8afAcIni+gp6vDJ6vBM/X0PO1wXOo4PkGer4xeL4RPN9Cz7cGz2GC5zvo+c7g+U7wfA893xs8hwueH6DnB4PnB8HzI/T8aPAcIXh+gp6fDJ6fBM/P0POzwXOk4PkFen4xeH4RPL+qzzz/2fuvnqMEzxD1mWeI+v/d839v/9tsSOgZ0uA5WvAMBT1DGTxDCZ6hoWdog+cYwTMM9Axj8AwjeIaFnmENnmMFz3DQM5zBM5zgGR56hjd4jhM8I0DPCAbPCIJnROgZ0eA5XvCMBD0jGTwjCZ6RoWdkg+cEwTMK9Ixi8IwieEaFnlENnhMFz2jQM5rBM5rgGR16Rjd4ThI8Y0DPGAbPGIJnTOgZ0+A5WfCMBT1jGTxjCZ6xoWdsg+cUwTMO9Ixj8IwjeMaFnnENnlMFz3jQM57BM57gGR96xjd4ThM8E0DPBAbPBIJnQuiZ0OA5XfBMBD0TGTwTCZ6JoWdig+cMwTMJ9Exi8EwieCaFnkkNnjMFz2TQM5nBM5ngGYCeAYPnLMEzOfRMbvBMLnimgJ4pDJ6zBc+U0DOlwTOl4JkKeqYyeM4RPFNDz9QGz9SCZxromcbgOVfwTAs90xo80wqe6aBnOoPnPMEzPfRMb/BML3hmgJ4ZDJ7zBc+M0DOjwTOj4JkJemYyeC4QPDNDz8wGz8yCZxbomcXguVDwzAo9sxo8swqe2aBnNoPnIsEzO/TMbvDMLnjmgJ45DJ6LBc+c0DOnwTOn4JkLeuYyeH4teOaGnrkNnrkFzzzQM4/Bc4ngmRd65jV45hU880HPfAbPbwTP/NAzv8Ezv+BZAHoWMHguFTwLQs+CBs+Cgmch6FnI4Pmt4FkYehY2eBYWPItAzyIGz2WCZ1HoWdTgWVTwLAY9ixk8vxM8i0PP4gbP4oJnCehZwuC5XPAsCT1LGjxLCp6loGcpg+f3gmdp6Fna4Fla8CwDPcsYPFcInmWhZ1mDZ1nBsxz0LGfw/EHwLA89yxs8ywueFaBnBYPnSsGzIvSsaPCsKHhWgp6VDJ4/Cp6VoWdlg2dlwbMK9Kxi8FwleFaFnlUNnlUFz2rQs5rB8yfBszr0rG7wrC541oCeNQyeqwXPmtCzpsGzpuBZC3rWMnj+LHjWhp61DZ61Bc860LOOwXON4FkXetY1eNYVPOtBz3oGz18Ez/rQs77Bs77g2QB6NjB4rhU8G0LPhgbPhoJnI+jZyOD5q+DZGHo2Nng2FjybQM8mBs91gmdT6NnU4NlU8GwGPZsZPNcLns2hZ3ODZ3PBswX0bGHw3CB4toSeLQ2eLQXPVtCzlcFzo+DZGnq2Nni2FjzbQM82Bs9Ngmdb6NnW4NlW8GwHPdsZPDcLnu2hZ3uDZ3vBswP07GDw3CJ4doSeHQ2eHQXPTtCzk8Fzq+DZGXp2Nnh2Fjy7QM8uBs9tgmdX6NnV4NlV8OwGPbsZPLcLnt2hZ3eDZ3fBswf07GHw3CF49oSePQ2ePQXPXtCzl8Fzp+DZG3r2Nnj2Fjz7QM8+Bs9dgmdf6NnX4NlX8OwHPfsZPHcLnv2hZ3+DZ3/BcwD0HGDw3CN4DoSeAw2eAwXPQdBzkMFzr+A5GHoONngOFjyHQM8hBs99gudQ6DnU4DlU8BwGPYcZPPcLnsOh53CD53DBcwT0HGHwPCB4joSeIw2eIwXPUdBzlMHzoOA5GnqONniOFjzHQM8xBs9DgudY6DnW4DlW8BwHPccZPA8LnuOh53iD53jBcwL0nGDwPCJ4ToSeEw2eEwXPSdBzksHzqOA5GXpONnhOFjynQM8pBs9jgudU6DnV4DlV8JwGPacZPI8LntOh53SD53TBcwb0nGHwPCF4zoSeMw2eMwXPWdBzlsHzpOA5G3rONnjOFjznQM85Bs9Tgudc6DnX4DlX8JwHPecZPE8LnvOh53yD53zBcwH0XGDwPCN4LoSeCw2eCwXPRdBzkcHzN8FzMfRcbPBcLHh+DT2/NnieFTyXQM8lBs8lguc30PMbg+fvgudS6LnU4LlU8PwWen5r8DwneC6DnssMnssEz++g53cGzz8Ez+XQc7nBc7ng+T30/N7geV7wXAE9Vxg8VwieP0DPHwyefwqeK6HnSoPnSsHzR+j5o8HzguC5CnquMniuEjx/gp4/GTz/EjxXQ8/VBs/VgufP0PNng+dFwXMN9Fxj8FwjeP4CPX8xeP4teK6FnmsNnmsFz1+h568Gz0uC5zrouc7guU7wXA891xs8LwueG6DnBoPnBsFzI/TcaPC8Inhugp6bDJ6bBM/N0HOzwfOq4LkFem4xeG4RPLdCz60Gz2uC5zbouc3guU3w3A49txs8rwueO6DnDoPnDsFzJ/TcafC8IXjugp67DJ67BM/d0HO3wfOm4LkHeu4xeO4RPPdCz70Gz1uC5z7ouc/guU/w3A899xs8bwueB6DnAYPnAcHzIPQ8aPC8I3gegp6HDJ6HBM/D0POwwfOu4HkEeh4xeB4RPI9Cz6MGz3uC5zHoeczgeUzwPA49jxs87wueJ6DnCYPnCcHzJPQ8afB8IHiegp6nDJ6nBM/T0PO0wfOh4HkGep4xeJ4RPH+Dnr8ZPB8Jnmeh51mD51nB83fo+bvB87HgeQ56njN4nhM8/4Cefxg8nwie56HneYPnecHzT+j5p8HzqeB5AXpeMHheEDz/gp5/GTyfCZ4XoedFg+dFwfNv6Pm3wfO54HkJel4yeF4SPC9Dz8sGzxeC5xXoecXgeUXwvAo9rxo8Xwqe16DnNYPnNcHzOvS8bvB8JXjegJ43DJ43BM+b0POmwfO14HkLet4yeN4SPG9Dz9sGzzeC5x3oecfgeUfwvAs97xo83wqe96DnPYPnPcHzPvS8b/B8J3g+gJ4PDJ4PBM+H0POhwfO94PkIej4yeD4SPB9Dz8cGzw+C5xPo+cTg+UTwfAo9nxo8Pwqez6DnM4PnM8HzOfR8bvD8JHi+gJ4vDJ4vBM+X0POlwfOz4PkKer4yeL4SPF9Dz9cGzy+C5xvo+cbg+UbwfAs93xo8v0offOc76PnO4PlO8HwPPd8bPEMInh+g5weD5wfB8yP0/GjwDCl4foKenwyenwTPz9Dzs8EzlOD5BXp+MXh+ETy/asA8/9n7r56hBc8QDZhniAb/3fN/b//bbEjoGdLgGUbwDAU9Qxk8QwmeoaFnaINnWMEzDPQMY/AMI3iGhZ5hDZ7hBM9w0DOcwTOc4BkeeoY3eIYXPCNAzwgGzwiCZ0ToGdHgGUHwjAQ9Ixk8IwmekaFnZINnRMEzCvSMYvCMInhGhZ5RDZ6RBM9o0DOawTOa4BkdekY3eEYWPGNAzxgGzxiCZ0zoGdPgGUXwjAU9Yxk8YwmesaFnbINnVMEzDvSMY/CMI3jGhZ5xDZ7RBM940DOewTOe4BkfesY3eEYXPBNAzwQGzwSCZ0LomdDgGUPwTAQ9Exk8EwmeiaFnYoNnTMEzCfRMYvBMIngmhZ5JDZ6xBM9k0DOZwTOZ4BmAngGDZ2zBMzn0TG7wTC54poCeKQyecQTPlNAzpcEzpeCZCnqmMnjGFTxTQ8/UBs/Ugmca6JnG4BlP8EwLPdMaPNMKnumgZzqDZ3zBMz30TG/wTC94ZoCeGQyeCQTPjNAzo8Ezo+CZCXpmMngmFDwzQ8/MBs/MgmcW6JnF4JlI8MwKPbMaPLMKntmgZzaDZ2LBMzv0zG7wzC545oCeOQyeSQTPnNAzp8Ezp+CZC3rmMngmFTxzQ8/cBs/cgmce6JnH4JlM8MwLPfMaPPMKnvmgZz6DZ0DwzA898xs88wueBaBnAYNncsGzIPQsaPAsKHgWgp6FDJ4pBM/C0LOwwbOw4FkEehYxeKYUPItCz6IGz6KCZzHoWczgmUrwLA49ixs8iwueJaBnCYNnasGzJPQsafAsKXiWgp6lDJ5pBM/S0LO0wbO04FkGepYxeKYVPMtCz7IGz7KCZznoWc7gmU7wLA89yxs8ywueFaBnBYNnesGzIvSsaPCsKHhWgp6VDJ4ZBM/K0LOywbOy4FkFelYxeGYUPKtCz6oGz6qCZzXoWc3gmUnwrA49qxs8qwueNaBnDYNnZsGzJvSsafCsKXjWgp61DJ5ZBM/a0LO2wbO24FkHetYxeGYVPOtCz7oGz7qCZz3oWc/gmU3wrA896xs86wueDaBnA4NndsGzIfRsaPBsKHg2gp6NDJ45BM/G0LOxwbOx4NkEejYxeOYUPJtCz6YGz6aCZzPo2czgmUvwbA49mxs8mwueLaBnC4NnbsGzJfRsafBsKXi2gp6tDJ55BM/W0LO1wbO14NkGerYxeOYVPNtCz7YGz7aCZzvo2c7gmU/wbA892xs82wueHaBnB4NnfsGzI/TsaPDsKHh2gp6dDJ4FBM/O0LOzwbOz4NkFenYxeBYUPLtCz64Gz66CZzfo2c3gWUjw7A49uxs8uwuePaBnD4NnYcGzJ/TsafDsKXj2gp69DJ5FBM/e0LO3wbO34NkHevYxeBYVPPtCz74Gz76CZz/o2c/gWUzw7A89+xs8+wueA6DnAINnccFzIPQcaPAcKHgOgp6DDJ4lBM/B0HOwwXOw4DkEeg4xeJYUPIdCz6EGz6GC5zDoOczgWUrwHA49hxs8hwueI6DnCINnacFzJPQcafAcKXiOgp6jDJ5lBM/R0HO0wXO04DkGeo4xeJYVPMdCz7EGz7GC5zjoOc7gWU7wHA89xxs8xwueE6DnBINnecFzIvScaPCcKHhOgp6TDJ4VBM/J0HOywXOy4DkFek4xeFYUPKdCz6kGz6mC5zToOc3gWUnwnA49pxs8pwueM6DnDINnZcFzJvScafCcKXjOgp6zDJ5VBM/Z0HO2wXO24DkHes4xeFYVPOdCz7kGz7mC5zzoOc/gWU3wnA895xs85wueC6DnAoNndcFzIfRcaPBcKHgugp6LDJ41BM/F0HOxwXOx4Pk19Pza4FlT8FwCPZcYPJcInt9Az28MnrUEz6XQc6nBc6ng+S30/NbgWVvwXAY9lxk8lwme30HP7wyedQTP5dBzucFzueD5PfT83uBZV/BcAT1XGDxXCJ4/QM8fDJ71BM+V0HOlwXOl4Pkj9PzR4Flf8FwFPVcZPFcJnj9Bz58Mng0Ez9XQc7XBc7Xg+TP0/Nng2VDwXAM91xg81wiev0DPXwyejQTPtdBzrcFzreD5K/T81eDZWPBcBz3XGTzXCZ7roed6g2cTwXMD9Nxg8NwgeG6EnhsNnk0Fz03Qc5PBc5PguRl6bjZ4NhM8t0DPLQbPLYLnVui51eDZXPDcBj23GTy3CZ7boed2g2cLwXMH9Nxh8NwheO6EnjsNni0Fz13Qc5fBc5fguRt67jZ4thI890DPPQbPPYLnXui51+DZWvDcBz33GTz3CZ77oed+g2cbwfMA9Dxg8DwgeB6EngcNnm0Fz0PQ85DB85DgeRh6HjZ4thM8j0DPIwbPI4LnUeh51ODZXvA8Bj2PGTyPCZ7Hoedxg2cHwfME9Dxh8DwheJ6EnicNnh0Fz1PQ85TB85TgeRp6njZ4dhI8z0DPMwbPM4Lnb9DzN4NnZ8HzLPQ8a/A8K3j+Dj1/N3h2ETzPQc9zBs9zgucf0PMPg2dXwfM89Dxv8DwveP4JPf80eHYTPC9AzwsGzwuC51/Q8y+DZ3fB8yL0vGjwvCh4/g09/zZ49hA8L0HPSwbPS4LnZeh52eDZU/C8Aj2vGDyvCJ5XoedVg2cvwfMa9Lxm8LwmeF6HntcNnr0FzxvQ84bB84bgeRN63jR49hE8b0HPWwbPW4Lnbeh52+DZV/C8Az3vGDzvCJ53oeddg2c/wfMe9Lxn8LwneN6HnvcNnv0FzwfQ84HB84Hg+RB6PjR4DhA8H0HPRwbPR4LnY+j52OA5UPB8Aj2fGDyfCJ5PoedTg+cgwfMZ9Hxm8HwmeD6Hns8NnoMFzxfQ84XB84Xg+RJ6vjR4DhE8X0HPVwbPV4Lna+j52uA5VPB8Az3fGDzfCJ5voedbg+cwwfMd9Hxn8HwneL6Hnu8NnsMFzw/Q84PB84Pg+RF6fjR4jhA8P0HPTwbPT4LnZ+j52eA5UvD8Aj2/GDy/CJ5fNWSe/+z9V89RgmeIhswzRMP/7vm/t/9tNiT0DGnwHC14hoKeoQyeoQTP0NAztMFzjOAZBnqGMXiGETzDQs+wBs+xgmc46BnO4BlO8AwPPcMbPMcJnhGgZwSDZwTBMyL0jGjwHC94RoKekQyekQTPyNAzssFzguAZBXpGMXhGETyjQs+oBs+Jgmc06BnN4BlN8IwOPaMbPCcJnjGgZwyDZwzBMyb0jGnwnCx4xoKesQyesQTP2NAztsFziuAZB3rGMXjGETzjQs+4Bs+pgmc86BnP4BlP8IwPPeMbPKcJngmgZwKDZwLBMyH0TGjwnC54JoKeiQyeiQTPxNAzscFzhuCZBHomMXgmETyTQs+kBs+Zgmcy6JnM4JlM8AxAz4DBc5bgmRx6Jjd4Jhc8U0DPFAbP2YJnSuiZ0uCZUvBMBT1TGTznCJ6poWdqg2dqwTMN9Exj8JwreKaFnmkNnmkFz3TQM53Bc57gmR56pjd4phc8M0DPDAbP+YJnRuiZ0eCZUfDMBD0zGTwXCJ6ZoWdmg2dmwTML9Mxi8FwoeGaFnlkNnlkFz2zQM5vBc5HgmR16Zjd4Zhc8c0DPHAbPxYJnTuiZ0+CZU/DMBT1zGTy/FjxzQ8/cBs/cgmce6JnH4LlE8MwLPfMaPPMKnvmgZz6D5zeCZ37omd/gmV/wLAA9Cxg8lwqeBaFnQYNnQcGzEPQsZPD8VvAsDD0LGzwLC55FoGcRg+cywbMo9Cxq8CwqeBaDnsUMnt8JnsWhZ3GDZ3HBswT0LGHwXC54loSeJQ2eJQXPUtCzlMHze8GzNPQsbfAsLXiWgZ5lDJ4rBM+y0LOswbOs4FkOepYzeP4geJaHnuUNnuUFzwrQs4LBc6XgWRF6VjR4VhQ8K0HPSgbPHwXPytCzssGzsuBZBXpWMXiuEjyrQs+qBs+qgmc16FnN4PmT4FkdelY3eFYXPGtAzxoGz9WCZ03oWdPgWVPwrAU9axk8fxY8a0PP2gbP2oJnHehZx+C5RvCsCz3rGjzrCp71oGc9g+cvgmd96Fnf4Flf8GwAPRsYPNcKng2hZ0ODZ0PBsxH0bGTw/FXwbAw9Gxs8GwueTaBnE4PnOsGzKfRsavBsKng2g57NDJ7rBc/m0LO5wbO54NkCerYweG4QPFtCz5YGz5aCZyvo2crguVHwbA09Wxs8WwuebaBnG4PnJsGzLfRsa/BsK3i2g57tDJ6bBc/20LO9wbO94NkBenYweG4RPDtCz44Gz46CZyfo2cnguVXw7Aw9Oxs8OwueXaBnF4PnNsGzK/TsavDsKnh2g57dDJ7bBc/u0LO7wbO74NkDevYweO4QPHtCz54Gz56CZy/o2cvguVPw7A09exs8ewuefaBnH4PnLsGzL/Tsa/DsK3j2g579DJ67Bc/+0LO/wbO/4DkAeg4weO4RPAdCz4EGz4GC5yDoOcjguVfwHAw9Bxs8BwueQ6DnEIPnPsFzKPQcavAcKngOg57DDJ77Bc/h0HO4wXO44DkCeo4weB4QPEdCz5EGz5GC5yjoOcrgeVDwHA09Rxs8RwueY6DnGIPnIcFzLPQca/AcK3iOg57jDJ6HBc/x0HO8wXO84DkBek4weB4RPCdCz4kGz4mC5yToOcngeVTwnAw9Jxs8JwueU6DnFIPnMcFzKvScavCcKnhOg57TDJ7HBc/p0HO6wXO64DkDes4weJ4QPGdCz5kGz5mC5yzoOcvgeVLwnA09Zxs8Zwuec6DnHIPnKcFzLvSca/CcK3jOg57zDJ6nBc/50HO+wXO+4LkAei4weJ4RPBdCz4UGz4WC5yLoucjg+ZvguRh6LjZ4LhY8v4aeXxs8zwqeS6DnEoPnEsHzG+j5jcHzd8FzKfRcavBcKnh+Cz2/NXieEzyXQc9lBs9lgud30PM7g+cfgudy6Lnc4Llc8Pween5v8DwveK6AnisMnisEzx+g5w8Gzz8Fz5XQc6XBc6Xg+SP0/NHgeUHwXAU9Vxk8VwmeP0HPnwyefwmeq6HnaoPnasHzZ+j5s8HzouC5BnquMXiuETx/gZ6/GDz/FjzXQs+1Bs+1guev0PNXg+clwXMd9Fxn8FwneK6HnusNnpcFzw3Qc4PBc4PguRF6bjR4XhE8N0HPTQbPTYLnZui52eB5VfDcAj23GDy3CJ5boedWg+c1wXMb9Nxm8NwmeG6HntsNntcFzx3Qc4fBc4fguRN67jR43hA8d0HPXQbPXYLnbui52+B5U/DcAz33GDz3CJ57oedeg+ctwXMf9Nxn8NwneO6HnvsNnrcFzwPQ84DB84DgeRB6HjR43hE8D0HPQwbPQ4LnYeh52OB5V/A8Aj2PGDyPCJ5HoedRg+c9wfMY9Dxm8DwmeB6HnscNnvcFzxPQ84TB84TgeRJ6njR4PhA8T0HPUwbPU4Lnaeh52uD5UPA8Az3PGDzPCJ6/Qc/fDJ6PBM+z0POswfOs4Pk79Pzd4PlY8DwHPc8ZPM8Jnn9Azz8Mnk8Ez/PQ87zB87zg+Sf0/NPg+VTwvAA9Lxg8Lwief0HPvwyezwTPi9DzosHzouD5N/T82+D5XPC8BD0vGTwvCZ6Xoedlg+cLwfMK9Lxi8LwieF6FnlcNni8Fz2vQ85rB85rgeR16Xjd4vhI8b0DPGwbPG4LnTeh50+D5WvC8BT1vGTxvCZ63oedtg+cbwfMO9Lxj8LwjeN6FnncNnm8Fz3vQ857B857geR963jd4vhM8H0DPBwbPB4LnQ+j50OD5XvB8BD0fGTwfCZ6Poedjg+cHwfMJ9Hxi8HwieD6Fnk8Nnh8Fz2fQ85nB85ng+Rx6Pjd4fhI8X0DPFwbPF4LnS+j50uGZMfjOVw2D/TfE/+v8Zy/iv3Qqt/9t9nXQnSH/X+frIDr/5YX4LHi+gZ5vDJ5vBM+30POtwfOL4PkOer4zeL4TPN9Dz/cGz68yBd/5AXp+MHh+EDw/Qs+PBs8Qgucn6PnJ4PlJ8PwMPT8bPEMKnl+g5xeD5xfB86tGzPOfvf/qGUrwDNGIeYZo9N89//f2v82GhJ4hDZ6hBc9Q0DOUwTOU4BkaeoY2eIYRPMNAzzAGzzCCZ1joGdbgGVbwDAc9wxk8wwme4aFneINnOMEzAvSMYPCMIHhGhJ4RDZ7hBc9I0DOSwTOS4BkZekY2eEYQPKNAzygGzyiCZ1ToGdXgGVHwjAY9oxk8owme0aFndINnJMEzBvSMYfCMIXjGhJ4xDZ6RBc9Y0DOWwTOW4BkbesY2eEYRPONAzzgGzziCZ1zoGdfgGVXwjAc94xk84wme8aFnfINnNMEzAfRMYPBMIHgmhJ4JDZ7RBc9E0DORwTOR4JkYeiY2eMYQPJNAzyQGzySCZ1LomdTgGVPwTAY9kxk8kwmeAegZMHjGEjyTQ8/kBs/kgmcK6JnC4Blb8EwJPVMaPFMKnqmgZyqDZxzBMzX0TG3wTC14poGeaQyecQXPtNAzrcEzreCZDnqmM3jGEzzTQ8/0Bs/0gmcG6JnB4Blf8MwIPTMaPDMKnpmgZyaDZwLBMzP0zGzwzCx4ZoGeWQyeCQXPrNAzq8Ezq+CZDXpmM3gmEjyzQ8/sBs/sgmcO6JnD4JlY8MwJPXMaPHMKnrmgZy6DZxLBMzf0zG3wzC145oGeeQyeSQXPvNAzr8Ezr+CZD3rmM3gmEzzzQ8/8Bs/8gmcB6FnA4BkQPAtCz4IGz4KCZyHoWcjgmVzwLAw9Cxs8CwueRaBnEYNnCsGzKPQsavAsKngWg57FDJ4pBc/i0LO4wbO44FkCepYweKYSPEtCz5IGz5KCZynoWcrgmVrwLA09Sxs8SwueZaBnGYNnGsGzLPQsa/AsK3iWg57lDJ5pBc/y0LO8wbO84FkBelYweKYTPCtCz4oGz4qCZyXoWcngmV7wrAw9Kxs8KwueVaBnFYNnBsGzKvSsavCsKnhWg57VDJ4ZBc/q0LO6wbO64FkDetYweGYSPGtCz5oGz5qCZy3oWcvgmVnwrA09axs8awuedaBnHYNnFsGzLvSsa/CsK3jWg571DJ5ZBc/60LO+wbO+4NkAejYweGYTPBtCz4YGz4aCZyPo2cjgmV3wbAw9Gxs8GwueTaBnE4NnDsGzKfRsavBsKng2g57NDJ45Bc/m0LO5wbO54NkCerYweOYSPFtCz5YGz5aCZyvo2crgmVvwbA09Wxs8WwuebaBnG4NnHsGzLfRsa/BsK3i2g57tDJ55Bc/20LO9wbO94NkBenYweOYTPDtCz44Gz46CZyfo2cngmV/w7Aw9Oxs8OwueXaBnF4NnAcGzK/TsavDsKnh2g57dDJ4FBc/u0LO7wbO74NkDevYweBYSPHtCz54Gz56CZy/o2cvgWVjw7A09exs8ewuefaBnH4NnEcGzL/Tsa/DsK3j2g579DJ5FBc/+0LO/wbO/4DkAeg4weBYTPAdCz4EGz4GC5yDoOcjgWVzwHAw9Bxs8BwueQ6DnEINnCcFzKPQcavAcKngOg57DDJ4lBc/h0HO4wXO44DkCeo4weJYSPEdCz5EGz5GC5yjoOcrgWVrwHA09Rxs8RwueY6DnGINnGcFzLPQca/AcK3iOg57jDJ5lBc/x0HO8wXO84DkBek4weJYTPCdCz4kGz4mC5yToOcngWV7wnAw9Jxs8JwueU6DnFINnBcFzKvScavCcKnhOg57TDJ4VBc/p0HO6wXO64DkDes4weFYSPGdCz5kGz5mC5yzoOcvgWVnwnA09Zxs8Zwuec6DnHINnFcFzLvSca/CcK3jOg57zDJ5VBc/50HO+wXO+4LkAei4weFYTPBdCz4UGz4WC5yLoucjgWV3wXAw9Fxs8FwueX0PPrw2eNQTPJdBzicFzieD5DfT8xuBZU/BcCj2XGjyXCp7fQs9vDZ61BM9l0HOZwXOZ4Pkd9PzO4Flb8FwOPZcbPJcLnt9Dz+8NnnUEzxXQc4XBc4Xg+QP0/MHgWVfwXAk9Vxo8VwqeP0LPHw2e9QTPVdBzlcFzleD5E/T8yeBZX/BcDT1XGzxXC54/Q8+fDZ4NBM810HONwXON4PkL9PzF4NlQ8FwLPdcaPNcKnr9Cz18Nno0Ez3XQc53Bc53guR56rjd4NhY8N0DPDQbPDYLnRui50eDZRPDcBD03GTw3CZ6boedmg2dTwXML9Nxi8NwieG6FnlsNns0Ez23Qc5vBc5vguR16bjd4Nhc8d0DPHQbPHYLnTui50+DZQvDcBT13GTx3CZ67oedug2dLwXMP9Nxj8NwjeO6FnnsNnq0Ez33Qc5/Bc5/guR967jd4thY8D0DPAwbPA4LnQeh50ODZRvA8BD0PGTwPCZ6Hoedhg2dbwfMI9Dxi8DwieB6FnkcNnu0Ez2PQ85jB85jgeRx6Hjd4thc8T0DPEwbPE4LnSeh50uDZQfA8BT1PGTxPCZ6noedpg2dHwfMM9Dxj8DwjeP4GPX8zeHYSPM9Cz7MGz7OC5+/Q83eDZ2fB8xz0PGfwPCd4/gE9/zB4dhE8z0PP8wbP84Lnn9DzT4NnV8HzAvS8YPC8IHj+BT3/Mnh2EzwvQs+LBs+Lguff0PNvg2d3wfMS9Lxk8LwkeF6GnpcNnj0EzyvQ84rB84rgeRV6XjV49hQ8r0HPawbPa4Lndeh53eDZS/C8AT1vGDxvCJ43oedNg2dvwfMW9Lxl8LwleN6GnrcNnn0EzzvQ847B847geRd63jV49hU870HPewbPe4Lnfeh53+DZT/B8AD0fGDwfCJ4PoedDg2d/wfMR9Hxk8HwkeD6Gno8NngMEzyfQ84nB84ng+RR6PjV4DhQ8n0HPZwbPZ4Lnc+j53OA5SPB8AT1fGDxfCJ4voedLg+dgwfMV9Hxl8HwleL6Gnq8NnkMEzzfQ843B843g+RZ6vjV4DhU830HPdwbPd4Lne+j53uA5TPD8AD0/GDw/CJ4foedHg+dwwfMT9Pxk8PwkeH6Gnp8NniMEzy/Q84vB84vg+VVj5vnP3n/1HCl4hmjMPEM0/u+e/3v732ZDQs+QBs9Rgmco6BnK4BlK8AwNPUMbPEcLnmGgZxiDZxjBMyz0DGvwHCN4hoOe4Qye4QTP8NAzvMFzrOAZAXpGMHhGEDwjQs+IBs9xgmck6BnJ4BlJ8IwMPSMbPMcLnlGgZxSDZxTBMyr0jGrwnCB4RoOe0Qye0QTP6NAzusFzouAZA3rGMHjGEDxjQs+YBs9Jgmcs6BnL4BlL8IwNPWMbPCcLnnGgZxyDZxzBMy70jGvwnCJ4xoOe8Qye8QTP+NAzvsFzquCZAHomMHgmEDwTQs+EBs9pgmci6JnI4JlI8EwMPRMbPKcLnkmgZxKDZxLBMyn0TGrwnCF4JoOeyQyeyQTPAPQMGDxnCp7JoWdyg2dywTMF9Exh8JwleKaEnikNnikFz1TQM5XBc7bgmRp6pjZ4phY800DPNAbPOYJnWuiZ1uCZVvBMBz3TGTznCp7poWd6g2d6wTMD9Mxg8JwneGaEnhkNnhkFz0zQM5PBc77gmRl6ZjZ4ZhY8s0DPLAbPBYJnVuiZ1eCZVfDMBj2zGTwXCp7ZoWd2g2d2wTMH9Mxh8FwkeOaEnjkNnjkFz1zQM5fBc7HgmRt65jZ45hY880DPPAbPrwXPvNAzr8Ezr+CZD3rmM3guETzzQ8/8Bs/8gmcB6FnA4PmN4FkQehY0eBYUPAtBz0IGz6WCZ2HoWdjgWVjwLAI9ixg8vxU8i0LPogbPooJnMehZzOC5TPAsDj2LGzyLC54loGcJg+d3gmdJ6FnS4FlS8CwFPUsZPJcLnqWhZ2mDZ2nBswz0LGPw/F7wLAs9yxo8ywqe5aBnOYPnCsGzPPQsb/AsL3hWgJ4VDJ4/CJ4VoWdFg2dFwbMS9Kxk8FwpeFaGnpUNnpUFzyrQs4rB80fBsyr0rGrwrCp4VoOe1QyeqwTP6tCzusGzuuBZA3rWMHj+JHjWhJ41DZ41Bc9a0LOWwXO14FkbetY2eNYWPOtAzzoGz58Fz7rQs67Bs67gWQ961jN4rhE860PP+gbP+oJnA+jZwOD5i+DZEHo2NHg2FDwbQc9GBs+1gmdj6NnY4NlY8GwCPZsYPH8VPJtCz6YGz6aCZzPo2czguU7wbA49mxs8mwueLaBnC4PnesGzJfRsafBsKXi2gp6tDJ4bBM/W0LO1wbO14NkGerYxeG4UPNtCz7YGz7aCZzvo2c7guUnwbA892xs82wueHaBnB4PnZsGzI/TsaPDsKHh2gp6dDJ5bBM/O0LOzwbOz4NkFenYxeG4VPLtCz64Gz66CZzfo2c3guU3w7A49uxs8uwuePaBnD4PndsGzJ/TsafDsKXj2gp69DJ47BM/e0LO3wbO34NkHevYxeO4UPPtCz74Gz76CZz/o2c/guUvw7A89+xs8+wueA6DnAIPnbsFzIPQcaPAcKHgOgp6DDJ57BM/B0HOwwXOw4DkEeg4xeO4VPIdCz6EGz6GC5zDoOczguU/wHA49hxs8hwueI6DnCIPnfsFzJPQcafAcKXiOgp6jDJ4HBM/R0HO0wXO04DkGeo4xeB4UPMdCz7EGz7GC5zjoOc7geUjwHA89xxs8xwueE6DnBIPnYcFzIvScaPCcKHhOgp6TDJ5HBM/J0HOywXOy4DkFek4xeB4VPKdCz6kGz6mC5zToOc3geUzwnA49pxs8pwueM6DnDIPnccFzJvScafCcKXjOgp6zDJ4nBM/Z0HO2wXO24DkHes4xeJ4UPOdCz7kGz7mC5zzoOc/geUrwnA895xs85wueC6DnAoPnacFzIfRcaPBcKHgugp6LDJ5nBM/F0HOxwXOx4Pk19Pza4Pmb4LkEei4xeC4RPL+Bnt8YPM8Knkuh51KD51LB81vo+a3B83fBcxn0XGbwXCZ4fgc9vzN4nhM8l0PP5QbP5YLn99Dze4PnH4LnCui5wuC5QvD8AXr+YPA8L3iuhJ4rDZ4rBc8foeePBs8/Bc9V0HOVwXOV4PkT9PzJ4HlB8FwNPVcbPFcLnj9Dz58Nnn8Jnmug5xqD5xrB8xfo+YvB86LguRZ6rjV4rhU8f4Wevxo8/xY810HPdQbPdYLneui53uB5SfDcAD03GDw3CJ4boedGg+dlwXMT9Nxk8NwkeG6GnpsNnlcEzy3Qc4vBc4vguRV6bjV4XhU8t0HPbQbPbYLndui53eB5TfDcAT13GDx3CJ47oedOg+d1wXMX9Nxl8NwleO6GnrsNnjcEzz3Qc4/Bc4/guRd67jV43hQ890HPfQbPfYLnfui53+B5S/A8AD0PGDwPCJ4HoedBg+dtwfMQ9Dxk8DwkeB6GnocNnncEzyPQ84jB84jgeRR6HjV43hU8j0HPYwbPY4Lnceh53OB5T/A8AT1PGDxPCJ4noedJg+d9wfMU9Dxl8DwleJ6GnqcNng8EzzPQ84zB84zg+Rv0/M3g+VDwPAs9zxo8zwqev0PP3w2ejwTPc9DznMHznOD5B/T8w+D5WPA8Dz3PGzzPC55/Qs8/DZ5PBM8L0POCwfOC4PkX9PzL4PlU8LwIPS8aPC8Knn9Dz78Nns8Ez0vQ85LB85LgeRl6XjZ4Phc8r0DPKwbPK4LnVeh51eD5QvC8Bj2vGTyvCZ7Xoed1g+dLwfMG9Lxh8LwheN6EnjcNnq8Ez1vQ85bB85bgeRt63jZ4vhY870DPOwbPO4LnXeh51+D5RvC8Bz3vGTzvCZ73oed9g+dbwfMB9Hxg8HwgeD6Eng8Nnu8Ez0fQ85HB85Hg+Rh6PjZ4vhc8n0DPJwbPJ4LnU+j51OD5QfB8Bj2fGTyfCZ7Poedzg+dHwfMF9Hxh8HwheL6Eni8Nnp8Ez1fQ85XB85Xg+Rp6vjZ4fhY830DPNwbPN4LnW+j51uD5RfB8Bz3fGTzfCZ7voed7g+dXmYPv/AA9Pxg8PwieH6HnR4NnCMHzE/T8ZPD8JHh+hp6fDZ4hBc8v0POLwfOL4PlVE+b5z95/9QwleIZowjxDNPnvnv97+99mQ0LPkAbP0IJnKOgZyuAZSvAMDT1DGzzDCJ5hoGcYg2cYwTMs9Axr8AwreIaDnuEMnuEEz/DQM7zBM5zgGQF6RjB4RhA8I0LPiAbP8IJnJOgZyeAZSfCMDD0jGzwjCJ5RoGcUg2cUwTMq9Ixq8IwoeEaDntEMntEEz+jQM7rBM5LgGQN6xjB4xhA8Y0LPmAbPyIJnLOgZy+AZS/CMDT1jGzyjCJ5xoGccg2ccwTMu9Ixr8IwqeMaDnvEMnvEEz/jQM77BM5rgmQB6JjB4JhA8E0LPhAbP6IJnIuiZyOCZSPBMDD0TGzxjCJ5JoGcSg2cSwTMp9Exq8IwpeCaDnskMnskEzwD0DBg8YwmeyaFncoNncsEzBfRMYfCMLXimhJ4pDZ4pBc9U0DOVwTOO4JkaeqY2eKYWPNNAzzQGz7iCZ1romdbgmVbwTAc90xk84wme6aFneoNnesEzA/TMYPCML3hmhJ4ZDZ4ZBc9M0DOTwTOB4JkZemY2eGYWPLNAzywGz4SCZ1bomdXgmVXwzAY9sxk8Ewme2aFndoNndsEzB/TMYfBMLHjmhJ45DZ45Bc9c0DOXwTOJ4JkbeuY2eOYWPPNAzzwGz6SCZ17omdfgmVfwzAc98xk8kwme+aFnfoNnfsGzAPQsYPAMCJ4FoWdBg2dBwbMQ9Cxk8EwueBaGnoUNnoUFzyLQs4jBM4XgWRR6FjV4FhU8i0HPYgbPlIJncehZ3OBZXPAsAT1LGDxTCZ4loWdJg2dJwbMU9Cxl8EwteJaGnqUNnqUFzzLQs4zBM43gWRZ6ljV4lhU8y0HPcgbPtIJneehZ3uBZXvCsAD0rGDzTCZ4VoWdFg2dFwbMS9Kxk8EwveFaGnpUNnpUFzyrQs4rBM4PgWRV6VjV4VhU8q0HPagbPjIJndehZ3eBZXfCsAT1rGDwzCZ41oWdNg2dNwbMW9Kxl8MwseNaGnrUNnrUFzzrQs47BM4vgWRd61jV41hU860HPegbPrIJnfehZ3+BZX/BsAD0bGDyzCZ4NoWdDg2dDwbMR9Gxk8MwueDaGno0Nno0FzybQs4nBM4fg2RR6NjV4NhU8m0HPZgbPnIJnc+jZ3ODZXPBsAT1bGDxzCZ4toWdLg2dLwbMV9Gxl8MwteLaGnq0Nnq0FzzbQs43BM4/g2RZ6tjV4thU820HPdgbPvIJne+jZ3uDZXvDsAD07GDzzCZ4doWdHg2dHwbMT9Oxk8MwveHaGnp0Nnp0Fzy7Qs4vBs4Dg2RV6djV4dhU8u0HPbgbPgoJnd+jZ3eDZXfDsAT17GDwLCZ49oWdPg2dPwbMX9Oxl8CwsePaGnr0Nnr0Fzz7Qs4/Bs4jg2Rd69jV49hU8+0HPfgbPooJnf+jZ3+DZX/AcAD0HGDyLCZ4DoedAg+dAwXMQ9Bxk8CwueA6GnoMNnoMFzyHQc4jBs4TgORR6DjV4DhU8h0HPYQbPkoLncOg53OA5XPAcAT1HGDxLCZ4joedIg+dIwXMU9Bxl8CwteI6GnqMNnqMFzzHQc4zBs4zgORZ6jjV4jhU8x0HPcQbPsoLneOg53uA5XvCcAD0nGDzLCZ4ToedEg+dEwXMS9Jxk8CwveE6GnpMNnpMFzynQc4rBs4LgORV6TjV4ThU8p0HPaQbPioLndOg53eA5XfCcAT1nGDwrCZ4zoedMg+dMwXMW9Jxl8KwseM6GnrMNnrMFzznQc47Bs4rgORd6zjV4zhU850HPeQbPqoLnfOg53+A5X/BcAD0XGDyrCZ4LoedCg+dCwXMR9Fxk8KwueC6GnosNnosFz6+h59cGzxqC5xLoucTguUTw/AZ6fmPwrCl4LoWeSw2eSwXPb6HntwbPWoLnMui5zOC5TPD8Dnp+Z/CsLXguh57LDZ7LBc/voef3Bs86gucK6LnC4LlC8PwBev5g8KwreK6EnisNnisFzx+h548Gz3qC5yroucrguUrw/Al6/mTwrC94roaeqw2eqwXPn6HnzwbPBoLnGui5xuC5RvD8BXr+YvBsKHiuhZ5rDZ5rBc9foeevBs9Gguc66LnO4LlO8FwPPdcbPBsLnhug5waD5wbBcyP03GjwbCJ4boKemwyemwTPzdBzs8GzqeC5BXpuMXhuETy3Qs+tBs9mguc26LnN4LlN8NwOPbcbPJsLnjug5w6D5w7Bcyf03GnwbCF47oKeuwyeuwTP3dBzt8GzpeC5B3ruMXjuETz3Qs+9Bs9Wguc+6LnP4LlP8NwPPfcbPFsLngeg5wGD5wHB8yD0PGjwbCN4HoKehwyehwTPw9DzsMGzreB5BHoeMXgeETyPQs+jBs92gucx6HnM4HlM8DwOPY8bPNsLnieg5wmD5wnB8yT0PGnw7CB4noKepwyepwTP09DztMGzo+B5BnqeMXieETx/g56/GTw7CZ5noedZg+dZwfN36Pm7wbOz4HkOep4zeJ4TPP+Ann8YPLsInueh53mD53nB80/o+afBs6vgeQF6XjB4XhA8/4Kefxk8uwmeF6HnRYPnRcHzb+j5t8Gzu+B5CXpeMnheEjwvQ8/LBs8egucV6HnF4HlF8LwKPa8aPHsKnteg5zWD5zXB8zr0vG7w7CV43oCeNwyeNwTPm9DzpsGzt+B5C3reMnjeEjxvQ8/bBs8+gucd6HnH4HlH8LwLPe8aPPsKnveg5z2D5z3B8z70vG/w7Cd4PoCeDwyeDwTPh9DzocGzv+D5CHo+Mng+EjwfQ8/HBs8BgucT6PnE4PlE8HwKPZ8aPAcKns+g5zOD5zPB8zn0fG7wHCR4voCeLwyeLwTPl9DzpcFzsOD5Cnq+Mni+EjxfQ8/XBs8hgucb6PnG4PlG8HwLPd8aPIcKnu+g5zuD5zvB8z30fG/wHCZ4foCeHwyeHwTPj9Dzo8FzuOD5CXp+Mnh+Ejw/Q8/PBs8RgucX6PnF4PlF8PyqKfP8Z++/eo4UPEM0ZZ4hmv53z/+9/W+zIaFnSIPnKMEzFPQMZfAMJXiGhp6hDZ6jBc8w0DOMwTOM4BkWeoY1eI4RPMNBz3AGz3CCZ3joGd7gOVbwjAA9Ixg8IwieEaFnRIPnOMEzEvSMZPCMJHhGhp6RDZ7jBc8o0DOKwTOK4BkVekY1eE4QPKNBz2gGz2iCZ3ToGd3gOVHwjAE9Yxg8YwieMaFnTIPnJMEzFvSMZfCMJXjGhp6xDZ6TBc840DOOwTOO4BkXesY1eE4RPONBz3gGz3iCZ3zoGd/gOVXwTAA9Exg8EwieCaFnQoPnNMEzEfRMZPBMJHgmhp6JDZ7TBc8k0DOJwTOJ4JkUeiY1eM4QPJNBz2QGz2SCZwB6BgyeMwXP5NAzucEzueCZAnqmMHjOEjxTQs+UBs+Ugmcq6JnK4Dlb8EwNPVMbPFMLnmmgZxqD5xzBMy30TGvwTCt4poOe6QyecwXP9NAzvcEzveCZAXpmMHjOEzwzQs+MBs+Mgmcm6JnJ4Dlf8MwMPTMbPDMLnlmgZxaD5wLBMyv0zGrwzCp4ZoOe2QyeCwXP7NAzu8Ezu+CZA3rmMHguEjxzQs+cBs+cgmcu6JnL4LlY8MwNPXMbPHMLnnmgZx6D59eCZ17omdfgmVfwzAc98xk8lwie+aFnfoNnfsGzAPQsYPD8RvAsCD0LGjwLCp6FoGchg+dSwbMw9Cxs8CwseBaBnkUMnt8KnkWhZ1GDZ1HBsxj0LGbwXCZ4FoeexQ2exQXPEtCzhMHzO8GzJPQsafAsKXiWgp6lDJ7LBc/S0LO0wbO04FkGepYxeH4veJaFnmUNnmUFz3LQs5zBc4XgWR56ljd4lhc8K0DPCgbPHwTPitCzosGzouBZCXpWMniuFDwrQ8/KBs/KgmcV6FnF4Pmj4FkVelY1eFYVPKtBz2oGz1WCZ3XoWd3gWV3wrAE9axg8fxI8a0LPmgbPmoJnLehZy+C5WvCsDT1rGzxrC551oGcdg+fPgmdd6FnX4FlX8KwHPesZPNcInvWhZ32DZ33BswH0bGDw/EXwbAg9Gxo8GwqejaBnI4PnWsGzMfRsbPBsLHg2gZ5NDJ6/Cp5NoWdTg2dTwbMZ9Gxm8FwneDaHns0Nns0FzxbQs4XBc73g2RJ6tjR4thQ8W0HPVgbPDYJna+jZ2uDZWvBsAz3bGDw3Cp5toWdbg2dbwbMd9Gxn8NwkeLaHnu0Nnu0Fzw7Qs4PBc7Pg2RF6djR4dhQ8O0HPTgbPLYJnZ+jZ2eDZWfDsAj27GDy3Cp5doWdXg2dXwbMb9Oxm8NwmeHaHnt0Nnt0Fzx7Qs4fBc7vg2RN69jR49hQ8e0HPXgbPHYJnb+jZ2+DZW/DsAz37GDx3Cp59oWdfg2dfwbMf9Oxn8NwlePaHnv0Nnv0FzwHQc4DBc7fgORB6DjR4DhQ8B0HPQQbPPYLnYOg52OA5WPAcAj2HGDz3Cp5DoedQg+dQwXMY9Bxm8NwneA6HnsMNnsMFzxHQc4TBc7/gORJ6jjR4jhQ8R0HPUQbPA4LnaOg52uA5WvAcAz3HGDwPCp5joedYg+dYwXMc9Bxn8DwkeI6HnuMNnuMFzwnQc4LB87DgORF6TjR4ThQ8J0HPSQbPI4LnZOg52eA5WfCcAj2nGDyPCp5ToedUg+dUwXMa9Jxm8DwmeE6HntMNntMFzxnQc4bB87jgORN6zjR4zhQ8Z0HPWQbPE4LnbOg52+A5W/CcAz3nGDxPCp5zoedcg+dcwXMe9Jxn8DwleM6HnvMNnvMFzwXQc4HB87TguRB6LjR4LhQ8F0HPRQbPM4Ln/7FCV2Fble0WhqW7u7u7u7u7BGTS3SIiIiIiIiIiIiLS3Q0iIiIi3d3d3Q3rcO9bW98/rnfM7fHM6z7OKdBzisFziuA5FXpONXgeFDynQc9pBs9pgud06Dnd4HlI8JwBPWcYPGcInjOh50yD52HBcxb0nGXwnCV4zoaesw2eRwTPOdBzjsFzjuA5F3rONXgeFTznQc95Bs95gud86Dnf4HlM8FwAPRcYPBcInguh50KD53HBcxH0XGTwXCR4Loaeiw2eJwTPJdBzicFzieC5FHouNXieFDyXQc9lBs9lgudy6Lnc4HlK8FwBPVcYPFcIniuh50qD52nBcxX0XGXwXCV4roaeqw2eZwTPNdBzjcFzjeC5FnquNXieFTzXQc91Bs91gudv0PM3g+c5wXM99Fxv8FwveP4OPX83eJ4XPDdAzw0Gzw2C5x/Q8w+D5wXBcyP03Gjw3Ch4/gk9/zR4XhQ8N0HPTQbPTYLnX9DzL4PnJcFzM/TcbPDcLHj+DT3/NnheFjy3QM8tBs8tguc/0PMfg+cVwXMr9Nxq8NwqeP4LPf81eF4VPLdBz20Gz22C53boud3geU3w3AE9dxg8dwieO6HnToPndcFzF/TcZfDcJXjuhp67DZ43BM890HOPwXOP4LkXeu41eN4UPPdBz30Gz32C537oud/geUvwPAA9Dxg8DwieB6HnQYPnbcHzEPQ8ZPA8JHgehp6HDZ53BM8j0POIwfOI4HkUeh41eN4VPI9Bz2MGz2OC53HoedzgeU/wPAE9Txg8TwieJ6HnSYPnfcHzFPQ8ZfA8JXiehp6nDZ4PBM8z0POMwfOM4HkWep41eD4UPM9Bz3MGz3OC53noed7g+UjwvAA9Lxg8LwieF6HnRYPnY8HzEvS8ZPC8JHhehp6XDZ5PBM8r0POKwfOK4HkVel41eD4VPK9Bz2sGz2uC53Xoed3g+UzwvAE9bxg8bwieN6HnTYPnc8HzFvS8ZfC8JXjehp63DZ4vBM870POOwfOO4HkXet41eL4UPO9Bz3sGz3uC533oed/g+UrwfAA9Hxg8HwieD6HnQ4Pna8HzEfR8ZPB8JHg+hp6PDZ5vBM8n0POJwfOJ4PkUej41eL4VPJ9Bz2cGz2eC53Po+dzg+U7wfAE9Xxg8XwieL6HnS4Pne3n/9ztfQc9XBs9Xgudr6Pna4BlB8HwDPd8YPN8Inm+h51uDZ0TB8x30fGfwfCd4vhcwz//eheoZSfCMEDDPCEHonmHb4W0jBswzYhC6Z2TBM1LAPCMFoXuGbYe3jRwwz8hB6J5RBM8oAfOMEoTuGbYd3jZqwDyjBqF7RhU8owXMM1oQumfYdnjb6AHzjB6E7hlN8IwRMM8YQeieYdvhbWMGzDNmELpndMEzVsA8YwWhe4Zth7eNHTDP2EHonjEEzzgB84wThO4Zth3eNm7APOMGoXvGFDzjBcwzXhC6Z9h2eNv4AfOMH4TuGUvwTBAwzwRB6J5h2+FtEwbMM2EQumdswTNRwDwTBaF7hm2Ht00cMM/EQeiecQTPJAHzTBKE7hm2Hd42acA8kwahe8YVPJMFzDNZELpn2HZ42+QB80wehO4ZT/BMETDPFEHonmHb4W1TBswzZRC6Z3zBM1XAPFMFoXuGbYe3TR0wz9RB6J4JBM80AfNME4TuGbYd3jZtwDzTBqF7JhQ80wXMM10QumfYdnjb9AHzTB+E7plI8MwQMM8MQeieYdvhbTMGzDNjELpnYsEzU8A8MwWhe4Zth7fNHDDPzEHonkkEzywB88wShO4Zth3eNmvAPLMGoXsmFTyzBcwzWxC6Z9h2eNvsAfPMHoTumUzwzBEwzxxB6J5h2+FtcwbMM2cQumdywTNXwDxzBaF7hm2Ht80dMM/cQeieKQTPPAHzzBOE7hm2Hd42b8A88wahe6YUPPMFzDNfELpn2HZ42/wB88wfhO6ZSvAsEDDPAkHonmHb4W0LBsyzYBC6Z2rBs1DAPAsFoXuGbYe3LRwwz8JB6J5pBM8iAfMsEoTuGbYd3rZowDyLBqF7phU8iwXMs1gQumfYdnjb4gHzLB6E7plO8CwRMM8SQeieYdvhbUsGzLNkELpnesGzVMA8SwWhe4Zth7ctHTDP0kHonhkEzzIB8ywThO4Zth3etmzAPMsGoXtmFDzLBcyzXBC6Z9h2eNvyAfMsH4TumUnwrBAwzwpB6J5h2+FtKwbMs2IQumdmwbNSwDwrBaF7hm2Ht60cMM/KQeieWQTPKgHzrBKE7hm2Hd62asA8qwahe2YVPKsFzLNaELpn2HZ42+oB86wehO6ZTfCsETDPGkHonmHb4W1rBsyzZhC6Z3bBs1bAPGsFoXuGbYe3rR0wz9pB6J45BM86AfOsE4TuGbYd3rZuwDzrBqF75hQ86wXMs14QumfYdnjb+gHzrB+E7plL8GwQMM8GQeieYdvhbRsGzLNhELpnbsGzUcA8GwWhe4Zth7dtHDDPxkHonnkEzyYB82wShO4Zth3etmnAPJsGoXvmFTybBcyzWRC6Z9h2eNvmAfNsHoTumU/wbBEwzxZB6J5h2+Ft3w+Y5/tB6J75Bc+WAfNsGYTuGbYd3rZVwDxbBaF7FhA8WwfMs3UQumfYdnjbDwLm+UEQumdBwbNNwDzbBKF7hm2Htw0C5hkEoXsWEjzbBsyzbRC6Z9h2eNt2AfNsF4TuWVjwbB8wz/ZB6J5h2+FtOwTMs0MQumcRwbNjwDw7BqF7hm2Ht+0UMM9OQeieRQXPzgHz7ByE7hm2Hd62S8A8uwShexYTPLsGzLNrELpn2HZ4224B8+wWhO5ZXPDsHjDP7kHonmHb4W17BMyzRxC6ZwnBs2fAPHsGoXuGbYe37RUwz15B6J4lBc/eAfPsHYTuGbYd3rZPwDz7BKF7lhI8+wbMs28QumfYdnjbfgHz7BeE7lla8OwfMM/+QeieYdvhbT8MmOeHQeieZQTPAQHzHBCE7hm2Hd72o4B5fhSE7llW8BwYMM+BQeieYdvhbT8OmOfHQeie5QTPQQHzHBSE7hm2Hd72k4B5fhKE7lle8BwcMM/BQeieYdvhbT8NmOenQeieFQTPIQHzHBKE7hm2Hd72s4B5fhaE7llR8BwaMM+hQeieYdvhbT8PmOfnQeielQTPYQHzHBaE7hm2Hd72i4B5fhGE7llZ8BweMM/hQeieYdvhbb8MmOeXQeieVQTPEQHzHBGE7hm2Hd72q4B5fhWE7llV8BwZMM+RQeieYdvhbb8OmOfXQeie1QTPUQHzHBWE7hm2Hd72m4B5fhOE7lld8BwdMM/RQeieYdvhbb8NmOe3QeieNQTPMQHzHBOE7hm2Hd72u4B5fheE7llT8BwbMM+xQeieYdvhbb8PmOf3QeietQTPcQHzHBeE7hm2Hd72h4B5/hCE7llb8BwfMM/xQeieYdvhbX8MmOePQeiedQTPCQHznBCE7hm2Hd72p4B5/hSE7llX8JwYMM+JQeieYdvhbX8OmOfPQeie9QTPSQHznBSE7hm2Hd72l4B5/hKE7llf8JwcMM/JQeieYdvhbX8NmOevQeieDQTPKQHznBKE7hm2Hd52asA8pwahezYUPKcFzHNaELpn2HZ42+kB85wehO7ZSPCcETDPGUHonmHb4W1nBsxzZhC6Z2PBc1bAPGcFoXuGbYe3nR0wz9lB6J5NBM85AfOcE4TuGbYd3nZuwDznBqF7NhU85wXMc14QumfYdnjb+QHznB+E7tlM8FwQMM8FQeieYdvhbRcGzHNhELpnc8FzUcA8FwWhe4Zth7ddHDDPxUHoni0EzyUB81wShO4Zth3edmnAPJcGoXu+L3guC5jnsiB0z7Dt8LbLA+a5PAjds6XguSJgniuC0D3DtsPbrgyY58ogdM9WgueqgHmuCkL3DNsOb7s6YJ6rg9A9WwueawLmuSYI3TNsO7zt2oB5rg1C9/xA8FwXMM91QeieYdvhbX8LmOdvQeiebQTP9QHzXB+E7hm2Hd7294B5/h6E7hkInhsC5rkhCN0zbDu87R8B8/wjCN2zreC5MWCeG4PQPcO2w9v+GTDPP4PQPdsJnpsC5rkpCN0zbDu87V8B8/wrCN2zveC5OWCem4PQPcO2w9v+HTDPv4PQPTsInlsC5rklCN0zbDu87T8B8/wnCN2zo+C5NWCeW4PQPcO2w9v+GzDPf4PQPTsJntsC5rktCN0zbDu87faAeW4PQvfsLHjuCJjnjiB0z7Dt8LY7A+a5Mwjds4vguStgnruC0D3DtsPb7g6Y5+4gdM+ugueegHnuCUL3DNsOb7s3YJ57g9A9uwme+wLmuS8I3TNsO7zt/oB57g9C9+wueB4ImOeBIHTPsO3wtgcD5nkwCN2zh+B5KGCeh4LQPcO2w9seDpjn4SB0z56C55GAeR4JQvcM2w5vezRgnkeD0D17CZ7HAuZ5LAjdM2w7vO3xgHkeD0L37C14ngiY54kgdM+w7fC2JwPmeTII3bOP4HkqYJ6ngtA9w7bD254OmOfpIHTPvoLnmYB5nglC9wzbDm97NmCeZ4PQPfsJnucC5nkuCN0zbDu87fmAeZ4PQvfsL3heCJjnhSB0z7Dt8LYXA+Z5MQjd80PB81LAPC8FoXuGbYe3vRwwz8tB6J4DBM8rAfO8EoTuGbYd3vZqwDyvBqF7fiR4XguY57UgdM+w7fC21wPmeT0I3XOg4HkjYJ43gtA9w7bD294MmOfNIHTPjwXPWwHzvBWE7hm2Hd72dsA8bwehew4SPO8EzPNOELpn2HZ427sB87wbhO75ieB5L2Ce94LQPcO2w9veD5jn/SB0z8GC54OAeT4IQvcM2w5v+zBgng+D0D0/FTwfBczzURC6Z9h2eNvHAfN8HITuOUTwfBIwzydB6J5h2+FtnwbM82kQuudnguezgHk+C0L3DNsOb/s8YJ7Pg9A9hwqeLwLm+SII3TNsO7zty4B5vgxC9/xc8HwVMM9XQeieYdvhbV8HzPN1ELrnMMHzTcA83wShe4Zth7d9GzDPt0Honl8Inu8C5vkuCN0zbDu87Xttmed/70L1HC54RmjLPCO0Dd0zbDu8bUToGdHg+aXgGQl6RjJ4RhI8I0PPyAbPEYJnFOgZxeAZRfCMCj2jGjy/EjyjQc9oBs9ogmd06Bnd4DlS8IwBPWMYPGMInjGhZ0yD59eCZyzoGcvgGUvwjA09Yxs8RwmecaBnHINnHMEzLvSMa/D8RvCMBz3jGTzjCZ7xoWd8g+dowTMB9Exg8EwgeCaEngkNnt8KnomgZyKDZyLBMzH0TGzwHCN4JoGeSQyeSQTPpNAzqcHzO8EzGfRMZvBMJngmh57JDZ5jBc8U0DOFwTOF4JkSeqY0eH4veKaCnqkMnqkEz9TQM7XBc5zgmQZ6pjF4phE800LPtAbPHwTPdNAzncEzneCZHnqmN3iOFzwzQM8MBs8MgmdG6JnR4Pmj4JkJemYyeGYSPDNDz8wGzwmCZxbomcXgmUXwzAo9sxo8fxI8s0HPbAbPbIJnduiZ3eA5UfDMAT1zGDxzCJ45oWdOg+fPgmcu6JnL4JlL8MwNPXMbPCcJnnmgZx6DZx7BMy/0zGvw/EXwzAc98xk88wme+aFnfoPnZMGzAPQsYPAsIHgWhJ4FDZ6/Cp6FoGchg2chwbMw9Cxs8JwieBaBnkUMnkUEz6LQs6jBc6rgWQx6FjN4FhM8i0PP4gbPaYJnCehZwuBZQvAsCT1LGjynC56loGcpg2cpwbM09Cxt8JwheJaBnmUMnmUEz7LQs6zBc6bgWQ56ljN4lhM8y0PP8gbPWYJnBehZweBZQfCsCD0rGjxnC56VoGclg2clwbMy9Kxs8JwjeFaBnlUMnlUEz6rQs6rBc67gWQ16VjN4VhM8q0PP6gbPeYJnDehZw+BZQ/CsCT1rGjznC561oGctg2ctwbM29Kxt8FwgeNaBnnUMnnUEz7rQs67Bc6HgWQ961jN41hM860PP+gbPRYJnA+jZwODZQPBsCD0bGjwXC56NoGcjg2cjwbMx9Gxs8FwieDaBnk0Mnk0Ez6bQs6nBc6ng2Qx6NjN4NhM8m0PP5gbPZYJnC+jZwuDZQvB8H3q+b/BcLni2hJ4tDZ4tBc9W0LOVwXOF4NkaerY2eLYWPD+Anh8YPFcKnm2gZxuDZxvBM4CegcFzleDZFnq2NXi2FTzbQc92Bs/Vgmd76Nne4Nle8OwAPTsYPNcInh2hZ0eDZ0fBsxP07GTwXCt4doaenQ2enQXPLtCzi8FzneDZFXp2NXh2FTy7Qc9uBs/fBM/u0LO7wbO74NkDevYweK4XPHtCz54Gz56CZy/o2cvg+bvg2Rt69jZ49hY8+0DPPgbPDYJnX+jZ1+DZV/DsBz37GTz/EDz7Q8/+Bs/+gueH0PNDg+dGwXMA9Bxg8BwgeH4EPT8yeP4peA6EngMNngMFz4+h58cGz02C5yDoOcjgOUjw/AR6fmLw/EvwHAw9Bxs8Bwuen0LPTw2emwXPIdBziMFziOD5GfT8zOD5t+A5FHoONXgOFTw/h56fGzy3CJ7DoOcwg+cwwfML6PmFwfMfwXM49Bxu8BwueH4JPb80eG4VPEdAzxEGzxGC51fQ8yuD57+C50joOdLgOVLw/Bp6fm3w3CZ4joKeowyeowTPb6DnNwbP7YLnaOg52uA5WvD8Fnp+a/DcIXiOgZ5jDJ5jBM/voOd3Bs+dgudY6DnW4DlW8Pween5v8NwleI6DnuMMnuMEzx+g5w8Gz92C53joOd7gOV7w/BF6/mjw3CN4ToCeEwyeEwTPn6DnTwbPvYLnROg50eA5UfD8GXr+bPDcJ3hOgp6TDJ6TBM9foOcvBs/9gudk6DnZ4DlZ8PwVev5q8DwgeE6BnlMMnlMEz6nQc6rB86DgOQ16TjN4ThM8p0PP6QbPQ4LnDOg5w+A5Q/CcCT1nGjwPC56zoOcsg+cswXM29Jxt8DwieM6BnnMMnnMEz7nQc67B86jgOQ96zjN4zhM850PP+QbPY4LnAui5wOC5QPBcCD0XGjyPC56LoOcig+ciwXMx9Fxs8DwheC6BnksMnksEz6XQc6nB86TguQx6LjN4LhM8l0PP5QbPU4LnCui5wuC5QvBcCT1XGjxPC56roOcqg+cqwXM19Fxt8DwjeK6BnmsMnmsEz7XQc63B86zguQ56rjN4rhM8f4Oevxk8zwme66HneoPnesHzd+j5u8HzvOC5AXpuMHhuEDz/gJ5/GDwvCJ4boedGg+dGwfNP6PmnwfOi4LkJem4yeG4SPP+Cnn8ZPC8Jnpuh52aD52bB82/o+bfB87LguQV6bjF4bhE8/4Ge/xg8rwieW6HnVoPnVsHzX+j5r8HzquC5DXpuM3huEzy3Q8/tBs9rgucO6LnD4LlD8NwJPXcaPK8Lnrug5y6D5y7Bczf03G3wvCF47oGeewyeewTPvdBzr8HzpuC5D3ruM3juEzz3Q8/9Bs9bgucB6HnA4HlA8DwIPQ8aPG8Lnoeg5yGD5yHB8zD0PGzwvCN4HoGeRwyeRwTPo9DzqMHzruB5DHoeM3geEzyPQ8/jBs97gucJ6HnC4HlC8DwJPU8aPO8Lnqeg5ymD5ynB8zT0PG3wfCB4noGeZwyeZwTPs9DzrMHzoeB5DnqeM3ieEzzPQ8/zBs9HgucF6HnB4HlB8LwIPS8aPB8Lnpeg5yWD5yXB8zL0vGzwfCJ4XoGeVwyeVwTPq9DzqsHzqeB5DXpeM3heEzyvQ8/rBs9ngucN6HnD4HlD8LwJPW8aPJ8Lnreg5y2D5y3B8zb0vG3wfCF43oGedwyedwTPu9DzrsHzpeB5D3reM3jeEzzvQ8/7Bs9XgucD6PnA4PlA8HwIPR8aPF8Lno+g5yOD5yPB8zH0fGzwfCN4PoGeTwyeTwTPp9DzqcHzreD5DHo+M3g+EzyfQ8/nBs93gucL6PnC4PlC8HwJPV8aPN/L97/f+Qp6vjJ4vhI8X0PP1wbPCILnG+j5xuD5RvB8Cz3fGjwjCp7voOc7g+c7wfO9dszzv3ehekYSPCO0Y54R2oXuGbYd3jYi9Ixo8IwseEaCnpEMnpEEz8jQM7LBM4rgGQV6RjF4RhE8o0LPqAbPqIJnNOgZzeAZTfCMDj2jGzyjCZ4xoGcMg2cMwTMm9Ixp8IwueMaCnrEMnrEEz9jQM7bBM4bgGQd6xjF4xhE840LPuAbPmIJnPOgZz+AZT/CMDz3jGzxjCZ4JoGcCg2cCwTMh9Exo8IwteCaCnokMnokEz8TQM7HBM47gmQR6JjF4JhE8k0LPpAbPuIJnMuiZzOCZTPBMDj2TGzzjCZ4poGcKg2cKwTMl9Exp8IwveKaCnqkMnqkEz9TQM7XBM4HgmQZ6pjF4phE800LPtAbPhIJnOuiZzuCZTvBMDz3TGzwTCZ4ZoGcGg2cGwTMj9Mxo8EwseGaCnpkMnpkEz8zQM7PBM4ngmQV6ZjF4ZhE8s0LPrAbPpIJnNuiZzeCZTfDMDj2zGzyTCZ45oGcOg2cOwTMn9Mxp8EwueOaCnrkMnrkEz9zQM7fBM4XgmQd65jF45hE880LPvAbPlIJnPuiZz+CZT/DMDz3zGzxTCZ4FoGcBg2cBwbMg9Cxo8EwteBaCnoUMnoUEz8LQs7DBM43gWQR6FjF4FhE8i0LPogbPtIJnMehZzOBZTPAsDj2LGzzTCZ4loGcJg2cJwbMk9Cxp8EwveJaCnqUMnqUEz9LQs7TBM4PgWQZ6ljF4lhE8y0LPsgbPjIJnOehZzuBZTvAsDz3LGzwzCZ4VoGcFg2cFwbMi9Kxo8MwseFaCnpUMnpUEz8rQs7LBM4vgWQV6VjF4VhE8q0LPqgbPrIJnNehZzeBZTfCsDj2rGzyzCZ41oGcNg2cNwbMm9Kxp8MwueNaCnrUMnrUEz9rQs7bBM4fgWQd61jF41hE860LPugbPnIJnPehZz+BZT/CsDz3rGzxzCZ4NoGcDg2cDwbMh9Gxo8MwteDaCno0Mno0Ez8bQs7HBM4/g2QR6NjF4NhE8m0LPpgbPvIJnM+jZzODZTPBsDj2bGzzzCZ4toGcLg2cLwfN96Pm+wTO/4NkSerY0eLYUPFtBz1YGzwKCZ2vo2drg2Vrw/AB6fmDwLCh4toGebQyebQTPAHoGBs9Cgmdb6NnW4NlW8GwHPdsZPAsLnu2hZ3uDZ3vBswP07GDwLCJ4doSeHQ2eHQXPTtCzk8GzqODZGXp2Nnh2Fjy7QM8uBs9igmdX6NnV4NlV8OwGPbsZPIsLnt2hZ3eDZ3fBswf07GHwLCF49oSePQ2ePQXPXtCzl8GzpODZG3r2Nnj2Fjz7QM8+Bs9Sgmdf6NnX4NlX8OwHPfsZPEsLnv2hZ3+DZ3/B80Po+aHBs4zgOQB6DjB4DhA8P4KeHxk8ywqeA6HnQIPnQMHzY+j5scGznOA5CHoOMngOEjw/gZ6fGDzLC56Doedgg+dgwfNT6PmpwbOC4DkEeg4xeA4RPD+Dnp8ZPCsKnkOh51CD51DB83Po+bnBs5LgOQx6DjN4DhM8v4CeXxg8Kwuew6HncIPncMHzS+j5pcGziuA5AnqOMHiOEDy/gp5fGTyrCp4joedIg+dIwfNr6Pm1wbOa4DkKeo4yeI4SPL+Bnt8YPKsLnqOh52iD52jB81vo+a3Bs4bgOQZ6jjF4jhE8v4Oe3xk8awqeY6HnWIPnWMHze+j5vcGzluA5DnqOM3iOEzx/gJ4/GDxrC57joed4g+d4wfNH6PmjwbOO4DkBek4weE4QPH+Cnj8ZPOsKnhOh50SD50TB82fo+bPBs57gOQl6TjJ4ThI8f4Gevxg86wuek6HnZIPnZMHzV+j5q8GzgeA5BXpOMXhOETynQs+pBs+Gguc06DnN4DlN8JwOPacbPBsJnjOg5wyD5wzBcyb0nGnwbCx4zoKeswyeswTP2dBztsGzieA5B3rOMXjOETznQs+5Bs+mguc86DnP4DlP8JwPPecbPJsJngug5wKD5wLBcyH0XGjwbC54LoKeiwyeiwTPxdBzscGzheC5BHouMXguETyXQs+lBs/3Bc9l0HOZwXOZ4Lkcei43eLYUPFdAzxUGzxWC50roudLg2UrwXAU9Vxk8Vwmeq6HnaoNna8FzDfRcY/BcI3iuhZ5rDZ4fCJ7roOc6g+c6wfM36PmbwbON4Lkeeq43eK4XPH+Hnr8bPAPBcwP03GDw3CB4/gE9/zB4thU8N0LPjQbPjYLnn9DzT4NnO8FzE/TcZPDcJHj+BT3/Mni2Fzw3Q8/NBs/Nguff0PNvg2cHwXML9Nxi8NwieP4DPf8xeHYUPLdCz60Gz62C57/Q81+DZyfBcxv03Gbw3CZ4boee2w2enQXPHdBzh8Fzh+C5E3ruNHh2ETx3Qc9dBs9dgudu6Lnb4NlV8NwDPfcYPPcInnuh516DZzfBcx/03Gfw3Cd47oee+w2e3QXPA9DzgMHzgOB5EHoeNHj2EDwPQc9DBs9Dgudh6HnY4NlT8DwCPY8YPI8Inkeh51GDZy/B8xj0PGbwPCZ4Hoeexw2evQXPE9DzhMHzhOB5EnqeNHj2ETxPQc9TBs9Tgudp6Hna4NlX8DwDPc8YPM8Inmeh51mDZz/B8xz0PGfwPCd4noee5w2e/QXPC9DzgsHzguB5EXpeNHh+KHhegp6XDJ6XBM/L0POywXOA4HkFel4xeF4RPK9Cz6sGz48Ez2vQ85rB85rgeR16Xjd4DhQ8b0DPGwbPG4LnTeh50+D5seB5C3reMnjeEjxvQ8/bBs9Bgucd6HnH4HlH8LwLPe8aPD8RPO9Bz3sGz3uC533oed/gOVjwfAA9Hxg8HwieD6HnQ4Pnp4LnI+j5yOD5SPB8DD0fGzyHCJ5PoOcTg+cTwfMp9Hxq8PxM8HwGPZ8ZPJ8Jns+h53OD51DB8wX0fGHwfCF4voSeLw2enwuer6DnK4PnK8HzNfR8bfAcJni+gZ5vDJ5vBM+30POtwfMLwfMd9Hxn8HwneL7Xnnn+9y5Uz+GCZ4T2zDNC+9A9w7bD20aEnhENnl8KnpGgZySDZyTBMzL0jGzwHCF4RoGeUQyeUQTPqNAzqsHzK8EzGvSMZvCMJnhGh57RDZ4jBc8Y0DOGwTOG4BkTesY0eH4teMaCnrEMnrEEz9jQM7bBc5TgGQd6xjF4xhE840LPuAbPbwTPeNAznsEznuAZH3rGN3iOFjwTQM8EBs8EgmdC6JnQ4Pmt4JkIeiYyeCYSPBNDz8QGzzGCZxLomcTgmUTwTAo9kxo8vxM8k0HPZAbPZIJncuiZ3OA5VvBMAT1TGDxTCJ4poWdKg+f3gmcq6JnK4JlK8EwNPVMbPMcJnmmgZxqDZxrBMy30TGvw/EHwTAc90xk80wme6aFneoPneMEzA/TMYPDMIHhmhJ4ZDZ4/Cp6ZoGcmg2cmwTMz9Mxs8JwgeGaBnlkMnlkEz6zQM6vB8yfBMxv0zGbwzCZ4Zoee2Q2eEwXPHNAzh8Ezh+CZE3rmNHj+LHjmgp65DJ65BM/c0DO3wXOS4JkHeuYxeOYRPPNCz7wGz18Ez3zQM5/BM5/gmR965jd4ThY8C0DPAgbPAoJnQehZ0OD5q+BZCHoWMngWEjwLQ8/CBs8pgmcR6FnE4FlE8CwKPYsaPKcKnsWgZzGDZzHBszj0LG7wnCZ4loCeJQyeJQTPktCzpMFzuuBZCnqWMniWEjxLQ8/SBs8ZgmcZ6FnG4FlG8CwLPcsaPGcKnuWgZzmDZznBszz0LG/wnCV4VoCeFQyeFQTPitCzosFztuBZCXpWMnhWEjwrQ8/KBs85gmcV6FnF4FlF8KwKPasaPOcKntWgZzWDZzXBszr0rG7wnCd41oCeNQyeNQTPmtCzpsFzvuBZC3rWMnjWEjxrQ8/aBs8Fgmcd6FnH4FlH8KwLPesaPBcKnvWgZz2DZz3Bsz70rG/wXCR4NoCeDQyeDQTPhtCzocFzseDZCHo2Mng2EjwbQ8/GBs8lgmcT6NnE4NlE8GwKPZsaPJcKns2gZzODZzPBszn0bG7wXCZ4toCeLQyeLQTP96Hn+wbP5YJnS+jZ0uDZUvBsBT1bGTxXCJ6toWdrg2drwfMD6PmBwXOl4NkGerYxeLYRPAPoGRg8VwmebaFnW4NnW8GzHfRsZ/BcLXi2h57tDZ7tBc8O0LODwXON4NkRenY0eHYUPDtBz04Gz7WCZ2fo2dng2Vnw7AI9uxg81wmeXaFnV4NnV8GzG/TsZvD8TfDsDj27Gzy7C549oGcPg+d6wbMn9Oxp8OwpePaCnr0Mnr8Lnr2hZ2+DZ2/Bsw/07GPw3CB49oWefQ2efQXPftCzn8HzD8GzP/Tsb/DsL3h+CD0/NHhuFDwHQM8BBs8BgudH0PMjg+efgudA6DnQ4DlQ8PwYen5s8NwkeA6CnoMMnoMEz0+g5ycGz78Ez8HQc7DBc7Dg+Sn0/NTguVnwHAI9hxg8hwien0HPzwyefwueQ6HnUIPnUMHzc+j5ucFzi+A5DHoOM3gOEzy/gJ5fGDz/ETyHQ8/hBs/hgueX0PNLg+dWwXME9Bxh8BwheH4FPb8yeP4reI6EniMNniMFz6+h59cGz22C5yjoOcrgOUrw/AZ6fmPw3C54joaeow2eowXPb6HntwbPHYLnGOg5xuA5RvD8Dnp+Z/DcKXiOhZ5jDZ5jBc/voef3Bs9dguc46DnO4DlO8PwBev5g8NwteI6HnuMNnuMFzx+h548Gzz2C5wToOcHgOUHw/Al6/mTw3Ct4ToSeEw2eEwXPn6HnzwbPfYLnJOg5yeA5SfD8BXr+YvDcL3hOhp6TDZ6TBc9foeevBs8DgucU6DnF4DlF8JwKPacaPA8KntOg5zSD5zTBczr0nG7wPCR4zoCeMwyeMwTPmdBzpsHzsOA5C3rOMnjOEjxnQ8/ZBs8jgucc6DnH4DlH8JwLPecaPI8KnvOg5zyD5zzBcz70nG/wPCZ4LoCeCwyeCwTPhdBzocHzuOC5CHouMnguEjwXQ8/FBs8TgucS6LnE4LlE8FwKPZcaPE8Knsug5zKD5zLBczn0XG7wPCV4roCeKwyeKwTPldBzpcHztOC5CnquMniuEjxXQ8/VBs8zguca6LnG4LlG8FwLPdcaPM8Knuug5zqD5zrB8zfo+ZvB85zguR56rjd4rhc8f4eevxs8zwueG6DnBoPnBsHzD+j5h8HzguC5EXpuNHhuFDz/hJ5/GjwvCp6boOcmg+cmwfMv6PmXwfOS4LkZem42eG4WPP+Gnn8bPC8Lnlug5xaD5xbB8x/o+Y/B84rguRV6bjV4bhU8/4We/xo8rwqe26DnNoPnNsFzO/TcbvC8JnjugJ47DJ47BM+d0HOnwfO64LkLeu4yeO4SPHdDz90GzxuC5x7oucfguUfw3As99xo8bwqe+6DnPoPnPsFzP/Tcb/C8JXgegJ4HDJ4HBM+D0POgwfO24HkIeh4yeB4SPA9Dz8MGzzuC5xHoecTgeUTwPAo9jxo87wqex6DnMYPnMcHzOPQ8bvC8J3iegJ4nDJ4nBM+T0POkwfO+4HkKep4yeJ4SPE9Dz9MGzweC5xnoecbgeUbwPAs9zxo8Hwqe56DnOYPnOcHzPPQ8b/B8JHhegJ4XDJ4XBM+L0POiwfOx4HkJel4yeF4SPC9Dz8sGzyeC5xXoecXgeUXwvAo9rxo8nwqe16DnNYPnNcHzOvS8bvB8JnjegJ43DJ43BM+b0POmwfO54HkLet4yeN4SPG9Dz9sGzxeC5x3oecfgeUfwvAs97xo8Xwqe96DnPYPnPcHzPvS8b/B8JXg+gJ4PDJ4PBM+H0POhw7PQ/37no//tzmjv3vX5f3f+9y5zOHcq7fC2j/+3O+O9e3v+/935+H+4M5wvwmvB8wn0fGLwfCJ4PoWeTw2ebwTPZ9DzmcHzmeD5HHo+N3i+FTxfQM8XBs8XgudL6PnS4PlO8HwFPV8ZPF8Jnq+h52uD53uF//c730DPNwbPN4LnW+j51uAZQfB8Bz3fGTzfCZ7vdWCe/70L1TOi4BmhA/OM0CF0z7Dt8LYRoWdEg2ckwTMS9Ixk8IwkeEaGnpENnpEFzyjQM4rBM4rgGRV6RjV4RhE8o0HPaAbPaIJndOgZ3eAZVfCMAT1jGDxjCJ4xoWdMg2c0wTMW9Ixl8IwleMaGnrENntEFzzjQM47BM47gGRd6xjV4xhA840HPeAbPeIJnfOgZ3+AZU/BMAD0TGDwTCJ4JoWdCg2cswTMR9Exk8EwkeCaGnokNnrEFzyTQM4nBM4ngmRR6JjV4xhE8k0HPZAbPZIJncuiZ3OAZV/BMAT1TGDxTCJ4poWdKg2c8wTMV9Exl8EwleKaGnqkNnvEFzzTQM43BM43gmRZ6pjV4JhA800HPdAbPdIJneuiZ3uCZUPDMAD0zGDwzCJ4ZoWdGg2ciwTMT9Mxk8MwkeGaGnpkNnokFzyzQM4vBM4vgmRV6ZjV4JhE8s0HPbAbPbIJnduiZ3eCZVPDMAT1zGDxzCJ45oWdOg2cywTMX9Mxl8MwleOaGnrkNnskFzzzQM4/BM4/gmRd65jV4phA880HPfAbPfIJnfuiZ3+CZUvAsAD0LGDwLCJ4FoWdBg2cqwbMQ9Cxk8CwkeBaGnoUNnqkFzyLQs4jBs4jgWRR6FjV4phE8i0HPYgbPYoJncehZ3OCZVvAsAT1LGDxLCJ4loWdJg2c6wbMU9Cxl8CwleJaGnqUNnukFzzLQs4zBs4zgWRZ6ljV4ZhA8y0HPcgbPcoJneehZ3uCZUfCsAD0rGDwrCJ4VoWdFg2cmwbMS9Kxk8KwkeFaGnpUNnpkFzyrQs4rBs4rgWRV6VjV4ZhE8q0HPagbPaoJndehZ3eCZVfCsAT1rGDxrCJ41oWdNg2c2wbMW9Kxl8KwleNaGnrUNntkFzzrQs47Bs47gWRd61jV45hA860HPegbPeoJnfehZ3+CZU/BsAD0bGDwbCJ4NoWdDg2cuwbMR9Gxk8GwkeDaGno0NnrkFzybQs4nBs4ng2RR6NjV45hE8m0HPZgbPZoJnc+jZ3OCZV/BsAT1bGDxbCJ7vQ8/3DZ75BM+W0LOlwbOl4NkKerYyeOYXPFtDz9YGz9aC5wfQ8wODZwHBsw30bGPwbCN4BtAzMHgWFDzbQs+2Bs+2gmc76NnO4FlI8GwPPdsbPNsLnh2gZweDZ2HBsyP07Gjw7Ch4doKenQyeRQTPztCzs8Gzs+DZBXp2MXgWFTy7Qs+uBs+ugmc36NnN4FlM8OwOPbsbPLsLnj2gZw+DZ3HBsyf07Gnw7Cl49oKevQyeJQTP3tCzt8Gzt+DZB3r2MXiWFDz7Qs++Bs++gmc/6NnP4FlK8OwPPfsbPPsLnh9Czw8NnqUFzwHQc4DBc4Dg+RH0/MjgWUbwHAg9Bxo8BwqeH0PPjw2eZQXPQdBzkMFzkOD5CfT8xOBZTvAcDD0HGzwHC56fQs9PDZ7lBc8h0HOIwXOI4PkZ9PzM4FlB8BwKPYcaPIcKnp9Dz88NnhUFz2HQc5jBc5jg+QX0/MLgWUnwHA49hxs8hwueX0LPLw2elQXPEdBzhMFzhOD5FfT8yuBZRfAcCT1HGjxHCp5fQ8+vDZ5VBc9R0HOUwXOU4PkN9PzG4FlN8BwNPUcbPEcLnt9Cz28NntUFzzHQc4zBc4zg+R30/M7gWUPwHAs9xxo8xwqe30PP7w2eNQXPcdBznMFznOD5A/T8weBZS/AcDz3HGzzHC54/Qs8fDZ61Bc8J0HOCwXOC4PkT9PzJ4FlH8JwIPScaPCcKnj9Dz58NnnUFz0nQc5LBc5Lg+Qv0/MXgWU/wnAw9Jxs8Jwuev0LPXw2e9QXPKdBzisFziuA5FXpONXg2EDynQc9pBs9pgud06Dnd4NlQ8JwBPWcYPGcInjOh50yDZyPBcxb0nGXwnCV4zoaesw2ejQXPOdBzjsFzjuA5F3rONXg2ETznQc95Bs95gud86Dnf4NlU8FwAPRcYPBcInguh50KDZzPBcxH0XGTwXCR4Loaeiw2ezQXPJdBzicFzieC5FHouNXi2EDyXQc9lBs9lgudy6Lnc4Pm+4LkCeq4weK4QPFdCz5UGz5aC5yroucrguUrwXA09Vxs8Wwmea6DnGoPnGsFzLfRca/BsLXiug57rDJ7rBM/foOdvBs8PBM/10HO9wXO94Pk79Pzd4NlG8NwAPTcYPDcInn9Azz8MnoHguRF6bjR4bhQ8/4Sefxo82wqem6DnJoPnJsHzL+j5l8GzneC5GXpuNnhuFjz/hp5/GzzbC55boOcWg+cWwfMf6PmPwbOD4LkVem41eG4VPP+Fnv8aPDsKntug5zaD5zbBczv03G7w7CR47oCeOwyeOwTPndBzp8Gzs+C5C3ruMnjuEjx3Q8/dBs8uguce6LnH4LlH8NwLPfcaPLsKnvug5z6D5z7Bcz/03G/w7CZ4HoCeBwyeBwTPg9DzoMGzu+B5CHoeMngeEjwPQ8/DBs8egucR6HnE4HlE8DwKPY8aPHsKnseg5zGD5zHB8zj0PG7w7CV4noCeJwyeJwTPk9DzpMGzt+B5CnqeMnieEjxPQ8/TBs8+gucZ6HnG4HlG8DwLPc8aPPsKnueg5zmD5znB8zz0PG/w7Cd4XoCeFwyeFwTPi9DzosGzv+B5CXpeMnheEjwvQ8/LBs8PBc8r0POKwfOK4HkVel41eA4QPK9Bz2sGz2uC53Xoed3g+ZHgeQN63jB43hA8b0LPmwbPgYLnLeh5y+B5S/C8DT1vGzw/FjzvQM87Bs87gudd6HnX4DlI8LwHPe8ZPO8Jnveh532D5yeC5wPo+cDg+UDwfAg9Hxo8Bwuej6DnI4PnI8HzMfR8bPD8VPB8Aj2fGDyfCJ5PoedTg+cQwfMZ9Hxm8HwmeD6Hns8Nnp8Jni+g5wuD5wvB8yX0fGnwHCp4voKerwyerwTP19DztcHzc8HzDfR8Y/B8I3i+hZ5vDZ7DBM930POdwfOd4PleR+b537tQPb8QPCN0ZJ4ROobuGbYd3jYi9Ixo8BwueEaCnpEMnpEEz8jQM7LB80vBMwr0jGLwjCJ4RoWeUQ2eIwTPaNAzmsEzmuAZHXpGN3h+JXjGgJ4xDJ4xBM+Y0DOmwXOk4BkLesYyeMYSPGNDz9gGz68FzzjQM47BM47gGRd6xjV4jhI840HPeAbPeIJnfOgZ3+D5jeCZAHomMHgmEDwTQs+EBs/Rgmci6JnI4JlI8EwMPRMbPL8VPJNAzyQGzySCZ1LomdTgOUbwTAY9kxk8kwmeyaFncoPnd4JnCuiZwuCZQvBMCT1TGjzHCp6poGcqg2cqwTM19Ext8Pxe8EwDPdMYPNMInmmhZ1qD5zjBMx30TGfwTCd4poee6Q2ePwieGaBnBoNnBsEzI/TMaPAcL3hmgp6ZDJ6ZBM/M0DOzwfNHwTML9Mxi8MwieGaFnlkNnhMEz2zQM5vBM5vgmR16Zjd4/iR45oCeOQyeOQTPnNAzp8FzouCZC3rmMnjmEjxzQ8/cBs+fBc880DOPwTOP4JkXeuY1eE4SPPNBz3wGz3yCZ37omd/g+YvgWQB6FjB4FhA8C0LPggbPyYJnIehZyOBZSPAsDD0LGzx/FTyLQM8iBs8igmdR6FnU4DlF8CwGPYsZPIsJnsWhZ3GD51TBswT0LGHwLCF4loSeJQ2e0wTPUtCzlMGzlOBZGnqWNnhOFzzLQM8yBs8ygmdZ6FnW4DlD8CwHPcsZPMsJnuWhZ3mD50zBswL0rGDwrCB4VoSeFQ2eswTPStCzksGzkuBZGXpWNnjOFjyrQM8qBs8qgmdV6FnV4DlH8KwGPasZPKsJntWhZ3WD51zBswb0rGHwrCF41oSeNQ2e8wTPWtCzlsGzluBZG3rWNnjOFzzrQM86Bs86gmdd6FnX4LlA8KwHPesZPOsJnvWhZ32D50LBswH0bGDwbCB4NoSeDQ2eiwTPRtCzkcGzkeDZGHo2NnguFjybQM8mBs8mgmdT6NnU4LlE8GwGPZsZPJsJns2hZ3OD51LBswX0bGHwbCF4vg893zd4LhM8W0LPlgbPloJnK+jZyuC5XPBsDT1bGzxbC54fQM8PDJ4rBM820LONwbON4BlAz8DguVLwbAs92xo82wqe7aBnO4PnKsGzPfRsb/BsL3h2gJ4dDJ6rBc+O0LOjwbOj4NkJenYyeK4RPDtDz84Gz86CZxfo2cXguVbw7Ao9uxo8uwqe3aBnN4PnOsGzO/TsbvDsLnj2gJ49DJ6/CZ49oWdPg2dPwbMX9Oxl8FwvePaGnr0Nnr0Fzz7Qs4/B83fBsy/07Gvw7Ct49oOe/QyeGwTP/tCzv8Gzv+D5IfT80OD5h+A5AHoOMHgOEDw/gp4fGTw3Cp4DoedAg+dAwfNj6PmxwfNPwXMQ9Bxk8BwkeH4CPT8xeG4SPAdDz8EGz8GC56fQ81OD51+C5xDoOcTgOUTw/Ax6fmbw3Cx4DoWeQw2eQwXPz6Hn5wbPvwXPYdBzmMFzmOD5BfT8wuC5RfAcDj2HGzyHC55fQs8vDZ7/CJ4joOcIg+cIwfMr6PmVwXOr4DkSeo40eI4UPL+Gnl8bPP8VPEdBz1EGz1GC5zfQ8xuD5zbBczT0HG3wHC14fgs9vzV4bhc8x0DPMQbPMYLnd9DzO4PnDsFzLPQca/AcK3h+Dz2/N3juFDzHQc9xBs9xgucP0PMHg+cuwXM89Bxv8BwveP4IPX80eO4WPCdAzwkGzwmC50/Q8yeD5x7BcyL0nGjwnCh4/gw9fzZ47hU8J0HPSQbPSYLnL9DzF4PnPsFzMvScbPCcLHj+Cj1/NXjuFzynQM8pBs8pgudU6DnV4HlA8JwGPacZPKcJntOh53SD50HBcwb0nGHwnCF4zoSeMw2ehwTPWdBzlsFzluA5G3rONngeFjznQM85Bs85gudc6DnX4HlE8JwHPecZPOcJnvOh53yD51HBcwH0XGDwXCB4LoSeCw2exwTPRdBzkcFzkeC5GHouNngeFzyXQM8lBs8lgudS6LnU4HlC8FwGPZcZPJcJnsuh53KD50nBcwX0XGHwXCF4roSeKw2epwTPVdBzlcFzleC5GnquNnieFjzXQM81Bs81guda6LnW4HlG8FwHPdcZPNcJnr9Bz98MnmcFz/XQc73Bc73g+Tv0/N3geU7w3AA9Nxg8Nwief0DPPwye5wXPjdBzo8Fzo+D5J/T80+B5QfDcBD03GTw3CZ5/Qc+/DJ4XBc/N0HOzwXOz4Pk39Pzb4HlJ8NwCPbcYPLcInv9Az38MnpcFz63Qc6vBc6vg+S/0/NfgeUXw3AY9txk8twme26HndoPnVcFzB/TcYfDcIXjuhJ47DZ7XBM9d0HOXwXOX4Lkbeu42eF4XPPdAzz0Gzz2C517oudfgeUPw3Ac99xk89wme+6HnfoPnTcHzAPQ8YPA8IHgehJ4HDZ63BM9D0POQwfOQ4HkYeh42eN4WPI9AzyMGzyOC51HoedTgeUfwPAY9jxk8jwmex6HncYPnXcHzBPQ8YfA8IXiehJ4nDZ73BM9T0POUwfOU4Hkaep42eN4XPM9AzzMGzzOC51noedbg+UDwPAc9zxk8zwme56HneYPnQ8HzAvS8YPC8IHhehJ4XDZ6PBM9L0POSwfOS4HkZel42eD4WPK9AzysGzyuC51XoedXg+UTwvAY9rxk8rwme16HndYPnU8HzBvS8YfC8IXjehJ43DZ7PBM9b0POWwfOW4Hkbet42eD4XPO9AzzsGzzuC513oedfg+ULwvAc97xk87wme96HnfYPnS8HzAfR8YPB8IHg+hJ4PDZ6vBM9H0PORwfOR4PkYej42eL4WPJ9AzycGzyeC51Po+dTg+UbwfAY9nxk8nwmez6Hnc4PnW8HzBfR8YfB8IXi+hJ4vDZ7vBM9X0POVwfOV4Pkaer42eL5X5H+/8w30fGPwfCN4voWebw2eEQTPd9DzncHzneD5Xifm+d+7UD0jCp4ROjHPCJ1C9wzbDm8bEXpGNHhGEjwjQc9IBs9Igmdk6BnZ4BlZ8IwCPaMYPKMInlGhZ1SDZxTBMxr0jGbwjCZ4Roee0Q2eUQXPGNAzhsEzhuAZE3rGNHhGEzxjQc9YBs9Ygmds6Bnb4Bld8IwDPeMYPOMInnGhZ1yDZwzBMx70jGfwjCd4xoee8Q2eMQXPBNAzgcEzgeCZEHomNHjGEjwTQc9EBs9Egmdi6JnY4Blb8EwCPZMYPJMInkmhZ1KDZxzBMxn0TGbwTCZ4JoeeyQ2ecQXPFNAzhcEzheCZEnqmNHjGEzxTQc9UBs9Ugmdq6Jna4Blf8EwDPdMYPNMInmmhZ1qDZwLBMx30TGfwTCd4poee6Q2eCQXPDNAzg8Ezg+CZEXpmNHgmEjwzQc9MBs9Mgmdm6JnZ4JlY8MwCPbMYPLMInlmhZ1aDZxLBMxv0zGbwzCZ4Zoee2Q2eSQXPHNAzh8Ezh+CZE3rmNHgmEzxzQc9cBs9cgmdu6Jnb4Jlc8MwDPfMYPPMInnmhZ16DZwrBMx/0zGfwzCd45oee+Q2eKQXPAtCzgMGzgOBZEHoWNHimEjwLQc9CBs9Cgmdh6FnY4Jla8CwCPYsYPIsInkWhZ1GDZxrBsxj0LGbwLCZ4FoeexQ2eaQXPEtCzhMGzhOBZEnqWNHimEzxLQc9SBs9Sgmdp6Fna4Jle8CwDPcsYPMsInmWhZ1mDZwbBsxz0LGfwLCd4loee5Q2eGQXPCtCzgsGzguBZEXpWNHhmEjwrQc9KBs9Kgmdl6FnZ4JlZ8KwCPasYPKsInlWhZ1WDZxbBsxr0rGbwrCZ4Voee1Q2eWQXPGtCzhsGzhuBZE3rWNHhmEzxrQc9aBs9agmdt6Fnb4Jld8KwDPesYPOsInnWhZ12DZw7Bsx70rGfwrCd41oee9Q2eOQXPBtCzgcGzgeDZEHo2NHjmEjwbQc9GBs9Ggmdj6NnY4Jlb8GwCPZsYPJsInk2hZ1ODZx7Bsxn0bGbwbCZ4NoeezQ2eeQXPFtCzhcGzheD5PvR83+CZT/BsCT1bGjxbCp6toGcrg2d+wbM19Gxt8GwteH4APT8weBYQPNtAzzYGzzaCZwA9A4NnQcGzLfRsa/BsK3i2g57tDJ6FBM/20LO9wbO94NkBenYweBYWPDtCz44Gz46CZyfo2cngWUTw7Aw9Oxs8OwueXaBnF4NnUcGzK/TsavDsKnh2g57dDJ7FBM/u0LO7wbO74NkDevYweBYXPHtCz54Gz56CZy/o2cvgWULw7A09exs8ewuefaBnH4NnScGzL/Tsa/DsK3j2g579DJ6lBM/+0LO/wbO/4Pkh9PzQ4Fla8BwAPQcYPAcInh9Bz48MnmUEz4HQc6DBc6Dg+TH0/NjgWVbwHAQ9Bxk8Bwmen0DPTwye5QTPwdBzsMFzsOD5KfT81OBZXvAcAj2HGDyHCJ6fQc/PDJ4VBM+h0HOowXOo4Pk59Pzc4FlR8BwGPYcZPIcJnl9Azy8MnpUEz+HQc7jBc7jg+SX0/NLgWVnwHAE9Rxg8RwieX0HPrwyeVQTPkdBzpMFzpOD5NfT82uBZVfAcBT1HGTxHCZ7fQM9vDJ7VBM/R0HO0wXO04Pkt9PzW4Fld8BwDPccYPMcInt9Bz+8MnjUEz7HQc6zBc6zg+T30/N7gWVPwHAc9xxk8xwmeP0DPHwyetQTP8dBzvMFzvOD5I/T80eBZW/CcAD0nGDwnCJ4/Qc+fDJ51BM+J0HOiwXOi4Pkz9PzZ4FlX8JwEPScZPCcJnr9Az18MnvUEz8nQc7LBc7Lg+Sv0/NXgWV/wnAI9pxg8pwieU6HnVINnA8FzGvScZvCcJnhOh57TDZ4NBc8Z0HOGwXOG4DkTes40eDYSPGdBz1kGz1mC52zoOdvg2VjwnAM95xg85wiec6HnXINnE8FzHvScZ/CcJ3jOh57zDZ5NBc8F0HOBwXOB4LkQei40eDYTPBdBz0UGz0WC52Loudjg2VzwXAI9lxg8lwieS6HnUoNnC8FzGfRcZvBcJnguh57LDZ7vC54roOcKg+cKwXMl9Fxp8GwpeK6CnqsMnqsEz9XQc7XBs5XguQZ6rjF4rhE810LPtQbP1oLnOui5zuC5TvD8DXr+ZvD8QPBcDz3XGzzXC56/Q8/fDZ5tBM8N0HODwXOD4PkH9PzD4BkInhuh50aD50bB80/o+afBs63guQl6bjJ4bhI8/4Kefxk82wmem6HnZoPnZsHzb+j5t8GzveC5BXpuMXhuETz/gZ7/GDw7CJ5boedWg+dWwfNf6PmvwbOj4LkNem4zeG4TPLdDz+0Gz06C5w7oucPguUPw3Ak9dxo8Owueu6DnLoPnLsFzN/TcbfDsInjugZ57DJ57BM+90HOvwbOr4LkPeu4zeO4TPPdDz/0Gz26C5wHoecDgeUDwPAg9Dxo8uwueh6DnIYPnIcHzMPQ8bPDsIXgegZ5HDJ5HBM+j0POowbOn4HkMeh4zeB4TPI9Dz+MGz16C5wnoecLgeULwPAk9Txo8ewuep6DnKYPnKcHzNPQ8bfDsI3iegZ5nDJ5nBM+z0POswbOv4HkOep4zeJ4TPM9Dz/MGz36C5wXoecHgeUHwvAg9Lxo8+wuel6DnJYPnJcHzMvS8bPD8UPC8Aj2vGDyvCJ5XoedVg+cAwfMa9Lxm8LwmeF6HntcNnh8Jnjeg5w2D5w3B8yb0vGnwHCh43oKetwyetwTP29DztsHzY8HzDvS8Y/C8I3jehZ53DZ6DBM970POewfOe4Hkfet43eH4ieD6Ang8Mng8Ez4fQ86HBc7Dg+Qh6PjJ4PhI8H0PPxwbPTwXPJ9DzicHzieD5FHo+NXgOETyfQc9nBs9ngudz6Pnc4PmZ4PkCer4weL4QPF9Cz5cGz6GC5yvo+crg+UrwfA09Xxs8Pxc830DPNwbPN4LnW+j51uA5TPB8Bz3fGTzfCZ7vdWae/70L1fMLwTNCZ+YZoXPonmHb4W0jQs+IBs/hgmck6BnJ4BlJ8IwMPSMbPL8UPKNAzygGzyiCZ1ToGdXgOULwjAY9oxk8owme0aFndIPnV4JnDOgZw+AZQ/CMCT1jGjxHCp6xoGcsg2cswTM29Ixt8Pxa8IwDPeMYPOMInnGhZ1yD5yjBMx70jGfwjCd4xoee8Q2e3wieCaBnAoNnAsEzIfRMaPAcLXgmgp6JDJ6JBM/E0DOxwfNbwTMJ9Exi8EwieCaFnkkNnmMEz2TQM5nBM5ngmRx6Jjd4fid4poCeKQyeKQTPlNAzpcFzrOCZCnqmMnimEjxTQ8/UBs/vBc800DONwTON4JkWeqY1eI4TPNNBz3QGz3SCZ3romd7g+YPgmQF6ZjB4ZhA8M0LPjAbP8YJnJuiZyeCZSfDMDD0zGzx/FDyzQM8sBs8sgmdW6JnV4DlB8MwGPbMZPLMJntmhZ3aD50+CZw7omcPgmUPwzAk9cxo8JwqeuaBnLoNnLsEzN/TMbfD8WfDMAz3zGDzzCJ55oWdeg+ckwTMf9Mxn8MwneOaHnvkNnr8IngWgZwGDZwHBsyD0LGjwnCx4FoKehQyehQTPwtCzsMHzV8GzCPQsYvAsIngWhZ5FDZ5TBM9i0LOYwbOY4FkcehY3eE4VPEtAzxIGzxKCZ0noWdLgOU3wLAU9Sxk8SwmepaFnaYPndMGzDPQsY/AsI3iWhZ5lDZ4zBM9y0LOcwbOc4FkeepY3eM4UPCtAzwoGzwqCZ0XoWdHgOUvwrAQ9Kxk8KwmelaFnZYPnbMGzCvSsYvCsInhWhZ5VDZ5zBM9q0LOawbOa4FkdelY3eM4VPGtAzxoGzxqCZ03oWdPgOU/wrAU9axk8awmetaFnbYPnfMGzDvSsY/CsI3jWhZ51DZ4LBM960LOewbOe4FkfetY3eC4UPBtAzwYGzwaCZ0Po2dDguUjwbAQ9Gxk8GwmejaFnY4PnYsGzCfRsYvBsIng2hZ5NDZ5LBM9m0LOZwbOZ4NkcejY3eC4VPFtAzxYGzxaC5/vQ832D5zLBsyX0bGnwbCl4toKerQyeywXP1tCztcGzteD5AfT8wOC5QvBsAz3bGDzbCJ4B9AwMnisFz7bQs63Bs63g2Q56tjN4rhI820PP9gbP9oJnB+jZweC5WvDsCD07Gjw7Cp6doGcng+cawbMz9Oxs8OwseHaBnl0MnmsFz67Qs6vBs6vg2Q16djN4rhM8u0PP7gbP7oJnD+jZw+D5m+DZE3r2NHj2FDx7Qc9eBs/1gmdv6Nnb4Nlb8OwDPfsYPH8XPPtCz74Gz76CZz/o2c/guUHw7A89+xs8+wueH0LPDw2efwieA6DnAIPnAMHzI+j5kcFzo+A5EHoONHgOFDw/hp4fGzz/FDwHQc9BBs9Bgucn0PMTg+cmwXMw9Bxs8BwseH4KPT81eP4leA6BnkMMnkMEz8+g52cGz82C51DoOdTgOVTw/Bx6fm7w/FvwHAY9hxk8hwmeX0DPLwyeWwTP4dBzuMFzuOD5JfT80uD5j+A5AnqOMHiOEDy/gp5fGTy3Cp4joedIg+dIwfNr6Pm1wfNfwXMU9Bxl8BwleH4DPb8xeG4TPEdDz9EGz9GC57fQ81uD53bBcwz0HGPwHCN4fgc9vzN47hA8x0LPsQbPsYLn99Dze4PnTsFzHPQcZ/AcJ3j+AD1/MHjuEjzHQ8/xBs/xgueP0PNHg+duwXMC9Jxg8JwgeP4EPX8yeO4RPCdCz4kGz4mC58/Q82eD517BcxL0nGTwnCR4/gI9fzF47hM8J0PPyQbPyYLnr9DzV4PnfsFzCvScYvCcInhOhZ5TDZ4HBM9p0HOawXOa4Dkdek43eB4UPGdAzxkGzxmC50zoOdPgeUjwnAU9Zxk8Zwmes6HnbIPnYcFzDvScY/CcI3jOhZ5zDZ5HBM950HOewXOe4Dkfes43eB4VPBdAzwUGzwWC50LoudDgeUzwXAQ9Fxk8Fwmei6HnYoPnccFzCfRcYvBcInguhZ5LDZ4nBM9l0HOZwXOZ4Lkcei43eJ4UPFdAzxUGzxWC50roudLgeUrwXAU9Vxk8Vwmeq6HnaoPnacFzDfRcY/BcI3iuhZ5rDZ5nBM910HOdwXOd4Pkb9PzN4HlW8FwPPdcbPNcLnr9Dz98NnucEzw3Qc4PBc4Pg+Qf0/MPgeV7w3Ag9Nxo8Nwqef0LPPw2eFwTPTdBzk8Fzk+D5F/T8y+B5UfDcDD03Gzw3C55/Q8+/DZ6XBM8t0HOLwXOL4PkP9PzH4HlZ8NwKPbcaPLcKnv9Cz38NnlcEz23Qc5vBc5vguR16bjd4XhU8d0DPHQbPHYLnTui50+B5TfDcBT13GTx3CZ67oedug+d1wXMP9Nxj8NwjeO6FnnsNnjcEz33Qc5/Bc5/guR967jd43hQ8D0DPAwbPA4LnQeh50OB5S/A8BD0PGTwPCZ6Hoedhg+dtwfMI9Dxi8DwieB6FnkcNnncEz2PQ85jB85jgeRx6Hjd43hU8T0DPEwbPE4LnSeh50uB5T/A8BT1PGTxPCZ6noedpg+d9wfMM9Dxj8DwjeJ6FnmcNng8Ez3PQ85zB85zgeR56njd4PhQ8L0DPCwbPC4LnReh50eD5SPC8BD0vGTwvCZ6Xoedlg+djwfMK9Lxi8LwieF6FnlcNnk8Ez2vQ85rB85rgeR16Xjd4PhU8b0DPGwbPG4LnTeh50+D5TPC8BT1vGTxvCZ63oedtg+dzwfMO9Lxj8LwjeN6FnncNni8Ez3vQ857B857geR963jd4Roj4v9/54H/1fJv+/935wOD5QPB8+L96vi7//+58aPCMKHg+gp6PDJ6PBM/H0POxwTOS4PkEej4xeD4RPJ9Cz6cGz8iC5zPo+czg+UzwfA49nxs8owieL6DnC4PnC8HzJfR8afCMKni+gp6vDJ6vBM/X0PO1wTOa4PkGer4xeL4RPN9Cz7cGz+iC5zvo+c7g+U7wfK8L8/zvXaieMQTPCF2YZ4QuoXuGbYe3jQg9Ixo8YwqekaBnJINnJMEzMvSMbPCMJXhGgZ5RDJ5RBM+o0DOqwTO24BkNekYzeEYTPKNDz+gGzziCZwzoGcPgGUPwjAk9Yxo84wqesaBnLINnLMEzNvSMbfCMJ3jGgZ5xDJ5xBM+40DOuwTO+4BkPesYzeMYTPONDz/gGzwSCZwLomcDgmUDwTAg9Exo8EwqeiaBnIoNnIsEzMfRMbPBMJHgmgZ5JDJ5JBM+k0DOpwTOx4JkMeiYzeCYTPJNDz+QGzySCZwromcLgmULwTAk9Uxo8kwqeqaBnKoNnKsEzNfRMbfBMJnimgZ5pDJ5pBM+00DOtwTO54JkOeqYzeKYTPNNDz/QGzxSCZwbomcHgmUHwzAg9Mxo8UwqemaBnJoNnJsEzM/TMbPBMJXhmgZ5ZDJ5ZBM+s0DOrwTO14JkNemYzeGYTPLNDz+wGzzSCZw7omcPgmUPwzAk9cxo80wqeuaBnLoNnLsEzN/TMbfBMJ3jmgZ55DJ55BM+80DOvwTO94JkPeuYzeOYTPPNDz/wGzwyCZwHoWcDgWUDwLAg9Cxo8MwqehaBnIYNnIcGzMPQsbPDMJHgWgZ5FDJ5FBM+i0LOowTOz4FkMehYzeBYTPItDz+IGzyyCZwnoWcLgWULwLAk9Sxo8swqepaBnKYNnKcGzNPQsbfDMJniWgZ5lDJ5lBM+y0LOswTO74FkOepYzeJYTPMtDz/IGzxyCZwXoWcHgWUHwrAg9Kxo8cwqelaBnJYNnJcGzMvSsbPDMJXhWgZ5VDJ5VBM+q0LOqwTO34FkNelYzeFYTPKtDz+oGzzyCZw3oWcPgWUPwrAk9axo88wqetaBnLYNnLcGzNvSsbfDMJ3jWgZ51DJ51BM+60LOuwTO/4FkPetYzeNYTPOtDz/oGzwKCZwPo2cDg2UDwbAg9Gxo8CwqejaBnI4NnI8GzMfRsbPAsJHg2gZ5NDJ5NBM+m0LOpwbOw4NkMejYzeDYTPJtDz+YGzyKCZwvo2cLg2ULwfB96vm/wLCp4toSeLQ2eLQXPVtCzlcGzmODZGnq2Nni2Fjw/gJ4fGDyLC55toGcbg2cbwTOAnoHBs4Tg2RZ6tjV4thU820HPdgbPkoJne+jZ3uDZXvDsAD07GDxLCZ4doWdHg2dHwbMT9Oxk8CwteHaGnp0Nnp0Fzy7Qs4vBs4zg2RV6djV4dhU8u0HPbgbPsoJnd+jZ3eDZXfDsAT17GDzLCZ49oWdPg2dPwbMX9Oxl8CwvePaGnr0Nnr0Fzz7Qs4/Bs4Lg2Rd69jV49hU8+0HPfgbPioJnf+jZ3+DZX/D8EHp+aPCsJHgOgJ4DDJ4DBM+PoOdHBs/KgudA6DnQ4DlQ8PwYen5s8KwieA6CnoMMnoMEz0+g5ycGz6qC52DoOdjgOVjw/BR6fmrwrCZ4DoGeQwyeQwTPz6DnZwbP6oLnUOg51OA5VPD8HHp+bvCsIXgOg57DDJ7DBM8voOcXBs+agudw6Dnc4Dlc8PwSen5p8KwleI6AniMMniMEz6+g51cGz9qC50joOdLgOVLw/Bp6fm3wrCN4joKeowyeowTPb6DnNwbPuoLnaOg52uA5WvD8Fnp+a/CsJ3iOgZ5jDJ5jBM/voOd3Bs/6gudY6DnW4DlW8Pween5v8GwgeI6DnuMMnuMEzx+g5w8Gz4aC53joOd7gOV7w/BF6/mjwbCR4ToCeEwyeEwTPn6DnTwbPxoLnROg50eA5UfD8GXr+bPBsInhOgp6TDJ6TBM9foOcvBs+mgudk6DnZ4DlZ8PwVev5q8GwmeE6BnlMMnlMEz6nQc6rBs7ngOQ16TjN4ThM8p0PP6QbPFoLnDOg5w+A5Q/CcCT1nGjzfFzxnQc9ZBs9Zguds6Dnb4NlS8JwDPecYPOcInnOh51yDZyvBcx70nGfwnCd4zoee8w2erQXPBdBzgcFzgeC5EHouNHh+IHgugp6LDJ6LBM/F0HOxwbON4LkEei4xeC4RPJdCz6UGz0DwXAY9lxk8lwmey6HncoNnW8FzBfRcYfBcIXiuhJ4rDZ7tBM9V0HOVwXOV4Lkaeq42eLYXPNdAzzUGzzWC51roudbg2UHwXAc91xk81wmev0HP3wyeHQXP9dBzvcFzveD5O/T83eDZSfDcAD03GDw3CJ5/QM8/DJ6dBc+N0HOjwXOj4Pkn9PzT4NlF8NwEPTcZPDcJnn9Bz78Mnl0Fz83Qc7PBc7Pg+Tf0/Nvg2U3w3AI9txg8twie/0DPfwye3QXPrdBzq8Fzq+D5L/T81+DZQ/DcBj23GTy3CZ7boed2g2dPwXMH9Nxh8NwheO6EnjsNnr0Ez13Qc5fBc5fguRt67jZ49hY890DPPQbPPYLnXui51+DZR/DcBz33GTz3CZ77oed+g2dfwfMA9Dxg8DwgeB6EngcNnv0Ez0PQ85DB85DgeRh6HjZ49hc8j0DPIwbPI4LnUeh51OD5oeB5DHoeM3geEzyPQ8/jBs8BgucJ6HnC4HlC8DwJPU8aPD8SPE9Bz1MGz1OC52noedrgOVDwPAM9zxg8zwieZ6HnWYPnx4LnOeh5zuB5TvA8Dz3PGzwHCZ4XoOcFg+cFwfMi9Lxo8PxE8LwEPS8ZPC8Jnpeh52WD52DB8wr0vGLwvCJ4XoWeVw2enwqe16DnNYPnNcHzOvS8bvAcInjegJ43DJ43BM+b0POmwfMzwfMW9Lxl8LwleN6GnrcNnkMFzzvQ847B847geRd63jV4fi543oOe9wye9wTP+9DzvsFzmOD5AHo+MHg+EDwfQs+HBs8vBM9H0PORwfOR4PkYej42eA4XPJ9AzycGzyeC51Po+dTg+aXg+Qx6PjN4PhM8n0PP5wbPEYLnC+j5wuD5QvB8CT1fGjy/EjxfQc9XBs9Xgudr6Pna4DlS8HwDPd8YPN8Inm+h51uD59eC5zvo+c7g+U7wfK8r8/zvXaieowTPCF2ZZ4SuoXuGbYe3jQg9Ixo8vxE8I0HPSAbPSIJnZOgZ2eA5WvCMAj2jGDyjCJ5RoWdUg+e3gmc06BnN4BlN8IwOPaMbPMcInjGgZwyDZwzBMyb0jGnw/E7wjAU9Yxk8YwmesaFnbIPnWMEzDvSMY/CMI3jGhZ5xDZ7fC57xoGc8g2c8wTM+9Ixv8BwneCaAngkMngkEz4TQM6HB8wfBMxH0TGTwTCR4JoaeiQ2e4wXPJNAzicEzieCZFHomNXj+KHgmg57JDJ7JBM/k0DO5wXOC4JkCeqYweKYQPFNCz5QGz58Ez1TQM5XBM5XgmRp6pjZ4ThQ800DPNAbPNIJnWuiZ1uD5s+CZDnqmM3imEzzTQ8/0Bs9JgmcG6JnB4JlB8MwIPTMaPH8RPDNBz0wGz0yCZ2bomdngOVnwzAI9sxg8swieWaFnVoPnr4JnNuiZzeCZTfDMDj2zGzynCJ45oGcOg2cOwTMn9Mxp8JwqeOaCnrkMnrkEz9zQM7fBc5rgmQd65jF45hE880LPvAbP6YJnPuiZz+CZT/DMDz3zGzxnCJ4FoGcBg2cBwbMg9Cxo8JwpeBaCnoUMnoUEz8LQs7DBc5bgWQR6FjF4FhE8i0LPogbP2YJnMehZzOBZTPAsDj2LGzznCJ4loGcJg2cJwbMk9Cxp8JwreJaCnqUMnqUEz9LQs7TBc57gWQZ6ljF4lhE8y0LPsgbP+YJnOehZzuBZTvAsDz3LGzwXCJ4VoGcFg2cFwbMi9Kxo8FwoeFaCnpUMnpUEz8rQs7LBc5HgWQV6VjF4VhE8q0LPqgbPxYJnNehZzeBZTfCsDj2rGzyXCJ41oGcNg2cNwbMm9Kxp8FwqeNaCnrUMnrUEz9rQs7bBc5ngWQd61jF41hE860LPugbP5YJnPehZz+BZT/CsDz3rGzxXCJ4NoGcDg2cDwbMh9Gxo8FwpeDaCno0Mno0Ez8bQs7HBc5Xg2QR6NjF4NhE8m0LPpgbP1YJnM+jZzODZTPBsDj2bGzzXCJ4toGcLg2cLwfN96Pm+wXOt4NkSerY0eLYUPFtBz1YGz3WCZ2vo2drg2Vrw/AB6fmDw/E3wbAM92xg82wieAfQMDJ7rBc+20LOtwbOt4NkOerYzeP4ueLaHnu0Nnu0Fzw7Qs4PBc4Pg2RF6djR4dhQ8O0HPTgbPPwTPztCzs8Gzs+DZBXp2MXhuFDy7Qs+uBs+ugmc36NnN4Pmn4NkdenY3eHYXPHtAzx4Gz02CZ0/o2dPg2VPw7AU9exk8/xI8e0PP3gbP3oJnH+jZx+C5WfDsCz37Gjz7Cp79oGc/g+ffgmd/6Nnf4Nlf8PwQen5o8NwieA6AngMMngMEz4+g50cGz38Ez4HQc6DBc6Dg+TH0/NjguVXwHAQ9Bxk8Bwmen0DPTwye/wqeg6HnYIPnYMHzU+j5qcFzm+A5BHoOMXgOETw/g56fGTy3C55DoedQg+dQwfNz6Pm5wXOH4DkMeg4zeA4TPL+Anl8YPHcKnsOh53CD53DB80vo+aXBc5fgOQJ6jjB4jhA8v4KeXxk8dwueI6HnSIPnSMHza+j5tcFzj+A5CnqOMniOEjy/gZ7fGDz3Cp6joedog+dowfNb6PmtwXOf4DkGeo4xeI4RPL+Dnt8ZPPcLnmOh51iD51jB83vo+b3B84DgOQ56jjN4jhM8f4CePxg8Dwqe46HneIPneMHzR+j5o8HzkOA5AXpOMHhOEDx/gp4/GTwPC54ToedEg+dEwfNn6PmzwfOI4DkJek4yeE4SPH+Bnr8YPI8KnpOh52SD52TB81fo+avB85jgOQV6TjF4ThE8p0LPqQbP44LnNOg5zeA5TfCcDj2nGzxPCJ4zoOcMg+cMwXMm9Jxp8DwpeM6CnrMMnrMEz9nQc7bB85TgOQd6zjF4zhE850LPuQbP04LnPOg5z+A5T/CcDz3nGzzPCJ4LoOcCg+cCwXMh9Fxo8DwreC6CnosMnosEz8XQc7HB85zguQR6LjF4LhE8l0LPpQbP84LnMui5zOC5TPBcDj2XGzwvCJ4roOcKg+cKwXMl9Fxp8LwoeK6CnqsMnqsEz9XQc7XB85LguQZ6rjF4rhE810LPtQbPy4LnOui5zuC5TvD8DXr+ZvC8Iniuh57rDZ7rBc/foefvBs+rgucG6LnB4LlB8PwDev5h8LwmeG6EnhsNnhsFzz+h558Gz+uC5yboucnguUnw/At6/mXwvCF4boaemw2emwXPv6Hn3wbPm4LnFui5xeC5RfD8B3r+Y/C8JXhuhZ5bDZ5bBc9/oee/Bs/bguc26LnN4LlN8NwOPbcbPO8Injug5w6D5w7Bcyf03GnwvCt47oKeuwyeuwTP3dBzt8HznuC5B3ruMXjuETz3Qs+9Bs/7guc+6LnP4LlP8NwPPfcbPB8Ingeg5wGD5wHB8yD0PGjwfCh4HoKehwyehwTPw9DzsMHzkeB5BHoeMXgeETyPQs+jBs/Hgucx6HnM4HlM8DwOPY8bPJ8Inieg5wmD5wnB8yT0PGnwfCp4noKepwyepwTP09DztMHzmeB5BnqeMXieETzPQs+zBs/nguc56HnO4HlO8DwPPc8bPF8Inheg5wWD5wXB8yL0vGjwfCl4XoKelwyelwTPy9DzssHzleB5BXpeMXheETyvQs+rBs/Xguc16HnN4HlN8LwOPa8bPN8Injeg5w2D5w3B8yb0vGnwfCt43oKetwyetwTP29DztsHzneB5B3reMXjeETzvQs+7Bs//fpb+f7zzHvS8Z/C8J3jeh573DZ4RBM8H0POBwfOB4PkQej40eEYUPB9Bz0cGz0eC52Po+djgGUnwfAI9nxg8nwieT6HnU4NnZMHzGfR8ZvB8Jng+h57PDZ5RBM8X0POFwfOF4PkSer40eEYVPF9Bz1cGz1eC52vo+drgGU3wfAM93xg83wieb6HnW4NndMHzHfR8Z/B8J3i+1415/vcuVM8YgmeEbswzQrfQPcO2w9tGhJ4RDZ4xBc9I0DOSwTOS4BkZekY2eMYSPKNAzygGzyiCZ1ToGdXgGVvwjAY9oxk8owme0aFndINnHMEzBvSMYfCMIXjGhJ4xDZ5xBc9Y0DOWwTOW4BkbesY2eMYTPONAzzgGzziCZ1zoGdfgGV/wjAc94xk84wme8aFnfINnAsEzAfRMYPBMIHgmhJ4JDZ4JBc9E0DORwTOR4JkYeiY2eCYSPJNAzyQGzySCZ1LomdTgmVjwTAY9kxk8kwmeyaFncoNnEsEzBfRMYfBMIXimhJ4pDZ5JBc9U0DOVwTOV4JkaeqY2eCYTPNNAzzQGzzSCZ1romdbgmVzwTAc90xk80wme6aFneoNnCsEzA/TMYPDMIHhmhJ4ZDZ4pBc9M0DOTwTOT4JkZemY2eKYSPLNAzywGzyyCZ1bomdXgmVrwzAY9sxk8swme2aFndoNnGsEzB/TMYfDMIXjmhJ45DZ5pBc9c0DOXwTOX4JkbeuY2eKYTPPNAzzwGzzyCZ17omdfgmV7wzAc98xk88wme+aFnfoNnBsGzAPQsYPAsIHgWhJ4FDZ4ZBc9C0LOQwbOQ4FkYehY2eGYSPItAzyIGzyKCZ1HoWdTgmVnwLAY9ixk8iwmexaFncYNnFsGzBPQsYfAsIXiWhJ4lDZ5ZBc9S0LOUwbOU4FkaepY2eGYTPMtAzzIGzzKCZ1noWdbgmV3wLAc9yxk8ywme5aFneYNnDsGzAvSsYPCsIHhWhJ4VDZ45Bc9K0LOSwbOS4FkZelY2eOYSPKtAzyoGzyqCZ1XoWdXgmVvwrAY9qxk8qwme1aFndYNnHsGzBvSsYfCsIXjWhJ41DZ55Bc9a0LOWwbOW4FkbetY2eOYTPOtAzzoGzzqCZ13oWdfgmV/wrAc96xk86wme9aFnfYNnAcGzAfRsYPBsIHg2hJ4NDZ4FBc9G0LORwbOR4NkYejY2eBYSPJtAzyYGzyaCZ1Po2dTgWVjwbAY9mxk8mwmezaFnc4NnEcGzBfRsYfBsIXi+Dz3fN3gWFTxbQs+WBs+Wgmcr6NnK4FlM8GwNPVsbPFsLnh9Azw8MnsUFzzbQs43Bs43gGUDPwOBZQvBsCz3bGjzbCp7toGc7g2dJwbM99Gxv8GwveHaAnh0MnqUEz47Qs6PBs6Pg2Ql6djJ4lhY8O0PPzgbPzoJnF+jZxeBZRvDsCj27Gjy7Cp7doGc3g2dZwbM79Oxu8OwuePaAnj0MnuUEz57Qs6fBs6fg2Qt69jJ4lhc8e0PP3gbP3oJnH+jZx+BZQfDsCz37Gjz7Cp79oGc/g2dFwbM/9Oxv8OwveH4IPT80eFYSPAdAzwEGzwGC50fQ8yODZ2XBcyD0HGjwHCh4fgw9PzZ4VhE8B0HPQQbPQYLnJ9DzE4NnVcFzMPQcbPAcLHh+Cj0/NXhWEzyHQM8hBs8hgudn0PMzg2d1wXMo9Bxq8BwqeH4OPT83eNYQPIdBz2EGz2GC5xfQ8wuDZ03Bczj0HG7wHC54fgk9vzR41hI8R0DPEQbPEYLnV9DzK4NnbcFzJPQcafAcKXh+DT2/NnjWETxHQc9RBs9Rguc30PMbg2ddwXM09Bxt8BwteH4LPb81eNYTPMdAzzEGzzGC53fQ8zuDZ33Bcyz0HGvwHCt4fg89vzd4NhA8x0HPcQbPcYLnD9DzB4NnQ8FzPPQcb/AcL3j+CD1/NHg2EjwnQM8JBs8JgudP0PMng2djwXMi9Jxo8JwoeP4MPX82eDYRPCdBz0kGz0mC5y/Q8xeDZ1PBczL0nGzwnCx4/go9fzV4NhM8p0DPKQbPKYLnVOg51eDZXPCcBj2nGTynCZ7Toed0g2cLwXMG9Jxh8JwheM6EnjMNnu8LnrOg5yyD5yzBczb0nG3wbCl4zoGecwyecwTPudBzrsGzleA5D3rOM3jOEzznQ8/5Bs/WgucC6LnA4LlA8FwIPRcaPD8QPBdBz0UGz0WC52Loudjg2UbwXAI9lxg8lwieS6HnUoNnIHgug57LDJ7LBM/l0HO5wbOt4LkCeq4weK4QPFdCz5UGz3aC5yroucrguUrwXA09Vxs82wuea6DnGoPnGsFzLfRca/DsIHiug57rDJ7rBM/foOdvBs+Ogud66Lne4Lle8Pwdev5u8OwkeG6AnhsMnhsEzz+g5x8Gz86C50boudHguVHw/BN6/mnw7CJ4boKemwyemwTPv6DnXwbProLnZui52eC5WfD8G3r+bfDsJnhugZ5bDJ5bBM9/oOc/Bs/ugudW6LnV4LlV8PwXev5r8OwheG6DntsMntsEz+3Qc7vBs6fguQN67jB47hA8d0LPnQbPXoLnLui5y+C5S/DcDT13Gzx7C557oOceg+cewXMv9Nxr8OwjeO6DnvsMnvsEz/3Qc7/Bs6/geQB6HjB4HhA8D0LPgwbPfoLnIeh5yOB5SPA8DD0PGzz7C55HoOcRg+cRwfMo9Dxq8PxQ8DwGPY8ZPI8Jnseh53GD5wDB8wT0PGHwPCF4noSeJw2eHwmep6DnKYPnKcHzNPQ8bfAcKHiegZ5nDJ5nBM+z0POswfNjwfMc9Dxn8DwneJ6HnucNnoMEzwvQ84LB84LgeRF6XjR4fiJ4XoKelwyelwTPy9DzssFzsOB5BXpeMXheETyvQs+rBs9PBc9r0POawfOa4Hkdel43eA4RPG9AzxsGzxuC503oedPg+ZngeQt63jJ43hI8b0PP2wbPoYLnHeh5x+B5R/C8Cz3vGjw/FzzvQc97Bs97gud96Hnf4DlM8HwAPR8YPB8Ing+h50OD5xeC5yPo+cjg+UjwfAw9Hxs8hwueT6DnE4PnE8HzKfR8avD8UvB8Bj2fGTyfCZ7Poedzg+cIwfMF9Hxh8HwheL6Eni8Nnl8Jnq+g5yuD5yvB8zX0fG3wHCl4voGebwyebwTPt9DzrcHza8HzHfR8Z/B8J3i+1515/vcuVM9RgmeE7swzQvfQPcO2w9tGhJ4RDZ7fCJ6RoGckg2ckwTMy9Ixs8BwteEaBnlEMnlEEz6jQM6rB81vBMxr0jGbwjCZ4Roee0Q2eYwTPGNAzhsEzhuAZE3rGNHh+J3jGgp6xDJ6xBM/Y0DO2wXOs4BkHesYxeMYRPONCz7gGz+8Fz3jQM57BM57gGR96xjd4jhM8E0DPBAbPBIJnQuiZ0OD5g+CZCHomMngmEjwTQ8/EBs/xgmcS6JnE4JlE8EwKPZMaPH8UPJNBz2QGz2SCZ3LomdzgOUHwTAE9Uxg8UwieKaFnSoPnT4JnKuiZyuCZSvBMDT1TGzwnCp5poGcag2cawTMt9Exr8PxZ8EwHPdMZPNMJnumhZ3qD5yTBMwP0zGDwzCB4ZoSeGQ2evwiemaBnJoNnJsEzM/TMbPCcLHhmgZ5ZDJ5ZBM+s0DOrwfNXwTMb9Mxm8MwmeGaHntkNnlMEzxzQM4fBM4fgmRN65jR4ThU8c0HPXAbPXIJnbuiZ2+A5TfDMAz3zGDzzCJ55oWdeg+d0wTMf9Mxn8MwneOaHnvkNnjMEzwLQs4DBs4DgWRB6FjR4zhQ8C0HPQgbPQoJnYehZ2OA5S/AsAj2LGDyLCJ5FoWdRg+dswbMY9Cxm8CwmeBaHnsUNnnMEzxLQs4TBs4TgWRJ6ljR4zhU8S0HPUgbPUoJnaehZ2uA5T/AsAz3LGDzLCJ5loWdZg+d8wbMc9Cxn8CwneJaHnuUNngsEzwrQs4LBs4LgWRF6VjR4LhQ8K0HPSgbPSoJnZehZ2eC5SPCsAj2rGDyrCJ5VoWdVg+diwbMa9Kxm8KwmeFaHntUNnksEzxrQs4bBs4bgWRN61jR4LhU8a0HPWgbPWoJnbehZ2+C5TPCsAz3rGDzrCJ51oWddg+dywbMe9Kxn8KwneNaHnvUNnisEzwbQs4HBs4Hg2RB6NjR4rhQ8G0HPRgbPRoJnY+jZ2OC5SvBsAj2bGDybCJ5NoWdTg+dqwbMZ9Gxm8GwmeDaHns0NnmsEzxbQs4XBs4Xg+T70fN/guVbwbAk9Wxo8WwqeraBnK4PnOsGzNfRsbfBsLXh+AD0/MHj+Jni2gZ5tDJ5tBM8AegYGz/WCZ1vo2dbg2VbwbAc92xk8fxc820PP9gbP9oJnB+jZweC5QfDsCD07Gjw7Cp6doGcng+cfgmdn6NnZ4NlZ8OwCPbsYPDcKnl2hZ1eDZ1fBsxv07Gbw/FPw7A49uxs8uwuePaBnD4PnJsGzJ/TsafDsKXj2gp69DJ5/CZ69oWdvg2dvwbMP9Oxj8NwsePaFnn0Nnn0Fz37Qs5/B82/Bsz/07G/w7C94fgg9PzR4bhE8B0DPAQbPAYLnR9DzI4PnP4LnQOg50OA5UPD8GHp+bPDcKngOgp6DDJ6DBM9PoOcnBs9/Bc/B0HOwwXOw4Pkp9PzU4LlN8BwCPYcYPIcInp9Bz88MntsFz6HQc6jBc6jg+Tn0/NzguUPwHAY9hxk8hwmeX0DPLwyeOwXP4dBzuMFzuOD5JfT80uC5S/AcAT1HGDxHCJ5fQc+vDJ67Bc+R0HOkwXOk4Pk19Pza4LlH8BwFPUcZPEcJnt9Az28MnnsFz9HQc7TBc7Tg+S30/NbguU/wHAM9xxg8xwie30HP7wye+wXPsdBzrMFzrOD5PfT83uB5QPAcBz3HGTzHCZ4/QM8fDJ4HBc/x0HO8wXO84Pkj9PzR4HlI8JwAPScYPCcInj9Bz58MnocFz4nQc6LBc6Lg+TP0/NngeUTwnAQ9Jxk8Jwmev0DPXwyeRwXPydBzssFzsuD5K/T81eB5TPCcAj2nGDynCJ5ToedUg+dxwXMa9Jxm8JwmeE6HntMNnicEzxnQc4bBc4bgORN6zjR4nhQ8Z0HPWQbPWYLnbOg52+B5SvCcAz3nGDznCJ5zoedcg+dpwXMe9Jxn8JwneM6HnvMNnmcEzwXQc4HBc4HguRB6LjR4nhU8F0HPRQbPRYLnYui52OB5TvBcAj2XGDyXCJ5LoedSg+d5wXMZ9Fxm8FwmeC6HnssNnhcEzxXQc4XBc4XguRJ6rjR4XhQ8V0HPVQbPVYLnaui52uB5SfBcAz3XGDzXCJ5roedag+dlwXMd9Fxn8FwneP4GPX8zeF4RPNdDz/UGz/WC5+/Q83eD51XBcwP03GDw3CB4/gE9/zB4XhM8N0LPjQbPjYLnn9DzT4PndcFzE/TcZPDcJHj+BT3/MnjeEDw3Q8/NBs/Nguff0PNvg+dNwXML9Nxi8NwieP4DPf8xeN4SPLdCz60Gz62C57/Q81+D523Bcxv03Gbw3CZ4boee2w2edwTPHdBzh8Fzh+C5E3ruNHjeFTx3Qc9dBs9dgudu6Lnb4HlP8NwDPfcYPPcInnuh516D533Bcx/03Gfw3Cd47oee+w2eDwTPA9DzgMHzgOB5EHoeNHg+FDwPQc9DBs9Dgudh6HnY4PlI8DwCPY8YPI8Inkeh51GD52PB8xj0PGbwPCZ4Hoeexw2eTwTPE9DzhMHzhOB5EnqeNHg+FTxPQc9TBs9Tgudp6Hna4PlM8DwDPc8YPM8Inmeh51mD53PB8xz0PGfwPCd4noee5w2eLwTPC9DzgsHzguB5EXpeNHi+FDwvQc9LBs9Lgudl6HnZ4PlK8LwCPa8YPK8Inleh51WD52vB8xr0vGbwvCZ4Xoee1w2ebwTPG9DzhsHzhuB5E3reNHi+FTxvQc9bBs9bgudt6Hnb4PlO8LwDPe8YPO8Inneh512D53uR//c770HPewbPe4Lnfeh53+AZIer/fucD6PnA4PlA8HwIPR8aPCMKno+g5yOD5yPB8zH0fGzwjCR4PoGeTwyeTwTPp9DzqcEzsuD5DHo+M3g+EzyfQ8/nBs8ogucL6PnC4PlC8HwJPV8aPKMKnq+g5yuD5yvB8zX0fG3wjCZ4voGebwyebwTPt9DzrcEzuuD5Dnq+M3i+Ezzf68E8/3sXqmcMwTNCD+YZoUfonmHb4W0jQs+IBs+Ygmck6BnJ4BlJ8IwMPSMbPGMJnlGgZxSDZxTBMyr0jGrwjC14RoOe0Qye0QTP6NAzusEzjuAZA3rGMHjGEDxjQs+YBs+4gmcs6BnL4BlL8IwNPWMbPOMJnnGgZxyDZxzBMy70jGvwjC94xoOe8Qye8QTP+NAzvsEzgeCZAHomMHgmEDwTQs+EBs+Egmci6JnI4JlI8EwMPRMbPBMJnkmgZxKDZxLBMyn0TGrwTCx4JoOeyQyeyQTP5NAzucEzieCZAnqmMHimEDxTQs+UBs+kgmcq6JnK4JlK8EwNPVMbPJMJnmmgZxqDZxrBMy30TGvwTC54poOe6Qye6QTP9NAzvcEzheCZAXpmMHhmEDwzQs+MBs+Ugmcm6JnJ4JlJ8MwMPTMbPFMJnlmgZxaDZxbBMyv0zGrwTC14ZoOe2Qye2QTP7NAzu8EzjeCZA3rmMHjmEDxzQs+cBs+0gmcu6JnL4JlL8MwNPXMbPNMJnnmgZx6DZx7BMy/0zGvwTC945oOe+Qye+QTP/NAzv8Ezg+BZAHoWMHgWEDwLQs+CBs+Mgmch6FnI4FlI8CwMPQsbPDMJnkWgZxGDZxHBsyj0LGrwzCx4FoOexQyexQTP4tCzuMEzi+BZAnqWMHiWEDxLQs+SBs+sgmcp6FnK4FlK8CwNPUsbPLMJnmWgZxmDZxnBsyz0LGvwzC54loOe5Qye5QTP8tCzvMEzh+BZAXpWMHhWEDwrQs+KBs+cgmcl6FnJ4FlJ8KwMPSsbPHMJnlWgZxWDZxXBsyr0rGrwzC14VoOe1Qye1QTP6tCzusEzj+BZA3rWMHjWEDxrQs+aBs+8gmct6FnL4FlL8KwNPWsbPPMJnnWgZx2DZx3Bsy70rGvwzC941oOe9Qye9QTP+tCzvsGzgODZAHo2MHg2EDwbQs+GBs+Cgmcj6NnI4NlI8GwMPRsbPAsJnk2gZxODZxPBsyn0bGrwLCx4NoOezQyezQTP5tCzucGziODZAnq2MHi2EDzfh57vGzyLCp4toWdLg2dLwbMV9Gxl8CwmeLaGnq0Nnq0Fzw+g5wcGz+KCZxvo2cbg2UbwDKBnYPAsIXi2hZ5tDZ5tBc920LOdwbOk4NkeerY3eLYXPDtAzw4Gz1KCZ0fo2dHg2VHw7AQ9Oxk8SwuenaFnZ4NnZ8GzC/TsYvAsI3h2hZ5dDZ5dBc9u0LObwbOs4NkdenY3eHYXPHtAzx4Gz3KCZ0/o2dPg2VPw7AU9exk8ywuevaFnb4Nnb8GzD/TsY/CsIHj2hZ59DZ59Bc9+0LOfwbOi4NkfevY3ePYXPD+Enh8aPCsJngOg5wCD5wDB8yPo+ZHBs7LgORB6DjR4DhQ8P4aeHxs8qwieg6DnIIPnIMHzE+j5icGzquA5GHoONngOFjw/hZ6fGjyrCZ5DoOcQg+cQwfMz6PmZwbO64DkUeg41eA4VPD+Hnp8bPGsInsOg5zCD5zDB8wvo+YXBs6bgORx6Djd4Dhc8v4SeXxo8awmeI6DnCIPnCMHzK+j5lcGztuA5EnqONHiOFDy/hp5fGzzrCJ6joOcog+cowfMb6PmNwbOu4Dkaeo42eI4WPL+Fnt8aPOsJnmOg5xiD5xjB8zvo+Z3Bs77gORZ6jjV4jhU8v4ee3xs8Gwie46DnOIPnOMHzB+j5g8GzoeA5HnqON3iOFzx/hJ4/GjwbCZ4ToOcEg+cEwfMn6PmTwbOx4DkRek40eE4UPH+Gnj8bPJsInpOg5ySD5yTB8xfo+YvBs6ngORl6TjZ4ThY8f4Wevxo8mwmeU6DnFIPnFMFzKvScavBsLnhOg57TDJ7TBM/p0HO6wbOF4DkDes4weM4QPGdCz5kGz/cFz1nQc5bBc5bgORt6zjZ4thQ850DPOQbPOYLnXOg51+DZSvCcBz3nGTznCZ7zoed8g2drwXMB9Fxg8FwgeC6EngsNnh8Inoug5yKD5yLBczH0XGzwbCN4LoGeSwyeSwTPpdBzqcEzEDyXQc9lBs9lgudy6Lnc4NlW8FwBPVcYPFcIniuh50qDZzvBcxX0XGXwXCV4roaeqw2e7QXPNdBzjcFzjeC5FnquNXh2EDzXQc91Bs91gudv0PM3g2dHwXM99Fxv8FwveP4OPX83eHYSPDdAzw0Gzw2C5x/Q8w+DZ2fBcyP03Gjw3Ch4/gk9/zR4dhE8N0HPTQbPTYLnX9DzL4NnV8FzM/TcbPDcLHj+DT3/Nnh2Ezy3QM8tBs8tguc/0PMfg2d3wXMr9Nxq8NwqeP4LPf81ePYQPLdBz20Gz22C53boud3g2VPw3AE9dxg8dwieO6HnToNnL8FzF/TcZfDcJXjuhp67DZ69Bc890HOPwXOP4LkXeu41ePYRPPdBz30Gz32C537oud/g2VfwPAA9Dxg8DwieB6HnQYNnP8HzEPQ8ZPA8JHgehp6HDZ79Bc8j0POIwfOI4HkUeh41eH4oeB6DnscMnscEz+PQ87jBc4DgeQJ6njB4nhA8T0LPkwbPjwTPU9DzlMHzlOB5GnqeNngOFDzPQM8zBs8zgudZ6HnW4Pmx4HkOep4zeJ4TPM9Dz/MGz0GC5wXoecHgeUHwvAg9Lxo8PxE8L0HPSwbPS4LnZeh52eA5WPC8Aj2vGDyvCJ5XoedVg+enguc16HnN4HlN8LwOPa8bPIcInjeg5w2D5w3B8yb0vGnw/EzwvAU9bxk8bwmet6HnbYPnUMHzDvS8Y/C8I3jehZ53DZ6fC573oOc9g+c9wfM+9Lxv8BwmeD6Ang8Mng8Ez4fQ86HB8wvB8xH0fGTwfCR4Poaejw2ewwXPJ9DzicHzieD5FHo+NXh+KXg+g57PDJ7PBM/n0PO5wXOE4PkCer4weL4QPF9Cz5cGz68Ez1fQ85XB85Xg+Rp6vjZ4jhQ830DPNwbPN4LnW+j51uD5teD5Dnq+M3i+Ezzf68k8/3sXqucowTNCT+YZoWfonmHb4W0jQs+IBs9vBM9I0DOSwTOS4BkZekY2eI4WPKNAzygGzyiCZ1ToGdXg+a3gGQ16RjN4RhM8o0PP6AbPMYJnDOgZw+AZQ/CMCT1jGjy/EzxjQc9YBs9Ygmds6Bnb4DlW8IwDPeMYPOMInnGhZ1yD5/eCZzzoGc/gGU/wjA894xs8xwmeCaBnAoNnAsEzIfRMaPD8QfBMBD0TGTwTCZ6JoWdig+d4wTMJ9Exi8EwieCaFnkkNnj8KnsmgZzKDZzLBMzn0TG7wnCB4poCeKQyeKQTPlNAzpcHzJ8EzFfRMZfBMJXimhp6pDZ4TBc800DONwTON4JkWeqY1eP4seKaDnukMnukEz/TQM73Bc5LgmQF6ZjB4ZhA8M0LPjAbPXwTPTNAzk8Ezk+CZGXpmNnhOFjyzQM8sBs8sgmdW6JnV4Pmr4JkNemYzeGYTPLNDz+wGzymCZw7omcPgmUPwzAk9cxo8pwqeuaBnLoNnLsEzN/TMbfCcJnjmgZ55DJ55BM+80DOvwXO64JkPeuYzeOYTPPNDz/wGzxmCZwHoWcDgWUDwLAg9Cxo8ZwqehaBnIYNnIcGzMPQsbPCcJXgWgZ5FDJ5FBM+i0LOowXO24FkMehYzeBYTPItDz+IGzzmCZwnoWcLgWULwLAk9Sxo85wqepaBnKYNnKcGzNPQsbfCcJ3iWgZ5lDJ5lBM+y0LOswXO+4FkOepYzeJYTPMtDz/IGzwWCZwXoWcHgWUHwrAg9Kxo8FwqelaBnJYNnJcGzMvSsbPBcJHhWgZ5VDJ5VBM+q0LOqwXOx4FkNelYzeFYTPKtDz+oGzyWCZw3oWcPgWUPwrAk9axo8lwqetaBnLYNnLcGzNvSsbfBcJnjWgZ51DJ51BM+60LOuwXO54FkPetYzeNYTPOtDz/oGzxWCZwPo2cDg2UDwbAg9Gxo8VwqejaBnI4NnI8GzMfRsbPBcJXg2gZ5NDJ5NBM+m0LOpwXO14NkMejYzeDYTPJtDz+YGzzWCZwvo2cLg2ULwfB96vm/wXCt4toSeLQ2eLQXPVtCzlcFzneDZGnq2Nni2Fjw/gJ4fGDx/EzzbQM82Bs82gmcAPQOD53rBsy30bGvwbCt4toOe7Qyevwue7aFne4Nne8GzA/TsYPDcIHh2hJ4dDZ4dBc9O0LOTwfMPwbMz9Oxs8OwseHaBnl0MnhsFz67Qs6vBs6vg2Q16djN4/il4doee3Q2e3QXPHtCzh8Fzk+DZE3r2NHj2FDx7Qc9eBs+/BM/e0LO3wbO34NkHevYxeG4WPPtCz74Gz76CZz/o2c/g+bfg2R969jd49hc8P4SeHxo8twieA6DnAIPnAMHzI+j5kcHzH8FzIPQcaPAcKHh+DD0/NnhuFTwHQc9BBs9Bgucn0PMTg+e/gudg6DnY4DlY8PwUen5q8NwmeA6BnkMMnkMEz8+g52cGz+2C51DoOdTgOVTw/Bx6fm7w3CF4DoOewwyewwTPL6DnFwbPnYLncOg53OA5XPD8Enp+afDcJXiOgJ4jDJ4jBM+voOdXBs/dgudI6DnS4DlS8Pwaen5t8NwjeI6CnqMMnqMEz2+g5zcGz72C52joOdrgOVrw/BZ6fmvw3Cd4joGeYwyeYwTP76DndwbP/YLnWOg51uA5VvD8Hnp+b/A8IHiOg57jDJ7jBM8foOcPBs+Dgud46Dne4Dle8PwRev5o8DwkeE6AnhMMnhMEz5+g508Gz8OC50ToOdHgOVHw/Bl6/mzwPCJ4ToKekwyekwTPX6DnLwbPo4LnZOg52eA5WfD8FXr+avA8JnhOgZ5TDJ5TBM+p0HOqwfO44DkNek4zeE4TPKdDz+kGzxOC5wzoOcPgOUPwnAk9Zxo8Twqes6DnLIPnLMFzNvScbfA8JXjOgZ5zDJ5zBM+50HOuwfO04DkPes4zeM4TPOdDz/kGzzOC5wLoucDguUDwXAg9Fxo8zwqei6DnIoPnIsFzMfRcbPA8J3gugZ5LDJ5LBM+l0HOpwfO84LkMei4zeC4TPJdDz+UGzwuC5wroucLguULwXAk9Vxo8Lwqeq6DnKoPnKsFzNfRcbfC8JHiugZ5rDJ5rBM+10HOtwfOy4LkOeq4zeK4TPH+Dnr8ZPK8Inuuh53qD53rB83fo+bvB86rguQF6bjB4bhA8/4Cefxg8rwmeG6HnRoPnRsHzT+j5p8HzuuC5CXpuMnhuEjz/gp5/GTxvCJ6boedmg+dmwfNv6Pm3wfOm4LkFem4xeG4RPP+Bnv8YPG8Jnluh51aD51bB81/o+a/B87bguQ16bjN4bhM8t0PP7QbPO4LnDui5w+C5Q/DcCT13GjzvCp67oOcug+cuwXM39Nxt8LwneO6BnnsMnnsEz73Qc6/B877guQ967jN47hM890PP/QbPB4LnAeh5wOB5QPA8CD0PGjwfCp6HoOchg+chwfMw9Dxs8HwkeB6BnkcMnkcEz6PQ86jB87HgeQx6HjN4HhM8j0PP4wbPJ4LnCeh5wuB5QvA8CT1PGjyfCp6noOcpg+cpwfM09Dxt8HwmeJ6BnmcMnmcEz7PQ86zB87ngeQ56njN4nhM8z0PP8wbPF4LnBeh5weB5QfC8CD0vGjxfCp6XoOclg+clwfMy9Lxs8HwleF6BnlcMnlcEz6vQ86rB87XgeQ16XjN4XhM8r0PP6wbPN4LnDeh5w+B5Q/C8CT1vGjzfCp63oOctg+ctwfM29Lxt8HwneN6BnncMnncEz7vQ867B871o//ud96DnPYPnPcHzPvS8b/CMIHg+gJ4PDJ4PBM+H0POhwTOi4PkIej4yeD4SPB9Dz8cGz0iC5xPo+cTg+UTwfAo9nxo8Iwuez6DnM4PnM8HzOfR8bvCMIni+gJ4vDJ4vBM+X0POlwTOq4PkKer4yeL4SPF9Dz9cGz2iC5xvo+cbg+UbwfAs93xo8owue76DnO4PnO8HzvV7M8793oXrGEDwj9GKeEXqF7hm2Hd42IvSMaPCMKXhGgp6RDJ6RBM/I0DOywTOW4BkFekYxeEYRPKNCz6gGz9iCZzToGc3gGU3wjA49oxs84wieMaBnDINnDMEzJvSMafCMK3jGgp6xDJ6xBM/Y0DO2wTOe4BkHesYxeMYRPONCz7gGz/iCZzzoGc/gGU/wjA894xs8EwieCaBnAoNnAsEzIfRMaPBMKHgmgp6JDJ6JBM/E0DOxwTOR4JkEeiYxeCYRPJNCz6QGz8SCZzLomczgmUzwTA49kxs8kwieKaBnCoNnCsEzJfRMafBMKnimgp6pDJ6pBM/U0DO1wTOZ4JkGeqYxeKYRPNNCz7QGz+SCZzromc7gmU7wTA890xs8UwieGaBnBoNnBsEzI/TMaPBMKXhmgp6ZDJ6ZBM/M0DOzwTOV4JkFemYxeGYRPLNCz6wGz9SCZzbomc3gmU3wzA49sxs80wieOaBnDoNnDsEzJ/TMafBMK3jmgp65DJ65BM/c0DO3wTOd4JkHeuYxeOYRPPNCz7wGz/SCZz7omc/gmU/wzA898xs8MwieBaBnAYNnAcGzIPQsaPDMKHgWgp6FDJ6FBM/C0LOwwTOT4FkEehYxeBYRPItCz6IGz8yCZzHoWczgWUzwLA49ixs8swieJaBnCYNnCcGzJPQsafDMKniWgp6lDJ6lBM/S0LO0wTOb4FkGepYxeJYRPMtCz7IGz+yCZznoWc7gWU7wLA89yxs8cwieFaBnBYNnBcGzIvSsaPDMKXhWgp6VDJ6VBM/K0LOywTOX4FkFelYxeFYRPKtCz6oGz9yCZzXoWc3gWU3wrA49qxs88wieNaBnDYNnDcGzJvSsafDMK3jWgp61DJ61BM/a0LO2wTOf4FkHetYxeNYRPOtCz7oGz/yCZz3oWc/gWU/wrA896xs8CwieDaBnA4NnA8GzIfRsaPAsKHg2gp6NDJ6NBM/G0LOxwbOQ4NkEejYxeDYRPJtCz6YGz8KCZzPo2czg2UzwbA49mxs8iwieLaBnC4NnC8Hzfej5vsGzqODZEnq2NHi2FDxbQc9WBs9igmdr6Nna4Nla8PwAen5g8CwueLaBnm0Mnm0EzwB6BgbPEoJnW+jZ1uDZVvBsBz3bGTxLCp7toWd7g2d7wbMD9Oxg8CwleHaEnh0Nnh0Fz07Qs5PBs7Tg2Rl6djZ4dhY8u0DPLgbPMoJnV+jZ1eDZVfDsBj27GTzLCp7doWd3g2d3wbMH9Oxh8CwnePaEnj0Nnj0Fz17Qs5fBs7zg2Rt69jZ49hY8+0DPPgbPCoJnX+jZ1+DZV/DsBz37GTwrCp79oWd/g2d/wfND6PmhwbOS4DkAeg4weA4QPD+Cnh8ZPCsLngOh50CD50DB82Po+bHBs4rgOQh6DjJ4DhI8P4Genxg8qwqeg6HnYIPnYMHzU+j5qcGzmuA5BHoOMXgOETw/g56fGTyrC55DoedQg+dQwfNz6Pm5wbOG4DkMeg4zeA4TPL+Anl8YPGsKnsOh53CD53DB80vo+aXBs5bgOQJ6jjB4jhA8v4KeXxk8awueI6HnSIPnSMHza+j5tcGzjuA5CnqOMniOEjy/gZ7fGDzrCp6joedog+dowfNb6PmtwbOe4DkGeo4xeI4RPL+Dnt8ZPOsLnmOh51iD51jB83vo+b3Bs4HgOQ56jjN4jhM8f4CePxg8Gwqe46HneIPneMHzR+j5o8GzkeA5AXpOMHhOEDx/gp4/GTwbC54ToedEg+dEwfNn6PmzwbOJ4DkJek4yeE4SPH+Bnr8YPJsKnpOh52SD52TB81fo+avBs5ngOQV6TjF4ThE8p0LPqQbP5oLnNOg5zeA5TfCcDj2nGzxbCJ4zoOcMg+cMwXMm9Jxp8Hxf8JwFPWcZPGcJnrOh52yDZ0vBcw70nGPwnCN4zoWecw2erQTPedBznsFznuA5H3rON3i2FjwXQM8FBs8FgudC6LnQ4PmB4LkIei4yeC4SPBdDz8UGzzaC5xLoucTguUTwXAo9lxo8A8FzGfRcZvBcJnguh57LDZ5tBc8V0HOFwXOF4LkSeq40eLYTPFdBz1UGz1WC52roudrg2V7wXAM91xg81wiea6HnWoNnB8FzHfRcZ/BcJ3j+Bj1/M3h2FDzXQ8/1Bs/1gufv0PN3g2cnwXMD9Nxg8NwgeP4BPf8weHYWPDdCz40Gz42C55/Q80+DZxfBcxP03GTw3CR4/gU9/zJ4dhU8N0PPzQbPzYLn39Dzb4NnN8FzC/TcYvDcInj+Az3/MXh2Fzy3Qs+tBs+tgue/0PNfg2cPwXMb9Nxm8NwmeG6HntsNnj0Fzx3Qc4fBc4fguRN67jR49hI8d0HPXQbPXYLnbui52+DZW/DcAz33GDz3CJ57oedeg2cfwXMf9Nxn8NwneO6HnvsNnn0FzwPQ84DB84DgeRB6HjR49hM8D0HPQwbPQ4LnYeh52ODZX/A8Aj2PGDyPCJ5HoedRg+eHgucx6HnM4HlM8DwOPY8bPAcInieg5wmD5wnB8yT0PGnw/EjwPAU9Txk8Twmep6HnaYPnQMHzDPQ8Y/A8I3iehZ5nDZ4fC57noOc5g+c5wfM89Dxv8BwkeF6AnhcMnhcEz4vQ86LB8xPB8xL0vGTwvCR4Xoaelw2egwXPK9DzisHziuB5FXpeNXh+Knheg57XDJ7XBM/r0PO6wXOI4HkDet4weN4QPG9Cz5sGz88Ez1vQ85bB85bgeRt63jZ4DhU870DPOwbPO4LnXeh51+D5ueB5D3reM3jeEzzvQ8/7Bs9hgucD6PnA4PlA8HwIPR8aPL8QPB9Bz0cGz0eC52Po+djgOVzwfAI9nxg8nwieT6HnU4Pnl4LnM+j5zOD5TPB8Dj2fGzxHCJ4voOcLg+cLwfMl9Hxp8PxK8HwFPV8ZPF8Jnq+h52uD50jB8w30fGPwfCN4voWebw2eXwue76DnO4PnO8Hzvd7M8793oXqOEjwj9GaeEXqH7hm2Hd42IvSMaPD8RvCMBD0jGTwjCZ6RoWdkg+dowTMK9Ixi8IwieEaFnlENnt8KntGgZzSDZzTBMzr0jG7wHCN4xoCeMQyeMQTPmNAzpsHzO8EzFvSMZfCMJXjGhp6xDZ5jBc840DOOwTOO4BkXesY1eH4veMaDnvEMnvEEz/jQM77Bc5zgmQB6JjB4JhA8E0LPhAbPHwTPRNAzkcEzkeCZGHomNniOFzyTQM8kBs8kgmdS6JnU4Pmj4JkMeiYzeCYTPJNDz+QGzwmCZwromcLgmULwTAk9Uxo8fxI8U0HPVAbPVIJnauiZ2uA5UfBMAz3TGDzTCJ5poWdag+fPgmc66JnO4JlO8EwPPdMbPCcJnhmgZwaDZwbBMyP0zGjw/EXwzAQ9Mxk8MwmemaFnZoPnZMEzC/TMYvDMInhmhZ5ZDZ6/Cp7ZoGc2g2c2wTM79Mxu8JwieOaAnjkMnjkEz5zQM6fBc6rgmQt65jJ45hI8c0PP3AbPaYJnHuiZx+CZR/DMCz3zGjynC575oGc+g2c+wTM/9Mxv8JwheBaAngUMngUEz4LQs6DBc6bgWQh6FjJ4FhI8C0PPwgbPWYJnEehZxOBZRPAsCj2LGjxnC57FoGcxg2cxwbM49Cxu8JwjeJaAniUMniUEz5LQs6TBc67gWQp6ljJ4lhI8S0PP0gbPeYJnGehZxuBZRvAsCz3LGjznC57loGc5g2c5wbM89Cxv8FwgeFaAnhUMnhUEz4rQs6LBc6HgWQl6VjJ4VhI8K0PPygbPRYJnFehZxeBZRfCsCj2rGjwXC57VoGc1g2c1wbM69Kxu8FwieNaAnjUMnjUEz5rQs6bBc6ngWQt61jJ41hI8a0PP2gbPZYJnHehZx+BZR/CsCz3rGjyXC571oGc9g2c9wbM+9Kxv8FwheDaAng0Mng0Ez4bQs6HBc6Xg2Qh6NjJ4NhI8G0PPxgbPVYJnE+jZxODZRPBsCj2bGjxXC57NoGczg2czwbM59Gxu8FwjeLaAni0Mni0Ez/eh5/sGz7WCZ0vo2dLg2VLwbAU9Wxk81wmeraFna4Nna8HzA+j5gcHzN8GzDfRsY/BsI3gG0DMweK4XPNtCz7YGz7aCZzvo2c7g+bvg2R56tjd4thc8O0DPDgbPDYJnR+jZ0eDZUfDsBD07GTz/EDw7Q8/OBs/OgmcX6NnF4LlR8OwKPbsaPLsKnt2gZzeD55+CZ3fo2d3g2V3w7AE9exg8NwmePaFnT4NnT8GzF/TsZfD8S/DsDT17Gzx7C559oGcfg+dmwbMv9Oxr8OwrePaDnv0Mnn8Lnv2hZ3+DZ3/B80Po+aHBc4vgOQB6DjB4DhA8P4KeHxk8/xE8B0LPgQbPgYLnx9DzY4PnVsFzEPQcZPAcJHh+Aj0/MXj+K3gOhp6DDZ6DBc9PoeenBs9tgucQ6DnE4DlE8PwMen5m8NwueA6FnkMNnkMFz8+h5+cGzx2C5zDoOczgOUzw/AJ6fmHw3Cl4Doeeww2ewwXPL6HnlwbPXYLnCOg5wuA5QvD8Cnp+ZfDcLXiOhJ4jDZ4jBc+voefXBs89guco6DnK4DlK8PwGen5j8NwreI6GnqMNnqMFz2+h57cGz32C5xjoOcbgOUbw/A56fmfw3C94joWeYw2eYwXP76Hn9wbPA4LnOOg5zuA5TvD8AXr+YPA8KHiOh57jDZ7jBc8foeePBs9DgucE6DnB4DlB8PwJev5k8DwseE6EnhMNnhMFz5+h588GzyOC5yToOcngOUnw/AV6/mLwPCp4Toaekw2ekwXPX6HnrwbPY4LnFOg5xeA5RfCcCj2nGjyPC57ToOc0g+c0wXM69Jxu8DwheM6AnjMMnjMEz5nQc6bB86TgOQt6zjJ4zhI8Z0PP2QbPU4LnHOg5x+A5R/CcCz3nGjxPC57zoOc8g+c8wXM+9Jxv8DwjeC6AngsMngsEz4XQc6HB86zguQh6LjJ4LhI8F0PPxQbPc4LnEui5xOC5RPBcCj2XGjzPC57LoOcyg+cywXM59Fxu8LwgeK6AnisMnisEz5XQc6XB86LguQp6rjJ4rhI8V0PP1QbPS4LnGui5xuC5RvBcCz3XGjwvC57roOc6g+c6wfM36PmbwfOK4Lkeeq43eK4XPH+Hnr8bPK8Knhug5waD5wbB8w/o+YfB85rguRF6bjR4bhQ8/4Sefxo8rwuem6DnJoPnJsHzL+j5l8HzhuC5GXpuNnhuFjz/hp5/GzxvCp5boOcWg+cWwfMf6PmPwfOW4LkVem41eG4VPP+Fnv8aPG8Lntug5zaD5zbBczv03G7wvCN47oCeOwyeOwTPndBzp8HzruC5C3ruMnjuEjx3Q8/dBs97guce6LnH4LlH8NwLPfcaPO8Lnvug5z6D5z7Bcz/03G/wfCB4HoCeBwyeBwTPg9DzoMHzoeB5CHoeMngeEjwPQ8/DBs9HgucR6HnE4HlE8DwKPY8aPB8Lnseg5zGD5zHB8zj0PG7wfCJ4noCeJwyeJwTPk9DzpMHzqeB5CnqeMnieEjxPQ8/TBs9ngucZ6HnG4HlG8DwLPc8aPJ8Lnueg5zmD5znB8zz0PG/wfCF4XoCeFwyeFwTPi9DzosHzpeB5CXpeMnheEjwvQ8/LBs9XgucV6HnF4HlF8LwKPa8aPF8Lnteg5zWD5zXB8zr0vG7wfCN43oCeNwyeNwTPm9DzpsHzreB5C3reMnjeEjxvQ8/bBs93gucd6HnH4HlH8LwLPe8aPN+L/r/feQ963jN43hM870PP+w7PzP/7nQ96/6//jRAt7J3/vYsZzp1KO7ztw//5zohxw9758H+4M5wvQgTB8xH0fGTwfCR4Poaejw2eEQXPJ9DzicHzieD5FHo+NXhGEjyfQc9nBs9ngudz6Pnc4BlZ8HwBPV8YPF8Ini+h50uDZxTB8xX0fGXwfCV4voaerw2eUQXPN9DzjcHzjeD5Fnq+NXhGEzzfQc93Bs93gud7fZjnf+9C9YwueEbowzwj9AndM2w7vG1E6BnR4BlD8IwEPSMZPCMJnpGhZ2SDZ0zBMwr0jGLwjCJ4RoWeUQ2esQTPaNAzmsEzmuAZHXpGN3jGFjxjQM8YBs8YgmdM6BnT4BlH8IwFPWMZPGMJnrGhZ2yDZ1zBMw70jGPwjCN4xoWecQ2e8QTPeNAznsEznuAZH3rGN3jGFzwTQM8EBs8EgmdC6JnQ4JlA8EwEPRMZPBMJnomhZ2KDZ0LBMwn0TGLwTCJ4JoWeSQ2eiQTPZNAzmcEzmeCZHHomN3gmFjxTQM8UBs8UgmdK6JnS4JlE8EwFPVMZPFMJnqmhZ2qDZ1LBMw30TGPwTCN4poWeaQ2eyQTPdNAzncEzneCZHnqmN3gmFzwzQM8MBs8MgmdG6JnR4JlC8MwEPTMZPDMJnpmhZ2aDZ0rBMwv0zGLwzCJ4ZoWeWQ2eqQTPbNAzm8Ezm+CZHXpmN3imFjxzQM8cBs8cgmdO6JnT4JlG8MwFPXMZPHMJnrmhZ26DZ1rBMw/0zGPwzCN45oWeeQ2e6QTPfNAzn8Ezn+CZH3rmN3imFzwLQM8CBs8CgmdB6FnQ4JlB8CwEPQsZPAsJnoWhZ2GDZ0bBswj0LGLwLCJ4FoWeRQ2emQTPYtCzmMGzmOBZHHoWN3hmFjxLQM8SBs8SgmdJ6FnS4JlF8CwFPUsZPEsJnqWhZ2mDZ1bBswz0LGPwLCN4loWeZQ2e2QTPctCznMGznOBZHnqWN3hmFzwrQM8KBs8KgmdF6FnR4JlD8KwEPSsZPCsJnpWhZ2WDZ07Bswr0rGLwrCJ4VoWeVQ2euQTPatCzmsGzmuBZHXpWN3jmFjxrQM8aBs8agmdN6FnT4JlH8KwFPWsZPGsJnrWhZ22DZ17Bsw70rGPwrCN41oWedQ2e+QTPetCznsGznuBZH3rWN3jmFzwbQM8GBs8GgmdD6NnQ4FlA8GwEPRsZPBsJno2hZ2ODZ0HBswn0bGLwbCJ4NoWeTQ2ehQTPZtCzmcGzmeDZHHo2N3gWFjxbQM8WBs+w7fC27/dhnv+9C9WziODZsg/zbNkndM+Wgmcr6NnK4FlU8GwNPVsbPFsLnh9Azw8MnsUEzzbQs43Bs43gGUDPwOBZXPBsCz3bGjzbCp7toGc7g2cJwbM99Gxv8GwveHaAnh0MniUFz47Qs6PBs6Pg2Ql6djJ4lhI8O0PPzgbPzoJnF+jZxeBZWvDsCj27Gjy7Cp7doGc3g2cZwbM79Oxu8OwuePaAnj0MnmUFz57Qs6fBs6fg2Qt69jJ4lhM8e0PP3gbP3oJnH+jZx+BZXvDsCz37Gjz7Cp79oGc/g2cFwbM/9Oxv8OwveH4IPT80eFYUPAdAzwEGzwGC50fQ8yODZyXBcyD0HGjwHCh4fgw9PzZ4VhY8B0HPQQbPQYLnJ9DzE4NnFcFzMPQcbPAcLHh+Cj0/NXhWFTyHQM8hBs8hgudn0PMzg2c1wXMo9Bxq8BwqeH4OPT83eFYXPIdBz2EGz2GC5xfQ8wuDZw3Bczj0HG7wHC54fgk9vzR41hQ8R0DPEQbPEYLnV9DzK4NnLcFzJPQcafAcKXh+DT2/NnjWFjxHQc9RBs9Rguc30PMbg2cdwXM09Bxt8BwteH4LPb81eNYVPMdAzzEGzzGC53fQ8zuDZz3Bcyz0HGvwHCt4fg89vzd41hc8x0HPcQbPcYLnD9DzB4NnA8FzPPQcb/AcL3j+CD1/NHg2FDwnQM8JBs8JgudP0PMng2cjwXMi9Jxo8JwoeP4MPX82eDYWPCdBz0kGz0mC5y/Q8xeDZxPBczL0nGzwnCx4/go9fzV4NhU8p0DPKQbPKYLnVOg51eDZTPCcBj2nGTynCZ7Toed0g2dzwXMG9Jxh8JwheM6EnjMNni0Ez1nQc5bBc5bgORt6zjZ4vi94zoGecwyecwTPudBzrsGzpeA5D3rOM3jOEzznQ8/5Bs9WgucC6LnA4LlA8FwIPRcaPFsLnoug5yKD5yLBczH0XGzw/EDwXAI9lxg8lwieS6HnUoNnG8FzGfRcZvBcJnguh57LDZ6B4LkCeq4weK4QPFdCz5UGz7aC5yroucrguUrwXA09Vxs82wmea6DnGoPnGsFzLfRca/BsL3iug57rDJ7rBM/foOdvBs8Ogud66Lne4Lle8Pwdev5u8OwoeG6AnhsMnhsEzz+g5x8Gz06C50boudHguVHw/BN6/mnw7Cx4boKemwyemwTPv6DnXwbPLoLnZui52eC5WfD8G3r+bfDsKnhugZ5bDJ5bBM9/oOc/Bs9ugudW6LnV4LlV8PwXev5r8OwueG6DntsMntsEz+3Qc7vBs4fguQN67jB47hA8d0LPnQbPnoLnLui5y+C5S/DcDT13Gzx7CZ57oOceg+cewXMv9Nxr8OwteO6DnvsMnvsEz/3Qc7/Bs4/geQB6HjB4HhA8D0LPgwbPvoLnIeh5yOB5SPA8DD0PGzz7CZ5HoOcRg+cRwfMo9Dxq8OwveB6DnscMnscEz+PQ87jB80PB8wT0PGHwPCF4noSeJw2eAwTPU9DzlMHzlOB5GnqeNnh+JHiegZ5nDJ5nBM+z0POswXOg4HkOep4zeJ4TPM9Dz/MGz48FzwvQ84LB84LgeRF6XjR4DhI8L0HPSwbPS4LnZeh52eD5ieB5BXpeMXheETyvQs+rBs/Bguc16HnN4HlN8LwOPa8bPD8VPG9AzxsGzxuC503oedPgOUTwvAU9bxk8bwmet6HnbYPnZ4LnHeh5x+B5R/C8Cz3vGjyHCp73oOc9g+c9wfM+9Lxv8Pxc8HwAPR8YPB8Ing+h50OD5zDB8xH0fGTwfCR4Poaejw2eXwieT6DnE4PnE8HzKfR8avAcLng+g57PDJ7PBM/n0PO5wfNLwfMF9Hxh8HwheL6Eni8NniMEz1fQ85XB85Xg+Rp6vjZ4fiV4voGebwyebwTPt9DzrcFzpOD5Dnq+M3i+Ezzf68s8/3sXqufXgmeEvswzQt/QPcO2w9tGhJ4RDZ6jBM9I0DOSwTOS4BkZekY2eH4jeEaBnlEMnlEEz6jQM6rBc7TgGQ16RjN4RhM8o0PP6AbPbwXPGNAzhsEzhuAZE3rGNHiOETxjQc9YBs9Ygmds6Bnb4Pmd4BkHesYxeMYRPONCz7gGz7GCZzzoGc/gGU/wjA894xs8vxc8E0DPBAbPBIJnQuiZ0OA5TvBMBD0TGTwTCZ6JoWdig+cPgmcS6JnE4JlE8EwKPZMaPMcLnsmgZzKDZzLBMzn0TG7w/FHwTAE9Uxg8UwieKaFnSoPnBMEzFfRMZfBMJXimhp6pDZ4/CZ5poGcag2cawTMt9Exr8JwoeKaDnukMnukEz/TQM73B82fBMwP0zGDwzCB4ZoSeGQ2ekwTPTNAzk8Ezk+CZGXpmNnj+InhmgZ5ZDJ5ZBM+s0DOrwXOy4JkNemYzeGYTPLNDz+wGz18FzxzQM4fBM4fgmRN65jR4ThE8c0HPXAbPXIJnbuiZ2+A5VfDMAz3zGDzzCJ55oWdeg+c0wTMf9Mxn8MwneOaHnvkNntMFzwLQs4DBs4DgWRB6FjR4zhA8C0HPQgbPQoJnYehZ2OA5U/AsAj2LGDyLCJ5FoWdRg+cswbMY9Cxm8CwmeBaHnsUNnrMFzxLQs4TBs4TgWRJ6ljR4zhE8S0HPUgbPUoJnaehZ2uA5V/AsAz3LGDzLCJ5loWdZg+c8wbMc9Cxn8CwneJaHnuUNnvMFzwrQs4LBs4LgWRF6VjR4LhA8K0HPSgbPSoJnZehZ2eC5UPCsAj2rGDyrCJ5VoWdVg+ciwbMa9Kxm8KwmeFaHntUNnosFzxrQs4bBs4bgWRN61jR4LhE8a0HPWgbPWoJnbehZ2+C5VPCsAz3rGDzrCJ51oWddg+cywbMe9Kxn8KwneNaHnvUNnssFzwbQs4HBs4Hg2RB6NjR4rhA8G0HPRgbPRoJnY+jZ2OC5UvBsAj2bGDybCJ5NoWdTg+cqwbMZ9Gxm8GwmeDaHns0NnqsFzxbQs4XBs4Xg+T70fN/guUbwbAk9Wxo8WwqeraBnK4PnWsGzNfRsbfBsLXh+AD0/MHiuEzzbQM82Bs82gmcAPQOD52+CZ1vo2dbg2VbwbAc92xk81wue7aFne4Nne8GzA/TsYPD8XfDsCD07Gjw7Cp6doGcng+cGwbMz9Oxs8OwseHaBnl0Mnn8Inl2hZ1eDZ1fBsxv07Gbw3Ch4doee3Q2e3QXPHtCzh8HzT8GzJ/TsafDsKXj2gp69DJ6bBM/e0LO3wbO34NkHevYxeP4lePaFnn0Nnn0Fz37Qs5/Bc7Pg2R969jd49hc8P4SeHxo8/xY8B0DPAQbPAYLnR9DzI4PnFsFzIPQcaPAcKHh+DD0/Nnj+I3gOgp6DDJ6DBM9PoOcnBs+tgudg6DnY4DlY8PwUen5q8PxX8BwCPYcYPIcInp9Bz88MntsEz6HQc6jBc6jg+Tn0/NzguV3wHAY9hxk8hwmeX0DPLwyeOwTP4dBzuMFzuOD5JfT80uC5U/AcAT1HGDxHCJ5fQc+vDJ67BM+R0HOkwXOk4Pk19Pza4Llb8BwFPUcZPEcJnt9Az28MnnsEz9HQc7TBc7Tg+S30/NbguVfwHAM9xxg8xwie30HP7wye+wTPsdBzrMFzrOD5PfT83uC5X/AcBz3HGTzHCZ4/QM8fDJ4HBM/x0HO8wXO84Pkj9PzR4HlQ8JwAPScYPCcInj9Bz58MnocEz4nQc6LBc6Lg+TP0/NngeVjwnAQ9Jxk8Jwmev0DPXwyeRwTPydBzssFzsuD5K/T81eB5VPCcAj2nGDynCJ5ToedUg+cxwXMa9Jxm8JwmeE6HntMNnscFzxnQc4bBc4bgORN6zjR4nhA8Z0HPWQbPWYLnbOg52+B5UvCcAz3nGDznCJ5zoedcg+cpwXMe9Jxn8JwneM6HnvMNnqcFzwXQc4HBc4HguRB6LjR4nhE8F0HPRQbPRYLnYui52OB5VvBcAj2XGDyXCJ5LoedSg+c5wXMZ9Fxm8FwmeC6HnssNnucFzxXQc4XBc4XguRJ6rjR4XhA8V0HPVQbPVYLnaui52uB5UfBcAz3XGDzXCJ5roedag+clwXMd9Fxn8FwneP4GPX8zeF4WPNdDz/UGz/WC5+/Q83eD5xXBcwP03GDw3CB4/gE9/zB4XhU8N0LPjQbPjYLnn9DzT4PnNcFzE/TcZPDcJHj+BT3/MnheFzw3Q8/NBs/Nguff0PNvg+cNwXML9Nxi8NwieP4DPf8xeN4UPLdCz60Gz62C57/Q81+D5y3Bcxv03Gbw3CZ4boee2w2etwXPHdBzh8Fzh+C5E3ruNHjeETx3Qc9dBs9dgudu6Lnb4HlX8NwDPfcYPPcInnuh516D5z3Bcx/03Gfw3Cd47oee+w2e9wXPA9DzgMHzgOB5EHoeNHg+EDwPQc9DBs9Dgudh6HnY4PlQ8DwCPY8YPI8Inkeh51GD5yPB8xj0PGbwPCZ4Hoeexw2ejwXPE9DzhMHzhOB5EnqeNHg+ETxPQc9TBs9Tgudp6Hna4PlU8DwDPc8YPM8Inmeh51mD5zPB8xz0PGfwPCd4noee5w2ezwXPC9DzgsHzguB5EXpeNHi+EDwvQc9LBs9Lgudl6HnZ4PlS8LwCPa8YPK8Inleh51WD5yvB8xr0vGbwvCZ4Xoee1w2erwXPG9DzhsHzhuB5E3reNHi+ETxvQc9bBs9bgudt6Hnb4PlW8LwDPe8YPO8Inneh512D5zvB8x70vGfwvCd43oee9w2e72X53+98AD0fGDwfCJ4PoedDg2cEwfMR9Hxk8HwkeD6Gno8NnhEFzyfQ84nB84ng+RR6PjV4RhI8n0HPZwbPZ4Lnc+j53OAZWfB8AT1fGDxfCJ4voedLg2cUwfMV9Hxl8HwleL6Gnq8NnlEFzzfQ843B843g+RZ6vjV4RhM830HPdwbPd4Lne/2Y53/vQvWMLnhG6Mc8I/QL3TNsO7xtROgZ0eAZQ/CMBD0jGTwjCZ6RoWdkg2dMwTMK9Ixi8IwieEaFnlENnrEEz2jQM5rBM5rgGR16Rjd4xhY8Y0DPGAbPGIJnTOgZ0+AZR/CMBT1jGTxjCZ6xoWdsg2dcwTMO9Ixj8IwjeMaFnnENnvEEz3jQM57BM57gGR96xjd4xhc8E0DPBAbPBIJnQuiZ0OCZQPBMBD0TGTwTCZ6JoWdig2dCwTMJ9Exi8EwieCaFnkkNnokEz2TQM5nBM5ngmRx6Jjd4JhY8U0DPFAbPFIJnSuiZ0uCZRPBMBT1TGTxTCZ6poWdqg2dSwTMN9Exj8EwjeKaFnmkNnskEz3TQM53BM53gmR56pjd4Jhc8M0DPDAbPDIJnRuiZ0eCZQvDMBD0zGTwzCZ6ZoWdmg2dKwTML9Mxi8MwieGaFnlkNnqkEz2zQM5vBM5vgmR16Zjd4phY8c0DPHAbPHIJnTuiZ0+CZRvDMBT1zGTxzCZ65oWdug2dawTMP9Mxj8MwjeOaFnnkNnukEz3zQM5/BM5/gmR965jd4phc8C0DPAgbPAoJnQehZ0OCZQfAsBD0LGTwLCZ6FoWdhg2dGwbMI9Cxi8CwieBaFnkUNnpkEz2LQs5jBs5jgWRx6Fjd4ZhY8S0DPEgbPEoJnSehZ0uCZRfAsBT1LGTxLCZ6loWdpg2dWwbMM9Cxj8CwjeJaFnmUNntkEz3LQs5zBs5zgWR56ljd4Zhc8K0DPCgbPCoJnRehZ0eCZQ/CsBD0rGTwrCZ6VoWdlg2dOwbMK9Kxi8KwieFaFnlUNnrkEz2rQs5rBs5rgWR16Vjd45hY8a0DPGgbPGoJnTehZ0+CZR/CsBT1rGTxrCZ61oWdtg2dewbMO9Kxj8KwjeNaFnnUNnvkEz3rQs57Bs57gWR961jd45hc8G0DPBgbPBoJnQ+jZ0OBZQPBsBD0bGTwbCZ6NoWdjg2dBwbMJ9Gxi8GwieDaFnk0NnoUEz2bQs5nBs5ng2Rx6Njd4FhY8W0DPFgbPFoLn+9DzfYNnEcGzJfRsafBsKXi2gp6tDJ5FBc/W0LO1wbO14PkB9PzA4FlM8GwDPdsYPNsIngH0DAyexQXPttCzrcGzreDZDnq2M3iWEDzbQ8/2Bs/2gmcH6NnB4FlS8OwIPTsaPDsKnp2gZyeDZynBszP07Gzw7Cx4doGeXQyepQXPrtCzq8Gzq+DZDXp2M3iWETy7Q8/uBs/ugmcP6NnD4FlW8OwJPXsaPHsKnr2gZy+DZznBszf07G3w7C149oGefQye5QXPvtCzr8Gzr+DZD3r2M3hWEDz7Q8/+Bs/+gueH0PNDg2dFwXMA9Bxg8BwgeH4EPT8yeFYSPAdCz4EGz4GC58fQ82ODZ2XBcxD0HGTwHCR4fgI9PzF4VhE8B0PPwQbPwYLnp9DzU4NnVcFzCPQcYvAcInh+Bj0/M3hWEzyHQs+hBs+hgufn0PNzg2d1wXMY9Bxm8BwmeH4BPb8weNYQPIdDz+EGz+GC55fQ80uDZ03BcwT0HGHwHCF4fgU9vzJ41hI8R0LPkQbPkYLn19Dza4NnbcFzFPQcZfAcJXh+Az2/MXjWETxHQ8/RBs/Rgue30PNbg2ddwXMM9Bxj8BwjeH4HPb8zeNYTPMdCz7EGz7GC5/fQ83uDZ33Bcxz0HGfwHCd4/gA9fzB4NhA8x0PP8QbP8YLnj9DzR4NnQ8FzAvScYPCcIHj+BD1/Mng2EjwnQs+JBs+JgufP0PNng2djwXMS9Jxk8JwkeP4CPX8xeDYRPCdDz8kGz8mC56/Q81eDZ1PBcwr0nGLwnCJ4ToWeUw2ezQTPadBzmsFzmuA5HXpON3g2FzxnQM8ZBs8ZgudM6DnT4NlC8JwFPWcZPGcJnrOh52yD5/uC5xzoOcfgOUfwnAs95xo8Wwqe86DnPIPnPMFzPvScb/BsJXgugJ4LDJ4LBM+F0HOhwbO14LkIei4yeC4SPBdDz8UGzw8EzyXQc4nBc4nguRR6LjV4thE8l0HPZQbPZYLncui53OAZCJ4roOcKg+cKwXMl9Fxp8GwreK6CnqsMnqsEz9XQc7XBs53guQZ6rjF4rhE810LPtQbP9oLnOui5zuC5TvD8DXr+ZvDsIHiuh57rDZ7rBc/foefvBs+OgucG6LnB4LlB8PwDev5h8OwkeG6EnhsNnhsFzz+h558Gz86C5yboucnguUnw/At6/mXw7CJ4boaemw2emwXPv6Hn3wbProLnFui5xeC5RfD8B3r+Y/DsJnhuhZ5bDZ5bBc9/oee/Bs/uguc26LnN4LlN8NwOPbcbPHsInjug5w6D5w7Bcyf03Gnw7Cl47oKeuwyeuwTP3dBzt8Gzl+C5B3ruMXjuETz3Qs+9Bs/eguc+6LnP4LlP8NwPPfcbPPsIngeg5wGD5wHB8yD0PGjw7Ct4HoKehwyehwTPw9DzsMGzn+B5BHoeMXgeETyPQs+jBs/+gucx6HnM4HlM8DwOPY8bPD8UPE9AzxMGzxOC50noedLgOUDwPAU9Txk8Twmep6HnaYPnR4LnGeh5xuB5RvA8Cz3PGjwHCp7noOc5g+c5wfM89Dxv8PxY8LwAPS8YPC8Inheh50WD5yDB8xL0vGTwvCR4Xoaelw2enwieV6DnFYPnFcHzKvS8avAcLHheg57XDJ7XBM/r0PO6wfNTwfMG9Lxh8LwheN6EnjcNnkMEz1vQ85bB85bgeRt63jZ4fiZ43oGedwyedwTPu9DzrsFzqOB5D3reM3jeEzzvQ8/7Bs/PBc8H0POBwfOB4PkQej40eA4TPB9Bz0cGz0eC52Po+djg+YXg+QR6PjF4PhE8n0LPpwbP4YLnM+j5zOD5TPB8Dj2fGzy/FDxfQM8XBs8XgudL6PnS4DlC8HwFPV8ZPF8Jnq+h52uD51eC5xvo+cbg+UbwfAs93xo8Rwqe76DnO4PnO8Hzvf7M8793oXp+LXhG6M88I/QP3TNsO7xtROgZ0eA5SvCMBD0jGTwjCZ6RoWdkg+c3gmcU6BnF4BlF8IwKPaMaPEcLntGgZzSDZzTBMzr0jG7w/FbwjAE9Yxg8YwieMaFnTIPnGMEzFvSMZfCMJXjGhp6xDZ7fCZ5xoGccg2ccwTMu9Ixr8BwreMaDnvEMnvEEz/jQM77B83vBMwH0TGDwTCB4JoSeCQ2e4wTPRNAzkcEzkeCZGHomNnj+IHgmgZ5JDJ5JBM+k0DOpwXO84JkMeiYzeCYTPJNDz+QGzx8FzxTQM4XBM4XgmRJ6pjR4ThA8U0HPVAbPVIJnauiZ2uD5k+CZBnqmMXimETzTQs+0Bs+Jgmc66JnO4JlO8EwPPdMbPH8WPDNAzwwGzwyCZ0bomdHgOUnwzAQ9Mxk8MwmemaFnZoPnL4JnFuiZxeCZRfDMCj2zGjwnC57ZoGc2g2c2wTM79Mxu8PxV8MwBPXMYPHMInjmhZ06D5xTBMxf0zGXwzCV45oaeuQ2eUwXPPNAzj8Ezj+CZF3rmNXhOEzzzQc98Bs98gmd+6Jnf4Dld8CwAPQsYPAsIngWhZ0GD5wzBsxD0LGTwLCR4FoaehQ2eMwXPItCziMGziOBZFHoWNXjOEjyLQc9iBs9igmdx6Fnc4Dlb8CwBPUsYPEsIniWhZ0mD5xzBsxT0LGXwLCV4loaepQ2ecwXPMtCzjMGzjOBZFnqWNXjOEzzLQc9yBs9ygmd56Fne4Dlf8KwAPSsYPCsInhWhZ0WD5wLBsxL0rGTwrCR4VoaelQ2eCwXPKtCzisGziuBZFXpWNXguEjyrQc9qBs9qgmd16Fnd4LlY8KwBPWsYPGsInjWhZ02D5xLBsxb0rGXwrCV41oaetQ2eSwXPOtCzjsGzjuBZF3rWNXguEzzrQc96Bs96gmd96Fnf4Llc8GwAPRsYPBsIng2hZ0OD5wrBsxH0bGTwbCR4NoaejQ2eKwXPJtCzicGzieDZFHo2NXiuEjybQc9mBs9mgmdz6Nnc4Lla8GwBPVsYPFsInu9Dz/cNnmsEz5bQs6XBs6Xg2Qp6tjJ4rhU8W0PP1gbP1oLn/7FCV2Fble0WhqW7u0FAREREREREQERERERERKS7u2vS3SAi3d3d3d3d3d21Dve+tfX943rH3B7PvO7jrAg9Kxo8lwmelaBnJYNnJcGzMvSsbPBcLnhWgZ5VDJ5VBM+q0LOqwXOF4FkNelYzeFYTPKtDz+oGz5WCZw3oWcPgWUPwrAk9axo8VwmetaBnLYNnLcGzNvSsbfBcLXjWgZ51DJ51BM+60LOuwXON4FkPetYzeNYTPOtDz/oGz7WCZwPo2cDg2UDwbAg9Gxo81wmejaBnI4NnI8GzMfRsbPBcL3g2gZ5NDJ5NBM+m0LOpwXOD4NkMejYzeDYTPJtDz+YGz42CZwvo2cLg2ULwbAk9Wxo8NwmeraBnK4NnK8GzNfRsbfDcLHi2gZ5tDJ5tBM+20LOtwXOL4NkOerYzeLYTPNtDz/YGz62CZwfo2cHg2UHw7Ag9Oxo8twmenaBnJ4NnJ8EzgJ6BwXO74NkZenY2eHYWPLtAzy4Gzx2CZ1fo2dXg2VXw7AY9uxk8dwqe3aFnd4Nnd8GzB/TsYfDcJXj2hJ49DZ49Bc9e0LOXwXO34NkbevY2ePYWPPtAzz4Gzz2CZ1/o2dfg2Vfw7Ac9+xk89wqe/aFnf4Nnf8FzAPQcYPDcJ3gOhJ4DDZ4DBc9B0HOQwXO/4DkYeg42eA4WPIdAzyEGzwOC51DoOdTgOVTwHAY9hxk8Dwqew6HncIPncMHzb+j5t8HzkOA5AnqOMHiOEDz/gZ7/GDwPC54joedIg+dIwfNf6PmvwfOI4DkKeo4yeI4SPEdDz9EGz6OC5xjoOcbgOUbwHAs9xxo8jwme46DnOIPnOMFzPPQcb/A8LnhOgJ4TDJ4TBM+J0HOiwfOE4DkJek4yeE4SPCdDz8kGz5OC5xToOcXgOUXwnAo9pxo8Twme06DnNIPnNMFzOvScbvA8LXjOgJ4zDJ4zBM+Z0HOmwfOM4DkLes4yeM4SPGdDz9kGz7OC5xzoOcfgOUfwnAs95xo8zwme86DnPIPnPMFzPvScb/A8L3gugJ4LDJ4LBM+F0HOhwfOC4LkIei4yeC4SPBdDz8UGz4uC5xLoucTguUTwXAo9lxo8Lwmey6DnMoPnMsFzOfRcbvC8LHiugJ4rDJ4rBM+V0HOlwfOK4LkKeq4yeK4SPFdDz9UGz6uC5xroucbguUbwXAs91xo8rwme66DnOoPnOsFzPfRcb/C8LnhugJ4bDJ4bBM+N0HOjwfOG4LkJem4yeG4SPDdDz80Gz5uC5xboucXguUXw3Ao9txo8bwme26DnNoPnNsFzO/TcbvC8LXjugJ47DJ47BM+d0HOnwfOO4LkLeu4yeO4SPHdDz90Gz7uC5x7oucfguUfw3As99xo87wme+6DnPoPnPsFzP/Tcb/C8L3gegJ4HDJ4HBM+D0POgwfOB4HkIeh4yeB4SPA9Dz8MGz4eC5xHoecTgeUTwPAo9jxo8Hwmex6DnMYPnMcHzOPQ8bvB8LHiegJ4nDJ4nBM+T0POkwfOJ4HkKep4yeJ4SPE9Dz9MGz6eC5xnoecbgeUbwPAs9zxo8nwme56DnOYPnOcHzPPQ8b/B8LnhegJ4XDJ4XBM+L0POiwfOF4HkJel4yeF4SPC9Dz8sGz5eC5xXoecXgeUXwvAo9rxo8Xwme16DnNYPnNcHzOvS8bvB8LXjegJ43DJ43BM+b0POmwfON4HkLet4yeN4SPG9Dz9sGz7eC5x3oecfgeUfwvAs97xo83wme96DnPYPnPcHzPvS8b/B874P//c4H0POBwfOB4PkQej40eEYQPB9Bz0cGz0eC52Po+djgGVHwfAI9nxg8nwieT6HnU4NnJMHzGfR8ZvB8Jng+h57PDZ6RBc8X0POFwfOF4PkSer40eEYRPF9Bz1cGz1eC52vo+drgGVXwfAM93xg83wieb6HnW4NnNMHzHfR8Z/B8J3i+15x5/vcuVM/ogmeE5swzQvPQPcO2w9tGhJ4RDZ4xBM9I0DOSwTOS4BkZekY2eMYUPKNAzygGzyiCZ1ToGdXgGUvwjAY9oxk8owme0aFndINnbMEzBvSMYfCMIXjGhJ4xDZ5xBM9Y0DOWwTOW4BkbesY2eMYVPONAzzgGzziCZ1zoGdfgGU/wjAc94xk84wme8aFnfINnfMEzAfRMYPBMIHgmhJ4JDZ4JBM9E0DORwTOR4JkYeiY2eCYUPJNAzyQGzySCZ1LomdTgmUjwTAY9kxk8kwmeyaFncoNnYsEzBfRMYfBMIXimhJ4pDZ5JBM9U0DOVwTOV4JkaeqY2eCYVPNNAzzQGzzSCZ1romdbgmUzwTAc90xk80wme6aFneoNncsEzA/TMYPDMIHi+Dz3fN3imEDwzQs+MBs+Mgmcm6JnJ4JlS8MwMPTMbPDMLnh9Azw8MnqkEzyzQM4vBM4vg+SH0/NDgmVrwzAo9sxo8swqeH0HPjwyeaQTPbNAzm8Ezm+D5MfT82OCZVvDMDj2zGzyzC56fQM9PDJ7pBM8c0DOHwTOH4Pkp9PzU4Jle8MwJPXMaPHMKnp9Bz88MnhkEz1zQM5fBM5fg+Tn0/Nzg+b7gmRt65jZ45hY8v4CeXxg8MwqeeaBnHoNnHsHzS+j5pcEzk+CZF3rmNXjmFTy/gp5fGTwzC575oGc+g2c+wfNr6Pm1wfMDwTM/9Mxv8MwveH4DPb8xeGYRPAtAzwIGzwKCZ0HoWdDg+aHgWQh6FjJ4FhI8v4We3xo8swqehaFnYYNnYcHzO+j5ncHzI8GzCPQsYvAsInh+Dz2/N3hmEzyLQs+iBs+igucP0PMHg+fHgmcx6FnM4FlM8PwRev5o8MwueBaHnsUNnsUFz5+g508Gz08EzxLQs4TBs4Tg+TP0/NngmUPwLAk9Sxo8Swqev0DPXwyenwqepaBnKYNnKcHzV+j5q8Ezp+BZGnqWNniWFjx/g56/GTw/EzzLQM8yBs8ygufv0PN3g2cuwbMs9Cxr8CwreP4BPf8weH4ueJaDnuUMnuUEzz+h558Gz9yCZ3noWd7gWV7w/At6/mXw/ELwrAA9Kxg8KwieFaFnRYNnHsGzEvSsZPCsJHhWhp6VDZ5fCp5VoGcVg2cVwbMq9Kxq8MwreFaDntUMntUEz+rQs7rB8yvBswb0rGHwrCF41oSeNQ2e+QTPWtCzlsGzluBZG3rWNnh+LXjWgZ51DJ51BM+60LOuwTO/4FkPetYzeNYTPOtDz/oGz28EzwbQs4HBs4Hg2RB6NjR4FhA8G0HPRgbPRoJnY+jZ2OBZUPBsAj2bGDybCJ5NoWdTg2chwbMZ9Gxm8GwmeDaHns0Nnt8Kni2gZwuDZwvBsyX0bGnwLCx4toKerQyerQTP1tCztcHzO8GzDfRsY/BsI3i2hZ5tDZ5FBM920LOdwbOd4NkeerY3eH4veHaAnh0Mnh0Ez47Qs6PBs6jg2Ql6djJ4dhI8A+gZGDx/EDw7Q8/OBs/OgmcX6NnF4FlM8OwKPbsaPLsKnt2gZzeD54+CZ3fo2d3g2V3w7AE9exg8iwuePaFnT4NnT8GzF/TsZfD8SfDsDT17Gzx7C559oGcfg2cJwbMv9Oxr8OwrePaDnv0Mnj8Lnv2hZ3+DZ3/BcwD0HGDwLCl4DoSeAw2eAwXPQdBzkMHzF8FzMPQcbPAcLHgOgZ5DDJ6lBM+h0HOowXOo4DkMeg4zeP4qeA6HnsMNnsMFz7+h598Gz9KC5wjoOcLgOULw/Ad6/mPw/E3wHAk9Rxo8Rwqe/0LPfw2eZQTPUdBzlMFzlOA5GnqONnj+LniOgZ5jDJ5jBM+x0HOswbOs4DkOeo4zeI4TPMdDz/EGzz8EzwnQc4LBc4LgORF6TjR4lhM8J0HPSQbPSYLnZOg52eD5p+A5BXpOMXhOETynQs+pBs/yguc06DnN4DlN8JwOPacbPP8SPGdAzxkGzxmC50zoOdPgWUHwnAU9Zxk8Zwmes6HnbINnRcFzDvScY/CcI3jOhZ5zDZ6VBM950HOewXOe4Dkfes43eFYWPBdAzwUGzwWC50LoudDgWUXwXAQ9Fxk8Fwmei6HnYoNnVcFzCfRcYvBcInguhZ5LDZ7VBM9l0HOZwXOZ4Lkcei43eFYXPFdAzxUGzxWC50roudLgWUPwXAU9Vxk8Vwmeq6HnaoNnTcFzDfRcY/BcI3iuhZ5rDZ61BM910HOdwXOd4Lkeeq43eNYWPDdAzw0Gzw2C50boudHgWUfw3AQ9Nxk8Nwmem6HnZoNnXcFzC/TcYvDcInhuhZ5bDZ71BM9t0HObwXOb4Lkdem43eNYXPHdAzx0Gzx2C507oudPg2UDw3AU9dxk8dwmeu6HnboNnQ8FzD/TcY/DcI3juhZ57DZ6NBM990HOfwXOf4Lkfeu43eDYWPA9AzwMGzwOC50HoedDg2UTwPAQ9Dxk8Dwmeh6HnYYNnU8HzCPQ8YvA8IngehZ5HDZ7NBM9j0POYwfOY4Hkceh43eDYXPE9AzxMGzxOC50noedLg2ULwPAU9Txk8Twmep6HnaYNnS8HzDPQ8Y/A8I3iehZ5nDZ6tBM9z0POcwfOc4Hkeep43eLYWPC9AzwsGzwuC50XoedHg2UbwvAQ9Lxk8Lwmel6HnZYNnW8HzCvS8YvC8InhehZ5XDZ7tBM9r0POawfOa4Hkdel43eLYXPG9AzxsGzxuC503oedPg2UHwvAU9bxk8bwmet6HnbYNnR8HzDvS8Y/C8I3jehZ53DZ6dBM970POewfOe4Hkfet43eAaC5wPo+cDg+UDwfAg9Hxo8Owuej6DnI4PnI8HzMfR8bPDsIng+gZ5PDJ5PBM+n0POpwbOr4PkMej4zeD4TPJ9Dz+cGz26C5wvo+cLg+ULwfAk9Xxo8uwuer6DnK4PnK8HzNfR8bfDsIXi+gZ5vDJ5vBM+30POtwbOn4PkOer4zeL4TPN9rwTz/exeqZy/BM0IL5hmhReieYdvhbSNCz4gGz96CZyToGcngGUnwjAw9Ixs8+wieUaBnFINnFMEzKvSMavDsK3hGg57RDJ7RBM/o0DO6wbOf4BkDesYweMYQPGNCz5gGz/6CZyzoGcvgGUvwjA09Yxs8BwiecaBnHINnHMEzLvSMa/AcKHjGg57xDJ7xBM/40DO+wXOQ4JkAeiYweCYQPBNCz4QGz8GCZyLomcjgmUjwTAw9Exs8hwieSaBnEoNnEsEzKfRMavAcKngmg57JDJ7JBM/k0DO5wXOY4JkCeqYweKYQPFNCz5QGz+GCZyromcrgmUrwTA09Uxs8/xY800DPNAbPNIJnWuiZ1uA5QvBMBz3TGTzTCZ7poWd6g+c/gmcG6JnB4JlB8Hwfer5v8BwpeGaEnhkNnhkFz0zQM5PB81/BMzP0zGzwzCx4fgA9PzB4jhI8s0DPLAbPLILnh9DzQ4PnaMEzK/TMavDMKnh+BD0/MniOETyzQc9sBs9sgufH0PNjg+dYwTM79Mxu8MwueH4CPT8xeI4TPHNAzxwGzxyC56fQ81OD53jBMyf0zGnwzCl4fgY9PzN4ThA8c0HPXAbPXILn59Dzc4PnRMEzN/TMbfDMLXh+AT2/MHhOEjzzQM88Bs88gueX0PNLg+dkwTMv9Mxr8MwreH4FPb8yeE4RPPNBz3wGz3yC59fQ82uD51TBMz/0zG/wzC94fgM9vzF4ThM8C0DPAgbPAoJnQehZ0OA5XfAsBD0LGTwLCZ7fQs9vDZ4zBM/C0LOwwbOw4Pkd9PzO4DlT8CwCPYsYPIsInt9Dz+8NnrMEz6LQs6jBs6jg+QP0/MHgOVvwLAY9ixk8iwmeP0LPHw2ecwTP4tCzuMGzuOD5E/T8yeA5V/AsAT1LGDxLCJ4/Q8+fDZ7zBM+S0LOkwbOk4PkL9PzF4Dlf8CwFPUsZPEsJnr9Cz18NngsEz9LQs7TBs7Tg+Rv0/M3guVDwLAM9yxg8ywiev0PP3w2eiwTPstCzrMGzrOD5B/T8w+C5WPAsBz3LGTzLCZ5/Qs8/DZ5LBM/y0LO8wbO84PkX9PzL4LlU8KwAPSsYPCsInhWhZ0WD5zLBsxL0rGTwrCR4VoaelQ2eywXPKtCzisGziuBZFXpWNXiuEDyrQc9qBs9qgmd16Fnd4LlS8KwBPWsYPGsInjWhZ02D5yrBsxb0rGXwrCV41oaetQ2eqwXPOtCzjsGzjuBZF3rWNXiuETzrQc96Bs96gmd96Fnf4LlW8GwAPRsYPBsIng2hZ0OD5zrBsxH0bGTwbCR4NoaejQ2e6wXPJtCzicGzieDZFHo2NXhuEDybQc9mBs9mgmdz6Nnc4LlR8GwBPVsYPFsIni2hZ0uD5ybBsxX0bGXwbCV4toaerQ2emwXPNtCzjcGzjeDZFnq2NXhuETzbQc92Bs92gmd76Nne4LlV8OwAPTsYPDsInh2hZ0eD5zbBsxP07GTw7CR4BtAzMHhuFzw7Q8/OBs/OgmcX6NnF4LlD8OwKPbsaPLsKnt2gZzeD507Bszv07G7w7C549oCePQyeuwTPntCzp8Gzp+DZC3r2MnjuFjx7Q8/eBs/egmcf6NnH4LlH8OwLPfsaPPsKnv2gZz+D517Bsz/07G/w7C94DoCeAwye+wTPgdBzoMFzoOA5CHoOMnjuFzwHQ8/BBs/BgucQ6DnE4HlA8BwKPYcaPIcKnsOg5zCD50HBczj0HG7wHC54/g09/zZ4HhI8R0DPEQbPEYLnP9DzH4PnYcFzJPQcafAcKXj+Cz3/NXgeETxHQc9RBs9Rgudo6Dna4HlU8BwDPccYPMcInmOh51iD5zHBcxz0HGfwHCd4joee4w2exwXPCdBzgsFzguA5EXpONHieEDwnQc9JBs9Jgudk6DnZ4HlS8JwCPacYPKcInlOh51SD5ynBcxr0nGbwnCZ4Toee0w2epwXPGdBzhsFzhuA5E3rONHieETxnQc9ZBs9Zguds6Dnb4HlW8JwDPecYPOcInnOh51yD5znBcx70nGfwnCd4zoee8w2e5wXPBdBzgcFzgeC5EHouNHheEDwXQc9FBs9Fgudi6LnY4HlR8FwCPZcYPJcInkuh51KD5yXBcxn0XGbwXCZ4Loeeyw2elwXPFdBzhcFzheC5EnquNHheETxXQc9VBs9Vgudq6Lna4HlV8FwDPdcYPNcInmuh51qD5zXBcx30XGfwXCd4roee6w2e1wXPDdBzg8Fzg+C5EXpuNHjeEDw3Qc9NBs9Ngudm6LnZ4HlT8NwCPbcYPLcInluh51aD5y3Bcxv03Gbw3CZ4boee2w2etwXPHdBzh8Fzh+C5E3ruNHjeETx3Qc9dBs9dgudu6Lnb4HlX8NwDPfcYPPcInnuh516D5z3Bcx/03Gfw3Cd47oee+w2e9wXPA9DzgMHzgOB5EHoeNHg+EDwPQc9DBs9Dgudh6HnY4PlQ8DwCPY8YPI8Inkeh51GD5yPB8xj0PGbwPCZ4Hoeexw2ejwXPE9DzhMHzhOB5EnqeNHg+ETxPQc9TBs9Tgudp6Hna4PlU8DwDPc8YPM8Inmeh51mD5zPB8xz0PGfwPCd4noee5w2ezwXPC9DzgsHzguB5EXpeNHi+EDwvQc9LBs9Lgudl6HnZ4PlS8LwCPa8YPK8Inleh51WD5yvB8xr0vGbwvCZ4Xoee1w2erwXPG9DzhsHzhuB5E3reNHi+ETxvQc9bBs9bgudt6Hnb4PlW8LwDPe8YPO8Inneh512D5zvB8x70vGfwvCd43oee9w2e72X53+98AD0fGDwfCJ4PoedDg2cEwfMR9Hxk8HwkeD6Gno8NnhEFzyfQ84nB84ng+RR6PjV4RhI8n0HPZwbPZ4Lnc+j53OAZWfB8AT1fGDxfCJ4voedLg2cUwfMV9Hxl8HwleL6Gnq8NnlEFzzfQ843B843g+RZ6vjV4RhM830HPdwbPd4Lney2Z53/vQvWMLnhGaMk8I7QM3TNsO7xtROgZ0eAZQ/CMBD0jGTwjCZ6RoWdkg2dMwTMK9Ixi8IwieEaFnlENnrEEz2jQM5rBM5rgGR16Rjd4xhY8Y0DPGAbPGIJnTOgZ0+AZR/CMBT1jGTxjCZ6xoWdsg2dcwTMO9Ixj8IwjeMaFnnENnvEEz3jQM57BM57gGR96xjd4xhc8E0DPBAbPBIJnQuiZ0OCZQPBMBD0TGTwTCZ6JoWdig2dCwTMJ9Exi8EwieCaFnkkNnokEz2TQM5nBM5ngmRx6Jjd4JhY8U0DPFAbPFIJnSuiZ0uCZRPBMBT1TGTxTCZ6poWdqg2dSwTMN9Exj8EwjeKaFnmkNnskEz3TQM53BM53gmR56pjd4Jhc8M0DPDAbPDILn+9DzfYNnCsEzI/TMaPDMKHhmgp6ZDJ4pBc/M0DOzwTOz4PkB9PzA4JlK8MwCPbMYPLMInh9Czw8NnqkFz6zQM6vBM6vg+RH0/MjgmUbwzAY9sxk8swmeH0PPjw2eaQXP7NAzu8Ezu+D5CfT8xOCZTvDMAT1zGDxzCJ6fQs9PDZ7pBc+c0DOnwTOn4PkZ9PzM4JlB8MwFPXMZPHMJnp9Dz88Nnu8LnrmhZ26DZ27B8wvo+YXBM6PgmQd65jF45hE8v4SeXxo8MwmeeaFnXoNnXsHzK+j5lcEzs+CZD3rmM3jmEzy/hp5fGzw/EDzzQ8/8Bs/8guc30PMbg2cWwbMA9Cxg8CwgeBaEngUNnh8KnoWgZyGDZyHB81vo+a3BM6vgWRh6FjZ4FhY8v4Oe3xk8PxI8i0DPIgbPIoLn99Dze4NnNsGzKPQsavAsKnj+AD1/MHh+LHgWg57FDJ7FBM8foeePBs/sgmdx6Fnc4Flc8PwJev5k8PxE8CwBPUsYPEsInj9Dz58NnjkEz5LQs6TBs6Tg+Qv0/MXg+angWQp6ljJ4lhI8f4Wevxo8cwqepaFnaYNnacHzN+j5m8HzM8GzDPQsY/AsI3j+Dj1/N3jmEjzLQs+yBs+ygucf0PMPg+fngmc56FnO4FlO8PwTev5p8MwteJaHnuUNnuUFz7+g518Gzy8EzwrQs4LBs4LgWRF6VjR45hE8K0HPSgbPSoJnZehZ2eD5peBZBXpWMXhWETyrQs+qBs+8gmc16FnN4FlN8KwOPasbPL8SPGtAzxoGzxqCZ03oWdPgmU/wrAU9axk8awmetaFnbYPn14JnHehZx+BZR/CsCz3rGjzzC571oGc9g2c9wbM+9Kxv8PxG8GwAPRsYPBsIng2hZ0ODZwHBsxH0bGTwbCR4NoaejQ2eBQXPJtCzicGzieDZFHo2NXgWEjybQc9mBs9mgmdz6Nnc4Pmt4NkCerYweLYQPFtCz5YGz8KCZyvo2crg2UrwbA09Wxs8vxM820DPNgbPNoJnW+jZ1uBZRPBsBz3bGTzbCZ7toWd7g+f3gmcH6NnB4NlB8OwIPTsaPIsKnp2gZyeDZyfBM4CegcHzB8GzM/TsbPDsLHh2gZ5dDJ7FBM+u0LOrwbOr4NkNenYzeP4oeHaHnt0Nnt0Fzx7Qs4fBs7jg2RN69jR49hQ8e0HPXgbPnwTP3tCzt8Gzt+DZB3r2MXiWEDz7Qs++Bs++gmc/6NnP4Pmz4NkfevY3ePYXPAdAzwEGz5KC50DoOdDgOVDwHAQ9Bxk8fxE8B0PPwQbPwYLnEOg5xOBZSvAcCj2HGjyHCp7DoOcwg+evgudw6Dnc4Dlc8Pwbev5t8CwteI6AniMMniMEz3+g5z8Gz98Ez5HQc6TBc6Tg+S/0/NfgWUbwHAU9Rxk8Rwmeo6HnaIPn74LnGOg5xuA5RvAcCz3HGjzLCp7joOc4g+c4wXM89Bxv8PxD8JwAPScYPCcInhOh50SDZznBcxL0nGTwnCR4Toaekw2efwqeU6DnFIPnFMFzKvScavAsL3hOg57TDJ7TBM/p0HO6wfMvwXMG9Jxh8JwheM6EnjMNnhUEz1nQc5bBc5bgORt6zjZ4VhQ850DPOQbPOYLnXOg51+BZSfCcBz3nGTznCZ7zoed8g2dlwXMB9Fxg8FwgeC6EngsNnlUEz0XQc5HBc5HguRh6LjZ4VhU8l0DPJQbPJYLnUui51OBZTfBcBj2XGTyXCZ7Loedyg2d1wXMF9Fxh8FwheK6EnisNnjUEz1XQc5XBc5XguRp6rjZ41hQ810DPNQbPNYLnWui51uBZS/BcBz3XGTzXCZ7roed6g2dtwXMD9Nxg8NwgeG6EnhsNnnUEz03Qc5PBc5PguRl6bjZ41hU8t0DPLQbPLYLnVui51eBZT/DcBj23GTy3CZ7boed2g2d9wXMH9Nxh8NwheO6EnjsNng0Ez13Qc5fBc5fguRt67jZ4NhQ890DPPQbPPYLnXui51+DZSPDcBz33GTz3CZ77oed+g2djwfMA9Dxg8DwgeB6EngcNnk0Ez0PQ85DB85DgeRh6HjZ4NhU8j0DPIwbPI4LnUeh51ODZTPA8Bj2PGTyPCZ7Hoedxg2dzwfME9Dxh8DwheJ6EnicNni0Ez1PQ85TB85TgeRp6njZ4thQ8z0DPMwbPM4LnWeh51uDZSvA8Bz3PGTzPCZ7noed5g2drwfMC9Lxg8LwgeF6EnhcNnm0Ez0vQ85LB85LgeRl6XjZ4thU8r0DPKwbPK4LnVeh51eDZTvC8Bj2vGTyvCZ7Xoed1g2d7wfMG9Lxh8LwheN6EnjcNnh0Ez1vQ85bB85bgeRt63jZ4dhQ870DPOwbPO4LnXeh51+DZSfC8Bz3vGTzvCZ73oed9g2cgeD6Ang8Mng8Ez4fQ86HBs7Pg+Qh6PjJ4PhI8H0PPxwbPLoLnE+j5xOD5RPB8Cj2fGjy7Cp7PoOczg+czwfM59Hxu8OwmeL6Ani8Mni8Ez5fQ86XBs7vg+Qp6vjJ4vhI8X0PP1wbPHoLnG+j5xuD5RvB8Cz3fGjx7Cp7voOc7g+c7wfO9Vszzv3ehevYSPCO0Yp4RWoXuGbYd3jYi9Ixo8OwteEaCnpEMnpEEz8jQM7LBs4/gGQV6RjF4RhE8o0LPqAbPvoJnNOgZzeAZTfCMDj2jGzz7CZ4xoGcMg2cMwTMm9Ixp8OwveMaCnrEMnrEEz9jQM7bBc4DgGQd6xjF4xhE840LPuAbPgYJnPOgZz+AZT/CMDz3jGzwHCZ4JoGcCg2cCwTMh9Exo8BwseCaCnokMnokEz8TQM7HBc4jgmQR6JjF4JhE8k0LPpAbPoYJnMuiZzOCZTPBMDj2TGzyHCZ4poGcKg2cKwTMl9Exp8BwueKaCnqkMnqkEz9TQM7XB82/BMw30TGPwTCN4poWeaQ2eIwTPdNAzncEzneCZHnqmN3j+I3hmgJ4ZDJ4ZBM/3oef7Bs+RgmdG6JnR4JlR8MwEPTMZPP8VPDNDz8wGz8yC5wfQ8wOD5yjBMwv0zGLwzCJ4fgg9PzR4jhY8s0LPrAbPrILnR9DzI4PnGMEzG/TMZvDMJnh+DD0/NniOFTyzQ8/sBs/sgucn0PMTg+c4wTMH9Mxh8MwheH4KPT81eI4XPHNCz5wGz5yC52fQ8zOD5wTBMxf0zGXwzCV4fg49Pzd4ThQ8c0PP3AbP3ILnF9DzC4PnJMEzD/TMY/DMI3h+CT2/NHhOFjzzQs+8Bs+8gudX0PMrg+cUwTMf9Mxn8MwneH4NPb82eE4VPPNDz/wGz/yC5zfQ8xuD5zTBswD0LGDwLCB4FoSeBQ2e0wXPQtCzkMGzkOD5LfT81uA5Q/AsDD0LGzwLC57fQc/vDJ4zBc8i0LOIwbOI4Pk99Pze4DlL8CwKPYsaPIsKnj9Azx8MnrMFz2LQs5jBs5jg+SP0/NHgOUfwLA49ixs8iwueP0HPnwyecwXPEtCzhMGzhOD5M/T82eA5T/AsCT1LGjxLCp6/QM9fDJ7zBc9S0LOUwbOU4Pkr9PzV4LlA8CwNPUsbPEsLnr9Bz98MngsFzzLQs4zBs4zg+Tv0/N3guUjwLAs9yxo8ywqef0DPPwyeiwXPctCznMGznOD5J/T80+C5RPAsDz3LGzzLC55/Qc+/DJ5LBc8K0LOCwbOC4FkRelY0eC4TPCtBz0oGz0qCZ2XoWdnguVzwrAI9qxg8qwieVaFnVYPnCsGzGvSsZvCsJnhWh57VDZ4rBc8a0LOGwbOG4FkTetY0eK4SPGtBz1oGz1qCZ23oWdvguVrwrAM96xg86wiedaFnXYPnGsGzHvSsZ/CsJ3jWh571DZ5rBc8G0LOBwbOB4NkQejY0eK4TPBtBz0YGz0aCZ2Po2djguV7wbAI9mxg8mwieTaFnU4PnBsGzGfRsZvBsJng2h57NDZ4bBc8W0LOFwbOF4NkSerY0eG4SPFtBz1YGz1aCZ2vo2drguVnwbAM92xg82wiebaFnW4PnFsGzHfRsZ/BsJ3i2h57tDZ5bBc8O0LODwbOD4NkRenY0eG4TPDtBz04Gz06CZwA9A4PndsGzM/TsbPDsLHh2gZ5dDJ47BM+u0LOrwbOr4NkNenYzeO4UPLtDz+4Gz+6CZw/o2cPguUvw7Ak9exo8ewqevaBnL4PnbsGzN/TsbfDsLXj2gZ59DJ57BM++0LOvwbOv4NkPevYzeO4VPPtDz/4Gz/6C5wDoOcDguU/wHAg9Bxo8Bwqeg6DnIIPnfsFzMPQcbPAcLHgOgZ5DDJ4HBM+h0HOowXOo4DkMeg4zeB4UPIdDz+EGz+GC59/Q82+D5yHBcwT0HGHwHCF4/gM9/zF4HhY8R0LPkQbPkYLnv9DzX4PnEcFzFPQcZfAcJXiOhp6jDZ5HBc8x0HOMwXOM4DkWeo41eB4TPMdBz3EGz3GC53joOd7geVzwnAA9Jxg8JwieE6HnRIPnCcFzEvScZPCcJHhOhp6TDZ4nBc8p0HOKwXOK4DkVek41eJ4SPKdBz2kGz2mC53ToOd3geVrwnAE9Zxg8ZwieM6HnTIPnGcFzFvScZfCcJXjOhp6zDZ5nBc850HOOwXOO4DkXes41eJ4TPOdBz3kGz3mC53zoOd/geV7wXAA9Fxg8FwieC6HnQoPnBcFzEfRcZPBcJHguhp6LDZ4XBc8l0HOJwXOJ4LkUei41eF4SPJdBz2UGz2WC53LoudzgeVnwXAE9Vxg8VwieK6HnSoPnFcFzFfRcZfBcJXiuhp6rDZ5XBc810HONwXON4LkWeq41eF4TPNdBz3UGz3WC53roud7geV3w3AA9Nxg8NwieG6HnRoPnDcFzE/TcZPDcJHhuhp6bDZ43Bc8t0HOLwXOL4LkVem41eN4SPLdBz20Gz22C53boud3geVvw3AE9dxg8dwieO6HnToPnHcFzF/TcZfDcJXjuhp67DZ53Bc890HOPwXOP4LkXeu41eN4TPPdBz30Gz32C537oud/geV/wPAA9Dxg8DwieB6HnQYPnA8HzEPQ8ZPA8JHgehp6HDZ4PBc8j0POIwfOI4HkUeh41eD4SPI9Bz2MGz2OC53Hoedzg+VjwPAE9Txg8TwieJ6HnSYPnE8HzFPQ8ZfA8JXiehp6nDZ5PBc8z0POMwfOM4HkWep41eD4TPM9Bz3MGz3OC53noed7g+VzwvAA9Lxg8LwieF6HnRYPnC8HzEvS8ZPC8JHhehp6XDZ4vBc8r0POKwfOK4HkVel41eL4SPK9Bz2sGz2uC53Xoed3g+VrwvAE9bxg8bwieN6HnTYPnG8HzFvS8ZfC8JXjehp63DZ5vBc870POOwfOO4HkXet51eGb93++897/dGe3d2/Tvhb3zv3eZwrlTaYe3vf+/3Rnv3euC/+/O+//DneF8Ed4Jng+g5wOD5wPB8yH0fGjwfO+j//3OR9DzkcHzkeD5GHo+NnhGEDyfQM8nBs8ngudT6PnU4BlR8HwGPZ8ZPJ8Jns+h53ODZyTB8wX0fGHwfCF4voSeLw2ekQXPV9DzlcHzleD5Gnq+NnhGETzfQM83Bs83gudb6PnW4BlV8HwHPd8ZPN8Jnu+1Zp7/vQvVM5rgGaE184zQOnTPsO3wthGhZ0SDZ3TBMxL0jGTwjCR4RoaekQ2eMQTPKNAzisEziuAZFXpGNXjGFDyjQc9oBs9ogmd06Bnd4BlL8IwBPWMYPGMInjGhZ0yDZ2zBMxb0jGXwjCV4xoaesQ2ecQTPONAzjsEzjuAZF3rGNXjGFTzjQc94Bs94gmd86Bnf4BlP8EwAPRMYPBMIngmhZ0KDZ3zBMxH0TGTwTCR4JoaeiQ2eCQTPJNAzicEzieCZFHomNXgmFDyTQc9kBs9kgmdy6Jnc4JlI8EwBPVMYPFMInimhZ0qDZ2LBMxX0TGXwTCV4poaeqQ2eSQTPNNAzjcEzjeCZFnqmNXgmFTzTQc90Bs90gmd66Jne4JlM8MwAPTMYPDMInu9Dz/cNnskFz4zQM6PBM6PgmQl6ZjJ4phA8M0PPzAbPzILnB9DzA4NnSsEzC/TMYvDMInh+CD0/NHimEjyzQs+sBs+sgudH0PMjg2dqwTMb9Mxm8MwmeH4MPT82eKYRPLNDz+wGz+yC5yfQ8xODZ1rBMwf0zGHwzCF4fgo9PzV4phM8c0LPnAbPnILnZ9DzM4NnesEzF/TMZfDMJXh+Dj0/N3hmEDxzQ8/cBs/cgucX0PMLg+f7gmce6JnH4JlH8PwSen5p8MwoeOaFnnkNnnkFz6+g51cGz0yCZz7omc/gmU/w/Bp6fm3wzCx45oee+Q2e+QXPb6DnNwbPDwTPAtCzgMGzgOBZEHoWNHhmETwLQc9CBs9Cgue30PNbg+eHgmdh6FnY4FlY8PwOen5n8MwqeBaBnkUMnkUEz++h5/cGz48Ez6LQs6jBs6jg+QP0/MHgmU3wLAY9ixk8iwmeP0LPHw2eHwuexaFncYNnccHzJ+j5k8Ezu+BZAnqWMHiWEDx/hp4/Gzw/ETxLQs+SBs+Sgucv0PMXg2cOwbMU9Cxl8CwleP4KPX81eH4qeJaGnqUNnqUFz9+g528Gz5yCZxnoWcbgWUbw/B16/m7w/EzwLAs9yxo8ywqef0DPPwyeuQTPctCznMGznOD5J/T80+D5ueBZHnqWN3iWFzz/gp5/GTxzC54VoGcFg2cFwbMi9Kxo8PxC8KwEPSsZPCsJnpWhZ2WDZx7Bswr0rGLwrCJ4VoWeVQ2eXwqe1aBnNYNnNcGzOvSsbvDMK3jWgJ41DJ41BM+a0LOmwfMrwbMW9Kxl8KwleNaGnrUNnvkEzzrQs47Bs47gWRd61jV4fi141oOe9Qye9QTP+tCzvsEzv+DZAHo2MHg2EDwbQs+GBs9vBM9G0LORwbOR4NkYejY2eBYQPJtAzyYGzyaCZ1Po2dTgWVDwbAY9mxk8mwmezaFnc4NnIcGzBfRsYfBsIXi2hJ4tDZ7fCp6toGcrg2crwbM19Gxt8CwseLaBnm0Mnm0Ez7bQs63B8zvBsx30bGfwbCd4toee7Q2eRQTPDtCzg8Gzg+DZEXp2NHh+L3h2gp6dDJ6dBM8AegYGz6KCZ2fo2dng2Vnw7AI9uxg8fxA8u0LPrgbProJnN+jZzeBZTPDsDj27Gzy7C549oGcPg+ePgmdP6NnT4NlT8OwFPXsZPIsLnr2hZ2+DZ2/Bsw/07GPw/Enw7As9+xo8+wqe/aBnP4NnCcGzP/Tsb/DsL3gOgJ4DDJ4/C54DoedAg+dAwXMQ9Bxk8CwpeA6GnoMNnoMFzyHQc4jB8xfBcyj0HGrwHCp4DoOewwyepQTP4dBzuMFzuOD5N/T82+D5q+A5AnqOMHiOEDz/gZ7/GDxLC54joedIg+dIwfNf6PmvwfM3wXMU9Bxl8BwleI6GnqMNnmUEzzHQc4zBc4zgORZ6jjV4/i54joOe4wye4wTP8dBzvMGzrOA5AXpOMHhOEDwnQs+JBs8/BM9J0HOSwXOS4DkZek42eJYTPKdAzykGzymC51ToOdXg+afgOQ16TjN4ThM8p0PP6QbP8oLnDOg5w+A5Q/CcCT1nGjz/EjxnQc9ZBs9Zguds6Dnb4FlB8JwDPecYPOcInnOh51yDZ0XBcx70nGfwnCd4zoee8w2elQTPBdBzgcFzgeC5EHouNHhWFjwXQc9FBs9Fgudi6LnY4FlF8FwCPZcYPJcInkuh51KDZ1XBcxn0XGbwXCZ4Loeeyw2e1QTPFdBzhcFzheC5EnquNHhWFzxXQc9VBs9Vgudq6Lna4FlD8FwDPdcYPNcInmuh51qDZ03Bcx30XGfwXCd4roee6w2etQTPDdBzg8Fzg+C5EXpuNHjWFjw3Qc9NBs9Ngudm6LnZ4FlH8NwCPbcYPLcInluh51aDZ13Bcxv03Gbw3CZ4boee2w2e9QTPHdBzh8Fzh+C5E3ruNHjWFzx3Qc9dBs9dgudu6Lnb4NlA8NwDPfcYPPcInnuh516DZ0PBcx/03Gfw3Cd47oee+w2ejQTPA9DzgMHzgOB5EHoeNHg2FjwPQc9DBs9Dgudh6HnY4NlE8DwCPY8YPI8Inkeh51GDZ1PB8xj0PGbwPCZ4Hoeexw2ezQTPE9DzhMHzhOB5EnqeNHg2FzxPQc9TBs9Tgudp6Hna4NlC8DwDPc8YPM8Inmeh51mDZ0vB8xz0PGfwPCd4noee5w2erQTPC9DzgsHzguB5EXpeNHi2FjwvQc9LBs9Lgudl6HnZ4NlG8LwCPa8YPK8Inleh51WDZ1vB8xr0vGbwvCZ4Xoee1w2e7QTPG9DzhsHzhuB5E3reNHi2FzxvQc9bBs9bgudt6Hnb4NlB8LwDPe8YPO8Inneh512DZ0fB8x70vGfwvCd43oee9w2enQTPB9DzgcHzgeD5EHo+NHgGgucj6PnI4PlI8HwMPR8bPDsLnk+g5xOD5xPB8yn0fGrw7CJ4PoOezwyezwTP59DzucGzq+D5Anq+MHi+EDxfQs+XBs9ugucr6PnK4PlK8HwNPV8bPLsLnm+g5xuD5xvB8y30fGvw7CF4voOe7wye7wTP99owz//eherZU/CM0IZ5RmgTumfYdnjbiNAzosGzl+AZCXpGMnhGEjwjQ8/IBs/egmcU6BnF4BlF8IwKPaMaPPsIntGgZzSDZzTBMzr0jG7w7Ct4xoCeMQyeMQTPmNAzpsGzn+AZC3rGMnjGEjxjQ8/YBs/+gmcc6BnH4BlH8IwLPeMaPAcInvGgZzyDZzzBMz70jG/wHCh4JoCeCQyeCQTPhNAzocFzkOCZCHomMngmEjwTQ8/EBs/BgmcS6JnE4JlE8EwKPZMaPIcInsmgZzKDZzLBMzn0TG7wHCp4poCeKQyeKQTPlNAzpcFzmOCZCnqmMnimEjxTQ8/UBs/hgmca6JnG4JlG8EwLPdMaPP8WPNNBz3QGz3SCZ3romd7gOULwzAA9Mxg8Mwie70PP9w2e/wieGaFnRoNnRsEzE/TMZPAcKXhmhp6ZDZ6ZBc8PoOcHBs9/Bc8s0DOLwTOL4Pkh9PzQ4DlK8MwKPbMaPLMKnh9Bz48MnqMFz2zQM5vBM5vg+TH0/NjgOUbwzA49sxs8swuen0DPTwyeYwXPHNAzh8Ezh+D5KfT81OA5TvDMCT1zGjxzCp6fQc/PDJ7jBc9c0DOXwTOX4Pk59Pzc4DlB8MwNPXMbPHMLnl9Azy8MnhMFzzzQM4/BM4/g+SX0/NLgOUnwzAs98xo88wqeX0HPrwyekwXPfNAzn8Ezn+D5NfT82uA5RfDMDz3zGzzzC57fQM9vDJ5TBc8C0LOAwbOA4FkQehY0eE4TPAtBz0IGz0KC57fQ81uD53TBszD0LGzwLCx4fgc9vzN4zhA8i0DPIgbPIoLn99Dze4PnTMGzKPQsavAsKnj+AD1/MHjOEjyLQc9iBs9igueP0PNHg+dswbM49Cxu8CwueP4EPX8yeM4RPEtAzxIGzxKC58/Q82eD51zBsyT0LGnwLCl4/gI9fzF4zhM8S0HPUgbPUoLnr9DzV4PnfMGzNPQsbfAsLXj+Bj1/M3guEDzLQM8yBs8ygufv0PN3g+dCwbMs9Cxr8CwreP4BPf8weC4SPMtBz3IGz3KC55/Q80+D52LBszz0LG/wLC94/gU9/zJ4LhE8K0DPCgbPCoJnRehZ0eC5VPCsBD0rGTwrCZ6VoWdlg+cywbMK9Kxi8KwieFaFnlUNnssFz2rQs5rBs5rgWR16Vjd4rhA8a0DPGgbPGoJnTehZ0+C5UvCsBT1rGTxrCZ61oWdtg+cqwbMO9Kxj8KwjeNaFnnUNnqsFz3rQs57Bs57gWR961jd4rhE8G0DPBgbPBoJnQ+jZ0OC5VvBsBD0bGTwbCZ6NoWdjg+c6wbMJ9Gxi8GwieDaFnk0NnusFz2bQs5nBs5ng2Rx6Njd4bhA8W0DPFgbPFoJnS+jZ0uC5UfBsBT1bGTxbCZ6toWdrg+cmwbMN9Gxj8GwjeLaFnm0NnpsFz3bQs53Bs53g2R56tjd4bhE8O0DPDgbPDoJnR+jZ0eC5VfDsBD07GTw7CZ4B9AwMntsEz87Qs7PBs7Pg2QV6djF4bhc8u0LPrgbProJnN+jZzeC5Q/DsDj27Gzy7C549oGcPg+dOwbMn9Oxp8OwpePaCnr0MnrsEz97Qs7fBs7fg2Qd69jF47hY8+0LPvgbPvoJnP+jZz+C5R/DsDz37Gzz7C54DoOcAg+dewXMg9Bxo8BwoeA6CnoMMnvsEz8HQc7DBc7DgOQR6DjF47hc8h0LPoQbPoYLnMOg5zOB5QPAcDj2HGzyHC55/Q8+/DZ4HBc8R0HOEwXOE4PkP9PzH4HlI8BwJPUcaPEcKnv9Cz38NnocFz1HQc5TBc5TgORp6jjZ4HhE8x0DPMQbPMYLnWOg51uB5VPAcBz3HGTzHCZ7joed4g+cxwXMC9Jxg8JwgeE6EnhMNnscFz0nQc5LBc5LgORl6TjZ4nhA8p0DPKQbPKYLnVOg51eB5UvCcBj2nGTynCZ7Toed0g+cpwXMG9Jxh8JwheM6EnjMNnqcFz1nQc5bBc5bgORt6zjZ4nhE850DPOQbPOYLnXOg51+B5VvCcBz3nGTznCZ7zoed8g+c5wXMB9Fxg8FwgeC6EngsNnucFz0XQc5HBc5HguRh6LjZ4XhA8l0DPJQbPJYLnUui51OB5UfBcBj2XGTyXCZ7Loedyg+clwXMF9Fxh8FwheK6EnisNnpcFz1XQc5XBc5XguRp6rjZ4XhE810DPNQbPNYLnWui51uB5VfBcBz3XGTzXCZ7roed6g+c1wXMD9Nxg8NwgeG6EnhsNntcFz03Qc5PBc5PguRl6bjZ43hA8t0DPLQbPLYLnVui51eB5U/DcBj23GTy3CZ7boed2g+ctwXMH9Nxh8NwheO6EnjsNnrcFz13Qc5fBc5fguRt67jZ43hE890DPPQbPPYLnXui51+B5V/DcBz33GTz3CZ77oed+g+c9wfMA9Dxg8DwgeB6EngcNnvcFz0PQ85DB85DgeRh6HjZ4PhA8j0DPIwbPI4LnUeh51OD5UPA8Bj2PGTyPCZ7Hoedxg+cjwfME9Dxh8DwheJ6EnicNno8Fz1PQ85TB85TgeRp6njZ4PhE8z0DPMwbPM4LnWeh51uD5VPA8Bz3PGTzPCZ7noed5g+czwfMC9Lxg8LwgeF6EnhcNns8Fz0vQ85LB85LgeRl6XjZ4vhA8r0DPKwbPK4LnVeh51eD5UvC8Bj2vGTyvCZ7Xoed1g+crwfMG9Lxh8LwheN6EnjcNnq8Fz1vQ85bB85bgeRt63jZ4vhE870DPOwbPO4LnXeh51+D5VvC8Bz3vGTzvCZ73oed9g+c7wfMB9Hxg8HwgeD6Eng8Nnu9l+9/vfAQ9Hxk8Hwmej6HnY4NnBMHzCfR8YvB8Ing+hZ5PDZ4RBc9n0POZwfOZ4Pkcej43eEYSPF9AzxcGzxeC50vo+dLgGVnwfAU9Xxk8Xwmer6Hna4NnFMHzDfR8Y/B8I3i+hZ5vDZ5RBc930POdwfOd4PleW+b537tQPaMJnhHaMs8IbUP3DNsObxsRekY0eEYXPCNBz0gGz0iCZ2ToGdngGUPwjAI9oxg8owieUaFnVINnTMEzGvSMZvCMJnhGh57RDZ6xBM8Y0DOGwTOG4BkTesY0eMYWPGNBz1gGz1iCZ2zoGdvgGUfwjAM94xg84wiecaFnXINnXMEzHvSMZ/CMJ3jGh57xDZ7xBM8E0DOBwTOB4JkQeiY0eMYXPBNBz0QGz0SCZ2LomdjgmUDwTAI9kxg8kwieSaFnUoNnQsEzGfRMZvBMJngmh57JDZ6JBM8U0DOFwTOF4JkSeqY0eCYWPFNBz1QGz1SCZ2romdrgmUTwTAM90xg80wieaaFnWoNnUsEzHfRMZ/BMJ3imh57pDZ7JBM8M0DODwTOD4Pk+9Hzf4Jlc8MwIPTMaPDMKnpmgZyaDZwrBMzP0zGzwzCx4fgA9PzB4phQ8s0DPLAbPLILnh9DzQ4NnKsEzK/TMavDMKnh+BD0/MnimFjyzQc9sBs9sgufH0PNjg2cawTM79Mxu8MwueH4CPT8xeKYVPHNAzxwGzxyC56fQ81ODZzrBMyf0zGnwzCl4fgY9PzN4phc8c0HPXAbPXILn59Dzc4NnBsEzN/TMbfDMLXh+AT2/MHi+L3jmgZ55DJ55BM8voeeXBs+Mgmde6JnX4JlX8PwKen5l8MwkeOaDnvkMnvkEz6+h59cGz8yCZ37omd/gmV/w/AZ6fmPw/EDwLAA9Cxg8CwieBaFnQYNnFsGzEPQsZPAsJHh+Cz2/NXh+KHgWhp6FDZ6FBc/voOd3Bs+sgmcR6FnE4FlE8Pween5v8PxI8CwKPYsaPIsKnj9Azx8MntkEz2LQs5jBs5jg+SP0/NHg+bHgWRx6Fjd4Fhc8f4KePxk8swueJaBnCYNnCcHzZ+j5s8HzE8GzJPQsafAsKXj+Aj1/MXjmEDxLQc9SBs9Sguev0PNXg+engmdp6Fna4Fla8PwNev5m8MwpeJaBnmUMnmUEz9+h5+8Gz88Ez7LQs6zBs6zg+Qf0/MPgmUvwLAc9yxk8ywmef0LPPw2enwue5aFneYNnecHzL+j5l8Ezt+BZAXpWMHhWEDwrQs+KBs8vBM9K0LOSwbOS4FkZelY2eOYRPKtAzyoGzyqCZ1XoWdXg+aXgWQ16VjN4VhM8q0PP6gbPvIJnDehZw+BZQ/CsCT1rGjy/EjxrQc9aBs9agmdt6Fnb4JlP8KwDPesYPOsInnWhZ12D59eCZz3oWc/gWU/wrA896xs88wueDaBnA4NnA8GzIfRsaPD8RvBsBD0bGTwbCZ6NoWdjg2cBwbMJ9Gxi8GwieDaFnk0NngUFz2bQs5nBs5ng2Rx6Njd4FhI8W0DPFgbPFoJnS+jZ0uD5reDZCnq2Mni2EjxbQ8/WBs/Cgmcb6NnG4NlG8GwLPdsaPL8TPNtBz3YGz3aCZ3vo2d7gWUTw7AA9Oxg8OwieHaFnR4Pn94JnJ+jZyeDZSfAMoGdg8CwqeHaGnp0Nnp0Fzy7Qs4vB8wfBsyv07Grw7Cp4doOe3QyexQTP7tCzu8Gzu+DZA3r2MHj+KHj2hJ49DZ49Bc9e0LOXwbO44NkbevY2ePYWPPtAzz4Gz58Ez77Qs6/Bs6/g2Q969jN4lhA8+0PP/gbP/oLnAOg5wOD5s+A5EHoONHgOFDwHQc9BBs+Sgudg6DnY4DlY8BwCPYcYPH8RPIdCz6EGz6GC5zDoOczgWUrwHA49hxs8hwuef0PPvw2evwqeI6DnCIPnCMHzH+j5j8GztOA5EnqONHiOFDz/hZ7/Gjx/EzxHQc9RBs9Rgudo6Dna4FlG8BwDPccYPMcInmOh51iD5++C5zjoOc7gOU7wHA89xxs8ywqeE6DnBIPnBMFzIvScaPD8Q/CcBD0nGTwnCZ6Toedkg2c5wXMK9Jxi8JwieE6FnlMNnn8KntOg5zSD5zTBczr0nG7wLC94zoCeMwyeMwTPmdBzpsHzL8FzFvScZfCcJXjOhp6zDZ4VBM850HOOwXOO4DkXes41eFYUPOdBz3kGz3mC53zoOd/gWUnwXAA9Fxg8FwieC6HnQoNnZcFzEfRcZPBcJHguhp6LDZ5VBM8l0HOJwXOJ4LkUei41eFYVPJdBz2UGz2WC53LoudzgWU3wXAE9Vxg8VwieK6HnSoNndcFzFfRcZfBcJXiuhp6rDZ41BM810HONwXON4LkWeq41eNYUPNdBz3UGz3WC53roud7gWUvw3AA9Nxg8NwieG6HnRoNnbcFzE/TcZPDcJHhuhp6bDZ51BM8t0HOLwXOL4LkVem41eNYVPLdBz20Gz22C53boud3gWU/w3AE9dxg8dwieO6HnToNnfcFzF/TcZfDcJXjuhp67DZ4NBM890HOPwXOP4LkXeu41eDYUPPdBz30Gz32C537oud/g2UjwPAA9Dxg8DwieB6HnQYNnY8HzEPQ8ZPA8JHgehp6HDZ5NBM8j0POIwfOI4HkUeh41eDYVPI9Bz2MGz2OC53Hoedzg2UzwPAE9Txg8TwieJ6HnSYNnc8HzFPQ8ZfA8JXiehp6nDZ4tBM8z0POMwfOM4HkWep41eLYUPM9Bz3MGz3OC53noed7g2UrwvAA9Lxg8LwieF6HnRYNna8HzEvS8ZPC8JHhehp6XDZ5tBM8r0POKwfOK4HkVel41eLYVPK9Bz2sGz2uC53Xoed3g2U7wvAE9bxg8bwieN6HnTYNne8HzFvS8ZfC8JXjehp63DZ4dBM870POOwfOO4HkXet41eHYUPO9Bz3sGz3uC533oed/g2UnwfAA9Hxg8HwieD6HnQ4NnIHg+gp6PDJ6PBM/H0POxwbOz4PkEej4xeD4RPJ9Cz6cGzy6C5zPo+czg+UzwfA49nxs8uwqeL6DnC4PnC8HzJfR8afDsJni+gp6vDJ6vBM/X0PO1wbO74PkGer4xeL4RPN9Cz7cGzx6C5zvo+c7g+U7wfK8d8/zvXaiePQXPCO2YZ4R2oXuGbYe3jQg9Ixo8ewmekaBnJINnJMEzMvSMbPDsLXhGgZ5RDJ5RBM+o0DOqwbOP4BkNekYzeEYTPKNDz+gGz76CZwzoGcPgGUPwjAk9Yxo8+wmesaBnLINnLMEzNvSMbfDsL3jGgZ5xDJ5xBM+40DOuwXOA4BkPesYzeMYTPONDz/gGz4GCZwLomcDgmUDwTAg9Exo8BwmeiaBnIoNnIsEzMfRMbPAcLHgmgZ5JDJ5JBM+k0DOpwXOI4JkMeiYzeCYTPJNDz+QGz6GCZwromcLgmULwTAk9Uxo8hwmeqaBnKoNnKsEzNfRMbfAcLnimgZ5pDJ5pBM+00DOtwfNvwTMd9Exn8EwneKaHnukNniMEzwzQM4PBM4Pg+T70fN/g+Y/gmRF6ZjR4ZhQ8M0HPTAbPkYJnZuiZ2eCZWfD8AHp+YPD8V/DMAj2zGDyzCJ4fQs8PDZ6jBM+s0DOrwTOr4PkR9PzI4Dla8MwGPbMZPLMJnh9Dz48NnmMEz+zQM7vBM7vg+Qn0/MTgOVbwzAE9cxg8cwien0LPTw2e4wTPnNAzp8Ezp+D5GfT8zOA5XvDMBT1zGTxzCZ6fQ8/PDZ4TBM/c0DO3wTO34PkF9PzC4DlR8MwDPfMYPPMInl9Czy8NnpMEz7zQM6/BM6/g+RX0/MrgOVnwzAc98xk88wmeX0PPrw2eUwTP/NAzv8Ezv+D5DfT8xuA5VfAsAD0LGDwLCJ4FoWdBg+c0wbMQ9Cxk8CwkeH4LPb81eE4XPAtDz8IGz8KC53fQ8zuD5wzBswj0LGLwLCJ4fg89vzd4zhQ8i0LPogbPooLnD9DzB4PnLMGzGPQsZvAsJnj+CD1/NHjOFjyLQ8/iBs/igudP0PMng+ccwbME9Cxh8CwheP4MPX82eM4VPEtCz5IGz5KC5y/Q8xeD5zzBsxT0LGXwLCV4/go9fzV4zhc8S0PP0gbP0oLnb9DzN4PnAsGzDPQsY/AsI3j+Dj1/N3guFDzLQs+yBs+ygucf0PMPg+ciwbMc9Cxn8CwneP4JPf80eC4WPMtDz/IGz/KC51/Q8y+D5xLBswL0rGDwrCB4VoSeFQ2eSwXPStCzksGzkuBZGXpWNnguEzyrQM8qBs8qgmdV6FnV4Llc8KwGPasZPKsJntWhZ3WD5wrBswb0rGHwrCF41oSeNQ2eKwXPWtCzlsGzluBZG3rWNniuEjzrQM86Bs86gmdd6FnX4Lla8KwHPesZPOsJnvWhZ32D5xrBswH0bGDwbCB4NoSeDQ2eawXPRtCzkcGzkeDZGHo2NniuEzybQM8mBs8mgmdT6NnU4Lle8GwGPZsZPJsJns2hZ3OD5wbBswX0bGHwbCF4toSeLQ2eGwXPVtCzlcGzleDZGnq2NnhuEjzbQM82Bs82gmdb6NnW4LlZ8GwHPdsZPNsJnu2hZ3uD5xbBswP07GDw7CB4doSeHQ2eWwXPTtCzk8Gzk+AZQM/A4LlN8OwMPTsbPDsLnl2gZxeD53bBsyv07Grw7Cp4doOe3QyeOwTP7tCzu8Gzu+DZA3r2MHjuFDx7Qs+eBs+egmcv6NnL4LlL8OwNPXsbPHsLnn2gZx+D527Bsy/07Gvw7Ct49oOe/QyeewTP/tCzv8Gzv+A5AHoOMHjuFTwHQs+BBs+Bgucg6DnI4LlP8BwMPQcbPAcLnkOg5xCD537Bcyj0HGrwHCp4DoOewwyeBwTP4dBzuMFzuOD5N/T82+B5UPAcAT1HGDxHCJ7/QM9/DJ6HBM+R0HOkwXOk4Pkv9PzX4HlY8BwFPUcZPEcJnqOh52iD5xHBcwz0HGPwHCN4joWeYw2eRwXPcdBznMFznOA5HnqON3geEzwnQM8JBs8JgudE6DnR4Hlc8JwEPScZPCcJnpOh52SD5wnBcwr0nGLwnCJ4ToWeUw2eJwXPadBzmsFzmuA5HXpON3ieEjxnQM8ZBs8ZgudM6DnT4Hla8JwFPWcZPGcJnrOh52yD5xnBcw70nGPwnCN4zoWecw2eZwXPedBznsFznuA5H3rON3ieEzwXQM8FBs8FgudC6LnQ4Hle8FwEPRcZPBcJnouh52KD5wXBcwn0XGLwXCJ4LoWeSw2eFwXPZdBzmcFzmeC5HHouN3heEjxXQM8VBs8VgudK6LnS4HlZ8FwFPVcZPFcJnquh52qD5xXBcw30XGPwXCN4roWeaw2eVwXPddBzncFzneC5HnquN3heEzw3QM8NBs8NgudG6LnR4Hld8NwEPTcZPDcJnpuh52aD5w3Bcwv03GLw3CJ4boWeWw2eNwXPbdBzm8Fzm+C5HXpuN3jeEjx3QM8dBs8dgudO6LnT4Hlb8NwFPXcZPHcJnruh526D5x3Bcw/03GPw3CN47oWeew2edwXPfdBzn8Fzn+C5H3ruN3jeEzwPQM8DBs8DgudB6HnQ4Hlf8DwEPQ8ZPA8Jnoeh52GD5wPB8wj0PGLwPCJ4HoWeRw2eDwXPY9DzmMHzmOB5HHoeN3g+EjxPQM8TBs8TgudJ6HnS4PlY8DwFPU8ZPE8Jnqeh52mD5xPB8wz0PGPwPCN4noWeZw2eTwXPc9DznMHznOB5HnqeN3g+EzwvQM8LBs8LgudF6HnR4Plc8LwEPS8ZPC8Jnpeh52WD5wvB8wr0vGLwvCJ4XoWeVw2eLwXPa9DzmsHzmuB5HXpeN3i+EjxvQM8bBs8bgudN6HnT4Pla8LwFPW8ZPG8Jnreh522HZ47//c477f7X/0b4f3f+9y5mOHcq7fC2d//nOyP+vzvv/g93hvNFeCN43oOe9wye9wTP+9DzvsHzreD5AHo+MHg+EDwfQs+HBs93gucj6PnI4PlI8HwMPR8bPN/79H+/8wn0fGLwfCJ4PoWeTw2eEQTPZ9DzmcHzmeD5HHo+N3hGFDxfQM8XBs8XgudL6PnS4BlJ8HwFPV8ZPF8Jnq+h52uDZ2TB8w30fGPwfCN4voWebw2eUQTPd9DzncHzneD5Xnvm+d+7UD2jCp4R2jPPCO1D9wzbDm8bEXpGNHhGEzwjQc9IBs9Igmdk6BnZ4Bld8IwCPaMYPKMInlGhZ1SDZwzBMxr0jGbwjCZ4Roee0Q2eMQXPGNAzhsEzhuAZE3rGNHjGEjxjQc9YBs9Ygmds6Bnb4Blb8IwDPeMYPOMInnGhZ1yDZxzBMx70jGfwjCd4xoee8Q2ecQXPBNAzgcEzgeCZEHomNHjGEzwTQc9EBs9Egmdi6JnY4Blf8EwCPZMYPJMInkmhZ1KDZwLBMxn0TGbwTCZ4JoeeyQ2eCQXPFNAzhcEzheCZEnqmNHgmEjxTQc9UBs9Ugmdq6Jna4JlY8EwDPdMYPNMInmmhZ1qDZxLBMx30TGfwTCd4poee6Q2eSQXPDNAzg8Ezg+D5PvR83+CZTPDMCD0zGjwzCp6ZoGcmg2dywTMz9Mxs8MwseH4APT8weKYQPLNAzywGzyyC54fQ80ODZ0rBMyv0zGrwzCp4fgQ9PzJ4phI8s0HPbAbPbILnx9DzY4NnasEzO/TMbvDMLnh+Aj0/MXimETxzQM8cBs8cguen0PNTg2dawTMn9Mxp8MwpeH4GPT8zeKYTPHNBz1wGz1yC5+fQ83ODZ3rBMzf0zG3wzC14fgE9vzB4ZhA880DPPAbPPILnl9DzS4Pn+4JnXuiZ1+CZV/D8Cnp+ZfDMKHjmg575DJ75BM+voefXBs9Mgmd+6Jnf4Jlf8PwGen5j8MwseBaAngUMngUEz4LQs6DB8wPBsxD0LGTwLCR4fgs9vzV4ZhE8C0PPwgbPwoLnd9DzO4Pnh4JnEehZxOBZRPD8Hnp+b/DMKngWhZ5FDZ5FBc8foOcPBs+PBM9i0LOYwbOY4Pkj9PzR4JlN8CwOPYsbPIsLnj9Bz58Mnh8LniWgZwmDZwnB82fo+bPBM7vgWRJ6ljR4lhQ8f4Gevxg8PxE8S0HPUgbPUoLnr9DzV4NnDsGzNPQsbfAsLXj+Bj1/M3h+KniWgZ5lDJ5lBM/foefvBs+cgmdZ6FnW4FlW8PwDev5h8PxM8CwHPcsZPMsJnn9Czz8NnrkEz/LQs7zBs7zg+Rf0/Mvg+bngWQF6VjB4VhA8K0LPigbP3IJnJehZyeBZSfCsDD0rGzy/EDyrQM8qBs8qgmdV6FnV4JlH8KwGPasZPKsJntWhZ3WD55eCZw3oWcPgWUPwrAk9axo88wqetaBnLYNnLcGzNvSsbfD8SvCsAz3rGDzrCJ51oWddg2c+wbMe9Kxn8KwneNaHnvUNnl8Lng2gZwODZwPBsyH0bGjwzC94NoKejQyejQTPxtCzscHzG8GzCfRsYvBsIng2hZ5NDZ4FBM9m0LOZwbOZ4NkcejY3eBYUPFtAzxYGzxaCZ0vo2dLgWUjwbAU9Wxk8WwmeraFna4Pnt4JnG+jZxuDZRvBsCz3bGjwLC57toGc7g2c7wbM99Gxv8PxO8OwAPTsYPDsInh2hZ0eDZxHBsxP07GTw7CR4BtAzMHh+L3h2hp6dDZ6dBc8u0LOLwbOo4NkVenY1eHYVPLtBz24Gzx8Ez+7Qs7vBs7vg2QN69jB4FhM8e0LPngbPnoJnL+jZy+D5o+DZG3r2Nnj2Fjz7QM8+Bs/igmdf6NnX4NlX8OwHPfsZPH8SPPtDz/4Gz/6C5wDoOcDgWULwHAg9Bxo8Bwqeg6DnIIPnz4LnYOg52OA5WPAcAj2HGDxLCp5DoedQg+dQwXMY9Bxm8PxF8BwOPYcbPIcLnn9Dz78NnqUEzxHQc4TBc4Tg+Q/0/Mfg+avgORJ6jjR4jhQ8/4We/xo8Swueo6DnKIPnKMFzNPQcbfD8TfAcAz3HGDzHCJ5joedYg2cZwXMc9Bxn8BwneI6HnuMNnr8LnhOg5wSD5wTBcyL0nGjwLCt4ToKekwyekwTPydBzssHzD8FzCvScYvCcInhOhZ5TDZ7lBM9p0HOawXOa4Dkdek43eP4peM6AnjMMnjMEz5nQc6bBs7zgOQt6zjJ4zhI8Z0PP2QbPvwTPOdBzjsFzjuA5F3rONXhWEDznQc95Bs95gud86Dnf4FlR8FwAPRcYPBcInguh50KDZyXBcxH0XGTwXCR4Loaeiw2elQXPJdBzicFzieC5FHouNXhWETyXQc9lBs9lgudy6Lnc4FlV8FwBPVcYPFcIniuh50qDZzXBcxX0XGXwXCV4roaeqw2e1QXPNdBzjcFzjeC5FnquNXjWEDzXQc91Bs91gud66Lne4FlT8NwAPTcYPDcInhuh50aDZy3BcxP03GTw3CR4boaemw2etQXPLdBzi8Fzi+C5FXpuNXjWETy3Qc9tBs9tgud26Lnd4FlX8NwBPXcYPHcInjuh506DZz3Bcxf03GXw3CV47oaeuw2e9QXPPdBzj8Fzj+C5F3ruNXg2EDz3Qc99Bs99gud+6Lnf4NlQ8DwAPQ8YPA8Ingeh50GDZyPB8xD0PGTwPCR4Hoaehw2ejQXPI9DziMHziOB5FHoeNXg2ETyPQc9jBs9jgudx6Hnc4NlU8DwBPU8YPE8Inieh50mDZzPB8xT0PGXwPCV4noaepw2ezQXPM9DzjMHzjOB5FnqeNXi2EDzPQc9zBs9zgud56Hne4NlS8LwAPS8YPC8Inheh50WDZyvB8xL0vGTwvCR4Xoaelw2erQXPK9DzisHziuB5FXpeNXi2ETyvQc9rBs9rgud16Hnd4NlW8LwBPW8YPG8Injeh502DZzvB8xb0vGXwvCV43oaetw2e7QXPO9DzjsHzjuB5F3reNXh2EDzvQc97Bs97gud96Hnf4NlR8HwAPR8YPB8Ing+h50ODZyfB8xH0fGTwfCR4Poaejw2egeD5BHo+MXg+ETyfQs+nBs/Ogucz6PnM4PlM8HwOPZ8bPLsIni+g5wuD5wvB8yX0fGnw7Cp4voKerwyerwTP19DztcGzm+D5Bnq+MXi+ETzfQs+3Bs/uguc76PnO4PlO8HyvA/P8712onj0EzwgdmGeEDqF7hm2Ht40IPSMaPHsKnpGgZySDZyTBMzL0jGzw7CV4RoGeUQyeUQTPqNAzqsGzt+AZDXpGM3hGEzyjQ8/oBs8+gmcM6BnD4BlD8IwJPWMaPPsKnrGgZyyDZyzBMzb0jG3w7Cd4xoGecQyecQTPuNAzrsGzv+AZD3rGM3jGEzzjQ8/4Bs8BgmcC6JnA4JlA8EwIPRMaPAcKnomgZyKDZyLBMzH0TGzwHCR4JoGeSQyeSQTPpNAzqcFzsOCZDHomM3gmEzyTQ8/kBs8hgmcK6JnC4JlC8EwJPVMaPIcKnqmgZyqDZyrBMzX0TG3wHCZ4poGeaQyeaQTPtNAzrcFzuOCZDnqmM3imEzzTQ8/0Bs+/Bc8M0DODwTOD4Pk+9Hzf4DlC8MwIPTMaPDMKnpmgZyaD5z+CZ2bomdngmVnw/AB6fmDwHCl4ZoGeWQyeWQTPD6HnhwbPfwXPrNAzq8Ezq+D5EfT8yOA5SvDMBj2zGTyzCZ4fQ8+PDZ6jBc/s0DO7wTO74PkJ9PzE4DlG8MwBPXMYPHMInp9Cz08NnmMFz5zQM6fBM6fg+Rn0/MzgOU7wzAU9cxk8cwmen0PPzw2e4wXP3NAzt8Ezt+D5BfT8wuA5QfDMAz3zGDzzCJ5fQs8vDZ4TBc+80DOvwTOv4PkV9PzK4DlJ8MwHPfMZPPMJnl9Dz68NnpMFz/zQM7/BM7/g+Q30/MbgOUXwLAA9Cxg8CwieBaFnQYPnVMGzEPQsZPAsJHh+Cz2/NXhOEzwLQ8/CBs/Cgud30PM7g+d0wbMI9Cxi8CwieH4PPb83eM4QPItCz6IGz6KC5w/Q8weD50zBsxj0LGbwLCZ4/gg9fzR4zhI8i0PP4gbP4oLnT9DzJ4PnbMGzBPQsYfAsIXj+DD1/NnjOETxLQs+SBs+Sgucv0PMXg+dcwbMU9Cxl8CwleP4KPX81eM4TPEtDz9IGz9KC52/Q8zeD53zBswz0LGPwLCN4/g49fzd4LhA8y0LPsgbPsoLnH9DzD4PnQsGzHPQsZ/AsJ3j+CT3/NHguEjzLQ8/yBs/ygudf0PMvg+diwbMC9Kxg8KwgeFaEnhUNnksEz0rQs5LBs5LgWRl6VjZ4LhU8q0DPKgbPKoJnVehZ1eC5TPCsBj2rGTyrCZ7VoWd1g+dywbMG9Kxh8KwheNaEnjUNnisEz1rQs5bBs5bgWRt61jZ4rhQ860DPOgbPOoJnXehZ1+C5SvCsBz3rGTzrCZ71oWd9g+dqwbMB9Gxg8GwgeDaEng0NnmsEz0bQs5HBs5Hg2Rh6NjZ4rhU8m0DPJgbPJoJnU+jZ1OC5TvBsBj2bGTybCZ7NoWdzg+d6wbMF9Gxh8GwheLaEni0NnhsEz1bQs5XBs5Xg2Rp6tjZ4bhQ820DPNgbPNoJnW+jZ1uC5SfBsBz3bGTzbCZ7toWd7g+dmwbMD9Oxg8OwgeHaEnh0NnlsEz07Qs5PBs5PgGUDPwOC5VfDsDD07Gzw7C55doGcXg+c2wbMr9Oxq8OwqeHaDnt0MntsFz+7Qs7vBs7vg2QN69jB47hA8e0LPngbPnoJnL+jZy+C5U/DsDT17Gzx7C559oGcfg+cuwbMv9Oxr8OwrePaDnv0MnrsFz/7Qs7/Bs7/gOQB6DjB47hE8B0LPgQbPgYLnIOg5yOC5V/AcDD0HGzwHC55DoOcQg+c+wXMo9Bxq8BwqeA6DnsMMnvsFz+HQc7jBc7jg+Tf0/NvgeUDwHAE9Rxg8Rwie/0DPfwyeBwXPkdBzpMFzpOD5L/T81+B5SPAcBT1HGTxHCZ6joedog+dhwXMM9Bxj8BwjeI6FnmMNnkcEz3HQc5zBc5zgOR56jjd4HhU8J0DPCQbPCYLnROg50eB5TPCcBD0nGTwnCZ6Toedkg+dxwXMK9Jxi8JwieE6FnlMNnicEz2nQc5rBc5rgOR16Tjd4nhQ8Z0DPGQbPGYLnTOg50+B5SvCcBT1nGTxnCZ6zoedsg+dpwXMO9Jxj8JwjeM6FnnMNnmcEz3nQc57Bc57gOR96zjd4nhU8F0DPBQbPBYLnQui50OB5TvBcBD0XGTwXCZ6Loedig+d5wXMJ9Fxi8FwieC6FnksNnhcEz2XQc5nBc5nguRx6Ljd4XhQ8V0DPFQbPFYLnSui50uB5SfBcBT1XGTxXCZ6roedqg+dlwXMN9Fxj8FwjeK6FnmsNnlcEz3XQc53Bc53guR56rjd4XhU8N0DPDQbPDYLnRui50eB5TfDcBD03GTw3CZ6boedmg+d1wXML9Nxi8NwieG6FnlsNnjcEz23Qc5vBc5vguR16bjd43hQ8d0DPHQbPHYLnTui50+B5S/DcBT13GTx3CZ67oedug+dtwXMP9Nxj8NwjeO6FnnsNnncEz33Qc5/Bc5/guR967jd43hU8D0DPAwbPA4LnQeh50OB5T/A8BD0PGTwPCZ6Hoedhg+d9wfMI9Dxi8DwieB6FnkcNng8Ez2PQ85jB85jgeRx6Hjd4PhQ8T0DPEwbPE4LnSeh50uD5SPA8BT1PGTxPCZ6noedpg+djwfMM9Dxj8DwjeJ6FnmcNnk8Ez3PQ85zB85zgeR56njd4PhU8L0DPCwbPC4LnReh50eD5TPC8BD0vGTwvCZ6Xoedlg+dzwfMK9Lxi8LwieF6FnlcNni8Ez2vQ85rB85rgeR16Xjd4vhQ8b0DPGwbPG4LnTeh50+D5SvC8BT1vGTxvCZ63oedtg+drwfMO9Lxj8LwjeN6FnncNnm8Ez3vQ857B857geR963jd4vhU8H0DPBwbPB4LnQ+j50OD5TvB8BD0fGTwfCZ6Poedjg+d7Of/3O59AzycGzyeC51Po+dTgGUHwfAY9nxk8nwmez6Hnc4NnRMHzBfR8YfB8IXi+hJ4vDZ6RBM9X0POVwfOV4Pkaer42eEYWPN9AzzcGzzeC51vo+dbgGUXwfAc93xk83wme73Vknv+9C9UzquAZoSPzjNAxdM+w7fC2EaFnRINnNMEzEvSMZPCMJHhGhp6RDZ7RBc8o0DOKwTOK4BkVekY1eMYQPKNBz2gGz2iCZ3ToGd3gGVPwjAE9Yxg8YwieMaFnTINnLMEzFvSMZfCMJXjGhp6xDZ6xBc840DOOwTOO4BkXesY1eMYRPONBz3gGz3iCZ3zoGd/gGVfwTAA9Exg8EwieCaFnQoNnPMEzEfRMZPBMJHgmhp6JDZ7xBc8k0DOJwTOJ4JkUeiY1eCYQPJNBz2QGz2SCZ3LomdzgmVDwTAE9Uxg8UwieKaFnSoNnIsEzFfRMZfBMJXimhp6pDZ6JBc800DONwTON4JkWeqY1eCYRPNNBz3QGz3SCZ3romd7gmVTwzAA9Mxg8Mwie70PP9w2eyQTPjNAzo8Ezo+CZCXpmMngmFzwzQ8/MBs/MgucH0PMDg2cKwTML9Mxi8MwieH4IPT80eKYUPLNCz6wGz6yC50fQ8yODZyrBMxv0zGbwzCZ4fgw9PzZ4phY8s0PP7AbP7ILnJ9DzE4NnGsEzB/TMYfDMIXh+Cj0/NXimFTxzQs+cBs+cgudn0PMzg2c6wTMX9Mxl8MwleH4OPT83eKYXPHNDz9wGz9yC5xfQ8wuDZwbBMw/0zGPwzCN4fgk9vzR4vi945oWeeQ2eeQXPr6DnVwbPjIJnPuiZz+CZT/D8Gnp+bfDMJHjmh575DZ75Bc9voOc3Bs/MgmcB6FnA4FlA8CwIPQsaPD8QPAtBz0IGz0KC57fQ81uDZxbBszD0LGzwLCx4fgc9vzN4fih4FoGeRQyeRQTP76Hn9wbPrIJnUehZ1OBZVPD8AXr+YPD8SPAsBj2LGTyLCZ4/Qs8fDZ7ZBM/i0LO4wbO44PkT9PzJ4Pmx4FkCepYweJYQPH+Gnj8bPLMLniWhZ0mDZ0nB8xfo+YvB8xPBsxT0LGXwLCV4/go9fzV45hA8S0PP0gbP0oLnb9DzN4Pnp4JnGehZxuBZRvD8HXr+bvDMKXiWhZ5lDZ5lBc8/oOcfBs/PBM9y0LOcwbOc4Pkn9PzT4JlL8CwPPcsbPMsLnn9Bz78Mnp8LnhWgZwWDZwXBsyL0rGjwzC14VoKelQyelQTPytCzssHzC8GzCvSsYvCsInhWhZ5VDZ55BM9q0LOawbOa4FkdelY3eH4peNaAnjUMnjUEz5rQs6bBM6/gWQt61jJ41hI8a0PP2gbPrwTPOtCzjsGzjuBZF3rWNXjmEzzrQc96Bs96gmd96Fnf4Pm14NkAejYweDYQPBtCz4YGz/yCZyPo2cjg2UjwbAw9Gxs8vxE8m0DPJgbPJoJnU+jZ1OBZQPBsBj2bGTybCZ7NoWdzg2dBwbMF9Gxh8GwheLaEni0NnoUEz1bQs5XBs5Xg2Rp6tjZ4fit4toGebQyebQTPttCzrcGzsODZDnq2M3i2EzzbQ8/2Bs/vBM8O0LODwbOD4NkRenY0eBYRPDtBz04Gz06CZwA9A4Pn94JnZ+jZ2eDZWfDsAj27GDyLCp5doWdXg2dXwbMb9Oxm8PxB8OwOPbsbPLsLnj2gZw+DZzHBsyf07Gnw7Cl49oKevQyePwqevaFnb4Nnb8GzD/TsY/AsLnj2hZ59DZ59Bc9+0LOfwfMnwbM/9Oxv8OwveA6AngMMniUEz4HQc6DBc6DgOQh6DjJ4/ix4Doaegw2egwXPIdBziMGzpOA5FHoONXgOFTyHQc9hBs9fBM/h0HO4wXO44Pk39Pzb4FlK8BwBPUcYPEcInv9Az38Mnr8KniOh50iD50jB81/o+a/Bs7TgOQp6jjJ4jhI8R0PP0QbP3wTPMdBzjMFzjOA5FnqONXiWETzHQc9xBs9xgud46Dne4Pm74DkBek4weE4QPCdCz4kGz7KC5yToOcngOUnwnAw9Jxs8/xA8p0DPKQbPKYLnVOg51eBZTvCcBj2nGTynCZ7Toed0g+efgucM6DnD4DlD8JwJPWcaPMsLnrOg5yyD5yzBczb0nG3w/EvwnAM95xg85wiec6HnXINnBcFzHvScZ/CcJ3jOh57zDZ4VBc8F0HOBwXOB4LkQei40eFYSPBdBz0UGz0WC52LoudjgWVnwXAI9lxg8lwieS6HnUoNnFcFzGfRcZvBcJnguh57LDZ5VBc8V0HOFwXOF4LkSeq40eFYTPFdBz1UGz1WC52roudrgWV3wXAM91xg81wiea6HnWoNnDcFzHfRcZ/BcJ3iuh57rDZ41Bc8N0HODwXOD4LkRem40eNYSPDdBz00Gz02C52boudngWVvw3AI9txg8twieW6HnVoNnHcFzG/TcZvDcJnhuh57bDZ51Bc8d0HOHwXOH4LkTeu40eNYTPHdBz10Gz12C527oudvgWV/w3AM99xg89wiee6HnXoNnA8FzH/TcZ/DcJ3juh577DZ4NBc8D0POAwfOA4HkQeh40eDYSPA9Bz0MGz0OC52Hoedjg2VjwPAI9jxg8jwieR6HnUYNnE8HzGPQ8ZvA8Jngeh57HDZ5NBc8T0POEwfOE4HkSep40eDYTPE9Bz1MGz1OC52noedrg2VzwPAM9zxg8zwieZ6HnWYNnC8HzHPQ8Z/A8J3ieh57nDZ4tBc8L0POCwfOC4HkRel40eLYSPC9Bz0sGz0uC52Xoedng2VrwvAI9rxg8rwieV6HnVYNnG8HzGvS8ZvC8Jnheh57XDZ5tBc8b0POGwfOG4HkTet40eLYTPG9Bz1sGz1uC523oedvg2V7wvAM97xg87wied6HnXYNnB8HzHvS8Z/C8J3jeh573DZ4dBc8H0POBwfOB4PkQej40eHYSPB9Bz0cGz0eC52Po+djgGQieT6DnE4PnE8HzKfR8avDsLHg+g57PDJ7PBM/n0PO5wbOL4PkCer4weL4QPF9Cz5cGz66C5yvo+crg+UrwfA09Xxs8uwmeb6DnG4PnG8HzLfR8a/DsLni+g57vDJ7vBM/3OjHP/96F6tlD8IzQiXlG6BS6Z9h2eNuI0DOiwbOn4BkJekYyeEYSPCNDz8gGz16CZxToGcXgGUXwjAo9oxo8ewue0aBnNINnNMEzOvSMbvDsI3jGgJ4xDJ4xBM+Y0DOmwbOv4BkLesYyeMYSPGNDz9gGz36CZxzoGcfgGUfwjAs94xo8+wue8aBnPINnPMEzPvSMb/AcIHgmgJ4JDJ4JBM+E0DOhwXOg4JkIeiYyeCYSPBNDz8QGz0GCZxLomcTgmUTwTAo9kxo8BwueyaBnMoNnMsEzOfRMbvAcInimgJ4pDJ4pBM+U0DOlwXOo4JkKeqYyeKYSPFNDz9QGz2GCZxromcbgmUbwTAs90xo8hwue6aBnOoNnOsEzPfRMb/D8W/DMAD0zGDwzCJ7vQ8/3DZ4jBM+M0DOjwTOj4JkJemYyeP4jeGaGnpkNnpkFzw+g5wcGz5GCZxbomcXgmUXw/BB6fmjw/FfwzAo9sxo8swqeH0HPjwyeowTPbNAzm8Ezm+D5MfT82OA5WvDMDj2zGzyzC56fQM9PDJ5jBM8c0DOHwTOH4Pkp9PzU4DlW8MwJPXMaPHMKnp9Bz88MnuMEz1zQM5fBM5fg+Tn0/NzgOV7wzA09cxs8cwueX0DPLwyeEwTPPNAzj8Ezj+D5JfT80uA5UfDMCz3zGjzzCp5fQc+vDJ6TBM980DOfwTOf4Pk19Pza4DlZ8MwPPfMbPPMLnt9Az28MnlMEzwLQs4DBs4DgWRB6FjR4ThU8C0HPQgbPQoLnt9DzW4PnNMGzMPQsbPAsLHh+Bz2/M3hOFzyLQM8iBs8iguf30PN7g+cMwbMo9Cxq8CwqeP4APX8weM4UPItBz2IGz2KC54/Q80eD5yzBszj0LG7wLC54/gQ9fzJ4zhY8S0DPEgbPEoLnz9DzZ4PnHMGzJPQsafAsKXj+Aj1/MXjOFTxLQc9SBs9Sguev0PNXg+c8wbM09Cxt8CwteP4GPX8zeM4XPMtAzzIGzzKC5+/Q83eD5wLBsyz0LGvwLCt4/gE9/zB4LhQ8y0HPcgbPcoLnn9DzT4PnIsGzPPQsb/AsL3j+BT3/MnguFjwrQM8KBs8KgmdF6FnR4LlE8KwEPSsZPCsJnpWhZ2WD51LBswr0rGLwrCJ4VoWeVQ2eywTPatCzmsGzmuBZHXpWN3guFzxrQM8aBs8agmdN6FnT4LlC8KwFPWsZPGsJnrWhZ22D50rBsw70rGPwrCN41oWedQ2eqwTPetCznsGznuBZH3rWN3iuFjwbQM8GBs8GgmdD6NnQ4LlG8GwEPRsZPBsJno2hZ2OD51rBswn0bGLwbCJ4NoWeTQ2e6wTPZtCzmcGzmeDZHHo2N3iuFzxbQM8WBs8WgmdL6NnS4LlB8GwFPVsZPFsJnq2hZ2uD50bBsw30bGPwbCN4toWebQ2emwTPdtCzncGzneDZHnq2N3huFjw7QM8OBs8OgmdH6NnR4LlF8OwEPTsZPDsJngH0DAyeWwXPztCzs8Gzs+DZBXp2MXhuEzy7Qs+uBs+ugmc36NnN4Lld8OwOPbsbPLsLnj2gZw+D5w7Bsyf07Gnw7Cl49oKevQyeOwXP3tCzt8Gzt+DZB3r2MXjuEjz7Qs++Bs++gmc/6NnP4Llb8OwPPfsbPPsLngOg5wCD5x7BcyD0HGjwHCh4DoKegwyeewXPwdBzsMFzsOA5BHoOMXjuEzyHQs+hBs+hgucw6DnM4Llf8BwOPYcbPIcLnn9Dz78NngcEzxHQc4TBc4Tg+Q/0/MfgeVDwHAk9Rxo8Rwqe/0LPfw2ehwTPUdBzlMFzlOA5GnqONngeFjzHQM8xBs8xgudY6DnW4HlE8BwHPccZPMcJnuOh53iD51HBcwL0nGDwnCB4ToSeEw2exwTPSdBzksFzkuA5GXpONngeFzynQM8pBs8pgudU6DnV4HlC8JwGPacZPKcJntOh53SD50nBcwb0nGHwnCF4zoSeMw2epwTPWdBzlsFzluA5G3rONnieFjznQM85Bs85gudc6DnX4HlG8JwHPecZPOcJnvOh53yD51nBcwH0XGDwXCB4LoSeCw2e5wTPRdBzkcFzkeC5GHouNnieFzyXQM8lBs8lgudS6LnU4HlB8FwGPZcZPJcJnsuh53KD50XBcwX0XGHwXCF4roSeKw2elwTPVdBzlcFzleC5GnquNnheFjzXQM81Bs81guda6LnW4HlF8FwHPdcZPNcJnuuh53qD51XBcwP03GDw3CB4boSeGw2e1wTPTdBzk8Fzk+C5GXpuNnheFzy3QM8tBs8tgudW6LnV4HlD8NwGPbcZPLcJntuh53aD503Bcwf03GHw3CF47oSeOw2etwTPXdBzl8Fzl+C5G3ruNnjeFjz3QM89Bs89gude6LnX4HlH8NwHPfcZPPcJnvuh536D513B8wD0PGDwPCB4HoSeBw2e9wTPQ9DzkMHzkOB5GHoeNnjeFzyPQM8jBs8jgudR6HnU4PlA8DwGPY8ZPI8Jnseh53GD50PB8wT0PGHwPCF4noSeJw2ejwTPU9DzlMHzlOB5GnqeNng+FjzPQM8zBs8zgudZ6HnW4PlE8DwHPc8ZPM8Jnueh53mD51PB8wL0vGDwvCB4XoSeFw2ezwTPS9DzksHzkuB5GXpeNng+FzyvQM8rBs8rgudV6HnV4PlC8LwGPa8ZPK8Jnteh53WD50vB8wb0vGHwvCF43oSeNw2erwTPW9DzlsHzluB5G3reNni+FjzvQM87Bs87gudd6HnX4PlG8LwHPe8ZPO8Jnveh532D51vB8wH0fGDwfCB4PoSeDw2e7wTPR9DzkcHzkeD5GHo+Nni+99n/fucT6PnE4PlE8HwKPZ8aPCMIns+g5zOD5zPB8zn0fG7wjCh4voCeLwyeLwTPl9DzpcEzkuD5Cnq+Mni+EjxfQ8/XBs/Igucb6PnG4PlG8HwLPd8aPKMInu+g5zuD5zvB872Aef73LlTPqIJnhIB5RghC9wzbDm8bMWCeEYPQPaMJnpEC5hkpCN0zbDu8beSAeUYOQveMLnhGCZhnlCB0z7Dt8LZRA+YZNQjdM4bgGS1gntGC0D3DtsPbRg+YZ/QgdM+YgmeMgHnGCEL3DNsObxszYJ4xg9A9YwmesQLmGSsI3TNsO7xt7IB5xg5C94wteMYJmGecIHTPsO3wtnED5hk3CN0zjuAZL2Ce8YLQPcO2w9vGD5hn/CB0z7iCZ4KAeSYIQvcM2w5vmzBgngmD0D3jCZ6JAuaZKAjdM2w7vG3igHkmDkL3jC94JgmYZ5IgdM+w7fC2SQPmmTQI3TOB4JksYJ7JgtA9w7bD2yYPmGfyIHTPhIJnioB5pghC9wzbDm+bMmCeKYPQPRMJnqkC5pkqCN0zbDu8beqAeaYOQvdMLHimCZhnmiB0z7Dt8LZpA+aZNgjdM4ngmS5gnumC0D3DtsPbpg+YZ/ogdM+kgmeGgHlmCEL3DNsOb/t+wDzfD0L3TCZ4ZgyYZ8YgdM+w7fC2mQLmmSkI3TO54Jk5YJ6Zg9A9w7bD234QMM8PgtA9UwieWQLmmSUI3TNsO7zthwHz/DAI3TOl4Jk1YJ5Zg9A9w7bD234UMM+PgtA9Uwme2QLmmS0I3TNsO7ztxwHz/DgI3TO14Jk9YJ7Zg9A9w7bD234SMM9PgtA90wieOQLmmSMI3TNsO7ztpwHz/DQI3TOt4JkzYJ45g9A9w7bD234WMM/PgtA90wmeuQLmmSsI3TNsO7zt5wHz/DwI3TO94Jk7YJ65g9A9w7bD234RMM8vgtA9MwieeQLmmScI3TNsO7ztlwHz/DII3fN9wTNvwDzzBqF7hm2Ht/0qYJ5fBaF7ZhQ88wXMM18QumfYdnjbrwPm+XUQumcmwTN/wDzzB6F7hm2Ht/0mYJ7fBKF7ZhY8CwTMs0AQumfYdnjbggHzLBiE7vmB4FkoYJ6FgtA9w7bD234bMM9vg9A9swiehQPmWTgI3TNsO7ztdwHz/C4I3fNDwbNIwDyLBKF7hm2Ht/0+YJ7fB6F7ZhU8iwbMs2gQumfYdnjbHwLm+UMQuudHgmexgHkWC0L3DNsOb/tjwDx/DEL3zCZ4Fg+YZ/EgdM+w7fC2PwXM86cgdM+PBc8SAfMsEYTuGbYd3vbngHn+HITumV3wLBkwz5JB6J5h2+FtfwmY5y9B6J6fCJ6lAuZZKgjdM2w7vO2vAfP8NQjdM4fgWTpgnqWD0D3DtsPb/hYwz9+C0D0/FTzLBMyzTBC6Z9h2eNvfA+b5exC6Z07Bs2zAPMsGoXuGbYe3/SNgnn8EoXt+JniWC5hnuSB0z7Dt8LZ/BszzzyB0z1yCZ/mAeZYPQvcM2w5v+1fAPP8KQvf8XPCsEDDPCkHonmHb4W0rBsyzYhC6Z27Bs1LAPCsFoXuGbYe3rRwwz8pB6J5fCJ5VAuZZJQjdM2w7vG3VgHlWDUL3zCN4VguYZ7UgdM+w7fC21QPmWT0I3fNLwbNGwDxrBKF7hm2Ht60ZMM+aQeieeQXPWgHzrBWE7hm2Hd62dsA8awehe34leNYJmGedIHTPsO3wtnUD5lk3CN0zn+BZL2Ce9YLQPcO2w9vWD5hn/SB0z68FzwYB82wQhO4Zth3etmHAPBsGoXvmFzwbBcyzURC6Z9h2eNvGAfNsHITu+Y3g2SRgnk2C0D3DtsPbNg2YZ9MgdM8CgmezgHk2C0L3DNsOb9s8YJ7Ng9A9CwqeLQLm2SII3TNsO7xty4B5tgxC9ywkeLYKmGerIHTPsO3wtq0D5tk6CN3zW8GzTcA82wShe4Zth7dtGzDPtkHonoUFz3YB82wXhO4Zth3etn3APNsHoXt+J3h2CJhnhyB0z7Dt8LYdA+bZMQjds4jg2Slgnp2C0D3DtsPbBgHzDILQPb8XPDsHzLNzELpn2HZ42y4B8+wShO5ZVPDsGjDPrkHonmHb4W27BcyzWxC65w+CZ/eAeXYPQvcM2w5v2yNgnj2C0D2LCZ49A+bZMwjdM2w7vG2vgHn2CkL3/FHw7B0wz95B6J5h2+Ft+wTMs08QumdxwbNvwDz7BqF7hm2Ht+0XMM9+QeiePwme/QPm2T8I3TNsO7ztgIB5DghC9ywheA4MmOfAIHTPsO3wtoMC5jkoCN3zZ8FzcMA8Bwehe4Zth7cdEjDPIUHoniUFz6EB8xwahO4Zth3edljAPIcFoXv+IngOD5jn8CB0z7Dt8LZ/B8zz7yB0z1KC54iAeY4IQvcM2w5v+0/APP8JQvf8VfAcGTDPkUHonmHb4W3/DZjnv0HonqUFz1EB8xwVhO4Zth3ednTAPEcHoXv+JniOCZjnmCB0z7Dt8LZjA+Y5Ngjds4zgOS5gnuOC0D3DtsPbjg+Y5/ggdM/fBc8JAfOcEITuGbYd3nZiwDwnBqF7lhU8JwXMc1IQumfYdnjbyQHznByE7vmH4DklYJ5TgtA9w7bD204NmOfUIHTPcoLntIB5TgtC9wzbDm87PWCe04PQPf8UPGcEzHNGELpn2HZ425kB85wZhO5ZXvCcFTDPWUHonmHb4W1nB8xzdhC651+C55yAec4JQvcM2w5vOzdgnnOD0D0rCJ7zAuY5LwjdM2w7vO38gHnOD0L3rCh4LgiY54IgdM+w7fC2CwPmuTAI3bOS4LkoYJ6LgtA9w7bD2y4OmOfiIHTPyoLnkoB5LglC9wzbDm+7NGCeS4PQPasInssC5rksCN0zbDu87fKAeS4PQvesKniuCJjniiB0z7Dt8LYrA+a5Mgjds5rguSpgnquC0D3DtsPbrg6Y5+ogdM/qgueagHmuCUL3DNsOb7s2YJ5rg9A9awie6wLmuS4I3TNsO7zt+oB5rg9C96wpeG4ImOeGIHTPsO3wthsD5rkxCN2zluC5KWCem4LQPcO2w9tuDpjn5iB0z9qC55aAeW4JQvcM2w5vuzVgnluD0D3rCJ7bAua5LQjdM2w7vO32gHluD0L3rCt47giY544gdM+w7fC2OwPmuTMI3bOe4LkrYJ67gtA9w7bD2+4OmOfuIHTP+oLnnoB57glC9wzbDm+7N2Cee4PQPRsInvsC5rkvCN0zbDu87f6Aee4PQvdsKHgeCJjngSB0z7Dt8LYHA+Z5MAjds5HgeShgnoeC0D3DtsPbHg6Y5+EgdM/GgueRgHkeCUL3DNsOb3s0YJ5Hg9A9mwiexwLmeSwI3TNsO7zt8YB5Hg9C92wqeJ4ImOeJIHTPsO3wticD5nkyCN2zmeB5KmCep4LQPcO2w9ueDpjn6SB0z+aC55mAeZ4JQvcM2w5vezZgnmeD0D1bCJ7nAuZ5LgjdM2w7vO35gHmeD0L3bCl4XgiY54UgdM+w7fC2FwPmeTEI3bOV4HkpYJ6XgtA9w7bD214OmOflIHTP1oLnlYB5XglC9wzbDm97NWCeV4PQPdsIntcC5nktCN0zbDu87fWAeV4PQvdsK3jeCJjnjSB0z7Dt8LY3A+Z5Mwjds53geStgnreC0D3DtsPb3g6Y5+0gdM/2guedgHneCUL3DNsOb3s3YJ53g9A9Owie9wLmeS8I3TNsO7zt/YB53g9C9+woeD4ImOeDIHTPsO3wtg8D5vkwCN2zk+D5KGCej4LQPcO2w9s+Dpjn4yB0z0DwfBIwzydB6J5h2+FtnwbM82kQumdnwfNZwDyfBaF7hm2Ht30eMM/nQeieXQTPFwHzfBGE7hm2Hd72ZcA8Xwahe3YVPF8FzPNVELpn2HZ429cB83wdhO7ZTfB8EzDPN0HonmHb4W3fBszzbRC6Z3fB813APN8FoXuGbYe3fa8z8/zvXaiePQTPCJ2ZZ4TOoXuGbYe3jQg9Ixo8ewqekaBnJINnJMEzMvSMbPDsJXhGgZ5RDJ5RBM+o0DOqwbO34BkNekYzeEYTPKNDz+gGzz6CZwzoGcPgGUPwjAk9Yxo8+wqesaBnLINnLMEzNvSMbfDsJ3jGgZ5xDJ5xBM+40DOuwbO/4BkPesYzeMYTPONDz/gGzwGCZwLomcDgmUDwTAg9Exo8BwqeiaBnIoNnIsEzMfRMbPAcJHgmgZ5JDJ5JBM+k0DOpwXOw4JkMeiYzeCYTPJNDz+QGzyGCZwromcLgmULwTAk9Uxo8hwqeqaBnKoNnKsEzNfRMbfAcJnimgZ5pDJ5pBM+00DOtwXO44JkOeqYzeKYTPNNDz/QGz78FzwzQM4PBM4Pg+T70fN/gOULwzAg9Mxo8MwqemaBnJoPnP4JnZuiZ2eCZWfD8AHp+YPAcKXhmgZ5ZDJ5ZBM8PoeeHBs9/Bc+s0DOrwTOr4PkR9PzI4DlK8MwGPbMZPLMJnh9Dz48NnqMFz+zQM7vBM7vg+Qn0/MTgOUbwzAE9cxg8cwien0LPTw2eYwXPnNAzp8Ezp+D5GfT8zOA5TvDMBT1zGTxzCZ6fQ8/PDZ7jBc/c0DO3wTO34PkF9PzC4DlB8MwDPfMYPPMInl9Czy8NnhMFz7zQM6/BM6/g+RX0/MrgOUnwzAc98xk88wmeX0PPrw2ekwXP/NAzv8Ezv+D5DfT8xuA5RfAsAD0LGDwLCJ4FoWdBg+dUwbMQ9Cxk8CwkeH4LPb81eE4TPAtDz8IGz8KC53fQ8zuD53TBswj0LGLwLCJ4fg89vzd4zhA8i0LPogbPooLnD9DzB4PnTMGzGPQsZvAsJnj+CD1/NHjOEjyLQ8/iBs/igudP0PMng+dswbME9Cxh8CwheP4MPX82eM4RPEtCz5IGz5KC5y/Q8xeD51zBsxT0LGXwLCV4/go9fzV4zhM8S0PP0gbP0oLnb9DzN4PnfMGzDPQsY/AsI3j+Dj1/N3guEDzLQs+yBs+ygucf0PMPg+dCwbMc9Cxn8CwneP4JPf80eC4SPMtDz/IGz/KC51/Q8y+D52LBswL0rGDwrCB4VoSeFQ2eSwTPStCzksGzkuBZGXpWNnguFTyrQM8qBs8qgmdV6FnV4LlM8KwGPasZPKsJntWhZ3WD53LBswb0rGHwrCF41oSeNQ2eKwTPWtCzlsGzluBZG3rWNniuFDzrQM86Bs86gmdd6FnX4LlK8KwHPesZPOsJnvWhZ32D52rBswH0bGDwbCB4NoSeDQ2eawTPRtCzkcGzkeDZGHo2NniuFTybQM8mBs8mgmdT6NnU4LlO8GwGPZsZPJsJns2hZ3OD53rBswX0bGHwbCF4toSeLQ2eGwTPVtCzlcGzleDZGnq2NnhuFDzbQM82Bs82gmdb6NnW4LlJ8GwHPdsZPNsJnu2hZ3uD52bBswP07GDw7CB4doSeHQ2eWwTPTtCzk8Gzk+AZQM/A4LlV8OwMPTsbPDsLnl2gZxeD5zbBsyv07Grw7Cp4doOe3Qye2wXP7tCzu8Gzu+DZA3r2MHjuEDx7Qs+eBs+egmcv6NnL4LlT8OwNPXsbPHsLnn2gZx+D5y7Bsy/07Gvw7Ct49oOe/QyeuwXP/tCzv8Gzv+A5AHoOMHjuETwHQs+BBs+Bgucg6DnI4LlX8BwMPQcbPAcLnkOg5xCD5z7Bcyj0HGrwHCp4DoOewwye+wXP4dBzuMFzuOD5N/T82+B5QPAcAT1HGDxHCJ7/QM9/DJ4HBc+R0HOkwXOk4Pkv9PzX4HlI8BwFPUcZPEcJnqOh52iD52HBcwz0HGPwHCN4joWeYw2eRwTPcdBznMFznOA5HnqON3geFTwnQM8JBs8JgudE6DnR4HlM8JwEPScZPCcJnpOh52SD53HBcwr0nGLwnCJ4ToWeUw2eJwTPadBzmsFzmuA5HXpON3ieFDxnQM8ZBs8ZgudM6DnT4HlK8JwFPWcZPGcJnrOh52yD52nBcw70nGPwnCN4zoWecw2eZwTPedBznsFznuA5H3rON3ieFTwXQM8FBs8FgudC6LnQ4HlO8FwEPRcZPBcJnouh52KD53nBcwn0XGLwXCJ4LoWeSw2eFwTPZdBzmcFzmeC5HHouN3heFDxXQM8VBs8VgudK6LnS4HlJ8FwFPVcZPFcJnquh52qD52XBcw30XGPwXCN4roWeaw2eVwTPddBzncFzneC5HnquN3heFTw3QM8NBs8NgudG6LnR4HlN8NwEPTcZPDcJnpuh52aD53XBcwv03GLw3CJ4boWeWw2eNwTPbdBzm8Fzm+C5HXpuN3jeFDx3QM8dBs8dgudO6LnT4HlL8NwFPXcZPHcJnruh526D523Bcw/03GPw3CN47oWeew2edwTPfdBzn8Fzn+C5H3ruN3jeFTwPQM8DBs8DgudB6HnQ4HlP8DwEPQ8ZPA8Jnoeh52GD533B8wj0PGLwPCJ4HoWeRw2eDwTPY9DzmMHzmOB5HHoeN3g+FDxPQM8TBs8TgudJ6HnS4PlI8DwFPU8ZPE8Jnqeh52mD52PB8wz0PGPwPCN4noWeZw2eTwTPc9DznMHznOB5HnqeN3g+FTwvQM8LBs8LgudF6HnR4PlM8LwEPS8ZPC8Jnpeh52WD53PB8wr0vGLwvCJ4XoWeVw2eLwTPa9DzmsHzmuB5HXpeN3i+FDxvQM8bBs8bgudN6HnT4PlK8LwFPW8ZPG8Jnreh522D52vB8w70vGPwvCN43oWedw2ebwTPe9DznsHznuB5H3reN3i+FTwfQM8HBs8HgudD6PnQ4PlO8HwEPR8ZPB8Jno+h52OD53u5/vc7n0DPJwbPJ4LnU+j51OAZQfB8Bj2fGTyfCZ7Poedzg2dEwfMF9Hxh8HwheL6Eni8NnpEEz1fQ85XB85Xg+Rp6vjZ4RhY830DPNwbPN4LnW+j51uAZRfB8Bz3fGTzfCZ7vdWGe/70L1TOq4BmhC/OM0CV0z7Dt8LYRoWdEg2c0wTMS9Ixk8IwkeEaGnpENntEFzyjQM4rBM4rgGRV6RjV4xhA8o0HPaAbPaIJndOgZ3eAZU/CMAT1jGDxjCJ4xoWdMg2cswTMW9Ixl8IwleMaGnrENnrEFzzjQM47BM47gGRd6xjV4xhE840HPeAbPeIJnfOgZ3+AZV/BMAD0TGDwTCJ4JoWdCg2c8wTMR9Exk8EwkeCaGnokNnvEFzyTQM4nBM4ngmRR6JjV4JhA8k0HPZAbPZIJncuiZ3OCZUPBMAT1TGDxTCJ4poWdKg2ciwTMV9Exl8EwleKaGnqkNnokFzzTQM43BM43gmRZ6pjV4JhE800HPdAbPdIJneuiZ3uCZVPDMAD0zGDwzCJ7vQ8/3DZ7JBM+M0DOjwTOj4JkJemYyeCYXPDNDz8wGz8yC5wfQ8wODZwrBMwv0zGLwzCJ4fgg9PzR4phQ8s0LPrAbPrILnR9DzI4NnKsEzG/TMZvDMJnh+DD0/NnimFjyzQ8/sBs/sgucn0PMTg2cawTMH9Mxh8MwheH4KPT81eKYVPHNCz5wGz5yC52fQ8zODZzrBMxf0zGXwzCV4fg49Pzd4phc8c0PP3AbP3ILnF9DzC4NnBsEzD/TMY/DMI3h+CT2/NHi+L3jmhZ55DZ55Bc+voOdXBs+Mgmc+6JnP4JlP8Pwaen5t8MwkeOaHnvkNnvkFz2+g5zcGz8yCZwHoWcDgWUDwLAg9Cxo8PxA8C0HPQgbPQoLnt9DzW4NnFsGzMPQsbPAsLHh+Bz2/M3h+KHgWgZ5FDJ5FBM/voef3Bs+sgmdR6FnU4FlU8PwBev5g8PxI8CwGPYsZPIsJnj9Czx8NntkEz+LQs7jBs7jg+RP0/Mng+bHgWQJ6ljB4lhA8f4aePxs8swueJaFnSYNnScHzF+j5i8HzE8GzFPQsZfAsJXj+Cj1/NXjmEDxLQ8/SBs/Sgudv0PM3g+engmcZ6FnG4FlG8Pwdev5u8MwpeJaFnmUNnmUFzz+g5x8Gz88Ez3LQs5zBs5zg+Sf0/NPgmUvwLA89yxs8ywuef0HPvwyenwueFaBnBYNnBcGzIvSsaPDMLXhWgp6VDJ6VBM/K0LOywfMLwbMK9Kxi8KwieFaFnlUNnnkEz2rQs5rBs5rgWR16Vjd4fil41oCeNQyeNQTPmtCzpsEzr+BZC3rWMnjWEjxrQ8/aBs+vBM860LOOwbOO4FkXetY1eOYTPOtBz3oGz3qCZ33oWd/g+bXg2QB6NjB4NhA8G0LPhgbP/IJnI+jZyODZSPBsDD0bGzy/ETybQM8mBs8mgmdT6NnU4FlA8GwGPZsZPJsJns2hZ3ODZ0HBswX0bGHwbCF4toSeLQ2ehQTPVtCzlcGzleDZGnq2Nnh+K3i2gZ5tDJ5tBM+20LOtwbOw4NkOerYzeLYTPNtDz/YGz+8Ezw7Qs4PBs4Pg2RF6djR4FhE8O0HPTgbPToJnAD0Dg+f3gmdn6NnZ4NlZ8OwCPbsYPIsKnl2hZ1eDZ1fBsxv07Gbw/EHw7A49uxs8uwuePaBnD4NnMcGzJ/TsafDsKXj2gp69DJ4/Cp69oWdvg2dvwbMP9Oxj8CwuePaFnn0Nnn0Fz37Qs5/B8yfBsz/07G/w7C94DoCeAwyeJQTPgdBzoMFzoOA5CHoOMnj+LHgOhp6DDZ6DBc8h0HOIwbOk4DkUeg41eA4VPIdBz2EGz18Ez+HQc7jBc7jg+Tf0/NvgWUrwHAE9Rxg8Rwie/0DPfwyevwqeI6HnSIPnSMHzX+j5r8GztOA5CnqOMniOEjxHQ8/RBs/fBM8x0HOMwXOM4DkWeo41eJYRPMdBz3EGz3GC53joOd7g+bvgOQF6TjB4ThA8J0LPiQbPsoLnJOg5yeA5SfCcDD0nGzz/EDynQM8pBs8pgudU6DnV4FlO8JwGPacZPKcJntOh53SD55+C5wzoOcPgOUPwnAk9Zxo8ywues6DnLIPnLMFzNvScbfD8S/CcAz3nGDznCJ5zoedcg2cFwXMe9Jxn8JwneM6HnvMNnhUFzwXQc4HBc4HguRB6LjR4VhI8F0HPRQbPRYLnYui52OBZWfBcAj2XGDyXCJ5LoedSg2cVwXMZ9Fxm8FwmeC6HnssNnlUFzxXQc4XBc4XguRJ6rjR4VhM8V0HPVQbPVYLnaui52uBZXfBcAz3XGDzXCJ5roedag2cNwXMd9Fxn8FwneK6HnusNnjUFzw3Qc4PBc4PguRF6bjR41hI8N0HPTQbPTYLnZui52eBZW/DcAj23GDy3CJ5boedWg2cdwXMb9Nxm8NwmeG6HntsNnnUFzx3Qc4fBc4fguRN67jR41hM8d0HPXQbPXYLnbui52+BZX/DcAz33GDz3CJ57oedeg2cDwXMf9Nxn8NwneO6HnvsNng0FzwPQ84DB84DgeRB6HjR4NhI8D0HPQwbPQ4LnYeh52ODZWPA8Aj2PGDyPCJ5HoedRg2cTwfMY9Dxm8DwmeB6HnscNnk0FzxPQ84TB84TgeRJ6njR4NhM8T0HPUwbPU4Lnaeh52uDZXPA8Az3PGDzPCJ5noedZg2cLwfMc9Dxn8DwneJ6HnucNni0FzwvQ84LB84LgeRF6XjR4thI8L0HPSwbPS4LnZeh52eDZWvC8Aj2vGDyvCJ5XoedVg2cbwfMa9Lxm8LwmeF6HntcNnm0FzxvQ84bB84bgeRN63jR4thM8b0HPWwbPW4Lnbeh52+DZXvC8Az3vGDzvCJ53oeddg2cHwfMe9Lxn8LwneN6HnvcNnh0FzwfQ84HB84Hg+RB6PjR4dhI8H0HPRwbPR4LnY+j52OAZCJ5PoOcTg+cTwfMp9Hxq8OwseD6Dns8Mns8Ez+fQ87nBs4vg+QJ6vjB4vhA8X0LPlwbProLnK+j5yuD5SvB8DT1fGzy7CZ5voOcbg+cbwfMt9Hxr8OwueL6Dnu8Mnu8Ez/e6Ms//3oXq2UPwjNCVeUboGrpn2HZ424jQM6LBs6fgGQl6RjJ4RhI8I0PPyAbPXoJnFOgZxeAZRfCMCj2jGjx7C57RoGc0g2c0wTM69Ixu8OwjeMaAnjEMnjEEz5jQM6bBs6/gGQt6xjJ4xhI8Y0PP2AbPfoJnHOgZx+AZR/CMCz3jGjz7C57xoGc8g2c8wTM+9Ixv8BwgeCaAngkMngkEz4TQM6HBc6DgmQh6JjJ4JhI8E0PPxAbPQYJnEuiZxOCZRPBMCj2TGjwHC57JoGcyg2cywTM59Exu8BwieKaAnikMnikEz5TQM6XBc6jgmQp6pjJ4phI8U0PP1AbPYYJnGuiZxuCZRvBMCz3TGjyHC57poGc6g2c6wTM99Exv8Pxb8MwAPTMYPDMInu9Dz/cNniMEz4zQM6PBM6PgmQl6ZjJ4/iN4ZoaemQ2emQXPD6DnBwbPkYJnFuiZxeCZRfD8EHp+aPD8V/DMCj2zGjyzCp4fQc+PDJ6jBM9s0DObwTOb4Pkx9PzY4Dla8MwOPbMbPLMLnp9Az08MnmMEzxzQM4fBM4fg+Sn0/NTgOVbwzAk9cxo8cwqen0HPzwye4wTPXNAzl8Ezl+D5OfT83OA5XvDMDT1zGzxzC55fQM8vDJ4TBM880DOPwTOP4Pkl9PzS4DlR8MwLPfMaPPMKnl9Bz68MnpMEz3zQM5/BM5/g+TX0/NrgOVnwzA898xs88wue30DPbwyeUwTPAtCzgMGzgOBZEHoWNHhOFTwLQc9CBs9Cgue30PNbg+c0wbMw9Cxs8CwseH4HPb8zeE4XPItAzyIGzyKC5/fQ83uD5wzBsyj0LGrwLCp4/gA9fzB4zhQ8i0HPYgbPYoLnj9DzR4PnLMGzOPQsbvAsLnj+BD1/MnjOFjxLQM8SBs8SgufP0PNng+ccwbMk9Cxp8CwpeP4CPX8xeM4VPEtBz1IGz1KC56/Q81eD5zzBszT0LG3wLC14/gY9fzN4zhc8y0DPMgbPMoLn79Dzd4PnAsGzLPQsa/AsK3j+AT3/MHguFDzLQc9yBs9yguef0PNPg+ciwbM89Cxv8CwveP4FPf8yeC4WPCtAzwoGzwqCZ0XoWdHguUTwrAQ9Kxk8KwmelaFnZYPnUsGzCvSsYvCsInhWhZ5VDZ7LBM9q0LOawbOa4FkdelY3eC4XPGtAzxoGzxqCZ03oWdPguULwrAU9axk8awmetaFnbYPnSsGzDvSsY/CsI3jWhZ51DZ6rBM960LOewbOe4FkfetY3eK4WPBtAzwYGzwaCZ0Po2dDguUbwbAQ9Gxk8GwmejaFnY4PnWsGzCfRsYvBsIng2hZ5NDZ7rBM9m0LOZwbOZ4NkcejY3eK4XPFtAzxYGzxaCZ0vo2dLguUHwbAU9Wxk8WwmeraFna4PnRsGzDfRsY/BsI3i2hZ5tDZ6bBM920LOdwbOd4NkeerY3eG4WPDtAzw4Gzw6CZ0fo2dHguUXw7AQ9Oxk8OwmeAfQMDJ5bBc/O0LOzwbOz4NkFenYxeG4TPLtCz64Gz66CZzfo2c3guV3w7A49uxs8uwuePaBnD4PnDsGzJ/TsafDsKXj2gp69DJ47Bc/e0LO3wbO34NkHevYxeO4SPPtCz74Gz76CZz/o2c/guVvw7A89+xs8+wueA6DnAIPnHsFzIPQcaPAcKHgOgp6DDJ57Bc/B0HOwwXOw4DkEeg4xeO4TPIdCz6EGz6GC5zDoOczguV/wHA49hxs8hwuef0PPvw2eBwTPEdBzhMFzhOD5D/T8x+B5UPAcCT1HGjxHCp7/Qs9/DZ6HBM9R0HOUwXOU4Dkaeo42eB4WPMdAzzEGzzGC51joOdbgeUTwHAc9xxk8xwme46HneIPnUcFzAvScYPCcIHhOhJ4TDZ7HBM9J0HOSwXOS4DkZek42eB4XPKdAzykGzymC51ToOdXgeULwnAY9pxk8pwme06HndIPnScFzBvScYfCcIXjOhJ4zDZ6nBM9Z0HOWwXOW4Dkbes42eJ4WPOdAzzkGzzmC51zoOdfgeUbwnAc95xk85wme86HnfIPnWcFzAfRcYPBcIHguhJ4LDZ7nBM9F0HORwXOR4LkYei42eJ4XPJdAzyUGzyWC51LoudTgeUHwXAY9lxk8lwmey6HncoPnRcFzBfRcYfBcIXiuhJ4rDZ6XBM9V0HOVwXOV4Lkaeq42eF4WPNdAzzUGzzWC51roudbgeUXwXAc91xk81wme66HneoPnVcFzA/TcYPDcIHhuhJ4bDZ7XBM9N0HOTwXOT4LkZem42eF4XPLdAzy0Gzy2C51boudXgeUPw3AY9txk8twme26HndoPnTcFzB/TcYfDcIXjuhJ47DZ63BM9d0HOXwXOX4Lkbeu42eN4WPPdAzz0Gzz2C517oudfgeUfw3Ac99xk89wme+6HnfoPnXcHzAPQ8YPA8IHgehJ4HDZ73BM9D0POQwfOQ4HkYeh42eN4XPI9AzyMGzyOC51HoedTg+UDwPAY9jxk8jwmex6HncYPnQ8HzBPQ8YfA8IXiehJ4nDZ6PBM9T0POUwfOU4Hkaep42eD4WPM9AzzMGzzOC51noedbg+UTwPAc9zxk8zwme56HneYPnU8HzAvS8YPC8IHhehJ4XDZ7PBM9L0POSwfOS4HkZel42eD4XPK9AzysGzyuC51XoedXg+ULwvAY9rxk8rwme16HndYPnS8HzBvS8YfC8IXjehJ43HZ65//c7b/1vd0Z79zb9/7vzv3eZwrlTaYe3vf2/3Rnv3euC/+/O2//DneF8EV4Jnneg5x2D5x3B8y70vGvwfC143oOe9wye9wTP+9DzvsHzjeD5AHo+MHg+EDwfQs+HBs+3gucj6PnI4PlI8HwMPR8bPN8Jnk+g5xOD5xPB8yn0fGrwfO+L//3OZ9DzmcHzmeD5HHo+N3hGEDxfQM8XBs8XgudL6PnS4BlR8HwFPV8ZPF8Jnq+h52uDZyTB8w30fGPwfCN4voWebw2ekQXPd9DzncHzneD5Xjfm+d+7UD2jCJ4RujHPCN1C9wzbDm8bEXpGNHhGFTwjQc9IBs9Igmdk6BnZ4BlN8IwCPaMYPKMInlGhZ1SDZ3TBMxr0jGbwjCZ4Roee0Q2eMQTPGNAzhsEzhuAZE3rGNHjGFDxjQc9YBs9Ygmds6Bnb4BlL8IwDPeMYPOMInnGhZ1yDZ2zBMx70jGfwjCd4xoee8Q2ecQTPBNAzgcEzgeCZEHomNHjGFTwTQc9EBs9Egmdi6JnY4BlP8EwCPZMYPJMInkmhZ1KDZ3zBMxn0TGbwTCZ4JoeeyQ2eCQTPFNAzhcEzheCZEnqmNHgmFDxTQc9UBs9Ugmdq6Jna4JlI8EwDPdMYPNMInmmhZ1qDZ2LBMx30TGfwTCd4poee6Q2eSQTPDNAzg8Ezg+D5PvR83+CZVPDMCD0zGjwzCp6ZoGcmg2cywTMz9Mxs8MwseH4APT8weCYXPLNAzywGzyyC54fQ80ODZwrBMyv0zGrwzCp4fgQ9PzJ4phQ8s0HPbAbPbILnx9DzY4NnKsEzO/TMbvDMLnh+Aj0/MXimFjxzQM8cBs8cguen0PNTg2cawTMn9Mxp8MwpeH4GPT8zeKYVPHNBz1wGz1yC5+fQ83ODZzrBMzf0zG3wzC14fgE9vzB4phc880DPPAbPPILnl9DzS4NnBsEzL/TMa/DMK3h+BT2/Mni+L3jmg575DJ75BM+voefXBs+Mgmd+6Jnf4Jlf8PwGen5j8MwkeBaAngUMngUEz4LQs6DBM7PgWQh6FjJ4FhI8v4We3xo8PxA8C0PPwgbPwoLnd9DzO4NnFsGzCPQsYvAsInh+Dz2/N3h+KHgWhZ5FDZ5FBc8foOcPBs+sgmcx6FnM4FlM8PwRev5o8PxI8CwOPYsbPIsLnj9Bz58MntkEzxLQs4TBs4Tg+TP0/Nng+bHgWRJ6ljR4lhQ8f4Gevxg8swuepaBnKYNnKcHzV+j5q8HzE8GzNPQsbfAsLXj+Bj1/M3jmEDzLQM8yBs8ygufv0PN3g+engmdZ6FnW4FlW8PwDev5h8MwpeJaDnuUMnuUEzz+h558Gz88Ez/LQs7zBs7zg+Rf0/MvgmUvwrAA9Kxg8KwieFaFnRYPn54JnJehZyeBZSfCsDD0rGzxzC55VoGcVg2cVwbMq9Kxq8PxC8KwGPasZPKsJntWhZ3WDZx7Bswb0rGHwrCF41oSeNQ2eXwqetaBnLYNnLcGzNvSsbfDMK3jWgZ51DJ51BM+60LOuwfMrwbMe9Kxn8KwneNaHnvUNnvkEzwbQs4HBs4Hg2RB6NjR4fi14NoKejQyejQTPxtCzscEzv+DZBHo2MXg2ETybQs+mBs9vBM9m0LOZwbOZ4NkcejY3eBYQPFtAzxYGzxaCZ0vo2dLgWVDwbAU9Wxk8WwmeraFna4NnIcGzDfRsY/BsI3i2hZ5tDZ7fCp7toGc7g2c7wbM99Gxv8CwseHaAnh0Mnh0Ez47Qs6PB8zvBsxP07GTw7CR4BtAzMHgWETw7Q8/OBs/OgmcX6NnF4Pm94NkVenY1eHYVPLtBz24Gz6KCZ3fo2d3g2V3w7AE9exg8fxA8e0LPngbPnoJnL+jZy+BZTPDsDT17Gzx7C559oGcfg+ePgmdf6NnX4NlX8OwHPfsZPIsLnv2hZ3+DZ3/BcwD0HGDw/EnwHAg9Bxo8Bwqeg6DnIINnCcFzMPQcbPAcLHgOgZ5DDJ4/C55DoedQg+dQwXMY9Bxm8CwpeA6HnsMNnsMFz7+h598Gz18EzxHQc4TBc4Tg+Q/0/MfgWUrwHAk9Rxo8Rwqe/0LPfw2evwqeo6DnKIPnKMFzNPQcbfAsLXiOgZ5jDJ5jBM+x0HOswfM3wXMc9Bxn8BwneI6HnuMNnmUEzwnQc4LBc4LgORF6TjR4/i54ToKekwyekwTPydBzssGzrOA5BXpOMXhOETynQs+pBs8/BM9p0HOawXOa4Dkdek43eJYTPGdAzxkGzxmC50zoOdPg+afgOQt6zjJ4zhI8Z0PP2QbP8oLnHOg5x+A5R/CcCz3nGjz/EjznQc95Bs95gud86Dnf4FlB8FwAPRcYPBcInguh50KDZ0XBcxH0XGTwXCR4Loaeiw2elQTPJdBzicFzieC5FHouNXhWFjyXQc9lBs9lgudy6Lnc4FlF8FwBPVcYPFcIniuh50qDZ1XBcxX0XGXwXCV4roaeqw2e1QTPNdBzjcFzjeC5FnquNXhWFzzXQc91Bs91gud66Lne4FlD8NwAPTcYPDcInhuh50aDZ03BcxP03GTw3CR4boaemw2etQTPLdBzi8Fzi+C5FXpuNXjWFjy3Qc9tBs9tgud26Lnd4FlH8NwBPXcYPHcInjuh506DZ13Bcxf03GXw3CV47oaeuw2e9QTPPdBzj8Fzj+C5F3ruNXjWFzz3Qc99Bs99gud+6Lnf4NlA8DwAPQ8YPA8Ingeh50GDZ0PB8xD0PGTwPCR4Hoaehw2ejQTPI9DziMHziOB5FHoeNXg2FjyPQc9jBs9jgudx6Hnc4NlE8DwBPU8YPE8Inieh50mDZ1PB8xT0PGXwPCV4noaepw2ezQTPM9DzjMHzjOB5FnqeNXg2FzzPQc9zBs9zgud56Hne4NlC8LwAPS8YPC8Inheh50WDZ0vB8xL0vGTwvCR4Xoaelw2erQTPK9DzisHziuB5FXpeNXi2FjyvQc9rBs9rgud16Hnd4NlG8LwBPW8YPG8Injeh502DZ1vB8xb0vGXwvCV43oaetw2e7QTPO9DzjsHzjuB5F3reNXi2FzzvQc97Bs97gud96Hnf4NlB8HwAPR8YPB8Ing+h50ODZ0fB8xH0fGTwfCR4Poaejw2enQTPJ9DzicHzieD5FHo+NXgGgucz6PnM4PlM8HwOPZ8bPDsLni+g5wuD5wvB8yX0fGnw7CJ4voKerwyerwTP19DztcGzq+D5Bnq+MXi+ETzfQs+3Bs9uguc76PnO4PlO8HyvO/P8712ont0FzwjdmWeE7qF7hm2Ht40IPSMaPHsInpGgZySDZyTBMzL0jGzw7Cl4RoGeUQyeUQTPqNAzqsGzl+AZDXpGM3hGEzyjQ8/oBs/egmcM6BnD4BlD8IwJPWMaPPsInrGgZyyDZyzBMzb0jG3w7Ct4xoGecQyecQTPuNAzrsGzn+AZD3rGM3jGEzzjQ8/4Bs/+gmcC6JnA4JlA8EwIPRMaPAcInomgZyKDZyLBMzH0TGzwHCh4JoGeSQyeSQTPpNAzqcFzkOCZDHomM3gmEzyTQ8/kBs/BgmcK6JnC4JlC8EwJPVMaPIcInqmgZyqDZyrBMzX0TG3wHCp4poGeaQyeaQTPtNAzrcFzmOCZDnqmM3imEzzTQ8/0Bs/hgmcG6JnB4JlB8Hwfer5v8Pxb8MwIPTMaPDMKnpmgZyaD5wjBMzP0zGzwzCx4fgA9PzB4/iN4ZoGeWQyeWQTPD6HnhwbPkYJnVuiZ1eCZVfD8CHp+ZPD8V/DMBj2zGTyzCZ4fQ8+PDZ6jBM/s0DO7wTO74PkJ9PzE4Dla8MwBPXMYPHMInp9Cz08NnmMEz5zQM6fBM6fg+Rn0/MzgOVbwzAU9cxk8cwmen0PPzw2e4wTP3NAzt8Ezt+D5BfT8wuA5XvDMAz3zGDzzCJ5fQs8vDZ4TBM+80DOvwTOv4PkV9PzK4DlR8MwHPfMZPPMJnl9Dz68NnpMEz/zQM7/BM7/g+Q30/MbgOVnwLAA9Cxg8CwieBaFnQYPnFMGzEPQsZPAsJHh+Cz2/NXhOFTwLQ8/CBs/Cgud30PM7g+c0wbMI9Cxi8CwieH4PPb83eE4XPItCz6IGz6KC5w/Q8weD5wzBsxj0LGbwLCZ4/gg9fzR4zhQ8i0PP4gbP4oLnT9DzJ4PnLMGzBPQsYfAsIXj+DD1/NnjOFjxLQs+SBs+Sgucv0PMXg+ccwbMU9Cxl8CwleP4KPX81eM4VPEtDz9IGz9KC52/Q8zeD5zzBswz0LGPwLCN4/g49fzd4zhc8y0LPsgbPsoLnH9DzD4PnAsGzHPQsZ/AsJ3j+CT3/NHguFDzLQ8/yBs/ygudf0PMvg+ciwbMC9Kxg8KwgeFaEnhUNnosFz0rQs5LBs5LgWRl6VjZ4LhE8q0DPKgbPKoJnVehZ1eC5VPCsBj2rGTyrCZ7VoWd1g+cywbMG9Kxh8KwheNaEnjUNnssFz1rQs5bBs5bgWRt61jZ4rhA860DPOgbPOoJnXehZ1+C5UvCsBz3rGTzrCZ71oWd9g+cqwbMB9Gxg8GwgeDaEng0NnqsFz0bQs5HBs5Hg2Rh6NjZ4rhE8m0DPJgbPJoJnU+jZ1OC5VvBsBj2bGTybCZ7NoWdzg+c6wbMF9Gxh8GwheLaEni0NnusFz1bQs5XBs5Xg2Rp6tjZ4bhA820DPNgbPNoJnW+jZ1uC5UfBsBz3bGTzbCZ7toWd7g+cmwbMD9Oxg8OwgeHaEnh0NnpsFz07Qs5PBs5PgGUDPwOC5RfDsDD07Gzw7C55doGcXg+dWwbMr9Oxq8OwqeHaDnt0MntsEz+7Qs7vBs7vg2QN69jB4bhc8e0LPngbPnoJnL+jZy+C5Q/DsDT17Gzx7C559oGcfg+dOwbMv9Oxr8OwrePaDnv0MnrsEz/7Qs7/Bs7/gOQB6DjB47hY8B0LPgQbPgYLnIOg5yOC5R/AcDD0HGzwHC55DoOcQg+dewXMo9Bxq8BwqeA6DnsMMnvsEz+HQc7jBc7jg+Tf0/NvguV/wHAE9Rxg8Rwie/0DPfwyeBwTPkdBzpMFzpOD5L/T81+B5UPAcBT1HGTxHCZ6joedog+chwXMM9Bxj8BwjeI6FnmMNnocFz3HQc5zBc5zgOR56jjd4HhE8J0DPCQbPCYLnROg50eB5VPCcBD0nGTwnCZ6Toedkg+cxwXMK9Jxi8JwieE6FnlMNnscFz2nQc5rBc5rgOR16Tjd4nhA8Z0DPGQbPGYLnTOg50+B5UvCcBT1nGTxnCZ6zoedsg+cpwXMO9Jxj8JwjeM6FnnMNnqcFz3nQc57Bc57gOR96zjd4nhE8F0DPBQbPBYLnQui50OB5VvBcBD0XGTwXCZ6Loedig+c5wXMJ9Fxi8FwieC6FnksNnucFz2XQc5nBc5nguRx6Ljd4XhA8V0DPFQbPFYLnSui50uB5UfBcBT1XGTxXCZ6roedqg+clwXMN9Fxj8FwjeK6FnmsNnpcFz3XQc53Bc53guR56rjd4XhE8N0DPDQbPDYLnRui50eB5VfDcBD03GTw3CZ6boedmg+c1wXML9Nxi8NwieG6FnlsNntcFz23Qc5vBc5vguR16bjd43hA8d0DPHQbPHYLnTui50+B5U/DcBT13GTx3CZ67oedug+ctwXMP9Nxj8NwjeO6FnnsNnrcFz33Qc5/Bc5/guR967jd43hE8D0DPAwbPA4LnQeh50OB5V/A8BD0PGTwPCZ6Hoedhg+c9wfMI9Dxi8DwieB6FnkcNnvcFz2PQ85jB85jgeRx6Hjd4PhA8T0DPEwbPE4LnSeh50uD5UPA8BT1PGTxPCZ6noedpg+cjwfMM9Dxj8DwjeJ6FnmcNno8Fz3PQ85zB85zgeR56njd4PhE8L0DPCwbPC4LnReh50eD5VPC8BD0vGTwvCZ6Xoedlg+czwfMK9Lxi8LwieF6FnlcNns8Fz2vQ85rB85rgeR16Xjd4vhA8b0DPGwbPG4LnTeh50+D5UvC8BT1vGTxvCZ63oedtg+crwfMO9Lxj8LwjeN6FnncNnq8Fz3vQ857B857geR963jd4vhE8H0DPBwbPB4LnQ+j50OD5VvB8BD0fGTwfCZ6Poedjg+c7wfMJ9Hxi8HwieD6Fnk8Nnu/l+d/vfAY9nxk8nwmez6Hnc4NnBMHzBfR8YfB8IXi+hJ4vDZ4RBc9X0POVwfOV4Pkaer42eEYSPN9AzzcGzzeC51vo+dbgGVnwfAc93xk83wme7/Vgnv+9C9UziuAZoQfzjNAjdM+w7fC2EaFnRINnVMEzEvSMZPCMJHhGhp6RDZ7RBM8o0DOKwTOK4BkVekY1eEYXPKNBz2gGz2iCZ3ToGd3gGUPwjAE9Yxg8YwieMaFnTINnTMEzFvSMZfCMJXjGhp6xDZ6xBM840DOOwTOO4BkXesY1eMYWPONBz3gGz3iCZ3zoGd/gGUfwTAA9Exg8EwieCaFnQoNnXMEzEfRMZPBMJHgmhp6JDZ7xBM8k0DOJwTOJ4JkUeiY1eMYXPJNBz2QGz2SCZ3LomdzgmUDwTAE9Uxg8UwieKaFnSoNnQsEzFfRMZfBMJXimhp6pDZ6JBM800DONwTON4JkWeqY1eCYWPNNBz3QGz3SCZ3romd7gmUTwzAA9Mxg8Mwie70PP9w2eSQXPjNAzo8Ezo+CZCXpmMngmEzwzQ8/MBs/MgucH0PMDg2dywTML9Mxi8MwieH4IPT80eKYQPLNCz6wGz6yC50fQ8yODZ0rBMxv0zGbwzCZ4fgw9PzZ4phI8s0PP7AbP7ILnJ9DzE4NnasEzB/TMYfDMIXh+Cj0/NXimETxzQs+cBs+cgudn0PMzg2dawTMX9Mxl8MwleH4OPT83eKYTPHNDz9wGz9yC5xfQ8wuDZ3rBMw/0zGPwzCN4fgk9vzR4ZhA880LPvAbPvILnV9DzK4Pn+4JnPuiZz+CZT/D8Gnp+bfDMKHjmh575DZ75Bc9voOc3Bs9MgmcB6FnA4FlA8CwIPQsaPDMLnoWgZyGDZyHB81vo+a3B8wPBszD0LGzwLCx4fgc9vzN4ZhE8i0DPIgbPIoLn99Dze4Pnh4JnUehZ1OBZVPD8AXr+YPDMKngWg57FDJ7FBM8foeePBs+PBM/i0LO4wbO44PkT9PzJ4JlN8CwBPUsYPEsInj9Dz58Nnh8LniWhZ0mDZ0nB8xfo+YvBM7vgWQp6ljJ4lhI8f4Wevxo8PxE8S0PP0gbP0oLnb9DzN4NnDsGzDPQsY/AsI3j+Dj1/N3h+KniWhZ5lDZ5lBc8/oOcfBs+cgmc56FnO4FlO8PwTev5p8PxM8CwPPcsbPMsLnn9Bz78MnrkEzwrQs4LBs4LgWRF6VjR4fi54VoKelQyelQTPytCzssEzt+BZBXpWMXhWETyrQs+qBs8vBM9q0LOawbOa4FkdelY3eOYRPGtAzxoGzxqCZ03oWdPg+aXgWQt61jJ41hI8a0PP2gbPvIJnHehZx+BZR/CsCz3rGjy/EjzrQc96Bs96gmd96Fnf4JlP8GwAPRsYPBsIng2hZ0OD59eCZyPo2cjg2UjwbAw9Gxs88wueTaBnE4NnE8GzKfRsavD8RvBsBj2bGTybCZ7NoWdzg2cBwbMF9Gxh8GwheLaEni0NngUFz1bQs5XBs5Xg2Rp6tjZ4FhI820DPNgbPNoJnW+jZ1uD5reDZDnq2M3i2EzzbQ8/2Bs/CgmcH6NnB4NlB8OwIPTsaPL8TPDtBz04Gz06CZwA9A4NnEcGzM/TsbPDsLHh2gZ5dDJ7fC55doWdXg2dXwbMb9Oxm8CwqeHaHnt0Nnt0Fzx7Qs4fB8wfBsyf07Gnw7Cl49oKevQyexQTP3tCzt8Gzt+DZB3r2MXj+KHj2hZ59DZ59Bc9+0LOfwbO44NkfevY3ePYXPAdAzwEGz58Ez4HQc6DBc6DgOQh6DjJ4lhA8B0PPwQbPwYLnEOg5xOD5s+A5FHoONXgOFTyHQc9hBs+Sgudw6Dnc4Dlc8Pwbev5t8PxF8BwBPUcYPEcInv9Az38MnqUEz5HQc6TBc6Tg+S/0/Nfg+avgOQp6jjJ4jhI8R0PP0QbP0oLnGOg5xuA5RvAcCz3HGjx/EzzHQc9xBs9xgud46Dne4FlG8JwAPScYPCcInhOh50SD5++C5yToOcngOUnwnAw9Jxs8ywqeU6DnFIPnFMFzKvScavD8Q/CcBj2nGTynCZ7Toed0g2c5wXMG9Jxh8JwheM6EnjMNnn8KnrOg5yyD5yzBczb0nG3wLC94zoGecwyecwTPudBzrsHzL8FzHvScZ/CcJ3jOh57zDZ4VBM8F0HOBwXOB4LkQei40eFYUPBdBz0UGz0WC52LoudjgWUnwXAI9lxg8lwieS6HnUoNnZcFzGfRcZvBcJnguh57LDZ5VBM8V0HOFwXOF4LkSeq40eFYVPFdBz1UGz1WC52roudrgWU3wXAM91xg81wiea6HnWoNndcFzHfRcZ/BcJ3iuh57rDZ41BM8N0HODwXOD4LkRem40eNYUPDdBz00Gz02C52boudngWUvw3AI9txg8twieW6HnVoNnbcFzG/TcZvDcJnhuh57bDZ51BM8d0HOHwXOH4LkTeu40eNYVPHdBz10Gz12C527oudvgWU/w3AM99xg89wiee6HnXoNnfcFzH/TcZ/DcJ3juh577DZ4NBM8D0POAwfOA4HkQeh40eDYUPA9Bz0MGz0OC52Hoedjg2UjwPAI9jxg8jwieR6HnUYNnY8HzGPQ8ZvA8Jngeh57HDZ5NBM8T0POEwfOE4HkSep40eDYVPE9Bz1MGz1OC52noedrg2UzwPAM9zxg8zwieZ6HnWYNnc8HzHPQ8Z/A8J3ieh57nDZ4tBM8L0POCwfOC4HkRel40eLYUPC9Bz0sGz0uC52Xoedng2UrwvAI9rxg8rwieV6HnVYNna8HzGvS8ZvC8Jnheh57XDZ5tBM8b0POGwfOG4HkTet40eLYVPG9Bz1sGz1uC523oedvg2U7wvAM97xg87wied6HnXYNne8HzHvS8Z/C8J3jeh573DZ4dBM8H0POBwfOB4PkQej40eHYUPB9Bz0cGz0eC52Po+djg2UnwfAI9nxg8nwieT6HnU4NnIHg+g57PDJ7PBM/n0PO5wbOz4PkCer4weL4QPF9Cz5cGzy6C5yvo+crg+UrwfA09Xxs8uwqeb6DnG4PnG8HzLfR8a/DsJni+g57vDJ7vBM/3ejLP/96F6tld8IzQk3lG6Bm6Z9h2eNuI0DOiwbOH4BkJekYyeEYSPCNDz8gGz56CZxToGcXgGUXwjAo9oxo8ewme0aBnNINnNMEzOvSMbvDsLXjGgJ4xDJ4xBM+Y0DOmwbOP4BkLesYyeMYSPGNDz9gGz76CZxzoGcfgGUfwjAs94xo8+wme8aBnPINnPMEzPvSMb/DsL3gmgJ4JDJ4JBM+E0DOhwXOA4JkIeiYyeCYSPBNDz8QGz4GCZxLomcTgmUTwTAo9kxo8BwmeyaBnMoNnMsEzOfRMbvAcLHimgJ4pDJ4pBM+U0DOlwXOI4JkKeqYyeKYSPFNDz9QGz6GCZxromcbgmUbwTAs90xo8hwme/8fbW0DHdXTrtm1mW7Iks6WWJTMzMzMzMzMzMzMzMzMzMzMzM9unnFTy7+QkUc3ePZbfq1v7nrMsz6yp79st544RPxf36eeGffqBfTpd3KfTDfscD/bp7+I+/d2wT3+wz3gu7jOeG/Y5AewzwMV9BrhhnwFgn4Eu7jPQDfucCPYZ38V9xnfDPuODfSZwcZ8J3LDPSWCfCV3cZ0I37DMh2GciF/eZyA37nAz2mdjFfSZ2wz4Tg30mcXGfSdywzylgn0ld3GdSN+wzKdhnMhf3mcwN+5wK9pncxX0md8M+k4N9pnBxnyncsM9pYJ8pXdxnSjfsMyXYZyoX95nKDfucDvaZ2sV9pnbDPlODfaZxcZ9p3LDPGWCfaV3cZ1o37DMt2Gc6F/eZzg37nAn2md7FfaZ3wz7Tg31mcHGfGdywz1lgnxld3GdGN+wzI9hnJhf3mckN+5wN9pnZxX1mdsM+M4N9ZnFxn1ncsM85YJ9ZXdxnVjfsMyvYZzYX95nNDfucC/aZ3cV9ZnfDPrODfeZwcZ853LDPeWCfOV3cZ0437DMn2GcuF/eZyw37nA/2mdvFfeZ2wz5zg33mcXGfedywzwVgn3ld3GdeN+wzL9hnPhf3mc8N+1wI9pnfxX3md8M+84N9FnBxnwXcsM9FYJ8FXdxnQTfssyDYZyEX91nIDftcDPZZ2MV9FnbDPguDfRZxcZ9F3LDPJWCfRV3cZ1E37LMo2GcxF/dZzA37XAr2WdzFfRZ3wz6Lg32WcHGfJdywz2VgnyVd3GdJN+yzJNhnKRf3WcoN+1wO9lnaxX2WdsM+S4N9lnFxn2XcsM8VYJ9lXdxnWTfssyzYZzkX91nODftcCfZZ3sV9lnfDPsuDfVZwcZ8V3LDPVWCfFV3cZ0U37LMi2GclF/dZyQ37XA32WdnFfVZ2wz4rg31WcXGfVdywzzVgn1Vd3GdVN+yzKthnNRf3Wc0N+1wL9lndxX1Wd8M+q4N91nBxnzXcsM91YJ81XdxnTTfssybYZy0X91nLDftcD/ZZ28V91nbDPmuDfdZxcZ913LDPDWCfdV3cZ1037LMu2Gc9F/dZzw373Aj2Wd/FfdZ3wz7rg302cHGfDdywz01gnw1d3GdDN+yzIdhnIxf32cgN+9wM9tnYxX02dsM+G4N9NnFxn03csM8tYJ9NXdxnUzfssynYZzMX99nMDfvcCvbZ3MV9NnfDPpuDfbZwcZ8t3LDPbWCfLV3cZ0s37LMl2GcrF/fZyg373A722drFfbZ2wz5bg322cXGfbdywzx1gn21d3GdbN+yzLdhnOxf32c4N+9wJ9tnexX22d8M+24N9dnBxnx3csM9dYJ8dXdxnRzfssyPYZycX99nJDfvcDfbZ2cV9dnbDPjuDfXZxcZ9d3LDPPWCfXV3cZ1c37LMr2Gc3F/fZzQ373Av22d3FfXZ3wz67g332cHGfPdywz31gnz1d3GdPN+yzJ9hnLxf32csN+9wP9tnbxX32dsM+e4N99nFxn33csM8DYJ99XdxnXzfssy/YZz8X99nPDfs8CPbZ38V99nfDPvuDfQ5wcZ8D3LDPQ2CfA13c50A37HMg2OcgF/c5yA37PAz2OdjFfQ52wz4Hg30OcXGfQ9ywzyNgn0Nd3OdQN+xzKNjnMBf3OcwN+zwK9jncxX0Od8M+h4N9jnBxnyPcsM9jYJ8jXdznSDfscyTY5ygX9znKDfs8DvY52sV9jnbDPkeDfY5xcZ9j3LDPE2CfY13c51g37HMs2Oc4F/c5zg37PAn2Od7FfY53wz7Hg31OcHGfE9ywz1NgnxNd3OdEN+xzItjnJBf3OckN+zwN9jnZxX1OdsM+J4N9TnFxn1PcsM8zYJ9TXdznVDfscyrY5zQX9znNDfs8C/Y53cV9TnfDPqeDfc5wcZ8z3LDPc2CfM13c50w37HMm2OcsF/c5yw37PA/2OdvFfc52wz5ng33OcXGfc9ywzwtgn3Nd3OdcN+xzLtjnPBf3Oc8N+7wI9jnfxX3Od8M+54N9LnBxnwvcsM9LYJ8LXdznQjfscyHY5yIX97nIDfu8DPa52MV9LnbDPheDfS5xcZ9L3LDPK2CfS13c51I37HMp2OcyF/e5zA37vAr2udzFfS53wz6Xg32ucHGfK9ywz2tgnytd3OdKN+xzJdjnKhf3ucoN+7wO9rnaxX2udsM+V4N9rnFxn2vcsM8bYJ9rXdznWjfscy3Y5zoX97nODfu8Cfa53sV9rnfDPteDfW5wcZ8b3LDPW2CfG13c50Y37HMj2OcmF/e5yQ37vA32udnFfW52wz43g31ucXGfW9ywzztgn1td3OdWN+xzK9jnNhf3uc0N+7wL9rndxX1ud8M+t4N97nBxnzvcsM97YJ87XdznTjfscyfY5y4X97nLDfu8D/a528V97nbDPneDfe5xcZ973LDPB2Cfe13c51437HMv2Oc+F/e5zw37fAj2ud/Ffe53wz73g30ecHGfB9ywz0dgnwdd3OdBN+zzINjnIRf3ecgN+3wM9nnYxX0edsM+D4N9HnFxn0fcsM8nYJ9HXdznUTfs8yjY5zEX93nMDft8CvZ53MV9HnfDPo+DfZ5wcZ8n3LDPZ2CfJ13c50k37PMk2OcpF/d5yg37fA72edrFfZ52wz5Pg32ecXGfZ9ywzxdgn2dd3OdZN+zzLNjnORf3ec4N+3wJ9nnexX2ed8M+z4N9XnBxnxfcsM9XYJ8XXdznRTfs8yLY5yUX93nJDft8DfZ52cV9XnbDPi+DfV5xcZ9X3LDPN2CfV13c51U37PMq2Oc1F/d5zQ37fAv2ed3FfV53wz6vg33ecHGfN9ywz3dgnzdd3OdNN+zzJtjnLRf3ecsN+3wP9nnbxX3edsM+b4N93nFxn3fcsM8PYJ93XdznXTfs8y7Y5z0X93nPDfv8CPZ538V93nfDPu+DfT5wcZ8P3LDPT2CfD13c50M37PMh2OcjF/f56B84Q/yNM4hfwYJFNecMFs1otu+rYGqfsYwZbPEHB/zBAX9wIf4QgD8E4A8hxB8S8IcE/CGF+EMB/lCAP5QQf2jAHxrwhxbiDwP4wwD+MEL8YQF/WMAfVog/HOAPB/jDCfGHB/zhAX94If4IgD8C4I8gxB8R8EcE/BGF+CMB/kiAP5IQf2TAHxnwRxbijwL4owD+KEL8HoDfA/B7CPF7An5PwO8pxB8V8EcF/FGF+L0Avxfg9xLi9wb83oDfW4jfB/D7AH4fIf5ogD8a4I8mxB8d8EcH/NGF+GMA/hiAP4YQf0zAHxPwxxTijwX4YwH+WEL8sQF/bMAfW4g/DuCPA/jjCPHHBfxxAX9cIX5fwO8L+H2F+P0Avx/g9xPidwJ+J+B3CvH7A35/wO8vxB8P8McD/PGE+AMAfwDgDxDiDwT8gYA/UIg/PuCPD/jjC/EnAPwJAH8CIf6EgD8h4E8oxJ8I8CcC/ImE+BMD/sSAP7EQfxLAnwTwJxHiTwr4kwL+pEL8yQB/MsCfTIg/OeBPDviTC/GnAPwpAH8KIf6UgD8l4E8pxJ8K8KcC/KmE+FMD/tSAP7UQfxrAnwbwpxHiTwv40wL+tEL86QB/OsCfTog/PeBPD/jTC/FnAPwZAH8GIf6MgD8j4M8oxJ8J8GcC/JmE+DMD/syAP7MQfxbAnwXwZxHizwr4swL+rEL82QB/NsCfTYg/O+DPDvizC/HnAPw5AH8OIf6cgD8n4M8pxJ8L8OcC/LmE+HMD/tyAP7cQfx7Anwfw5xHizwv48wL+vEL8+QB/PsCfT4g/P+DPD/jzC/EXAPwFAH8BIf6CgL8g4C8oxF8I8BcC/IWE+AsD/sKAv7AQfxHAXwTwFxHiLwr4iwL+okL8xQB/McBfTIi/OOAvDviLC/GXAPwlAH8JIf6SgL8k4C8pxF8K8JcC/KWE+EsD/tKAv7QQfxnAXwbwlxHiLwv4ywL+skL85QB/OcBfToi/POAvD/jLC/FXAPwVAH8FIf6KgL8i4K8oxF8J8FcC/JWE+CsD/sqAv7IQfxXAXwXwVxHirwr4qwL+qkL81QB/NcBfTYi/OuCvDvirC/HXAPw1AH8NIf6agL8m4K8pxF8L8NcC/LWE+GsD/tqAv7YQfx3AXwfw1xHirwv46wL+ukL89QB/PcBfT4i/PuCvD/jrC/E3APwNAH8DIf6GgL8h4G8oxN8I8DcC/I2E+BsD/saAv7EQfxPA3wTwNxHibwr4mwL+pkL8zQB/M8DfTIi/OeBvDvibC/G3APwtAH8LIf6WgL8l4G8pxN8K8LcC/K2E+FsD/taAv7UQfxvA3wbwtxHibwv42wL+tkL87QB/O8DfToi/PeBvD/jbC/F3APwdAH8HIf6OgL8j4O8oxN8J8HcC/J2E+DsD/s6Av7MQfxfA3wXwdxHi7wr4uwL+rkL83QB/N8DfTYi/O+DvDvi7C/H3APw9AH8PIf6egL8n4O8pxN8L8PcC/L2E+HsD/t6Av7cQfx/A3wfw9xHi7wv4+wL+vkL8/QB/P8DfT4i/P+DvD/j7C/EPAPwDAP8AIf6BgH8g4B8oxD8I8A8C/IOE+AcD/sGAf7AQ/xDAPwTwDxHiHwr4hwL+oUL8wwD/MMA/TIh/OOAfDviHC/GPAPwjAP8IIf6RgH8k4B8pxD8K8I8C/KOE+EcD/tGAf7QQ/xjAPwbwjxHiHwv4xwL+sUL84wD/OMA/Toh/POAfD/jHC/FPAPwTAP8EIf6JgH8i4J8oxD8J8E8C/JOE+CcD/smAf7IQ/xTAPwXwTxHinwr4pwL+qUL80wD/NMA/TYh/OuCfDvinC/HPAPwzAP8MIf6ZgH8m4J8pxD8L8M8C/LOE+GcD/tmAf7YQ/xzAPwfwzxHinwv45wL+uUL88wD/PMA/T4h/PuCfD/jnC/EvAPwLAP8CIf6FgH8h4F8oxL8I8C8C/IuE+BcD/sWAf7EQ/xLAvwTwLxHiXwr4lwL+pUL8ywD/MsC/TIh/OeBfDviXC/GvAPwrAP8KIf6VgH8l4F8pxL8K8K8C/KuE+FcD/tWAf7UQ/xrAvwbwrxHiXwv41wL+tUL86wD/OsC/Toh/PeBfD/jXC/FvAPwbAP8GIf6NgH8j4N8oxL8J8G8C/JuE+DcD/s2Af7MQ/xbAvwXwbxHi3wr4twL+rUL82wD/NsC/TYh/O+DfDvi3C/HvAPw7AP8OIf6dgH8n4N8pxL8L8O8C/LuE+HcD/t2Af7cQ/x7Avwfw7xHi3wv49wL+vUL8+wD/PsC/T4h/P+DfD/j3C/EfAPwHAP8BIf6DgP8g4D8oxH8I8B8C/IeE+A8D/sOA/7AQ/xHAfwTwHxHiPwr4jwL+o0L8xwD/McB/TIj/OOA/DviPC/GfAPwnAP8JIf6TgP8k4D8pxH8K8J8C/KeE+E8D/tOA/7QQ/xnAfwbwnxHiPwv4zwL+s0L85wD/OcB/Toj/POA/D/jPC/FfAPwXAP8FIf6LgP8i4L8oxH8J8F8C/JeE+C8D/suA/7IQ/xXAfwXwXxHivwr4rwL+q0L81wD/NcB/TYj/OuC/DvivC/HfAPw3AP8NIf6bgP8m4L8pxH8L8N8C/LeE+G8D/tuA/7YQ/x3Afwfw3xHivwv47wL+u0L89wD/PcB/T4j/PuC/D/jvC/E/APwPAP8DIf6HgP8h4H8oxP8I8D8C/I+E+B8D/seA/7EQ/xPA/wTwPxHifwr4nwL+p0L8zwD/M8D/TIj/OeB/DvifC/G/APwvAP8LIf6XgP8l4H8pxP8K8L8C/K+E+F8D/teA/7UQ/xvA/wbwvxHifwv43wL+t0L87wD/O8D/Toj/PeB/D/jfC/F/APwfAP8HIf6PgP8j4P8oxP8J8H8C/J+E+D8D/s+A/7MQ/xfA/wXwfxHi/wr4vwL+r0L83wD/N8D/TYj/O+D/Dvi/C/H/APw/AP8PIf6fgP8n4P8pxO/wMud3RDfnd8SW4Q8G+IMB/mBC/MEBf3DAH1yIPwTgDwH4QwjxhwT8IQF/SCH+UIA/FOAPJcQfGvCHBvyhhfjDAP4wgD+MEH9YwB8W8IcV4g8H+MMB/nBC/OEBf3jAH16IPwLgjwD4IwjxRwT8EQF/RCH+SIA/EuCPJMQfGfBHBvyRhfijAP4ogD+KEL8H4PcA/B5C/J6A3xPwewrxRwX8UQF/VCF+L8DvBfi9hPi9Ab834PcW4vcB/D6A30eIPxrgjwb4ownxRwf80QF/dCH+GIA/BuCPIcQfE/DHBPwxhfhjAf5YgD+WEH9swB8b8McW4o8D+OMA/jhC/HEBf1zAH1eI3xfw+wJ+XyF+P8DvB/j9hPidgN8J+J1C/P6A3x/w+wvxxwP88QB/PCH+AMAfAPgDhPgDAX8g4A8U4o8P+OMD/vhC/AkAfwLAn0CIPyHgTwj4EwrxJwL8iQB/IiH+xIA/MeBPLMSfBPAnAfxJhPiTAv6kgD+pEH8ywJ8M8CcT4k8O+JMD/uRC/CkAfwrAn0KIPyXgTwn4UwrxpwL8qQB/KiH+1IA/NeBPLcSfBvCnAfxphPjTAv60gD+tEH86wJ8O8KcT4k8P+NMD/vRC/BkAfwbAn0GIPyPgzwj4MwrxZwL8mQB/JiH+zIA/M+DPLMSfBfBnAfxZhPizAv6sgD+rEH82wJ8N8GcT4s8O+LMD/uxC/DkAfw7An0OIPyfgzwn4cwrx5wL8uQB/LiH+3IA/N+DPLcSfB/DnAfx5hPjzAv68gD+vEH8+wJ8P8OcT4s8P+PMD/vxC/AUAfwHAX0CIvyDgLwj4CwrxFwL8hQB/ISH+woC/MOAvLMRfBPAXAfxFhPiLAv6igL+oEH8xwF8M8BcT4i8O+IsD/uJC/CUAfwnAX0KIvyTgLwn4SwrxlwL8pQB/KSH+0oC/NOAvLcRfBvCXAfxlhPjLAv6ygL+sEH85wF8O8JcT4i8P+MsD/vJC/BUAfwXAX0GIvyLgrwj4KwrxVwL8lQB/JSH+yoC/MuCvLMRfBfBXAfxVhPirAv6qgL+qEH81wF8N8FcT4q8O+KsD/upC/DUAfw3AX0OIvybgrwn4awrx1wL8tQB/LSH+2oC/NuCvLcRfB/DXAfx1hPjrAv66gL+uEH89wF8P8NcT4q8P+OsD/vpC/A0AfwPA30CIvyHgbwj4GwrxNwL8jQB/IyH+xoC/MeBvLMTfBPA3AfxNhPibAv6mgL+pEH8zwN8M8DcT4m8O+JsD/uZC/C0AfwvA30KIvyXgbwn4WwrxtwL8rQB/KyH+1oC/NeBvLcTfBvC3AfxthPjbAv62gL+tEH87wN8O8LcT4m8P+NsD/vZC/B0AfwfA30GIvyPg7wj4OwrxdwL8nQB/JyH+zoC/M+DvLMTfBfB3AfxdhPi7Av6ugL+rEH83wN8N8HcT4u8O+LsD/u5C/D0Afw/A30OIvyfg7wn4ewrx9wL8vQB/LyH+3oC/N+DvLcTfB/D3Afx9hPj7Av6+gL+vEH8/wN8P8PcT4u8P+PsD/v5C/AMA/wDAP0CIfyDgHwj4BwrxDwL8gwD/ICH+wYB/MOAfLMQ/BPAPAfxDhPiHAv6hgH+oEP8wwD8M8A8T4h8O+IcD/uFC/CMA/wjAP0KIfyTgHwn4RwrxjwL8owD/KCH+0YB/NOAfLcQ/BvCPAfxjhPjHAv6xgH+sEP84wD8O8I8T4h8P+McD/vFC/BMA/wTAP0GIfyLgnwj4JwrxTwL8kwD/JCH+yYB/MuCfLMQ/BfBPAfxThPinAv6pgH+qEP80wD8N8E8T4p8O+KcD/ulC/DMA/wzAP0OIfybgnwn4ZwrxzwL8swD/LCH+2YB/NuCfLcQ/B/DPAfxzhPjnAv65gH+uEP88wD8P8M8T4p8P+OcD/vlC/AsA/wLAv0CIfyHgXwj4FwrxLwL8iwD/IiH+xYB/MeBfLMS/BPAvAfxLhPiXAv6lgH+pEP8ywL8M8C8T4l8O+JcD/uVC/CsA/wrAv0KIfyXgXwn4VwrxrwL8qwD/KiH+1YB/NeBfLcS/BvCvAfxrhPjXAv61gH+tEP86wL8O8K8T4l8P+NcD/vVC/BsA/wbAv0GIfyPg3wj4NwrxbwL8mwD/JiH+zYB/M+DfLMS/BfBvAfxbhPi3Av6tgH+rEP82wL8N8G8T4t8O+LcD/u1C/DsA/w7Av0OIfyfg3wn4dwrx7wL8uwD/LiH+3YB/N+DfLcS/B/DvAfx7hPj3Av69gH+vEP8+wL8P8O8T4t8P+PcD/v1C/AcA/wHAf0CI/yDgPwj4DwrxHwL8hwD/ISH+w4D/MOA/LMR/BPAfAfxHhPiPAv6jgP+oEP8xwH8M8B8T4j8O+I8D/uNC/CcA/wnAf0KI/yTgPwn4TwrxnwL8pwD/KSH+04D/NOA/LcR/BvCfAfxnhPjPAv6zgP+sEP85wH8O8J8T4j8P+M8D/vNC/BcA/wXAf0GI/yLgvwj4LwrxXwL8lwD/JSH+y4D/MuC/LMR/BfBfAfxXhPivAv6rgP+qEP81wH8N8F8T4r8O+K8D/utC/DcA/w3Af0OI/ybgvwn4bwrx3wL8twD/LSH+24D/NuC/LcR/B/DfAfx3hPjvAv67gP+uEP89wH8P8N8T4r8P+O8D/vtC/A8A/wPA/0CI/yHgfwj4HwrxPwL8jwD/IyH+x4D/MeB/LMT/BPA/AfxPhPifAv6ngP+pEP8zwP8M8D8T4n8O+J8D/udC/C8A/wvA/0KI/yXgfwn4XwrxvwL8rwD/KyH+14D/NeB/LcT/BvC/AfxvhPjfAv63gP+tEP87wP8O8L8T4n8P+N8D/vdC/B8A/wfA/0GI/yPg/wj4PwrxfwL8nwD/JyH+z4D/M+D/LMT/BfB/AfxfhPi/Av6vgP+rEP83wP8N8H8T4v8O+L8D/u9C/D8A/w/A/0OI/yfg/wn4fwrxO7zN+R0xzPkdcWT4g0U15w9myh9ilyOYEH9wwB8c8AcX4g8B+EMA/hBC/CEBf0jAH1KIPxTgDwX4Qwnxhwb8oQF/aCH+MIA/DOAPI8QfFvCHBfxhhfjDAf5wgD+cEH94wB8e8IcX4o8A+CMA/ghC/BEBf0TAH1GIPxLgjwT4IwnxRwb8kQF/ZCH+KIA/CuCPIsTvAfg9AL+HEL8n4PcE/J5C/FEBf1TAH1WI3wvwewF+LyF+b8DvDfi9hfh9AL8P4PcR4o8G+KMB/mhC/NEBf3TAH12IPwbgjwH4YwjxxwT8MQF/TCH+WIA/FuCPJcQfG/DHBvyxhfjjAP44gD+OEH9cwB8X8McV4vcF/L6A31eI3w/w+wF+PyF+J+B3An6nEL8/4PcH/P5C/PEAfzzAH0+IPwDwBwD+ACH+QMAfCPgDhfjjA/74gD++EH8CwJ8A8CcQ4k8I+BMC/oRC/IkAfyLAn0iIPzHgTwz4EwvxJwH8SQB/EiH+pIA/KeBPKsSfDPAnA/zJhPiTA/7kgD+5EH8KwJ8C8KcQ4k8J+FMC/pRC/KkAfyrAn0qIPzXgTw34UwvxpwH8aQB/GiH+tIA/LeBPK8SfDvCnA/zphPjTA/70gD+9EH8GwJ8B8GcQ4s8I+DMC/oxC/JkAfybAn0mIPzPgzwz4MwvxZwH8WQB/FiH+rIA/K+DPKsSfDfBnA/zZhPizA/7sgD+7EH8OwJ8D8OcQ4s8J+HMC/pxC/LkAfy7An0uIPzfgzw34cwvx5wH8eQB/HiH+vIA/L+DPK8SfD/DnA/z5hPjzA/78gD+/EH8BwF8A8BcQ4i8I+AsC/oJC/IUAfyHAX0iIvzDgLwz4CwvxFwH8RQB/ESH+ooC/KOAvKsRfDPAXA/zFhPiLA/7igL+4EH8JwF8C8JcQ4i8J+EsC/pJC/KUAfynAX0qIvzTgLw34SwvxlwH8ZQB/GSH+soC/LOAvK8RfDvCXA/zlhPjLA/7ygL+8EH8FwF8B8FcQ4q8I+CsC/opC/JUAfyXAX0mIvzLgrwz4KwvxVwH8VQB/FSH+qoC/KuCvKsRfDfBXA/zVhPirA/7qgL+6EH8NwF8D8NcQ4q8J+GsC/ppC/LUAfy3AX0uIvzbgrw34awvx1wH8dQB/HSH+uoC/LuCvK8RfD/DXA/z1hPjrA/76gL++EH8DwN8A8DcQ4m8I+BsC/oZC/I0AfyPA30iIvzHgbwz4GwvxNwH8TQB/EyH+poC/KeBvKsTfDPA3A/zNhPibA/7mgL+5EH8LwN8C8LcQ4m8J+FsC/pZC/K0AfyvA30qIvzXgbw34WwvxtwH8bQB/GyH+toC/LeBvK8TfDvC3A/zthPjbA/72gL+9EH8HwN8B8HcQ4u8I+DsC/o5C/J0AfyfA30mIvzPg7wz4OwvxdwH8XQB/FyH+roC/K+DvKsTfDfB3A/zdhPi7A/7ugL+7EH8PwN8D8PcQ4u8J+HsC/p5C/L0Afy/A30uIvzfg7w34ewvx9wH8fQB/HyH+voC/L+DvK8TfD/D3A/z9hPj7A/7+gL+/EP8AwD8A8A8Q4h8I+AcC/oFC/IMA/yDAP0iIfzDgHwz4BwvxDwH8QwD/ECH+oYB/KOAfKsQ/DPAPA/zDhPiHA/7hgH+4EP8IwD8C8I8Q4h8J+EcC/pFC/KMA/yjAP0qIfzTgHw34RwvxjwH8YwD/GCH+sYB/LOAfK8Q/DvCPA/zjhPjHA/7xgH+8EP8EwD8B8E8Q4p8I+CcC/olC/JMA/yTAP0mIfzLgnwz4JwvxTwH8UwD/FCH+qYB/KuCfKsQ/DfBPA/zThPinA/7pgH+6EP8MwD8D8M8Q4p8J+GcC/plC/LMA/yzAP0uIfzbgnw34ZwvxzwH8cwD/HCH+uYB/LuCfK8Q/D/DPA/zzhPjnA/75gH++EP8CwL8A8C8Q4l8I+BcC/oVC/IsA/yLAv0iIfzHgXwz4FwvxLwH8SwD/EiH+pYB/KeBfKsS/DPAvA/zLhPiXA/7lgH+5EP8KwL8C8K8Q4l8J+FcC/pVC/KsA/yrAv0qIfzXgXw34VwvxrwH8awD/GiH+tYB/LeBfK8S/DvCvA/zrhPjXA/71gH+9EP8GwL8B8G8Q4t8I+DcC/o1C/JsA/ybAv0mIfzPg3wz4NwvxbwH8WwD/FiH+rYB/K+DfKsS/DfBvA/zbhPi3A/7tgH+7EP8OwL8D8O8Q4t8J+HcC/p1C/LsA/y7Av0uIfzfg3w34dwvx7wH8ewD/HiH+vYB/L+DfK8S/D/DvA/z7hPj3A/79gH+/EP8BwH8A8B8Q4j8I+A8C/oNC/IcA/yHAf0iI/zDgPwz4DwvxHwH8RwD/ESH+o4D/KOA/KsR/DPAfA/zHhPiPA/7jgP+4EP8JwH8C8J8Q4j8J+E8C/pNC/KcA/ynAf0qI/zTgPw34TwvxnwH8ZwD/GSH+s4D/LOA/K8R/DvCfA/znhPjPA/7zgP+8EP8FwH8B8F8Q4r8I+C8C/otC/JcA/yXAf0mI/zLgvwz4LwvxXwH8VwD/FSH+q4D/KuC/KsR/DfBfA/zXhPivA/7rgP+6EP8NwH8D8N8Q4r8J+G8C/ptC/LcA/y3Af0uI/zbgvw34bwvx3wH8dwD/HSH+u4D/LuC/K8R/D/DfA/z3hPjvA/77gP++EP8DwP8A8D8Q4n8I+B8C/odC/I8A/yPA/0iI/zHgfwz4HwvxPwH8TwD/EyH+p4D/KeB/KsT/DPA/A/zPhPifA/7ngP+5EP8LwP8C8L8Q4n8J+F8C/pdC/K8A/yvA/0qI/zXgfw34XwvxvwH8bwD/GyH+t4D/LeB/K8T/DvC/A/zvhPjfA/73gP+9EP8HwP8B8H8Q4v8I+D8C/o9C/J8A/yfA/0mI/zPg/wz4PwvxfwH8XwD/FyH+r4D/K+D/KsT/DfB/A/zfhPi/A/7vgP+7EP8PwP8D8P8Q4v8J+H8C/p9C/A4vc35HTHN+R1wZ/mCAPxjgDybEHxzwBwf8wYX4QwD+EIA/hBB/SMAfEvCHFOIPBfhDAf5QQvyhAX9owB9aiD8M4A8D+MMI8YcF/GEBf1gh/nCAPxzgDyfEHx7whwf84YX4IwD+CIA/ghB/RMAfEfBHFOKPBPgjAf5IQvyRAX9kwB9ZiD8K4I8C+KMI8XsAfg/A7yHE7wn4PQG/pxB/VMAfFfBHFeL3AvxegN9LiN8b8HsDfm8hfh/A7wP4fYT4owH+aIA/mhB/dMAfHfBHF+KPAfhjAP4YQvwxAX9MwB9TiD8W4I8F+GMJ8ccG/LEBf2wh/jiAPw7gjyPEHxfwxwX8cYX4fQG/L+D3FeL3A/x+gN9PiN8J+J2A3ynE7w/4/QG/vxB/PMAfD/DHE+IPAPwBgD9AiD8Q8AcC/kAh/viAPz7gjy/EnwDwJwD8CYT4EwL+hIA/oRB/IsCfCPAnEuJPDPgTA/7EQvxJAH8SwJ9EiD8p4E8K+JMK8ScD/MkAfzIh/uSAPzngTy7EnwLwpwD8KYT4UwL+lIA/pRB/KsCfCvCnEuJPDfhTA/7UQvxpAH8awJ9GiD8t4E8L+NMK8acD/OkAfzoh/vSAPz3gTy/EnwHwZwD8GYT4MwL+jIA/oxB/JsCfCfBnEuLPDPgzA/7MQvxZAH8WwJ9FiD8r4M8K+LMK8WcD/NkAfzYh/uyAPzvgzy7EnwPw5wD8OYT4cwL+nIA/pxB/LsCfC/DnEuLPDfhzA/7cQvx5AH8ewJ9HiD8v4M8L+PMK8ecD/PkAfz4h/vyAPz/gzy/EXwDwFwD8BYT4CwL+goC/oBB/IcBfCPAXEuIvDPgLA/7CQvxFAH8RwF9EiL8o4C8K+IsK8RcD/MUAfzEh/uKAvzjgLy7EXwLwlwD8JYT4SwL+koC/pBB/KcBfCvCXEuIvDfhLA/7SQvxlAH8ZwF9GiL8s4C8L+MsK8ZcD/OUAfzkh/vKAvzzgLy/EXwHwVwD8FYT4KwL+ioC/ohB/JcBfCfBXEuKvDPgrA/7KQvxVAH8VwF9FiL8q4K8K+KsK8VcD/NUAfzUh/uqAvzrgry7EXwPw1wD8NYT4awL+moC/phB/LcBfC/DXEuKvDfhrA/7aQvx1AH8dwF9HiL8u4K8L+OsK8dcD/PUAfz0h/vqAvz7gry/E3wDwNwD8DYT4GwL+hoC/oRB/I8DfCPA3EuJvDPgbA/7GQvxNAH8TwN9EiL8p4G8K+JsK8TcD/M0AfzMh/uaAvzngby7E3wLwtwD8LYT4WwL+loC/pRB/K8DfCvC3EuJvDfhbA/7WQvxtAH8bwN9GiL8t4G8L+NsK8bcD/O0Afzsh/vaAvz3gby/E3wHwdwD8HYT4OwL+joC/oxB/J8DfCfB3EuLvDPg7A/7OQvxdAH8XwN9FiL8r4O8K+LsK8XcD/N0Afzch/u6Avzvg7y7E3wPw9wD8PYT4ewL+noC/pxB/L8DfC/D3EuLvDfh7A/7eQvx9AH8fwN9HiL8v4O8L+PsK8fcD/P0Afz8h/v6Avz/g7y/EPwDwDwD8A4T4BwL+gYB/oBD/IMA/CPAPEuIfDPgHA/7BQvxDAP8QwD9EiH8o4B8K+IcK8Q8D/MMA/zAh/uGAfzjgHy7EPwLwjwD8I4T4RwL+kYB/pBD/KMA/CvCPEuIfDfhHA/7RQvxjAP8YwD9GiH8s4B8L+McK8Y8D/OMA/zgh/vGAfzzgHy/EPwHwTwD8E4T4JwL+iYB/ohD/JMA/CfBPEuKfDPgnA/7JQvxTAP8UwD9FiH8q4J8K+KcK8U8D/NMA/zQh/umAfzrgny7EPwPwzwD8M4T4ZwL+mYB/phD/LMA/C/DPEuKfDfhnA/7ZQvxzAP8cwD9HiH8u4J8L+OcK8c8D/PMA/zwh/vmAfz7gny/EvwDwLwD8C4T4FwL+hYB/oRD/IsC/CPAvEuJfDPgXA/7FQvxLAP8SwL9EiH8p4F8K+JcK8S8D/MsA/zIh/uWAfzngXy7EvwLwrwD8K4T4VwL+lYB/pRD/KsC/CvCvEuJfDfhXA/7VQvxrAP8awL9GiH8t4F8L+NcK8a8D/OsA/zoh/vWAfz3gXy/EvwHwbwD8G4T4NwL+jYB/oxD/JsC/CfBvEuLfDPg3A/7NQvxbAP8WwL9FiH8r4N8K+LcK8W8D/NsA/zYh/u2Afzvg3y7EvwPw7wD8O4T4dwL+nYB/pxD/LsC/C/DvEuLfDfh3A/7dQvx7AP8ewL9HiH8v4N8L+PcK8e8D/PsA/z4h/v2Afz/g3y/EfwDwHwD8B4T4DwL+g4D/oBD/IcB/CPAfEuI/DPgPA/7DQvxHAP8RwH9EiP8o4D8K+I8K8R8D/McA/zEh/uOA/zjgPy7EfwLwnwD8J4T4TwL+k4D/pBD/KcB/CvCfEuI/DfhPA/7TQvxnAP8ZwH9GiP8s4D8L+M8K8Z8D/OcA/zkh/vOA/zzgPy/EfwHwXwD8F4T4LwL+i4D/ohD/JcB/CfBfEuK/DPgvA/7LQvxXAP8VwH9FiP8q4L8K+K8K8V8D/NcA/zUh/uuA/zrgvy7EfwPw3wD8N4T4bwL+m4D/phD/LcB/C/DfEuK/DfhvA/7bQvx3AP8dwH9HiP8u4L8L+O8K8d8D/PcA/z0h/vuA/z7gvy/E/wDwPwD8D4T4HwL+h4D/oRD/I8D/CPA/EuJ/DPgfA/7HQvxPAP8TwP9EiP8p4H8K+J8K8T8D/M8A/zMh/ueA/zngfy7E/wLwvwD8L4T4XwL+l4D/pRD/K8D/CvC/EuJ/DfhfA/7XQvxvAP8bwP9GiP8t4H8L+N8K8b8D/O8A/zsh/veA/z3gfy/E/wHwfwD8H4T4PwL+j4D/oxD/J8D/CfB/EuL/DPg/A/7PQvxfAP8XwP9FiP8r4P8K+L8K8X8D/N8A/zch/u+A/zvg/y7E/wPw/wD8P4T4fwL+n4D/pxC/w9uc3xHLnN/h6xp/sL/xB/l3OgP//c+J6Li3v+D7yD2if3v9afD6E6Gs/7swf/tz/vqn/zOX85//x//vV3DHvzP9/TeEcASxJ8tvCOkw2envvyGU0ezvvyG0A/wd1F/27fGf/4f1F913GIf5vsM6zPcdzmG+7/AO831HcJjvO6ID/J2Z0L4jOcz3Hdlhvu8oDvN9ezjM9+3pMN93VAf4Oz6w718kv1yGtJD96qNf9xN9P9X3r6/7x9xz9fxCnZfqvBr4V9iw+nb+9R/B8W+/vBzm3rwd5t58HObeogU1a/kN0Y1mf/8NMcDsi4Hg74FczBR1E9Nh7iaWw9xNbIe5mzgOczdxHeb79gWzL4GbN0Ju/BzmbpwOczf+DnM38RzmbgIc5vsOBLOvgJu3Nrvxue7C1/p+o++3lm58p57fq/NBnY82uzG+w9xxAoe544QOc8eJgpq1/IbERrO//4YkYPY9cPxJKH9JHeZukjnM3SR3mLtJ4TB3k9Jhvu9UYPYDcPNZyE1qh7mbNA5zN2kd5m7SOczdpHeY7zsDmP0I3Hyx2Y3vdBd+0vdnfX+xdONX9fxNne/q/LDZjRkd5o4zOcwdZ3aYO84S1KzlN2Q1mv39N2QDs9+A459C+cvuMHeTw2HuJqfD3E0uh7mb3A7zfecBs9+BG8cgGTd5HeZu8jnM3eR3mLsp4DB3U9Bhvu9CYPYHcBMMuPmnbvyqu/Cnvn+5Dqa/7h9zwdVziF//d3VCDforLHVc2GHuuIjD3HFRh7njYkHNWn5DcaPZ339DCTAbYpC549BC+SvpMHdTymHuprTD3E0Zh7mbsg7zfZcDsyGBmzBCbso7zN1UcJi7qegwd1PJYe6mssN831XAbCjgJqzNbgyuuzC0vsPoO6ylG8Op5/DqRFAnos1urOowd1zNYe64usPccY2gZi2/oabR7O+/oRaYDQ8cRxLKX22HuZs6DnM3dR3mbuo5zN3Ud5jvuwGYjQDcRBZy09Bh7qaRw9xNY4e5myYOczdNHeb7bgZmIwI3UWx2YzjdhZH0HVnfUSzd6KGePdWJqo6XzW5s7jB33MJh7rilw9xxq6BmLb+htdHs77+hDZj1BI69hfLX1mHupp3D3E17h7mbDg5zNx0d5vvuBGajAjc+Qm46O8zddHGYu+nqMHfTzWHuprvDfN89wKwXcBPNZjd66C701rePvqNZujG6eo6hTkx1Ytnsxp4Oc8e9HOaOezvMHfcJatbyG/oazf7+G/qB2RjAcWyh/PV3mLsZ4DB3M9Bh7maQw9zNYIf5voeA2ZjATRwhN0Md5m6GOczdDHeYuxnhMHcz0mG+71FgNhZwE9dmN0bXXRhb33H0HdfSjb7q2e/Xn6OOv81uHO0wdzzGYe54rMPc8bigZi2/YbzR7O+/YQKY9QOO4wnlb6LD3M0kh7mbyQ5zN1Mc5m6mOsz3PQ3MOoGbACE30x3mbmY4zN3MdJi7meUwdzPbYb7vOWDWH7gJtNmNvroL4+k7QN+Blm6Mr54TqJNQnUQ2u3Guw9zxPIe54/kOc8cLgpq1/IaFRrO//4ZFYDYBcJxYKH+LHeZuljjM3Sx1mLtZ5jB3s9xhvu8VYDYhcJNEyM1Kh7mbVQ5zN6sd5m7WOMzdrHWY73sdmE0E3CS12Y3xdRcm1ncSfSe1dGMy9ZxcnRTqpLTZjesd5o43OMwdb3SYO94U1KzlN2w2mv39N2wBs8mB41RC+dvqMHezzWHuZrvD3M0Oh7mbnQ7zfe8CsymAm9RCbnY7zN3scZi72eswd7PPYe5mv8N83wfAbErgJo3NbkymuzCVvlPrO42lG9Oq53TqpFcng81uPOgwd3zIYe74sMPc8ZGgZi2/4ajR7O+/4RiYTQccZxTK33GHuZsTDnM3Jx3mbk45zN2cdpjv+wyYTQ/cZBJyc9Zh7uacw9zNeYe5mwsOczcXHeb7vgRmMwA3mW12Y1rdhRn1nUnfmS3dmEU9Z1UnmzrZbXbjZYe54ysOc8dXHeaOrwU1a/kN141mf/8NN8BsVuA4h1D+bjrM3dxymLu57TB3c8dh7uauw3zf98BsNuAmp5Cb+w5zNw8c5m4eOszdPHKYu3nsMN/3EzCbHbjJZbMbs+guzKHvnPrOZenG3Oo5jzp51clnsxufOswdP3OYO37uMHf8IqhZy294aTT7+294BWbzAMf5hfL32mHu5o3D3M1bh7mbdw5zN+8d5vv+AGbzAjcFhNx8dJi7+eQwd/PZYe7mi8PczVeH+b6/gdl8wE1Bm92YW3dhfn0X0HdBSzcWUs+F1SmiTlGb3fjdYe74h8Pc8U+HueNfz/85a/kNwYxmfx8NDmYLA8fFhPIXIpi5m5DBzN2ECmbuJjRwEwbsOyyYLQLcFBdyEw64CQ/cRABuIgI3kcC+I4PZosBNCZvdWEh3YTF9F9d3CUs3llTPpdQprU4Zm90YBTj2AI49geOowLEX8OYNZksBx2WF8ucD3EQDbqIDNzGAm5hg37HAbGngppyQm9jATRzgJi5w4wvc+IF9O8FsGeCmvM1uLKm7sKy+y+m7vKUbK6jniupUUqeyzW70B47jAccBwHEgcBwfeEsAZisCx1WE8pcQuEkE3CQGbpIAN0nBvpOB2UrATVUhN8mBmxTATUrgJhVwkxrsOw2YrQzcVLPZjRV0F1bRd1V9V7N0Y3X1XEOdmurUstmNaYHjdMBxeuA4A3CcEXjLBGZrAMe1hfKXGbjJAtxkBW6yATfZwb5zgNmawE0dITc5gZtcwE1u4CYPcJMX7DsfmK0F3NS12Y3VdRfW1ncdfde1dGM99VxfnQbqNLTZjfmB4wLAcUHguBBwXBh4KwJm6wPHjYTyVxS4KQbcFAduSgA3JcG+S4HZBsBNYyE3pYGbMsBNWeCmHHBTHuy7AphtCNw0sdmN9XQXNtJ3Y303sXRjU/XcTJ3m6rSw2Y0VgeNKwHFl4LgKcFwVeKsGZpsBxy2F8lcduKkB3NQEbmoBN7XBvuuA2ebATSshN3WBm3rATX3gpgFw0xDsuxGYbQHctLbZjU11F7bUdyt9t7Z0Yxv13Fadduq0t9mNjYHjJsBxU+C4GXDcnHgDs22B4w5C+WsJ3LQCbloDN22Am7Zg3+3ILHDTUchNe+CmA3DTEbjpBNx0BvvuAmbbAzedbHZjG92FHfTdUd+dLN3YWT13UaerOt1sdmNX4LgbcNwdOO4BHPcE3nqR7wfguLtQ/noDN32Am77ATT/gpj/Y9wAw2xW46SHkZiBwMwi4GQzcDAFuhoJ9DwOz3YCbnja7sbPuwu767qHvnpZu7KWee6vTR52+NrtxOHA8AjgeCRyPAo5HA29jwGxv4LifUP7GAjfjgJvxwM0E4GYi2PckMNsHuOkv5GYycDMFuJkK3EwDbqaDfc8As32BmwE2u7GX7sJ++u6v7wGWbhyongepM1idITa7cSZwPAs4ng0czwGO5wJv88DsIOB4qFD+5gM3C4CbhcDNIuBmMdj3EjA7GLgZJuRmKXCzDLhZDtysAG5Wgn2vArNDgJvhNrtxoO7Cofoepu/hlm4coZ5HqjNKndE2u3E1cLwGOF4LHK8DjtcDbxvA7EjgeIxQ/jYCN5uAm83AzRbgZivY9zYwOwq4GSvkZjtwswO42Qnc7AJudoN97wGzo4GbcTa7cYTuwjH6HqvvcZZuHK+eJ6gzUZ1JNrtxL3C8DzjeDxwfAI4PAm+HwOwE4HiyUP4OAzdHgJujwM0x4OY42PcJMDsRuJki5OYkcHMKuDkN3JwBbs6CfZ8Ds5OAm6k2u3G87sLJ+p6i76mWbpymnqerM0OdmTa78TxwfAE4vggcXwKOLwNvV8DsdOB4llD+rgI314Cb68DNDeDmJtj3LTA7A7iZLeTmNnBzB7i5C9zcA27ug30/ALMzgZs5Nrtxmu7CWfqere85lm6cq57nqTNfnQU2u/EhcPwIOH4MHD8Bjp8Cb8/A7DzgeKFQ/p4DNy+Am5fAzSvg5jXY9xswOx+4WSTk5i1w8w64eQ/cfABuPoJ9fwKzC4CbxTa7ca7uwoX6XqTvxZZuXKKel6qzTJ3lNrvxM3D8BTj+Chx/A46/A28/wOxS4HiFi/n7w5/zr3+0499+/QRuHMHN/1mXgX/WlUJdEyy4+T9r8ODm34chgpt/H4YMbv59GArsOzSYXQ7crLLZNUt0t6zQ90p9r7J0zWr1vEadteqss9k1YYDjsMBxOOA4PHAcAXiLCGbXAMfrhfIXCbiJDNxEAW48gBtPsO+oYHYtcLNByI0XcOMN3PgAN9GAm+hg3zHA7DrgZqPNblytu3C9vjfoe6OlGzep583qbFFnq81ujAkcxwKOYwPHcYDjuMCbL5jdDBxvE8qfH3DjBG78gZt4wE0A2HcgmN0C3GwXchMfuEkA3CQEbhIBN4nBvpOA2a3AzQ6b3bhJd+E2fW/X9w5LN+5Uz7vU2a3OHpvdmBQ4TgYcJweOUwDHKYG3VGB2F3C8Vyh/qYGbNMBNWuAmHXCTHuw7A5jdDdzsE3KTEbjJBNxkBm6yADdZwb6zgdk9wM1+m924U3fhXn3v0/d+SzceUM8H1TmkzmGb3ZgdOM4BHOcEjnMBx7mBtzxg9iBwfEQof3mBm3zATX7gpgBwUxDsuxCYPQTcHBVyUxi4KQLcFAVuigE3xcG+S4DZw8DNMZvdeEB34RF9H9X3MUs3HlfPJ9Q5qc4pm91YEjguBRyXBo7LAMdlgbdyYPYEcHxaKH/lgZsKwE1F4KYScFMZ7LsKmD0J3JwRclMVuKkG3FQHbmoANzXBvmuB2VPAzVmb3Xhcd+FpfZ/R91lLN55Tz+fVuaDORZvdWBs4rgMc1wWO6wHH9YG3BmD2PHB8SSh/DYGbRsBNY+CmCXDTFOy7GZi9ANxcFnLTHLhpAdy0BG5aATetwb7bgNmLwM0Vm914TnfhJX1f1vcVSzdeVc/X1Lmuzg2b3dgWOG4HHLcHjjsAxx2Bt05g9hpwfFMof52Bmy7ATVfgphtw0x3suweYvQ7c3BJy0xO46QXc9AZu+gA3fcG++4HZG8DNbZvdeFV34U1939L3bUs33lHPd9W5p859m93YHzgeABwPBI4HAceDgbchYPYucPxAKH9DgZthwM1w4GYEcDMS7HsUmL0H3DwUcjMauBkD3IwFbsYBN+PBvieA2fvAzSOb3XhHd+EDfT/U9yNLNz5Wz0/UearOM5vdOBE4ngQcTwaOpwDHU4G3aWD2CXD8XCh/04GbGcDNTOBmFnAzG+x7Dph9Cty8EHIzF7iZB9zMB24WADcLwb4XgdlnwM1Lm934WHfhc32/0PdLSze+Us+v1Xmjzlub3bgYOF4CHC8FjpcBx8uBtxVg9jVw/E4ofyuBm1XAzWrgZg1wsxbsex2YfQPcvBdysx642QDcbARuNgE3m8G+t4DZt8DNB5vd+Ep34Tt9v9f3B0s3flTPn9T5rM4Xm924FTjeBhxvB453AMc7gbddYPYTcPxVKH+7gZs9wM1e4GYfcLMf7PsAmP0M3HwTcnMQuDkE3BwGbo4AN0fBvo+B2S/AzXeb3fhRd+FXfX/T93dLN/5Qzz9/deJg9b8b/FdY6vg4cHwCOD4JHJ8Cjk8Db2fA7E/gOPhgmfydBW7OATfngZsLwM1FsO9LYNYx2NxNCCE3l4GbK8DNVeDmGnBznfz7FTAbDLgJCdz8Uzf+0F34K3+/7hD6/vV1/5gLpZ5DqxNGnbA2u/EmcHwLOL4NHN8Bju+Sv8MHs6GB43BC+bsP3DwAbh4CN4+Am8fk73fBbBjgJryQm6fAzTPg5jlw8wK4eQn2/QrMhgVuItjsxlC6C8PpO7y+I1i6MaJ6jqROZHWi2OzG18DxG+D4LXD8Djh+D7x9ALORgGMPofx9BG4+ATefgZsvwM1XsO9vYDYycOMp5OY7cPMDuPkJ3DhCmLsJFsJ838HBbBTgJqrNboyou9BD3576jmrpRi/17K2OjzrRbHZjiBDmjkOGMHccKoS549DAcRjgLSyY9QaOowvlLxxwEx64iQDcRARuIoF9RwazPsBNDCE3UYAbD+DGE7iJCtx4kSyA2WjATUyb3eiluzC6vmPoO6alG2Op59jqxFEnrs1u9AGOowHH0YHjGMBxTOAtFpiNDRz7CuUvNnATB7iJC9z4Ajd+YN9OMBsHuPETcuMP3MQDbgKAm0DgJj7YdwIwGxe4cdrsxli6C3317advp6Ub/dVzPHUC1Am02Y0JgeNEwHFi4DgJcJwUeEsGZuMBx/GF8pccuEkB3KQEblIBN6nBvtOA2QDgJoGQm7TATTrgJj1wkwG4yQj2nQnMBgI3CW12o7/uwvj6TqDvhJZuTKSeE6uTRJ2kNrsxM3CcBTjOChxnA46zA285wGxi4DiZUP5yAje5gJvcwE0e4CYv2Hc+MJsEuEku5CY/cFMAuCkI3BQCbgqDfRcBs0mBmxQ2uzGR7sJk+k6u7xSWbkypnlOpk1qdNDa7sShwXAw4Lg4clwCOSwJvpcBsKuA4rVD+SgM3ZYCbssBNOeCmPNh3BTCbGrhJJ+SmInBTCbipDNxUAW6qgn1XI5//gZv0Nrsxpe7CtPpOp+/0lm7MoJ4zqpNJncw2u7E6cFwDOK4JHNcCjmsDb3XAbEbgOItQ/uoCN/WAm/rATQPgpiHYdyPyMx5wk1XITWPgpglw0xS4aQbcNAf7bgFmMwM32Wx2YwbdhVn0nVXf2SzdmF0951Anpzq5bHZjS+C4FXDcGjhuAxy3Bd7akZ+/gePcQvlrD9x0AG46AjedgJvOYN9dwGxO4CaPkJuuwE034KY7cNMDuOkJ9t0LzOYCbvLa7Mbsugtz6zuPvvNaujGfes6vTgF1Ctrsxt7AcR/guC9w3A847g+8DQCz+YHjQkL5GwjcDAJuBgM3Q4CboWDfw8BsAeCmsJCb4cDNCOBmJHAzCrgZDfY9BswWBG6K2OzGfLoLC+m7sL6LWLqxqHoupk5xdUrY7MaxwPE44Hg8cDwBOJ4IvE0Cs8WA45JC+ZsM3EwBbqYCN9OAm+lg3zPAbHHgppSQm5nAzSzgZjZwMwe4mQv2PQ/MlgBuStvsxqK6C0vqu5S+S1u6sYx6LqtOOXXK2+zG+cDxAuB4IXC8CDheDLwtAbNlgeMKQvlbCtwsA26WAzcrgJuVYN+rwGw54KaikJvVwM0a4GYtcLMOuFkP9r0BzJYHbirZ7MYyugsr6LuivitZurGyeq6iTlV1qtnsxo3A8SbgeDNwvAU43gq8bQOzVYDj6kL52w7c7ABudgI3u4Cb3WDfe8BsVeCmhpCbvcDNPuBmP3BzALg5CPZ9iPw7beCmps1urKy7sLq+a+i7pqUba6nn2urUUaeuzW48DBwfAY6PAsfHgOPjwNsJMFsbOK4nlL+TwM0p4OY0cHMGuDkL9n2O/L83AG7qC7k5D9xcAG4uAjeXgJvLYN9XwGxd4KaBzW6spbuwnr7r67uBpRsbqudG6jRWp4nNbrwKHF8Djq8DxzeA45vA2y3y/6YEOG4qlL/bwM0d4OYucHMPuLkP9v0AzDYGbpoJuXkI3DwCbh4DN0+Am6dg38/AbBPgprnNbmyou7Cpvpvpu7mlG1uo55bqtFKntc1ufA4cvwCOXwLHr4Dj18DbGzDbEjhuI5S/t8DNO+DmPXDzAbj5CPb9Ccy2Am7aCrn5DNx8AW6+AjffgJvvYN8/wGxr4KadzW5sobuwjb7b6rudpRvbq+cO6nRUp9PfuvGPGedf/xEc//brJ3D864s7HUa/gnUAO+ss9P0cLKT5P2vwkObfzyFCmn8/hwxp/v0cCuw7NJjtCNx0EXITBrgJC9yEA27CAzcRwL4jgtlOwE1Xm13TXndLZ3130XdXS9d0U8/d1emhTk+bn8MiAceRgeMowLEHcOwJvEUFs92B415C+fMCbryBGx/gJhpwEx3sOwaY7QHc9BZyExO4iQXcxAZu4gA3ccG+fcFsT+Cmj81u7Ka7sJe+e+u7j6Ub+6rnfur0V2eAzW70A46dwLE/cBwPOA4A3gLBbD/geKBQ/uIDNwmAm4TATSLgJjHYdxIw2x+4GSTkJilwkwy4SQ7cpABuUoJ9pwKzA4CbwTa7sa/uwoH6HqTvwZZuHKKeh6ozTJ3hNrsxNXCcBjhOCxynA47TA28ZwOxQ4HiEUP4yAjeZgJvMwE0W4CYr2Hc2MDsMuBkp5CY7cJMDuMkJ3OQCbnKDfecBs8OBm1E2u3GI7sIR+h6p71GWbhytnseoM1adcTa7MS9wnA84zg8cFwCOCwJvhcDsGOB4vFD+CgM3RYCbosBNMeCmONh3CTA7FriZIOSmJHBTCrgpDdyUAW7Kgn2XA7PjgJuJNrtxtO7C8fqeoO+Jlm6cpJ4nqzNFnak2u7E8cFwBOK4IHFcCjisDb1XA7GTgeJpQ/qoCN9WAm+rATQ3gpibYdy0wOwW4mS7kpjZwUwe4qQvc1ANu6oN9NwCzU4GbGTa7cZLuwmn6nq7vGZZunKmeZ6kzW505NruxIXDcCDhuDBw3AY6bAm/NwOws4HiuUP6aAzctgJuWwE0r4KY12HcbMDsbuJkn5KYtcNMOuGkP3HQAbjqSf/cMZucAN/NtduNM3YVz9T1P3/Mt3bhAPS9UZ5E6i212Y2fguAtw3BU47gYcdyf/fhPMLgSOlwjlrydw0wu46Q3c9AFu+pJ/9wVmFwE3S4Xc9AduBgA3A4GbQcDNYLDvIWB2MXCzzGY3LtBduETfS/W9zNKNy9XzCnVWqrPKZjcOBY6HAcfDgeMRwPFI4G0UmF0BHK8Wyt9o4GYMcDMWuBkH3IwH+54AZlcCN2uE3EwEbiYBN5OBmynAzVSw72lgdhVws9ZmNy7XXbha32v0vdbSjevU83p1Nqiz0WY3TgeOZwDHM4HjWcDxbPJ5H8yuB443CeVvLnAzD7iZD9wsAG4Wks+CYHYDcLNZyM1i4GYJcLMUuFkG3CwnnxPA7EbgZovNblynu3CTvjfre4ulG7eq523qbFdnh81uXAkcrwKOVwPHa4DjtcDbOjC7DTjeKZS/9cDNBuBmI3CzCbjZDPa9BcxuB252CbnZCtxsA262Azc7gJudYN+7wOwO4Ga3zW7cqrtwp7536Xu3pRv3qOe96uxTZ7/NbtwNHO8BjvcCx/uA4/3A2wEwuxc4PiCUv4PAzSHg5jBwcwS4OQr2fQzM7gNuDgq5OQ7cnABuTgI3p4Cb02DfZ8DsfuDmkM1u3KO78IC+D+r7kKUbD6vnI+ocVeeYzW48CxyfA47PA8cXgOOLwNslMHsEOD4ulL/LwM0V4OYqcHMNuLkO9n0DzB4Fbk4IubkJ3NwCbm4DN3eAm7tg3/fIOw64OWmzGw/rLjyu7xP6PmnpxlPq+bQ6Z9Q5a7Mb7wPHD4Djh8DxI+D4MfD2BMyeBo7PCeXvKXDzDLh5Dty8AG5egn2/Ip9jgJvzQm5eAzdvgJu3wM074OY92PcHMHsWuLlgsxtP6S48p+/z+r5g6caL6vmSOpfVuWKzGz8Cx5+A48/A8Rfg+Cvw9o18xgSOrwrl7ztw8wO4+QncOEKZuwkWynzfwcHsZeDmmpCbEKHM3YQMZe4mVChzN6GBmzBg32HB7BXg5rrNbryou/Cqvq/p+7qlG2+o55vq3FLnts1uDAcchweOIwDHEYHjSMBbZDB7Ezi+I5S/KMCNB3DjCdxEBW68wL69wewt4OaukBsf4CYacBMduIkB3MQE+44FZm8DN/dsduMN3YV39H1X3/cs3XhfPT9Q56E6j2x2Y2zgOA5wHBc49gWO/YA3J5h9ABw/FsqfP3ATD7gJAG4CgZv4YN8JwOxD4OaJkJuEwE0i4CYxcJMEuEkK9p0MzD4Cbp7a7Mb7ugsf6/uJvp9auvGZen6uzgt1XtrsxuTAcQrgOCVwnAo4Tg28pQGzz4HjV0L5SwvcpANu0gM3GYCbjGDfmcDsC+DmtZCbzMBNFuAmK3CTDbjJDvadA8y+BG7e2OzGZ7oLX+n7tb7fWLrxrXp+p857dT7Y7MacwHEu4Dg3cJwHOM4LvOUDs++A449C+csP3BQAbgoCN4WAm8Jg30XA7Hvg5pOQm6LATTHgpjhwUwK4KQn2XQrMfgBuPtvsxre6Cz/q+5O+P1u68Yt6/qrON3W+2+zG0sBxGeC4LHBcDjguD7xVALNfgeMfQvmrCNxUAm4qAzdVgJuqYN/VwOw34OankJvqwE0N4KYmcFMLuKkN9l0HzH4HbhxD7HXjF92FP/T9U9+/vu6fc+o5uDohfv3PhvwVljquCxzXA47rA8cNgOOGwFsj8u9Nh5g7DgUcW39RN42BmybATVPgphlw0xzsuwWYDQHchBZy0xK4aQXctAZu2gA3bcG+24HZkMBNGJvd+Kv3ft2h9B1a32Es3RhWPYdTJ7w6EWx2Y3vguANw3BE47gQcdwbeuoDZcMBxRKH8dQVuugE33YGbHsBNT7DvXmA2PHATSchNb+CmD3DTF7jpB9z0B/seAGYjADeRbXZjWN2FEfUdSd+RLd0YRT17qOOpTlSb3TgQOB4EHA8GjocAx0OBt2Fg1gM49hLK33DgZgRwMxK4GQXcjAb7HgNmPYEbbyE3Y4GbccDNeOBmAnAzEex7EpiNCtz42OzGKLoLvfTtrW8fSzdGU8/R1YmhTkyb3TgZOJ4CHE8FjqcBx9OBtxlgNjpwHEsofzOBm1nAzWzgZg5wMxfsex6YjQHcxBZyMx+4WQDcLARuFgE3i8G+l4DZmMBNHJvdGE13YSx9x9Z3HEs3xlXPvur4/fqzbHbjUuB4GXC8HDheARyvBN5WgVlf4NhfKH+rgZs1wM1a4GYdcLMe7HsDmPUDbuIJudkI3GwCbjYDN1uAm61g39vArBO4CbDZjXF1F/rrO56+AyzdGKie46uTQJ2ENrtxO3C8AzjeCRzvAo53A297wGx84DiRUP72Ajf7gJv9wM0B4OYg2PchMJsAuEks5OYwcHMEuDkK3BwDbo6DfZ8AswmBmyQ2uzFQd2EifSfWdxJLNyZVz8nUSa5OCpvdeBI4PgUcnwaOzwDHZ4G3c2A2GXCcUih/54GbC8DNReDmEnBzGez7CphNDtykEnJzFbi5BtxcB25uADc3wb5vgdkUwE1qm92YVHdhSn2n0ndqSzemUc9p1UmnTnqb3XgbOL4DHN8Fju8Bx/eBtwdgNi1wnEEofw+Bm0fAzWPg5glw8xTs+xmYTQfcZBRy8xy4eQHcvARuXgE3r8G+34DZ9MBNJpvdmEZ3YQZ9Z9R3Jks3ZlbPWdTJqk42m934Fjh+Bxy/B44/AMcfgbdPYDYLcJxdKH+fgZsvwM1X4OYbcPMd7PsHmM0K3ORw0c0f2XL+9Y92/Nuvn8CNI7T5P2s28M+a02bXZNbdkl3fOfSd09I1udRzbnXyqJPXZtcEC22+s+Chzb+fQ4Q2/34OGdr8+zkU8BYazOYGjvMJdU0Y4CYscBMOuAkP3EQA+44IZvMAN/mF3EQCbiIDN1GAGw/gxhPsOyqYzQvcFLDZjbl0F+bTd359F7B0Y0H1XEidwuoUsdmNXsCxN3DsAxxHA46jA28xwGwh4LioUP5iAjexgJvYwE0c4CYu2LcvmC0M3BQTcuMH3DiBG3/gJh5wEwD2HQhmiwA3xW12Y0HdhUX1XUzfxS3dWEI9l1SnlDqlbXZjfOA4AXCcEDhOBBwnBt6SgNmSwHEZofwlBW6SATfJgZsUwE1KsO9UYLYUcFNWyE1q4CYNcJMWuEkH3KQH+84AZksDN+VsdmMJ3YVl9F1W3+Us3VhePVdQp6I6lWx2Y0bgOBNwnBk4zgIcZyV/FwJmKwDHlYXylx24yQHc5ARucgE3ucnPyWC2InBTRchNXuAmH3CTH7gpANwUJD9DgdlKwE1Vm91YXndhZX1X0XdVSzdWU8/V1amhTk2b3VgYOC4CHBcFjosBx8WBtxJgtjpwXEsofyWBm1LATWngpgxwUxbsuxyYrQHc1BZyUx64qQDcVARuKgE3lcG+q4DZmsBNHZvdWE13YS1919Z3HUs31lXP9dSpr04Dm91YFTiuBhxXB45rAMc1gbdaYLYecNxQKH+1gZs6wE1d4KYecFMf7LsBmK0P3DQSctMQuGkE3DQGbpoAN03BvpsRj8BNY5vdWFd3YUN9N9J3Y0s3NlHPTdVppk5zm93YHDhuARy3BI5bAcetgbc2YLYpcNxCKH9tgZt2wE174KYDcNMR7LsTySpw01LITWfgpgtw0xW46QbcdAf77gFmmwM3rWx2YxPdhS303VLfrSzd2Fo9t1GnrTrtbHZjT+C4F3DcGzjuAxz3Bd76kR4FjtsL5a8/cDMAuBkI3AwCbgaDfQ8Bs22Bmw5CboYCN8OAm+HAzQjgZiTY9ygw2w646WizG1vrLmyv7w767mjpxk7qubM6XdTparMbRwPHY4DjscDxOOB4PPA2Acx2Bo67CeVvInAzCbiZDNxMAW6mgn1PA7NdgJvuQm6mAzczgJuZwM0s4GY22PccMNsVuOlhsxs76S7spu/u+u5h6cae6rmXOr3V6WOzG+cCx/OA4/nA8QLgeCHwtgjM9gKO+wrlbzFwswS4WQrcLANuloN9rwCzvYGbfkJuVgI3q4Cb1cDNGuBmLdj3OjDbB7jpb7Mbe+ou7Kvvfvrub+nGAep5oDqD1BlssxvXA8cbgOONwPEm4Hgz8LYFzA4EjocI5W8rcLMNuNkO3OwAbnaCfe8Cs4OAm6FCbnYDN3uAm73AzT7gZj/Y9wEwOxi4GWazGwfoLhyi76H6HmbpxuHqeYQ6I9UZZbMbDwLHh4Djw8DxEeD4KPB2DMyOAI5HC+XvOHBzArg5CdycAm5Og32fAbMjgZsxQm7OAjfngJvzwM0F4OYi2Pcl8neTwM1Ym904XHfhaH2P0fdYSzeOU8/j1ZmgzkSb3XgZOL4CHF8Fjq8Bx9eBtxtgdjxwPEkofzeBm1vAzW3g5g5wcxfs+x75e2PgZrKQm/vAzQPg5iFw8wi4eQz2/QTMTgRuptjsxnG6Cyfpe7K+p1i6cap6nqbOdHVm2OzGp8DxM+D4OXD8Ajh+Cby9Iv9uADieKZS/18DNG+DmLXDzDrh5D/b9AcxOB25mCbn5CNx8Am4+AzdfgJuvYN/fwOwM4Ga2zW6cqrtwpr5n6Xu2pRvnqOe56sxTZ77NbvwOHP8Ajn8Cx44w5o6DGc3+PhoczM4FjhcI5S9EGHM3IcOYuwkVxtxNaOAmDNh3WDA7D7hZKOQmHHATHriJANxEBG4igX1HBrPzgZtFNrtxju7CBfpeqO9Flm5crJ6XqLNUnWU2uzEKcOwBHHsCx1GBYy/gzRvMLgGOlwvlzwe4iQbcRAduYgA3McG+Y4HZpcDNCiE3sYGbOMBNXODGF7jxA/t2gtllwM1Km924WHfhcn2v0PdKSzeuUs+r1Vmjzlqb3egPHMcDjgOA40DgOD7wlgDMrgaO1wnlLyFwkwi4SQzcJAFukoJ9JwOza4Cb9UJukgM3KYCblMBNKuAmNdh3GjC7FrjZYLMbV+kuXKfv9freYOnGjep5kzqb1dlisxvTAsfpgOP0wHEG4Dgj8JYJzG4CjrcK5S8zcJMFuMkK3GQDbrKDfecAs5uBm21CbnICN7mAm9zATR7gJi/Ydz4wuwW42W6zGzfqLtyq72363m7pxh3qeac6u9TZbbMb8wPHBYDjgsBxIeC4MPBWBMzuBI73COWvKHBTDLgpDtyUAG5Kgn2XArO7gJu9Qm5KAzdlgJuywE054KY82HcFMLsbuNlnsxt36C7co++9+t5n6cb96vmAOgfVOWSzGysCx5WA48rAcRXguCrwVg3MHgCODwvlrzpwUwO4qQnc1AJuaoN91wGzB4GbI0Ju6gI39YCb+sBNA+CmIdh3IzB7CLg5arMb9+suPKzvI/o+aunGY+r5uDon1DlpsxsbA8dNgOOmwHEz4Lg58NYCzB4Hjk8J5a8lcNMKuGkN3LQBbtqCfbcDsyeAm9NCbtoDNx2Am47ATSfgpjPYdxcwexK4OWOzG4/pLjyl79P6PmPpxrPq+Zw659W5YLMbuwLH3YDj7sBxD+C4J/DWC8yeA44vCuWvN3DTB7jpC9z0A276g30PALPngZtLQm4GAjeDgJvBwM0Q4GYo2PcwMHsBuLlssxvP6i68qO9L+r5s6cYr6vmqOtfUuW6zG4cDxyOA45HA8SjgeDTwNgbMXgWObwjlbyxwMw64GQ/cTABuJoJ9TwKz14Cbm0JuJgM3U4CbqcDNNOBmOtj3DDB7Hbi5ZbMbr+guvKHvm/q+ZenG2+r5jjp31blnsxtnAsezgOPZwPEc4Hgu8DYPzN4Bju8L5W8+cLMAuFkI3CwCbhaDfS8Bs3eBmwdCbpYCN8uAm+XAzQrgZiXY9yowew+4eWizG2/rLryv7wf6fmjpxkfq+bE6T9R5arMbVwPHa4DjtcDxOuB4PfC2Acw+Bo6fCeVvI3CzCbjZDNxsAW62gn1vA7NPgJvnQm62Azc7gJudwM0u4GY32PceMPsUuHlhsxsf6S58pu/n+n5h6caX6vmVOq/VeWOzG/cCx/uA4/3A8QHg+CD5d2hg9hVw/FYof4eBmyPAzVHg5hhwc5z8+xUw+xq4eSfk5iRwcwq4OQ3cnAFuzpK/ewezb4Cb9za78aXuwrf6fqfv95Zu/KCeP6rzSZ3PNrvxPHB8ATi+CBxfAo4vA29XwOxH4PiLUP6uAjfXgJvrwM0N4OYm2PctMPsJuPkq5OY2cHMHuLkL3NwDbu6DfT8As5+Bm282u/GD7sIv+v6q72+Wbvyunn+o8/NXLw79Kyx1/BA4fgQcPwaOnwDHT4G3Z2D2B3AcbKhM/p4DNy+Am5fAzSvg5jX5vAFmfwI3wYXcvAVu3gE374GbD8DNR/IuArOOoeZuQgA3/9SN33UX/srfrzu4vn993T/mQqrnUOqEVieMzW78DBx/AY6/AsffgOPvpO/AbCjgOKyL+fvDn/Ovf7Tj3379BG5+iXc6jH4FCw3+WcPZ/H4Oqb9/w+o7nL7DWL6fw6vnCOpEVCfS376fg+vbachrnQ1qDxGGGs/+9TdCpsj/8eeknFO5bsy0c6f9CL11efguflus/7swf/tz/vqn/wNXWPPvl+BhzbMcIqx5lkOGNc9yKPI9G9Z831FczCfddxiw77Bg3+HAvsODfUcA+44I9u1hsyMiD/3fP9KvO4r+v3tYOsJTPUdVx0sdb5vvvEjAW2TgLQrw5gG8eQJvUckseA/4CH3m9AJuvIEbH+AmGnATHew7Bpj1Am6iCbmJCdzEAm5iAzdxgJu4YN++YNYbuIlusxs9dRf66DuavqNbujGGeo6pTix1YtvsRj/g2Akc+wPH8YDjAOAtEMzGBI7jCOUvPnCTALhJCNwkAm4Sg30nAbOxgJu4Qm6SAjfJgJvkwE0K4CYl2HcqMBsbuPG12Y0xdBfG0XdcfftautHv15+hjr868Wx2Y2rgOA1wnBY4TgccpwfeMoBZJ3AcIJS/jMBNJuAmM3CTBbjJCvadDcz6AzeBQm6yAzc5gJucwE0u4CY32HceMBsPuIlvsxv9dBcG6DtQ3/Et3ZhAPSdUJ5E6iW12Y17gOB9wnB84LgAcFwTeCoHZhMBxEqH8FQZuigA3RYGbYsBNcbDvEmA2EXCTVMhNSeCmFHBTGrgpA9yUBfsuB2YTAzfJbHZjAt2FSfSdVN/JLN2YXD2nUCelOqlsdmN54LgCcFwROK4EHFcG3qqA2RTAcWqh/FUFbqoBN9WBmxrATU2w71pgNiVwk0bITW3gpg5wUxe4qQfc1Af7bkB+/gZu0trsxuS6C1PrO42+01q6MZ16Tq9OBnUy2uzGhsBxI+C4MXDcBDhuCrw1A7PpgeNMQvlrDty0AG5aAjetgJvWYN9tyN+NADeZhdy0BW7aATftgZsOwE1HsO9OYDYjcJPFZjem012YSd+Z9Z3F0o1Z1XM2dbKrk8NmN3YGjrsAx12B427AcXfgrQf5+y/gOKdQ/noCN72Am97ATR/gpi/Ydz8wmx24ySXkpj9wMwC4GQjcDAJuBoN9DwGzOYCb3Da7Mavuwpz6zqXv3JZuzKOe86qTT538NrtxKHA8DDgeDhyPAI5HAm+jwGxe4LiAUP5GAzdjgJuxwM044GY82PcEMJsPuCko5GYicDMJuJkM3EwBbqaCfU8Ds/mBm0I2uzGP7sIC+i6o70KWbiysnouoU1SdYja7cTpwPAM4ngkczwKOZwNvc8BsEeC4uFD+5gI384Cb+cDNAuBmIdj3IjBbFLgpIeRmMXCzBLhZCtwsA26Wg32vALPFgJuSNruxsO7C4vouoe+Slm4spZ5Lq1NGnbI2u3ElcLwKOF4NHK8BjtcCb+vAbGnguJxQ/tYDNxuAm43AzSbgZjPY9xYwWwa4KS/kZitwsw242Q7c7ABudoJ97wKzZYGbCja7sZTuwnL6Lq/vCpZurKieK6lTWZ0qNrtxN3C8BzjeCxzvA473A28HwGwl4LiqUP4OAjeHgJvDwM0R4OYo2PcxMFsZuKkm5OY4cHMCuDkJ3JwCbk6DfZ8Bs1WAm+o2u7Gi7sKq+q6m7+qWbqyhnmuqU0ud2ja78SxwfA44Pg8cXwCOLwJvl8BsTeC4jlD+LgM3V4Cbq8DNNeDmOtj3DTBbC7ipK+TmJnBzC7i5DdzcAW7ugn3fA7O1gZt6Nruxhu7COvquq+96lm6sr54bqNNQnUY2u/E+cPwAOH4IHD8Cjh8Db0/AbAPguLFQ/p4CN8+Am+fAzQvg5iXY9ysw2xC4aSLk5jVw8wa4eQvcvANu3oN9fwCzjYCbpja7sb7uwsb6bqLvppZubKaem6vTQp2WNrvxI3D8CTj+DBx/AY6/Am/fwGxz4LiVUP6+Azc/gJufwI0jnLmbYOHM9x0czLYAbloLuQkRztxNyHDmbkKFM3cTGrgJA/YdFsy2BG7a2OzGZroLW+m7tb7bWLqxrXpup057dTrY7MZwwHF44DgCcBwROI4EvEUGs+2A445C+YsC3HgAN57ATVTgxgvs2xvMtgduOgm58QFuogE30YGbGMBNTLDvWGC2A3DT2WY3ttVd2FHfnfTd2dKNXdRzV3W6qdPdZjfGBo7jAMdxgWNf4NgPeHOC2a7AcQ+h/PkDN/GAmwDgJhC4iQ/2nQDMdgNuegq5SQjcJAJuEgM3SYCbpGDfycBsd+Cml81u7KK7sIe+e+q7l6Ube6vnPur0VaefzW5MDhynAI5TAsepgOPUwFsaMNsHOO4vlL+0wE064CY9cJMBuMkI9p0JzPYFbgYIuckM3GQBbrICN9mAm+xg3znAbD/gZqDNbuytu7C/vgfoe6ClGwep58HqDFFnqM1uzAkc5wKOcwPHeYDjvMBbPjA7GDgeJpS//MBNAeCmIHBTCLgpDPZdBMwOAW6GC7kpCtwUA26KAzclgJuSYN+lwOxQ4GaEzW4cpLtwmL6H63uEpRtHqudR6oxWZ4zNbiwNHJcBjssCx+WA4/LAWwUwOwo4HiuUv4rATSXgpjJwUwW4qQr2XQ3MjgZuxgm5qQ7c1ABuagI3tYCb2mDfdcDsGOBmvM1uHKm7cKy+x+l7vKUbJ6jniepMUmeyzW6sCxzXA47rA8cNgOOGwFsjMDsROJ4ilL/GwE0T4KYpcNMMuGlO/t0zmJ0E3EwVctMSuGkF3LQGbtoAN23Jv5cEs5OBm2k2u3GC7sIp+p6q72mWbpyunmeoM1OdWTa7sT1w3AE47ggcdwKOOwNvXcDsDOB4tlD+ugI33YCb7sBND+CmJ9h3LzA7E7iZI+SmN3DTB7jpC9z0A276g30PALOzgJu5Nrtxuu7C2fqeo++5lm6cp57nq7NAnYU2u3EgcDwIOB4MHA8BjocCb8PA7HzgeJFQ/oYDNyOAm5HAzSjgZjT5WQzMLgBuFgu5GQvcjANuxgM3E4CbieRzOphdCNwssdmN83QXLtL3Yn0vsXTjUvW8TJ3l6qyw2Y2TgeMpwPFU4HgacDydfBYEs8uA45VC+ZsJ3MwCbmYDN3OAm7lg3/PA7HLgZpWQm/nAzQLgZiFwswi4WQz2vQTMrgBuVtvsxqW6C1fqe5W+V1u6cY16XqvOOnXW2+zGpcDxMuB4OXC8AjheCbytArNrgeMNQvlbDdysAW7WAjfrgJv1YN8bwOw64GajkJuNwM0m4GYzcLMFuNkK9r0NzK4HbjbZ7MY1ugs36HujvjdZunGzet6izlZ1ttnsxu3A8Q7geCdwvAs43g287QGzW4Dj7UL52wvc7ANu9gM3B4Cbg2Dfh8DsVuBmh5Cbw8DNEeDmKHBzDLg5DvZ9gvQocLPTZjdu1l24Xd879L3T0o271PNudfaos9dmN54Ejk8Bx6eB4zPA8Vng7RyY3Q0c7xPK33ng5gJwcxG4uQTcXAb7vkLeccDNfiE3V4Gba8DNdeDmBnBzE+z7FpjdC9wcsNmNu3QX7tP3fn0fsHTjQfV8SJ3D6hyx2Y23geM7wPFd4PgecHwfeHtAPscAx0eF8vcQuHkE3DwGbp4AN0/Bvp+B2cPAzTEhN8+BmxfAzUvg5hVw8xrs+w2YPQLcHLfZjQd1Fx7V9zF9H7d04wn1fFKdU+qcttmNb4Hjd8Dxe+D4A3D8EXj7BGZPAsdnhPL3Gbj5Atx8BW6+ATffwb5/gNlTwM1ZF938kS3nX/9ox7/9+gncOMKb/7OeBv+s52x2zQndLWf0fVbf5yxdc149X1DnojqXbHZNsPDmOwse3vz7OUR48+/nkOHNv59DAW+hwewF4PiyUNeEAW7CAjfhgJvwwE0EsO+IYPYicHNFyE0k4CYycBMFuPEAbjzBvqOC2UvAzVWb3Xhed+FlfV/R91VLN15Tz9fVuaHOTZvd6AUcewPHPsBxNOA4OvAWA8xeB45vCeUvJnATC7iJDdzEAW7ign37gtkbwM1tITd+wI0TuPEHbuIBNwFg34Fg9iZwc8dmN17TXXhL37f1fcfSjXfV8z117qvzwGY3xgeOEwDHCYHjRMBxYuAtCZi9Bxw/FMpfUuAmGXCTHLhJAdykBPtOBWbvAzePhNykBm7SADdpgZt0wE16sO8MYPYBcPPYZjfe1V34UN+P9P3Y0o1P1PNTdZ6p89xmN2YEjjMBx5mB4yzAcVbgLRuYfQocvxDKX3bgJgdwkxO4yQXc5Ab7zgNmnwE3L4Xc5AVu8gE3+YGbAsBNQbDvQmD2OXDzymY3PtFd+ELfL/X9ytKNr9XzG3XeqvPOZjcWBo6LAMdFgeNiwHFx4K0EmH0DHL8Xyl9J4KYUcFMauCkD3JQF+y4HZt8CNx+E3JQHbioANxWBm0rATWWw7ypg9h1w89FmN77WXfhe3x/0/dHSjZ/U82d1vqjz1WY3VgWOqwHH1YHjGsBxTeCtFpj9DBx/E8pfbeCmDnBTF7ipB9zUB/tuAGa/ADffhdw0BG4aATeNgZsmwE1TsO9mYPYrcPPDZjd+0l34Td/f9f3D0o0/f/XhMPU/Vyf4sL/CUsfNgeMWwHFL4LgVcNwaeGsDZn/t84/ZoByHGCaTv7bATTvgpj1w0wG46Qj23QnMBgNuQgq56QzcdAFuugI33YCb7mDfPcBscOAmFHDzT934U3fhr/z9ukPq+9fX/WMutHoOo05YdcLZ7MaewHEv4Lg3cNwHOO4LvPUDs2GA4/BC+esP3AwAbgYCN4OAm8Fg30PAbFjgJoKQm6HAzTDgZjhwMwK4GQn2PQrMhgNuItrsxtC6C8PrO4K+I1q6MZJ6jqxOFHU8bHbjaOB4DHA8FjgeBxyPB94mgNnIwLGnUP4mAjeTgJvJwM0U4GYq2Pc0MBsFuIkq5GY6cDMDuJkJ3MwCbmaDfc8Bsx7AjZfNboyku9BT31H17WXpRm/17KNONHWi2+zGucDxPOB4PnC8ADheCLwtArM+wHEMofwtBm6WADdLgZtlwM1ysO8VYDYacBNTyM1K4GYVcLMauFkD3KwF+14HZqMDN7FsdqO37sIY+o6p71iWboytnuOoE1cdX5vduB443gAcbwSONwHHm4G3LWA2DnDsJ5S/rcDNNuBmO3CzA7jZCfa9C8zGBW6cQm52Azd7gJu9wM0+4GY/2PcBMOsL3Pjb7MbYugv99O3Ut7+lG+Op5wB1AtWJb7MbDwLHh4Djw8DxEeD4KPB2DMwGAMcJhPJ3HLg5AdycBG5OATenwb7PgNlA4CahkJuzwM054OY8cHMBuLkI9n0JzMYHbhLZ7MZ4ugsT6DuhvhNZujGxek6iTlJ1ktnsxsvA8RXg+CpwfA04vg683QCzSYDj5EL5uwnc3AJubgM3d4Cbu2Df98BsUuAmhZCb+8DNA+DmIXDzCLh5DPb9BMwmA25S2uzGxLoLk+s7hb5TWroxlXpOrU4addLa7ManwPEz4Pg5cPwCOH4JvL0Cs6mB43RC+XsN3LwBbt4CN++Am/dg3x/AbBrgJr2Qm4/AzSfg5jNw8wW4+Qr2/Q3MpgVuMtjsxlS6C9PpO72+M1i6MaN6zqROZnWy2OzG78DxD+D4J3DsiGDuOJjR7O+jwcFsJuA4q1D+QkQwdxMygrmbUBHM3YQGbsKAfYcFs5mBm2xCbsIBN+GBmwjATUTgJhLYd2QwmwW4yW6zGzPqLsyq72z6zm7pxhzqOac6udTJbbMbowDHHsCxJ3AcFTj2At68wWxO4DiPUP58gJtowE104CYGcBMT7DsWmM0F3OQVchMbuIkD3MQFbnyBGz+wbyeYzQ3c5LPZjTl0F+bRd15957N0Y371XECdguoUstmN/sBxPOA4ADgOBI7jA28JwGwB4LiwUP4SAjeJgJvEwE0S4CYp2HcyMFsQuCki5CY5cJMCuEkJ3KQCblKDfacBs4WAm6I2uzG/7sLC+i6i76KWbiymnourU0Kdkja7MS1wnA44Tg8cZwCOM5Kfk8FsceC4lFD+MgM3WYCbrMBNNuAmO9h3DjBbArgpLeQmJ3CTC7jJDdzkAW7ygn3nA7MlgZsyNruxmO7CUvoure8ylm4sq57LqVNenQo2uzE/cFwAOC4IHBcCjgsDb0XAbDnguKJQ/ooCN8WAm+LATQngpiTYdykwWx64qSTkpjRwUwa4KQvclANuyoN9VyCzwE1lm91YVndhRX1X0ndlSzdWUc9V1ammTnWb3VgROK4EHFcGjqsAx1WBt2pgtipwXEMof9WBmxrATU3gphZwUxvsuw7xCNzUFHJTF7ipB9zUB24aADcNwb4bgdnqwE0tm91YRXdhDX3X1HctSzfWVs911KmrTj2b3dgYOG4CHDcFjpsBx82BtxYkq8BxfaH8tQRuWgE3rYGbNsBNW7DvdmC2LnDTQMhNe+CmA3DTEbjpBNx0BvvuAmbrATcNbXZjbd2F9fXdQN8NLd3YSD03VqeJOk1tdmNX4LgbcNwdOO4BHPcE3nqB2cbAcTOh/PUGbvoAN32Bm37ATX+w7wFgtglw01zIzUDgZhBwMxi4GQLcDAX7HgZmmwI3LWx2YyPdhc303VzfLSzd2FI9t1KntTptbHbjcOB4BHA8EjgeBRyPBt7GgNlWwHFbofyNBW7GATfjgZsJwM1EsO9JYLY1cNNOyM1k4GYKcDMVuJkG3EwH+54BZtsAN+1tdmNL3YVt9d1O3+0t3dhBPXdUp5M6nW1240zgeBZwPBs4ngMczwXe5oHZjsBxF6H8zQduFgA3C4GbRcDNYrDvJWC2E3DTVcjNUuBmGXCzHLhZAdysBPteBWY7AzfdbHZjB92FXfTdVd/dLN3YXT33UKenOr1sduNq4HgNcLwWOF4HHK8H3jaA2R7AcW+h/G0EbjYBN5uBmy3AzVaw721gtidw00fIzXbgZgdwsxO42QXc7Ab73kP+3gq46WuzG7vrLuyt7z767mvpxn7qub86A9QZaLMb9wLH+4Dj/cDxAeD4IPB2CMz2B44HCeXvMHBzBLg5CtwcA26Og32fIH83CdwMFnJzErg5BdycBm7OADdnwb7PgdmBwM0Qm93YT3fhIH0P1vcQSzcOVc/D1Bmuzgib3XgeOL4AHF8Eji8Bx5eBtyvk75+B45FC+bsK3FwDbq4DNzeAm5tg37fA7HDgZpSQm9vAzR3g5i5wcw+4uQ/2/QDMjgBuRtvsxqG6C0fqe5S+R1u6cYx6HqvOOHXG2+zGh8DxI+D4MXD8BDh+Crw9A7NjgeMJQvl7Dty8AG5eAjevgJvXYN9vwOw44GaikJu3wM074OY9cPMBuPkI9v0JzI4HbibZ7MYxugsn6HuividZunGyep6izlR1ptnsxs/A8Rfg+Ctw/A04/g68/QCzU4Dj6S7m7w9/zr/+0Y5/+/UTuPn1jeR0GP0KNhX8s84Q6ppgEc3/WYNHNP8+DBHR/PswZETz78NQYN+hwew04Gamza6ZrLtlur5n6HumpWtmqefZ6sxRZ67NrgkDHIcFjsMBx+GB4wjAW0QwOxs4nieUv0jATWTgJgpw4wHceIJ9RwWzc4Cb+UJuvIAbb+DGB7iJBtxEB/uOAWbnAjcLbHbjLN2F8/Q9X98LLN24UD0vUmexOktsdmNM4DgWcBwbOI4DHMcF3nzB7CLgeKlQ/vyAGydw4w/cxANuAsC+A8HsYuBmmZCb+MBNAuAmIXCTCLhJDPadBMwuAW6W2+zGhboLl+p7mb6XW7pxhXpeqc4qdVbb7MakwHEy4Dg5cJwCOE4JvKUCsyuB4zVC+UsN3KQBbtICN+mAm/Rg3xnA7CrgZq2Qm4zATSbgJjNwkwW4yQr2nQ3MrgZu1tnsxhW6C9foe62+11m6cb163qDORnU22ezG7MBxDuA4J3CcCzjODbzlAbMbgOPNQvnLC9zkA27yAzcFgJuCYN+FwOxG4GaLkJvCwE0R4KYocFMMuCkO9l0CzG4Cbrba7Mb1ugs363uLvrdaunGbet6uzg51dtrsxpLAcSnguDRwXAY4Lgu8lQOz24HjXUL5Kw/cVABuKgI3lYCbymDfVcDsDuBmt5CbqsBNNeCmOnBTA7ipCfZdC8zuBG722OzGbboLd+l7t773WLpxr3rep85+dQ7Y7MbawHEd4LgucFwPOK4PvDUAs/uA44NC+WsI3DQCbhoDN02Am6Zg383A7H7g5pCQm+bATQvgpiVw0wq4aQ323QbMHgBuDtvsxr26Cw/q+5C+D1u68Yh6PqrOMXWO2+zGtsBxO+C4PXDcATjuCLx1ArNHgeMTQvnrDNx0AW66AjfdgJvuYN89wOwx4OakkJuewE0v4KY3cNMHuOkL9t0PzB4Hbk7Z7MYjugtP6Pukvk9ZuvG0ej6jzll1ztnsxv7A8QDgeCBwPAg4Hgy8DQGzZ4Dj80L5GwrcDANuhgM3I4CbkWDfo8DsWeDmgpCb0cDNGOBmLHAzDrgZD/Y9AcyeA24u2uzG07oLz+v7gr4vWrrxknq+rM4Vda7a7MaJwPEk4HgycDwFOJ4KvE0Ds5eB42tC+ZsO3MwAbmYCN7OAm9lg33PA7BXg5rqQm7nAzTzgZj5wswC4WQj2vQjMXgVubtjsxku6C6/p+7q+b1i68aZ6vqXObXXu2OzGxcDxEuB4KXC8DDheDrytALO3gOO7QvlbCdysAm5WAzdrgJu1YN/rwOxt4OaekJv1wM0G4GYjcLMJuNkM9r0FzN4Bbu7b7Mabugvv6vuevu9buvGBen6oziN1Htvsxq3A8TbgeDtwvAM43gm87QKzD4HjJ0L52w3c7AFu9gI3+4Cb/WDfB8DsI+DmqZCbg8DNIeDmMHBzBLg5CvZ9DMw+Bm6e2ezGB7oLn+j7qb6fWbrxuXp+oc5LdV7Z7MbjwPEJ4PgkcHwKOD4NvJ0Bsy+A49dC+TsL3JwDbs4DNxeAm4tg35fA7Evg5o2Qm8vAzRXg5ipwcw24uQ72fQPMvgJu3trsxue6C1/r+42+31q68Z16fq/OB3U+2uzGm8DxLeD4NnB8Bzi+C7zdA7PvgeNPQvm7D9w8AG4eAjePgJvHYN9PwOwH4OazkJunwM0z4OY5cPMCuHlJ+g7MfgRuvtjsxne6Cz/p+7O+v1i68at6/qbOd3V+2OzG18DxG+D4LXD8Djh+TzIFZr8Bxz+F8vcRuPkE3HwGbr4AN1/JvsHsd+DGMVzGzXfg5gdw8xO4cUQydxMskvm+g4PZH8BNMODmn7rxq+7Cn/r+5TqY/rp/zAVXzyF+/d/VCTX8r7DUcYhI5o5DRjJ3HCqSuePQwHEY4C0smA0x3NxxaKH8hQNuwgM3EYCbiMBNJLDvyGA2JHATRshNFODGA7jxBG6iAjdeYN/eYDYUcBPWZjcG110YWt9h9B3W0o3h1HN4dSKoE9FmN/oAx9GA4+jAcQzgOCbwFgvMhgeOIwnlLzZwEwe4iQvc+AI3fmDfTjAbAbiJLOTGH7iJB9wEADeBwE18sO8EYDYicBPFZjeG010YSd+R9R3F0o0e6tlTnajqeNnsxoTAcSLgODFwnAQ4Tgq8JQOznsCxt1D+kgM3KYCblMBNKuAmNdh3GjAbFbjxEXKTFrhJB9ykB24yADcZwb4zgVkv4CaazW700F3orW8ffUezdGN09RxDnZjqxLLZjZmB4yzAcVbgOBtwnB14ywFmYwDHsYXylxO4yQXc5AZu8gA3ecG+84HZmMBNHCE3+YGbAsBNQeCmEHBTGOy7CPnZDLiJa7Mbo+sujK3vOPqOa+lGX/Xs9+vPUcffZjcWBY6LAcfFgeMSwHFJ4K0UmPUDjuMJ5a80cFMGuCkL3JQDbsqDfVcgP38DNwFCbioCN5WAm8rATRXgpirYdzUw6w/cBNrsRl/dhfH0HaDvQEs3xlfPCdRJqE4im91YHTiuARzXBI5rAce1gbc65O9YgOPEQvmrC9zUA27qAzcNgJuGYN+NwGxC4CaJkJvGwE0T4KYpcNMMuGkO9t0CzCYCbpLa7Mb4ugsT6zuJvpNaujGZek6uTgp1UtrsxpbAcSvguDVw3AY4bgu8tQOzyYHjVEL5aw/cdABuOgI3nYCbzmDfXcBsCuAmtZCbrsBNN+CmO3DTA7jpCfbdC8ymBG7S2OzGZLoLU+k7tb7TWLoxrXpOp056dTLY7MbewHEf4LgvcNwPOO4PvA0As+mA44xC+RsI3AwCbgYDN0OAm6Fg38PAbHrgJpOQm+HAzQjgZiRwMwq4GQ32PQbMZgBuMtvsxrS6CzPqO5O+M1u6MYt6zqpONnWy2+zGscDxOOB4PHA8ATieCLxNArNZgeMcQvmbDNxMAW6mAjfTgJvpYN8zwGw24CankJuZwM0s4GY2cDMHuJkL9j0PzGYHbnLZ7MYsugtz6DunvnNZujG3es6jTl518tnsxvnA8QLgeCFwvAg4Xgy8LQGzeYDj/EL5WwrcLANulgM3K4CblWDfq8BsXuCmgJCb1cDNGuBmLXCzDrhZD/a9AczmA24K2uzG3LoL8+u7gL4LWrqxkHourE4RdYra7MaNwPEm4HgzcLwFON4KvG0Ds4WB42JC+dsO3OwAbnYCN7uAm91g33vAbBHgpriQm73AzT7gZj9wcwC4OQj2fQjMFgVuStjsxkK6C4vpu7i+S1i6saR6LqVOaXXK2OzGw8DxEeD4KHB8DDg+DrydALOlgOOyQvk7CdycAm5OAzdngJuzYN/nwGxp4KackJvzwM0F4OYicHMJuLkM9n0FzJYBbsrb7MaSugvL6rucvstburGCeq6oTiV1KtvsxqvA8TXg+DpwfAM4vgm83QKzFYHjKkL5uw3c3AFu7gI394Cb+2DfD8BsJeCmqpCbh8DNI+DmMXDzBLh5Cvb9DMxWBm6q2ezGCroLq+i7qr6rWbqxunquoU5NdWrZ7MbnwPEL4PglcPwKOH4NvL0BszWA49pC+XsL3LwDbt4DNx+Am49g35/AbE3gpo6Qm8/AzRfg5itw8w24+Q72/QPM1gJu6trsxuq6C2vru46+61q6sZ56rq9OA3Ua/q0b/5hx/vUfwfFvv34Cx47I5jurD3bWSOj7OVhk83/W4JHNv59DRDb/fg4Z2fz7ORTYd2gw2wC4aSzkJgxwExa4CQfchAduIoB9RwSzDYGbJja7pp7ulkb6bqzvJpauaaqem6nTXJ0WNj+HRQKOIwPHUYBjD+DYE3iLCmabAccthfLnBdx4Azc+wE004CY62HcMMNscuGkl5CYmcBMLuIkN3MQBbuKCffuC2RbATWub3dhUd2FLfbfSd2tLN7ZRz23VaadOe5vd6AccO4Fjf+A4HnAcALwFgtm2wHEHofzFB24SADcJgZtEwE1isO8kYLYdcNNRyE1S4CYZcJMcuEkB3KQE+04FZtsDN51sdmMb3YUd9N1R350s3dhZPXdRp6s63Wx2Y2rgOA1wnBY4TgccpwfeMoDZLsBxd6H8ZQRuMgE3mYGbLMBNVrDvbGC2K3DTQ8hNduAmB3CTE7jJBdzkBvvOA2a7ATc9bXZjZ92F3fXdQ989Ld3YSz33VqePOn1tdmNe4DgfcJwfOC4AHBcE3gqB2d7AcT+h/BUGbooAN0WBm2LATXGw7xJgtg9w01/ITUngphRwUxq4KQPclAX7Lgdm+wI3A2x2Yy/dhf303V/fAyzdOFA9D1JnsDpDbHZjeeC4AnBcETiuBBxXBt6qgNlBwPFQofxVBW6qATfVgZsawE1NsO9aYHYwcDNMyE1t4KYOcFMXuKkH3NQn/+4LzA4Bbobb7MaBuguH6nuYvodbunGEeh6pzih1RtvsxobAcSPguDFw3AQ4bkr+/QqYHQkcjxHKX3PgpgVw0xK4aQXctAb7bgNmRwE3Y4XctAVu2gE37YGbDsBNR7DvTmB2NHAzzmY3jtBdOEbfY/U9ztKN49XzBHUmqjPJZjd2Bo67AMddgeNuwHF34K0HmJ0AHE8Wyl9P4KYXcNMbuOkD3PQF++4HZicCN1OE3PQHbgYANwOBm0HAzWDyWRDMTgJuptrsxvG6Cyfre4q+p1q6cZp6nq7ODHVm2uzGocDxMOB4OHA8AjgeST5vgNnpwPEsofyNBm7GADdjgZtxwM148i4CszOAm9lCbiYCN5OAm8nAzRTgZirY9zQwOxO4mWOzG6fpLpyl79n6nmPpxrnqeZ4689VZYLMbpwPHM4DjmcDxLOB4NvA2B8zOA44XCuVvLnAzD7iZD9wsAG4Wgn0vArPzgZtFQm4WAzdLgJulwM0y4GY52PcKMLsAuFlssxvn6i5cqO9F+l5s6cYl6nmpOsvUWW6zG1cCx6uA49XA8RrgeC3wtg7MLgWOVwjlbz1wswG42QjcbAJuNoN9bwGzy4CblUJutgI324Cb7cDNDuBmJ9j3LjC7HLhZZbMbl+guXKHvlfpeZenG1ep5jTpr1Vlnsxt3A8d7gOO9wPE+4Hg/8HYAzK4BjtcL5e8gcHMIuDkM3BwBbo6CfR8Ds2uBmw1Cbo4DNyeAm5PAzSng5jTY9xny+QO42WizG1frLlyv7w363mjpxk3qebM6W9TZarMbzwLH54Dj88DxBeD4IvB2CcxuBo63CeXvMnBzBbi5CtxcA26ug33fIJ8xgZvtQm5uAje3gJvbwM0d4OYu2Pc9MLsVuNlhsxs36S7cpu/t+t5h6cad6nmXOrvV2WOzG+8Dxw+A44fA8SPg+DHw9oT8HAEc7xXK31Pg5hlw8xy4eQHcvAT7fgVmdwM3+4TcvAZu3gA3b4Gbd8DNe7DvD2B2D3Cz32Y37tRduFff+/S939KNB9TzQXUOqXPYZjd+BI4/AcefgeMvwPFX4O0bmD0IHB8Ryt934OYHcPMTuHFEMXcTLIr5voOD2UPAzVEhNyGimLsJGcXcTago5m5CAzdhwL7DgtnDwM0xm914QHfhEX0f1fcxSzceV88n1Dmpzimb3RgOOA4PHEcAjiMCx5GAt8hg9gRwfFoof1GAGw/gxhO4iQrceIF9e4PZk8DNGSE3PsBNNOAmOnATA7iJCfYdC8yeAm7O2uzG47oLT+v7jL7PWrrxnHo+r84FdS7a7MbYwHEc4DgucOwLHPsBb04wex44viSUP3/gJh5wEwDcBAI38cG+E4DZC8DNZSE3CYGbRMBNYuAmCXCTFOw7GZi9CNxcsdmN53QXXtL3ZX1fsXTjVfV8TZ3r6tyw2Y3JgeMUwHFK4DgVcJwaeEsDZq8BxzeF8pcWuEkH3KQHbjIANxnBvjOB2evAzS0hN5mBmyzATVbgJhtwkx3sOweYvQHc3LbZjVd1F97U9y1937Z04x31fFede+rct9mNOYHjXMBxbuA4D3CcF3jLB2bvAscPhPKXH7gpANwUBG4KATeFwb6LgNl7wM1DITdFgZtiwE1x4KYEcFMS7LsUmL0P3Dyy2Y13dBc+0PdDfT+ydONj9fxEnafqPLPZjaWB4zLAcVnguBxwXB54qwBmnwDHz4XyVxG4qQTcVAZuqgA3VcG+q4HZp8DNCyE31YGbGsBNTeCmFnBTG+y7Dph9Bty8tNmNj3UXPtf3C32/tHTjK/X8Wp036ry12Y11geN6wHF94LgBcNwQeGsEZl8Dx++E8tcYuGkC3DQFbpoBN83BvluA2TfAzXshNy2Bm1bATWvgpg1w0xbsux2YfQvcfLDZja90F77T93t9f7B040f1/Emdz+p8sdmN7YHjDsBxR+C4E3DcGXjrAmY/AcdfhfLXFbjpBtx0B256ADc9wb57gdnPwM03ITe9gZs+wE1f4KYfcNMf7HsAmP0C3Hy32Y0fdRd+1fc3fX+3dOMP9fzzVyeOUP+7EX+FpY4HAseDgOPBwPEQ4Hgo8DYMzP4EjoOPkMnfcOBmBHAzErgZBdyMBvseA2YdI8zdhBByMxa4GQfcjAduJgA3E8G+J4HZYMBNSODmn7rxh+7CX/n7dYfQ96+v+8dcKPUcWp0w6oS12Y2TgeMpwPFU4HgacDwdeJsBZkMDx+GE8jcTuJkF3MwGbuYAN3PBvueB2TDATXghN/OBmwXAzULgZhFwsxjsewmYDQvcRLDZjaF0F4bTd3h9R7B0Y0T1HEmdyOpEsdmNS4HjZcDxcuB4BXC8EnhbBWYjAcceQvlbDdysAW7WAjfrgJv1YN8bwGxk4MZTyM1G4GYTcLMZuNkC3GwF+94GZqMAN1FtdmNE3YUe+vbUd1RLN3qpZ291fNSJZrMbtwPHO4DjncDxLuB4N/C2B8x6A8fRhfK3F7jZB9zsB24OADcHwb4PgVkf4CaGkJvDwM0R4OYocHMMuDkO9n0CzEYDbmLa7EYv3YXR9R1D3zEt3RhLPcdWJ446cW1240ng+BRwfBo4PgMcnwXezoHZ2MCxr1D+zgM3F4Cbi8DNJeDmMtj3FTAbB7jxE3JzFbi5BtxcB25uADc3wb5vgdm4wI3TZjfG0l3oq28/fTst3eivnuOpE6BOoM1uvA0c3wGO7wLH94Dj+8DbAzAbDziOL5S/h8DNI+DmMXDzBLh5Cvb9DMwGADcJhNw8B25eADcvgZtXwM1rsO83YDYQuElosxv9dRfG13cCfSe0dGMi9ZxYnSTqJLXZjW+B43fA8Xvg+ANw/BF4+wRmEwPHyYTy9xm4+QLcfAVuvgE338G+f4DZJMBNchfd/JEt51//aMe//foJ3Pz605wOo1/BkoJ/1hQ2uyaR7pZk+k6u7xSWrkmpnlOpk1qdNH/rmuj6djosX/S//uGi/mUPHv81G/yvs//5pUNE/ft+//1Lh/x/s//+pUNF/Qdv//KlQ//T7L986TBR//n74Z++dNh/mf2nLx0u6r9+n/2/Lx0+qnlfRIj6X9+/f/3SEf9z9q9fOlLUIHJh+dKRg5q1fOkoQc7+70t7GMz+8aU9TWb1l45qNvvbl/YynP31pb2NZ9XfRYLZVKB30lpmgzk8/vP/t/6ifREN9EV00BcxQF/EBH0RC/RFbNAXcUBfxAV94Qv6wg/0hRP0hT/oi3igLwJAXwSCvogP+iIB6IuEoC8Sgb5IDDogCZhNDfoinVBfJAV9kQz0RXLQFylAX6QEfZEK9EVq0BdpQF+kBX2RDvRFetAXGUBfZAR9kQn0RWbQF1lAX2QFfZEN9EV20Bc5QAfkBLNpQF+kB33xTz/XpNQ/x6TVdzp9p7f8XJNBPWdUJ5M6mW3+XJML9E5u0Dt5QO/kBb2TD/ROftA7BUDvFAS9Uwj0TmHQO0VA7xQFvVMM9E5x0DslQO+UBL1TCvROadA7ZUDvlAVdUg7MZgS9k0Xoc0p50BcVQF9UBH1RCfRFZdAXVUBfVAV9UQ30RXXQFzVAX9QEfVEL9EVt0Bd1QF/UBX1RD/RFfdAXDUBfNAR90Qh0QGMwmwn0RVahvmgC+qIp6ItmoC+ag75oAfqiJeiLVqAvWoO+aAP6oi3oi3agL9qDvugA+qIj6ItOoC86g77oAvqiK+iLbqAvuoMO6AFmM4O+yGbz55oM+ueYLPrOqu9slp9rsqvnHOrkVCeXzZ9reoLe6QV6pzfonT6gd/qC3ukHeqc/6J0BoHcGgt4ZBHpnMOidIaB3hoLeGQZ6ZzjonRGgd0aC3hkFemc06J0xoEvGgtkcoHdyC31OGQf6YjzoiwmgLyaCvpgE+mIy6IspoC+mgr6YBvpiOuiLGaAvZoK+mAX6YjboizmgL+aCvpgH+mI+6IsFoC8Wgg5YRP6uFvRFHqG+WAz6Ygnoi6WgL5aBvlgO+mIF6IuVoC9Wgb5YDfpiDeiLtaAv1oG+WA/6YgPoi42gLzaBvtgM+mIL6IutoC+2gQ7YDmZzgb7Ia/Pnmuz655jc+s6j77yWn2vyqef86hRQp6DNn2t2gN7ZCXpnF+id3aB39oDe2Qt6Zx/onf2gdw6A3jkIeucQ6J3DoHeOgN45CnrnGOid46B3ToDeOQl65xTondOgS86A2fygdwoJfU45C/riHOiL86AvLoC+uAj64hLoi8ugL66AvrgK+uIa6IvroC9ugL64CfriFuiL26Av7oC+uAv64h7oi/ugLx6ADngIZguAvigs1BePQF88Bn3xBPTFU9AXz0BfPAd98QL0xUvQF69AX7wGffEG9MVb0BfvQF+8B33xAfTFR9AXn0BffAZ98QX0xVfQAd/AbEHQF0Vs/lyTT/8cU0jfhfVdxPJzTVH1XEyd4uqUsPlzzXfQOz9A7/wEvePwMu+dYF7mvRPcy7x3QniZ905IL/PeCeVl3juhvcx7J4yXee+E9TLvnXBe5r0TPqhZy5eOEOTs/750RIPZP750JJNZ/aUjm83+9qWjGM7++tIexrOOYJ5gthjonZJCn1Oiepn3hZeXeV94e5n3hQ/oi2igL6KDvogB+iIm6ItYoC9ig76IA/oiLugLX9AXfqAvnKAv/EFfxAN9EQD6IhD0RXzQAQnAbHHQF6WE+iIh6ItEoC8Sg75IAvoiKeiLZKAvkoO+SAH6IiXoi1SgL1KDvkgD+iIt6It0oC/Sg77IAPoiI+iLTKAvMoO+yAI6ICuYLQH6orTNn2uK6p9jSuq7lL5LW36uKaOey6pTTp3yNn+uyQZ6JzvonRygd3KC3skFeic36J08oHfygt7JB3onP+idAqB3CoLeKQR6pzDonSKgd4qC3ikGeqc46J0SoHdKgi4pBWbLgt6pIPQ5pTToizKgL8qCvigH+qI86IsKoC8qgr6oBPqiMuiLKqAvqoK+qAb6ojroixqgL2qCvqgF+qI26Is6oC/qgr6oBzqgPpgtB/qiolBfNAB90RD0RSPQF41BXzQBfdEU9EUz0BfNQV+0AH3REvRFK9AXrUFftAF90Rb0RTvQF+1BX3QAfdER9EUn0BedQQd0AbPlQV9UsvlzTRn9c0wFfVfUdyXLzzWV1XMVdaqqU83mzzVdQe90A73THfROD9A7PUHv9AK90xv0Th/QO31B7/QDvdMf9M4A0DsDQe8MAr0zGPTOENA7Q0HvDAO9Mxz0zgjQJSPBbBXQO9WFPqeMAn0xGvTFGNAXY0FfjAN9MR70xQTQFxNBX0wCfTEZ9MUU0BdTQV9MA30xHfTFDNAXM0FfzAJ9MRv0xRzQF3NBB8wDs1VBX9QQ6ov5oC8WgL5YCPpiEeiLxaAvloC+WAr6Yhnoi+WgL1aAvlgJ+mIV6IvVoC/WgL5YC/piHeiL9aAvNoC+2Aj6YhPogM1gthroi5o2f66prH+Oqa7vGvquafm5ppZ6rq1OHXXq2vy5Zgvona2gd7aB3tkOemcH6J2doHd2gd7ZDXpnD+idvaB39oHe2Q965wDonYOgdw6B3jkMeucI6J2joHeOgd45DrrkBJitDXqnntDnlJOgL06BvjgN+uIM6IuzoC/Ogb44D/riAuiLi6AvLoG+uAz64groi6ugL66BvrgO+uIG6IuboC9ugb64DfriDuiAu2C2DuiL+kJ9cQ/0xX3QFw9AXzwEffEI9MVj0BdPQF88BX3xDPTFc9AXL0BfvAR98Qr0xWvQF29AX7wFffEO9MV70BcfQF98BB3wCczWBX3RwObPNbX0zzH19F1f3w0sP9c0VM+N1GmsTpO//VwTXt9Oh+WL/sevz6B3voDe+Qp65xvone+gd36A3vkJesfhbf690wh87zQVetcE8zZ3Htzb3HkIb3PnIb3NnYfyNnce2tvceRhvc+dhvc3fNeG8zd814b3N3zURvM3fNRG9zd81kYL6frZ86chBfu//70tHMcjJH1/awyRT+kt7muXvty8d1TCrv760l3GuPRzeoAN8wGxj0BfNpP6bRaAvooO+iAH6Iiboi1igL2KDvogD+iIu6Atf0Bd+oC+coC/8QV/EA30RAPoiEPRFfNAXCUBfJAR9kQj0RWLQAUnAbBPQF81tfjZtqD+LNtV3M303t3w2baGeW6rTSp3WNv/OPSnonWSgd5KD3kkBeicl6J1UoHdSg95JA3onLeiddKB30oPeyQB6JyPonUygdzKD3skCeicr6J1soHeyg97JAbokJ5htCXqnjdDnlFygL3KDvsgD+iIv6It8oC/yg74oAPqiIOiLQqAvCoO+KAL6oijoi2KgL4qDvigB+qIk6ItSoC9Kg74oA/qiLOiAcmC2FeiLtlL/zSLQFxVAX1QEfVEJ9EVl0BdVQF9UBX1RDfRFddAXNUBf1AR9UQv0RW3QF3VAX9QFfVEP9EV90BcNQF80BH3RiPzdBphtDfqinc2fa1ron2Pa6LutvttZfq5pr547qNNRnU42f65pAnqnKeidZqB3moPeaQF6pyXonVagd1qD3mkDeqct6J12oHfag97pAHqnI+idTqB3OoPe6QJ6pyvonW6gd7qDLukBZjuA3uks9DmlJ+iLXqAveoO+6AP6oi/oi36gL/qDvhgA+mIg6ItBoC8Gg74YAvpiKOiLYaAvhoO+GAH6YiToi1GgL0aDvhgDOmAsmO0I+qKL1H+zCPTFeNAXE0BfTAR9MQn0xWTQF1NAX0wFfTEN9MV00BczQF/MBH0xC/TFbNAXc0BfzAV9MQ/0xXzQFwtAXywEHbAIzHYCfdHV5s817fXPMZ313UXfXS0/13RTz93V6aFOT5s/1ywGvbME9M5S0DvLQO8sB72zAvTOStA7q0DvrAa9swb0zlrQO+tA76wHvbMB9M5G0DubQO9sBr2zBfTOVtA720CXbAez3UHv9BL6nLID9MVO0Be7QF/sBn2xB/TFXtAX+0Bf7Ad9cQD0xUHQF4dAXxwGfXEE9MVR0BfHQF8cB31xAvTFSdAXp0BfnAYdcIb8nQnoi95S/80i0BfnQF+cB31xAfTFRdAXl0BfXAZ9cQX0xVXQF9dAX1wHfXED9MVN0Be3QF/cBn1xB/TFXdAX90Bf3Ad98QB0wEMw2xP0RR+bP9d00z/H9NJ3b333sfxc01c991OnvzoDbP5c8wj0zmPQO09A7zwFvfMM9M5z0DsvQO+8BL3zCvTOa9A7b0DvvAW98w70znvQOx9A73wEvfMJ9M5n0DtfQO98BV3yDcz2A70zUOhzynfQFz9AX/wEfeHwMe+LYD7mfRHcx7wvQviY90VIH/O+COVj3hehfcz7IoyPeV+E9THvi3A+5n0RPqhZy5eOEOTs/750RIPZP750JJNZ/aUjm83+9qWjGM7++tIexrOOYJ5gtj/oi0FS/80iH/O+8PIx7wtvH/O+8AF9EQ30RXTQFzFAX8QEfREL9EVs0BdxQF/EBX3hC/rCD/SFE/SFP+iLeKAvAkBfBIK+iA86IAGYHQD6YrDNn2v66p9jBup7kL4HW36uGaKeh6ozTJ3hNn+uSQh6JxHoncSgd5KA3kkKeicZ6J3koHdSgN5JCXonFeid1KB30oDeSQt6Jx3onfSgdzKA3skIeicT6J3MoHeygC7JCmaHgt4ZIfQ5JRvoi+ygL3KAvsgJ+iIX6IvcoC/ygL7IC/oiH+iL/KAvCoC+KAj6ohDoi8KgL4qAvigK+qIY6IvioC9KgL4oCTqgFJgdBvpipNR/swj0RRnQF2VBX5QDfVEe9EUF0BcVQV9UAn1RGfRFFdAXVUFfVAN9UR30RQ3QFzVBX9QCfVEb9EUd0Bd1QV/UAx1QH8wOB30xyubPNUP0zzEj9D1S36MsP9eMVs9j1BmrzjibP9c0AL3TEPROI9A7jUHvNAG90xT0TjPQO81B77QAvdMS9E4r0DutQe+0Ab3TFvROO9A77UHvdAC90xH0TifQO51Bl3QBs2NA74wX+pzSFfRFN9AX3UFf9AB90RP0RS/QF71BX/QBfdEX9EU/0Bf9QV8MAH0xEPTFINAXg0FfDAF9MRT0xTDQF8NBX4wAHTASzI4FfTFB6r9ZBPpiNOiLMaAvxoK+GAf6YjzoiwmgLyaCvpgE+mIy6IspoC+mgr6YBvpiOuiLGaAvZoK+mAX6YjboizmgL+aCDpgHZseBvpho8+ea0frnmPH6nqDviZafayap58nqTFFnqs2fa+aD3lkAemch6J1FoHcWg95ZAnpnKeidZaB3loPeWQF6ZyXonVWgd1aD3lkDemct6J11oHfWg97ZAHpnI+idTaBLNoPZyaB3pgl9TtkC+mIr6IttoC+2g77YAfpiJ+iLXaAvdoO+2AP6Yi/oi32gL/aDvjgA+uIg6ItDoC8Og744AvriKOiLY6AvjoMOOAFmp4C+mC713ywCfXEK9MVp0BdnQF+cBX1xDvTFedAXF0BfXAR9cQn0xWXQF1dAX1wFfXEN9MV10Bc3QF/cBH1xC/TFbdAXd0AH3AWzU0FfzLD5c80k/XPMNH1P1/cMy881M9XzLHVmqzPH5s8190Dv3Ae98wD0zkPQO49A7zwGvfME9M5T0DvPQO88B73zAvTOS9A7r0DvvAa98wb0zlvQO+9A77wHvfMB9M5H0CWfwOws0DtzXfycgv+bRaAvvoC++Ar64hvoi++gL36AvvgJ+sIRzdz5bOB8novO/fXt/PNPdfw3lIeV/7+Hg/9l9r+HQ3iYf3+E/Nvsfw2H+vvsfwyH9jD/Xgrz/2f/dTjsP8z+23A4D/Pvu/D/OPvPwxH+efYfhyN6mL/TIv3b7D8MR/7X2f8/HMXD/P3n8R+zfx/2/K/Zvw1H9TB/V3r99+xfhr2DmLUO+wQ1axmOFuTs/4ajBz3753AMg9k/hmOazOrhWEazvw/HNpv9bTiO4eyv4bims2rY13jWEcwPzM4BPT/fMqu+8f/z1z/9TDFT/wwxV9/z9D3f8jPFAvW8UJ1F6iz+288U9H3hBO8Lf/C+iAfeFwHgfREI3hfxwfsiAXhfJATvi0TgfZEYvC+SgPdFUvC+SAbeF8nB+yIFeF+kBO+LVOB9kRq8L9KA90Va8L5IB94X6cH7IgN4X2QE74tM4H2RGbwvsoD3RVbwvsgG3hfZwTsgB5hdCN4XS8D7wvqH0J7PCXo+F+j53KDn84Cezwt6Ph/o+fyg5wuAni8Ier4Q6PnCoOeLgJ4vCnq+GOj54qDnS4CeLwl6vhTo+dKg58uAni8Ler4c6PnyoOcrgJ6vCHq+Euj5yqDnq4Cerwp6vhro7upgdhHo+aVCPV8D9HxN0PO1QM/XBj1fB/R8XdDz9UDP1wc93wD0fEPQ841AzzcGPd8E9HxT0PPNQM83Bz3fAvR8S9DzrUDPtwY93wb0fFvQ8+1Az7cHPd8B9HxH0POdQM93Bj3fBfR8V9Dd3cDsYtDzy2z+/c8C/fc9S/S9VN/LLH//s1w9r1BnpTqrbP79T3fwvugB3hc9wfuiF3hf9Abviz7gfdEXvC/6gfdFf/C+GADeFwPB+2IQeF8MBu+LIeB9MRS8L4aB98Vw8L4YAd4XI8H7YhR4X4wG74sx4H0xFrwvxoH3xXjwvpgA3hcTwftiEnhfTAbviyngHTAVzK4A74vVQj8XTAM9Px30/AzQ8zNBz88CPT8b9Pwc0PNzQc/PAz0/H/T8AtDzC0HPLwI9vxj0/BLQ80tBzy8DPb8c9PwK0PMrQc+vAj2/GvT8GtDza0HPrwM9vx70/AbQ8xtBz28CPb8ZdPcWMLsS9PwaoZ7fCnp+G+j57aDnd4Ce3wl6fhfo+d2g5/eAnt8Len4f6Pn9oOcPgJ4/CHr+EOj5w6Dnj4CePwp6/hjo+eOg50+Anj8Jev4U6PnToOfPgJ4/C3r+HOj586DnL4Cevwh6/hLo7stgdhXo+bU2//5nuf77ntX6XqPvtZa//1mnnters0GdjTb//ucKeF9cBe+La+B9cR28L26A98VN8L64Bd4Xt8H74g54X9wF74t74H1xH7wvHoD3xUPwvngE3hePwfviCXhfPAXvi2fgffEcvC9egPfFS/C+eAXeF6/B++INeF+8Be+Ld+B98R68Lz6A98VH8A74BGbXg/fFJqGfCz6Dnv8Cev4r6PlvoOe/g57/AXr+J+h5h6d5zwfzNO/54J7mPR/C07znQ3qa93woT/OeD+1p3vNhPM17Pqynec+H8zTv+fCe5j0fwdO85yN6mvd8pKBmLcORg5z933CUoGf/HPYwmP1j2NNkVg9HNZr9fdjLbPa3YW/D2V/DPqazajia8awjWHQwuwH0/Gahno/had7zMT3Nez6Wp3nPx/Y07/k4nuY9H9fTvOd9Pc173g/0vBP0vD/o+Xig5wNAzweCno8Pej4B6PmEoOcTgZ5PDHo+Cej5pKDnk4GeTw56PgXo+ZSg51OBnk8Nej4N6Pm0oOfTgZ5PD7o7A5jdCHp+i82//1mn/75nk74363uL5e9/tqrnbepsV2eHzb//yQjeF5nA+yIzeF9kAe+LrOB9kQ28L7KD90UO8L7ICd4XucD7Ijd4X+QB74u84H2RD7wv8oP3RQHwvigI3heFwPuiMHhfFAHvi6LgfVEMvC+Kg/dFCfC+KAneF6XA+6I0eF+UAe+LsuB9UQ68A8qD2W3gfbFT6OeCCqDnK4KerwR6vjLo+Sqg56uCnq8Ger466PkaoOdrgp6vBXq+Nuj5OqDn64Kerwd6vj7o+Qag5xuCnm8Eer4x6PkmoOebgp5vBnq+Oej5FqDnW4KebwV6vjXo+Tag59uC7m4HZreDnt8l1PPtQc93AD3fEfR8J9DznUHPdwE93xX0fDfQ891Bz/cAPd8T9Hwv0PO9Qc/3AT3fF/R8P9Dz/UHPDwA9PxD0/CDQ84NBzw8BPT8U9Pww0PPDQc+PAD0/EvT8KNDzo0HPjwHdPRbM7gA9v9vm3/9s1X/fs1Pfu/S92/L3P3vU81519qmz3+bf/4wD74vx4H0xAbwvJoL3xSTwvpgM3hdTwPtiKnhfTAPvi+ngfTEDvC9mgvfFLPC+mA3eF3PA+2IueF/MA++L+eB9sQC8LxaC98Ui8L5YDN4XS8D7Yil4XywD74vl4H2xArwvVoL3xSrwvlgN3gFrwOxe8L44IPRzwVrQ8+tAz68HPb8B9PxG0PObQM9vBj2/BfT8VtDz20DPbwc9vwP0/E7Q87tAz+8GPb8H9Pxe0PP7QM/vBz1/APT8QdDzh0DPHwY9fwT0/FHQ88dAzx8HPX8C9PxJ0POnQHefBrP7QM8fFOr5M6Dnz4KePwd6/jzo+Qug5y+Cnr8Eev4y6PkroOevgp6/Bnr+Ouj5G6Dnb4KevwV6/jbo+Tug5++Cnr8Hev4+6PkHoOcfgp5/BHr+Mej5J6Dnn4KefwZ6/jno+Reg51+C7n4FZveDnj9k8+9/9ui/7zmg74P6PmT5+5/D6vmIOkfVOfa3v/+Jqm+nw/JF/+PXa/C+eAPeF2/B++IdeF+8B++LD+B98RG8Lz6B98Vn8L74At4XX8H74ht4X3wH74sf4H3xE7wvfn0T/9vs33/rEZDN4y5+BqP/naZgvn/h9/iv2eC+5jkJ4fv3vfz7lw7pa/69H8r3H/b9L186tK/593MY33/2+E9fOqyv+fdoON9//f74f186vK/5910E3//6vvvrl47oa/7ZI5JvEN/Pli8dOahZy5eOEuTs/760h8HsH1/a02RWf+moZrO/fWkvw9lfX9rb17wDfMDsUdAXJ4T+e5LRQF9EB30RA/RFTNAXsUBfxAZ9EQf0RVzQF76gL/xAXzhBX/iDvogH+iIA9EUg6Iv4oC8SgL5ICPoiEeiLxKADkoDZY6AvTtr870ke1p/1j+v7hL5PWj77n1LPp9U5o85Zm/89yaSgd5KB3kkOeicF6J2UoHdSgd5JDXonDeidtKB30oHeSQ96JwPonYygdzKB3skMeicL6J2soHeygd7JDnonB+iSnGD2NOidc0KfU3KBvsgN+iIP6Iu8oC/ygb7ID/qiAOiLgqAvCoG+KAz6ogjoi6KgL4qBvigO+qIE6IuSoC9Kgb4oDfqiDOiLsqADyoHZM6Avzgv1RXnQFxVAX1QEfVEJ9EVl0BdVQF9UBX1RDfRFddAXNUBf1AR9UQv0RW3QF3VAX9QFfVEP9EV90BcNQF80BH3RCHRAYzB7FvTFBZs/15zSP8ec0/d5fV+w/FxzUT1fUueyOlds/lzTBPROU9A7zUDvNAe90wL0TkvQO61A77QGvdMG9E5b0DvtQO+0B73TAfROR9A7nUDvdAa90wX0TlfQO91A73QHXdIDzF4CvXNV6HNKT9AXvUBf9AZ90Qf0RV/QF/1AX/QHfTEA9MVA0BeDQF8MBn0xBPTFUNAXw0BfDAd9MQL0xUjQF6NAX4wGfTEGdMBYMHsZ9MU1ob4YB/piPOiLCaAvJoK+mAT6YjLoiymgL6aCvpgG+mI66IsZoC9mgr6YBfpiNuiLOaAv5oK+mAf6Yj7oiwWgLxaCDlgEZq+Avrhu8+eai/rnmKv6vqbv65afa26o55vq3FLnts2faxaD3lkCemcp6J1loHeWg95ZAXpnJeidVaB3VoPeWQN6Zy3onXWgd9aD3tkAemcj6J1NoHc2g97ZAnpnK+idbaBLtoPZm6B37gh9TtkB+mIn6ItdoC92g77YA/piL+iLfaAv9oO+OAD64iDoi0OgLw6DvjgC+uIo6ItjoC+Og744AfriJOiLU6AvToMOOANmb4G+uCvUF2dBX5wDfXEe9MUF0BcXQV9cAn1xGfTFFdAXV0FfXAN9cR30xQ3QFzdBX9wCfXEb9MUd0Bd3QV/cA31xH/TFA9ABD8HsbdAX92z+XHND/xxzR9939X3P8nPNffX8QJ2H6jyy+XPNI9A7j0HvPAG98xT0zjPQO89B77wAvfMS9M4r0DuvQe+8Ab3zFvTOO9A770HvfAC98xH0zifQO59B73wBvfMVdMk3MPsA9M5joc8p30Ff/AB98RP0hcPPvC+C+Zn3RXA/874I4WfeFyH9zPsilJ95X4T2M++LMH7mfRHWz7wvwvmZ90X4oGYtXzpCkLP/+9IRDWb/+NKRTGb1l45sNvvbl45iOPvrS3sYzzqCeYLZh6Avngj1RVQ/877w8jPvC28/877wAX0RDfRFdNAXMUBfxAR9EQv0RWzQF3FAX8QFfeEL+sIP9IUT9IU/6It4oC8CQF8Egr6IDzogAZh9BPriqc2fa+7rn2Me6/uJvp9afq55pp6fq/NCnZc2f65JCHonEeidxKB3koDeSQp6JxnoneSgd1KA3kkJeicV6J3UoHfSgN5JC3onHeid9KB3MoDeyQh6JxPoncygd7KALskKZp+D3nkl9DklG+iL7KAvcoC+yAn6Ihfoi9ygL/KAvsgL+iIf6Iv8oC8KgL4oCPqiEOiLwqAvioC+KAr6ohjoi+KgL0qAvigJOqAUmH0B+uK1UF+UBn1RBvRFWdAX5UBflAd9UQH0RUXQF5VAX1QGfVEF9EVV0BfVQF9UB31RA/RFTdAXtUBf1AZ9UQf0RV3QF/VAB9QHsy9BX7yx+XPNM/1zzCt9v9b3G8vPNW/V8zt13qvzwebPNQ1A7zQEvdMI9E5j0DtNQO80Bb3TDPROc9A7LUDvtAS90wr0TmvQO21A77QFvdMO9E570DsdQO90BL3TCfROZ9AlXcDsO9A7H4U+p3QFfdEN9EV30Bc9QF/0BH3RC/RFb9AXfUBf9AV90Q/0RX/QFwNAXwwEfTEI9MVg0BdDQF8MBX0xDPTFcNAXI0AHjASz70FffBLqi1GgL0aDvhgD+mIs6ItxoC/Gg76YAPpiIuiLSaAvJoO+mAL6Yiroi2mgL6aDvpgB+mIm6ItZoC9mg76YA/piLuiAeWD2A+iLzzZ/rnmrf475qO9P+v5s+bnmi3r+qs43db7b/LlmPuidBaB3FoLeWQR6ZzHonSWgd5aC3lkGemc56J0VoHdWgt5ZBXpnNeidNaB31oLeWQd6Zz3onQ2gdzaC3tkEumQzmP0KeueH0OeULaAvtoK+2Ab6Yjvoix2gL3aCvtgF+mI36Is9oC/2gr7YB/piP+iLA6AvDoK+OAT64jDoiyOgL46CvjgG+uI46IATYPYb6IufQn1xEvTFKdAXp0FfnAF9cRb0xTnQF+dBX1wAfXER9MUl0BeXQV9cAX1xFfTFNdAX10Ff3AB9cRP0xS3QF7dBX9wBHXAXzH4HfeEYae/nmi/655gf+v6p719f98859RxcnRC//mcj/wpLe+ce6J37oHcegN55CHrnEeidx6B3noDeeQp65xnoneegd16A3nkJeucV6J3XoHfegN55C3rnHeid96B3PoDe+Qi65BOYDT7SvHdCgd6x/gqvb+eff6rjP399Bn3xBfTFV9AX30BffAd98QP0xU/QF78G/2n2H34FCwGch3bRuef/sP78cx3/BeX8G/9/TAd3mrsJ4fyHvfzLdEjnP+7wH6dDOc37ObTzX938v+kwzv/w+LfpsE7zzg3nDOL7wzIdPqhZy3SEoGf/nI5oMqunI5nN/jYd2XRWTUcBsyFBTsKMtH5dj//8//7pM9mvz1u/7lD6Dq3vMJbPZGHVczh1wqsT4W+fyWjePJzmefN0muctqtM8b15O87x5O83z5uM0z1s0p3neojvN8xbDaZ63mEHNWqZjBT3753Rsk1k9Hcds9rfpuKazatoXzIYDeYsI8mb9RXPi5zTPidNpnhN/p3lO4jnNcxLgNM9JoNM8J/Gd5jlJ4DTPSUKneU4SBTVrmU4c9Oyf00lMZvV0UrPZ36aTmc6q6eRgNjzISSShnKRwmuckpdM8J6mc5jlJ7TTPSRqneU7SOs1zks5pnpP0TvOcZHCa5yRjULOW6UxBz/45ndlkVk9nMZv9bTqr6ayazgZmI4CcRLb5+S2s/rwWUd+R9B3Z8vktinr2UMdTnag2P79ld5rnLYfTPG85neZ5y+U0z1tup3ne8jjN85bXaZ63fE7zvOV3muetQFCzlumCQc/+OV3IZFZPFzab/W26iOmsmi4KZj1A3ryE3kvFnOY5Ke40z0kJp3lOSjrNc1LKaZ6T0k7znJRxmuekrNM8J+Wc5jkpH9SsZbpC0LN/Tlc0mdXTlcxmf5uubDqrpquAWU+QE2+hnFR1muekmtM8J9Wd5jmp4TTPSU2neU5qOc1zUttpnpM6TvOc1HWa56ReULOW6fpBz/453cBkVk83NJv9bbqR6ayabgxmo4Kc+Nj8/BZFf17z0re3vn0sn9+iqefo6sRQJ6bNz29NnOZ5a+o0z1szp3nemjvN89bCaZ63lk7zvLVymuettdM8b22c5nlrG9SsZbpd0LN/Trc3mdXTHcxmf5vuaDqrpjuB2eggb7GE3kudneY56eI0z0lXp3lOujnNc9LdaZ6THk7znPR0muekl9M8J72d5jnpE9SsZbpv0LN/TvczmdXT/c1mf5seYDqrpgeC2RggJ7GFcjLIaZ6TwU7znAxxmudkqNM8J8Oc5jkZ7jTPyQineU5GOs1zMsppnpPRQc1apscEPfvn9FiTWT09zmz2t+nxprNqegKYjQlyEsfm57do+vNaLH3H1nccy+e3uOrZVx2/X3+Wzc9vE53meZvkNM/bZKd53qY4zfM21Wmet2lO87xNd5rnbYbTPG8zneZ5mxXUrGV6dtCzf07PMZnV03PNZn+bnmc6q6bng1lfkDd/offSAqd5ThY6zXOyyGmek8VO85wscZrnZKnTPCfLnOY5We40z8kKp3lOVgY1a5leFfTsn9OrTWb19Bqz2d+m15rOqul1YNYP5CSeUE7WO81zssFpnpONTvOcbHKa52Sz0zwnW5zmOdnqNM/JNqd5TrY7zXOyI6hZy/TOoGf/nN5lMqund5vN/ja9x3RWTe8Fs06QkwCbn9/i6s9r/vqOp+8Ay+e3QPUcX50E6iS0+fltn9M8b/ud5nk74DTP20Gned4OOc3zdthpnrcjTvO8HXWa5+2Y0zxvx4OatUyfCHr2z+mTJrN6+pTZ7G/Tp01n1fQZMBsf5C2R0HvprNM8J+ec5jk57zTPyQWneU4uOs1zcslpnpPLTvOcXHGa5+Sq0zwn14KatUxfD3r2z+kbJrN6+qbZ7G/Tt0xn1fRtMJsA5CSxUE7uOM1zctdpnpN7TvOc3Hea5+SB0zwnD53mOXnkNM/JY6d5Tp44zXPyNKhZy/SzoGf/nH5uMqunX5jN/jb90nRWTb8CswlBTpLY/PwWqD+vJdJ3Yn0nsXx+S6qek6mTXJ0UNj+/vXaa5+2N0zxvb53meXvnNM/be6d53j44zfP20Wmet09O87x9dprn7UtQs5bpr0HP/jn9zWRWT383m/1t+ofprJr+CWaTgbylFHovOfzNcxLM3zwnwf3NcxLC3zwnIf3NcxLK3zwnof3NcxLG3zwnYf3NcxIuqFnLdPigZ/+cjmAyq6cjms3+Nh3JdFZNRwazyUFOUgnlJArIiQfIiSfISVSQEy+QE2+QEx+Qk2ggJ9FBTmKAnMQEOYkFchIb5CQO+N6PC2ZTgJyktvn5Lan+vJZS36n0ndry+S2Nek6rTjp10tv8/OYL8uYH8uYEefMHeYsH8hYA8hYI8hYf5C0ByFtCkLdEIG+JQd6SmOZCTSc1nf31mQzMpgV5yyD0XkoOcpIC5CQlyEkqkJPUICdpQE7SgpykAzlJD3KSAeQkI8hJJpCTzCAnWcD3flYwmw7kJKNQTrKBnGQHOckBcpIT5CQXyElukJM8ICd5QU7ygZzkBzkpAHJSEOSkEMhJYfC9XwTMpgc5yWTz81sa/Xktg74z6juT5fNbZvWcRZ2s6mSz+fmtKMhbMZC34iBvJUDeSoK8lQJ5Kw3yVgbkrSzIWzmQt/IgbxVA3iqa5kJNVzKdVdOVwWwWkLfsQu+lKiAnVUFOqoGcVAc5qQFyUhPkpBbISW2QkzogJ3VBTuqBnNQHOWkActIQfO83ArNZQU5yCOWkMchJE5CTpiAnzUBOmoOctAA5aQly0grkpDXISRuQk7YgJ+1ATtqDnHQA3/sdwWw2kJOcNj+/Zdaf17LrO4e+c1o+v+VSz7nVyaNOXpuf3zqBvHUGeesC8tYV5K0byFt3kLceIG89Qd56gbz1BnnrA/LWF+Stn2ku1HR/01k1PQDM5gZ5yyf0XhoIcjII5GQwyMkQkJOhICfDQE6Gg5yMADkZCXIyCuRkNMjJGJCTsSAn48D3/ngwmwfkJL9QTiaAnEwEOZkEcjIZ5GQKyMlUkJNpICfTQU5mgJzMBDmZBXIyG+RkDsjJXPC9Pw/M5gU5KWDz81su/Xktn77z67uA5fNbQfVcSJ3C6hSx+fltPsjbApC3hSBvi0DeFoO8LQF5WwrytgzkbTnI2wqQt5Ugb6tA3lab5kJNrzGdVdNrwWwhkLeiQu+ldSAn60FONoCcbAQ52QRyshnkZAvIyVaQk20gJ9tBTnaAnOwEOdkFcrIbfO/vAbOFQU6KCeVkL8jJPpCT/SAnB0BODoKcHAI5OQxycgTk5CjIyTGQk+MgJydATk6CnJwC3/unwWwRkJPiNj+/FdSf14rqu5i+i1s+v5VQzyXVKaVOaZuf386AvJ0FeTsH8nYe5O0CyNtFkLdLIG+XQd6ugLxdBXm7BvJ2HeTthmku1PRN01k1fQvMlgR5KyP0XroNcnIH5OQuyMk9kJP7ICcPQE4egpw8Ajl5DHLyBOTkKcjJM5CT5yAnL8D3/kswWwrkpKxQTl6BnLwGOXkDcvIW5OQdyMl7kJMPICcfQU4+gZx8Bjn5AnLyFeTkG8jJd/C9/wPMlgY5KWfz81sJ/XmtjL7L6ruc5fNbefVcQZ2K6lSy+fntJ8ibI5553oLFM89b8HjmeQsRzzxvIeOZ5y1UPPO8hY5nnrcw8czzFjaoWct0uKBn/5wObzKrpyOYzf42HdF0Vk1HArMVQN4qC72XIsczz0kUkBMPkBNPkJOoICdeICfeICc+ICfRQE6ig5zEADmJCXISC+QkNvjejwNmK4KcVBHKSVyQE1+QEz+QEyfIiT/ISTyQkwCQk0CQk/ggJwlAThKCnCQCOUkMcpIEfO8nBbOVQE6q2vz8Vl5/Xqus7yr6rmr5/FZNPVdXp4Y6NW1+fksG8pYc5C0FyFtKkLdUIG+pQd7SgLylBXlLB/KWHuQtA8hbRpC3TCBvmUGGsoDZ6iBvtYTeS1lBTrKBnGQHOckBcpIT5CQXyElukJM8ICd5QU7ygZzkBzkpAHJSEOSkEPjeLwxma4Cc1BbKSRGQk6IgJ8VAToqDnJQAOSkJclIK5KQ0yEkZkJOyICflQE7Kg5xUADmpSD6TgdmaICd1bH5+q6Y/r9XSd21917F8fqurnuupU1+dBjY/v1UGeasC8lYV5K0ayFt1kLcaIG81Qd5qgbzVBnmrA/JWF+StHshbfZC3BiBDDcFsPZC3hkLvpUYgJ41BTpqAnDQFOWkGctIc5KQFyElLkJNWICetQU7agJy0BTlpB3LSHnzvdwCz9UFOGgnlpCPISSeQk84gJ11ATrqCnHQDOekOctID5KQnyEkvkJPeICd9QE76gpz0A9/7/cFsA5CTxjY/v9XVn9ca6ruRvhtbPr81Uc9N1WmmTnObn98GgLwNBHkbBPI2GORtCMjbUJC3YSBvw0HeRoC8jQR5GwXyNhrkbQzI21iQoXFgtinIWwuh99J4kJMJICcTQU4mgZxMBjmZAnIyFeRkGsjJdJCTGSAnM0FOZoGczAY5mQO+9+eC2WYgJy2FcjIP5GQ+yMkCkJOFICeLQE4Wg5wsATlZCnKyDORkOcjJCpCTlSAnq0BOVoPv/TVgtjnISSubn9+a6M9rLfTdUt+tLJ/fWqvnNuq0Vaedzc9va0He1oG8rQd52wDythHkbRPI22aQty0gb1tB3raBvG0HedsB8rYT5G0XyNBuMNsG5K290HtpD8jJXpCTfSAn+0FODoCcHAQ5OQRychjk5AjIyVGQk2MgJ8dBTk6AnJwE3/unwGxbkJMOQjk5DXJyBuTkLMjJOZCT8yAnF0BOLoKcXAI5uQxycgXk5CrIyTWQk+sgJzfA9/5NMNsO5KSjzc9vrfXntfb67qDvjpbPb53Uc2d1uqjT1ebnt1sgb7dB3u6AvN0FebsH8nYf5O0ByNtDkLdHIG+PQd6egLw9BXl7BvL2HGToBZjtDPLWTei99BLk5BXIyWuQkzcgJ29BTt6BnLwHOfkAcvIR5OQTyMlnkJMvICdfQU6+ge/972C2C8hJd6Gc/AA5+Qly4ggwz0mwAPOcBA8wz0mIAPOchAwwz0moAPOchA4wz0mYoGYt02GDnv1zOpzJrJ4Obzb723QE01k1HRHMdgU56WHz81sn/Xmtm76767uH5fNbT/XcS53e6vSx+fktUoB53iIHmOctCsibB8ibJ8hbVJA3L5A3b5A3H5C3aCBv0UHeYoC8xQR5iwUyFBvM9gJ56yv0XooDchIX5MQX5MQP5MQJcuIPchIP5CQA5CQQ5CQ+yEkCkJOEICeJQE4Sg+/9JGC2N8hJP6GcJAU5SQZykhzkJAXISUqQk1QgJ6lBTtKAnKQFOUkHcpIe5CQDyElGkJNM4Hs/M5jtA3LS3+bnt57681pffffTd3/L57cB6nmgOoPUGWzz81sWkLesIG/ZQN6yg7zlAHnLCfKWC+QtN8hbHpC3vCBv+UDe8oO8FQB5KwgyVAjMDgR5GyL0XioMclIE5KQoyEkxkJPiICclQE5KgpyUAjkpDXJSBuSkLMhJOZCT8iAnFcD3fkUwOwjkZKhQTiqBnFQGOakCclIV5KQayEl1kJMaICc1QU5qgZzUBjmpA3JSF+SkHshJffC93wDMDgY5GWbz89sA/XltiL6H6nuY5fPbcPU8Qp2R6oyy+fmtIchbI5C3xiBvTUDemoK8NQN5aw7y1gLkrSXIWyuQt9Ygb21A3tqCvLUDGWoPZkeAvI0Wei91ADnpCHLSCeSkM8hJF5CTriAn3UBOuoOc9AA56Qly0gvkpDfISR+Qk77ge78fmB0JcjJGKCf9QU4GgJwMBDkZBHIyGORkCMjJUJCTYSAnw0FORoCcjAQ5GQVyMhrkZAz43h8LZkeBnIy1+fltuP68NlrfY/Q91vL5bZx6Hq/OBHUm2vz8Ng7kbTzI2wSQt4kgb5NA3iaDvE0BeZsK8jYN5G06yNsMkLeZIG+zQN5mgwzNAbPjQd4mCb2X5oKczAM5mQ9ysgDkZCHIySKQk8UgJ0tATpaCnCwDOVkOcrIC5GQlyMkq8L2/GsxOADmZLJSTNSAna0FO1oGcrAc52QByshHkZBPIyWaQky0gJ1tBTraBnGwHOdkBcrITfO/vArMTQU6m2Pz8Nk5/Xpuk78n6nmL5/DZVPU9TZ7o6M2x+ftsN8rYH5G0vyNs+kLf9IG8HQN4OgrwdAnk7DPJ2BOTtKMjbMZC34yBvJ0CGToLZaSBvM4XeS6dATk6DnJwBOTkLcnIO5OQ8yMkFkJOLICeXQE4ug5xcATm5CnJyDeTkOvjevwFmp4OczBLKyU2Qk1sgJ7dBTu6AnNwFObkHcnIf5OQByMlDkJNHICePQU6egJw8BTl5Br73n4PZGSAns21+fpuqP6/N1Pcsfc+2fH6bo57nqjNPnfk2P7+9AHl7CfL2CuTtNcjbG5C3tyBv70De3oO8fQB5+wjy9gnk7TPI2xeQt68gQ9/A7FyQtwUuvpdC6dv5l3+if//1HeTkB8jJT7CXeWAvC4Xe145A870ECzTfS/BA8/4IEWjeHyEDzfsjVKB5f4QONO+PMIHm/RE20Lw/wgU1a5kOH/Tsn9MRTGb1dESz2d+mI5nOqunIYHY+yMkim+/rOfr9vEDfC/W9yPK+Xqyel6izVJ1lNt/XUUDePEDePEHeooK8eYG8eYO8+YC8RQN5iw7yFgPkLSbIWyyQt9ggb3FAhuKC2SUgb8uF3ku+ICd+ICdOkBN/kJN4ICcBICeBICfxQU4SgJwkBDlJBHKSGOQkCchJUvC9nwzMLgU5WSGUk+QgJylATlKCnKQCOUkNcpIG5CQtyEk6kJP0ICcZQE4ygpxkAjnJDHKSBXzvZwWzy0BOVtr8/LZYf15bru8V+l5p+fy2Sj2vVmeNOmttfn7LBvKWHeQtB8hbTpC3XCBvuUHe8oC85QV5ywfylh/krQDIW0GQt0Igb4VBhoqA2dUgb+uE3ktFQU6KgZwUBzkpAXJSEuSkFMhJaZCTMiAnZUFOyoGclAc5qQByUhHkpBL43q8MZteAnKwXykkVkJOqICfVQE6qg5zUADmpCXJSC+SkNshJHZCTuiAn9UBO6oOcNAA5aQi+9xuB2bUgJxtsfn5bpT+vrdP3en1vsHx+26ieN6mzWZ0tNj+/NQZ5awLy1hTkrRnIW3OQtxYgby1B3lqBvLUGeWsD8tYW5K0dyFt7kLcOIEMdwewmkLetQu+lTiAnnUFOuoCcdAU56QZy0h3kpAfISU+Qk14gJ71BTvqAnPQFOekHctIffO8PALObQU62CeVkIMjJIJCTwSAnQ0BOhoKcDAM5+T9e/QJqjjM923bbkmUxM7eYmZmZmZmZmZmZmS3JkiwwyBYzMzMzM1rSLuerZL+TP4nrvHvNNXvVX72/9WTGR1991luBcaCT8aCTCaCTiaCTSaCTyaCTKaCTqeC3Pw2c3QQ62Rrg+9tG931ts3vf4t63Bnl/2+Z83u5cO5xrZ4Dvb9NBbzNAbzNBb7NAb7NBb3NAb3NBb/NAb/NBbwtAbwtBb4tAb4tBb0tAQ0vB2e2gt12iv0vLQCc/gk6Wg05WgE5Wgk5+Ap2sAp2sBp2sAZ38DDpZCzpZBzpZDzrZQP5nBeDsDtDJblEnv4JOfgOd/A462Qg6+QN08ifoZBPoZDPoZAvoZCvoZBvoZDvoZAfoZCf47e8CZ3eCTvYE+P62zX1f2+Xed7v3PUHe3/Y6n/c5137nOhDg+9tu0Nse0Nte0Ns+0Nt+0NsB0NtB0Nsh0Nth0NsR0NtR0Nsx0Ntx0NsJ0NBJcHYf6O2g6O/SKdDJadDJGdDJWdDJOdDJedDJBdDJRdDJJdDJZdDJFdDJVdDJNdDJdfDbvwHO7gedHBJ1chN0cgt0cht0cgd0chd0cg90ch908gB08hB08gh08hh08gR08hR08gz89p+DswdAJ4cDfH/b676vHXTvh9z74SDvb0ecz0ed65hzHQ/w/e0F6O0l6O0V6O016O0N6O0t6O0d6O096O0D6O0j6O0T6O0z6O0v0NsX0NBXcPYo6O2E6O/SN9CJL5n3Tr5L5r2TYMm8dxI8mfdOvk/mvZMQybx38kMy752ETOa9k1D/dDbI6dD/fPa/TofxctY9Hdbb2f84Hc7rWed0eHD2GOjkpKiTCMm8dxIRdBIJdBIZdBIFdBIVdBINdBIddBIDdBITdBILdBIbdBIHdBIX/PbjgbPHQSenAnx/O+K+r51w7yfd+6kg72+nnc9nnOusc50L8P0tPugtAegtIejND3pLBHpLDHpLAnpLCnpLBnpLDnpLAXpLCXpLBXpLDRpKA86eAb2dF/1dSgs6SQc6SQ86yQA6yQg6yQQ6yQw6yQI6yQo6yQY6yQ46yQE6yQk6yQV++7nB2bOgkwuiTvKATvKCTvKBTvKDTgqATgqCTgqBTgqDToqAToqCToqBToqDTkqATkqC334pcPYc6ORigO9vp933tfPu/YJ7vxjk/e2S8/myc11xrqsBvr+VBr2VAb2VBb2VA72VB71VAL1VBL1VAr1VBr1VAb1VBb1VA71VB73VAA3VBGcvg96uif4u1QKd1Aad1AGd1AWd1AOd1AedNACdNASdNAKdNAadNAGdNAWdNAOdNAe//Rbg7BXQyXVRJy1BJ61AJ61BJ21AJ21BJ+1AJ+1BJx1AJx1BJ51AJ51BJ11AJ11BJ93Ab787OHsVdHIjwPe3S+772jX3ft293wjy/nbT+XzLuW47150A3996gN56gt56gd56g976gN76gt76gd76g94GgN4Ggt4Ggd4Gg96GgN6GgoaGgbO3QG93RX+XhoNORoBORoJORoFORoNOxoBOxoJOxoFOxoNOJoBOJoJOJoFOJoNOpoDf/lRw9jbo5J6ok2mgk+mgkxmgk5mgk1mgk9mgkzmgk7mgk3mgk/mgkwWgk4Wgk0Wgk8Xgt78EnL0DOrkf4PvbTfd97a57v+fe7wd5f3vgfH7oXI+c63GA729LQW/LQG8/gt6Wg95WgN5Wgt5+Ar2tAr2tBr2tAb39DHpbC3pbB3pbDxraAM4+BL09Ef1d+gV08ivo5DfQye+gk42gkz9AJ3+CTjaBTjaDTraATraCTraBTraDTnaA3/5OcPYR6OSpqJNdoJPdoJM9oJO9oJN9oJP9oJMDoJODoJNDoJPDoJMjoJOjoJNjoJPj4Ld/Apx9DDp5FuD72wP3fe2Je3/q3p8FeX977nx+4VwvnetVgO9vJ0Fvp0Bvp0FvZ0BvZ0Fv50Bv50FvF0BvF0Fvl0Bvl0FvV0BvV0Fv10BD18HZF6C316K/SzdAJzdBJ7dAJ7dBJ3dAJ3dBJ/dAJ/dBJw9AJw9BJ49AJ49BJ09AJ0/Bb/8ZOPsSdPJG1Mlz0MkL0MlL0Mkr0Mlr0Mkb0Mlb0Mk70Ml70MkH0MlH0Mkn0Mln0Mlf4Lf/BZx9BTp5G+D723P3fe21e3/j3t8GeX9753x+71wfnOtjgO9vX0Fv30BvvuTee/suuffegiX33lvw5N57+z65995CJPfe2w/JvfcW8p/OBjkd6p/P/tfp0F7OuqfDeDv7H6fDej3rnA4Hzr4HvX0S/V0Kn9x7JxGSe+8kIugkEugkMugkCugkKugkGugkOugkBugkJugkFugkNugkDvjtxwVnP4BOPos6iQc6iQ86SQA6SQg68YNOEoFOEoNOkoBOkoJOkoFOkoNOUoBOUoJOUoHffmpw9iPo5K8A39/eue9rn9z7Z/f+V5D3ty/O56/O9e3vd7eJ//oPS3tLA3pLC3pLB3pLD3rLAHrLCHrLBHrLDHrLAnrLCnrLBnrLDnrLAXrLCRrKBc5+Bb19N1Hzdyk36CQP6CQv6CQf6CQ/6KQA6KQg6KQQ6KQw6KQI6KQo6KQY6KQ46KQE+O2XBGe/gU6CiTopBTopDTopAzopCzopBzopDzqpADqpCDqpBDqpDDqpAjqpCjqpBjqpDn77NcBZ30TvnQQHnfxP729f3Pe1v/8u/X0P5t7//vf9z3PfO59DONcPzhUywPe3mqC3WqC32qC3OqC3uqC3eqC3+qC3BqC3hqC3RqC3xqC3JqC3pqC3ZqCh5uBsCNBbKNHfpRagk5agk1agk9agkzagk7agk3agk/agkw6gk46gk06gk86gky6gk67gt98NnP0BdBJa1El30EkP0ElP0Ekv0Elv0Ekf0Elf0Ek/0El/0MkA0MlA0Mkg0Mlg0MkQ8NsfCs6GBJ2ECfD97Xv3fS2Uew/t3sMEeX8L63wO51zhnStCgO9vw0Bvw0FvI0BvI0Fvo0Bvo0FvY0BvY0Fv40Bv40FvE0BvE0Fvk0Bvk0FDU8DZcKC3iKK/S1NBJ9NAJ9NBJzNAJzNBJ7NAJ7NBJ3NAJ3NBJ/NAJ/NBJwtAJwtBJ4vAb38xOBsedBJJ1MkS0MlS0Mky0MmPoJPloJMVoJOVoJOfQCerQCerQSdrQCc/g07Wgk7Wgd/+enA2AugkcoDvb2Hd97WI7j2Se48c5P0tivM5qnNFc67oAb6/bQC9/QJ6+xX09hvo7XfQ20bQ2x+gtz9Bb5tAb5tBb1tAb1tBb9tAb9tBQzvA2aigtxiiv0s7QSe7QCe7QSd7QCd7QSf7QCf7QScHQCcHQSeHQCeHQSdHQCdHQSfHwG//ODgbDXQSU9TJCdDJSdDJKdDJadDJGdDJWdDJOdDJedDJBdDJRdDJJdDJZdDJFdDJVfDbvwbORgedxArw/S2K+74Ww73HdO+xgry/xXY+x3GuuM4VL8D3t+ugtxugt5ugt1ugt9ugtzugt7ugt3ugt/ugtwegt4egt0egt8egtyegoafgbBzQW3zR36VnoJPnoJMXoJOXoJNXoJPXoJM3oJO3oJN3oJP3oJMPoJOPoJNPoJPP4Lf/FzgbF3SSQNTJF9DJV9DJN9CJL4X3Tr5L4b2TYCm8dxI8hfdOvk/hvZMQKbx38sM/nQ1yOuQ/n/2v06G8nHVPh/Z29j9Oh/F61jkdFpyNBzpJGOD7W2z3fS2+e0/g3hMGeX/zO58TOVdi50oS4PtbuBTeewufwntvEVJ47y0i6C0S6C0y6C0K6C0q6C0a6C066C0G6C0m6C0W6C02aCgOOJsI9JZU9HcpLugkHugkPugkAegkIejEDzpJBDpJDDpJAjpJCjpJBjpJDjpJATpJCX77qcDZxKCTZKJOUoNO0oBO0oJO0oFO0oNOMoBOMoJOMoFOMoNOsoBOsoJOsoFOsoNOcoDffk5wNgnoJHmA729+930tqXtP5t6TB3l/S+F8TulcqZwrdYDvb7lAb7lBb3lAb3lBb/lAb/lBbwVAbwVBb4VAb4VBb0VAb0VBb8VAb8VBQyXA2ZSgtzSiv0slQSelQCelQSdlQCdlQSflQCflQScVQCcVQSeVQCeVQSdVQCdVQSfVwG+/OnnXA52kFXVSA3RSE3RSC3RSG3RSB3RSF3RSD3RSH3TSAHTSEHTSCHTSGHTSBHTSFPz2m4GzqUEn6QJ8f0vhvq+lce9p3Xu6IO9v6Z3PGZwro3NlCvD9rTnorQXorSXorRXorTXorQ3orS3orR3orT3orQPorSPorRPorTPorQtoqCs4mwH0lln0d6kb6KQ76KQH6KQn6KQX6KQ36KQP6KQv6KQf6KQ/6GQA6GQg6GQQ6GQw+O0PAWczgk6yiDoZCjoZBjoZDjoZAToZCToZBToZDToZAzoZCzoZBzoZDzqZADqZCDqZBH77k8HZTKCTrAG+v6V339cyu/cs7j1rkPe3bM7n7M6Vw7lyBvj+NgX0NhX0Ng30Nh30NgP0NhP0Ngv0Nhv0Ngf0Nhf0Ng/0Nh/0tgD0thA0tAiczQ56yyX6u7QYdLIEdLIUdLIMdPIj6GQ56GQF6GQl6OQn0Mkq0Mlq0Mka0MnPoJO14Le/DpzNATrJLepkPehkA+jkF9DJr6CT30Anv4NONoJO/gCd/Ak62QQ62Qw62QI62Qo62QZ++9vB2ZygkzwBvr9lc9/Xcrn33O49T5D3t7zO53zOld+5CgT4/rYD9LYT9LYL9LYb9LYH9LYX9LYP9LYf9HYA9HYQ9HYI9HYY9HYE9HYUNHQMnM0Heiso+rt0HHRyAnRyEnRyCnRyGnRyBnRyFnRyDnRyHnRyAXRyEXRyCXRyGXRyBfz2r4Kz+UEnhUSdXAOdXAed3ACd3ASd3AKd3Aad3AGd3AWd3AOd3AedPACdPASdPAKdPAa//SfgbAHQSeEA39/yuu9rBd17IfdeOMj7WxHnc1HnKuZcxQN8f3sKensGensOensBensJensFensNensDensLensHensPevsAevsIevsEGvoMzhYFvZUw/l0K4d79/yL63//1F+jkC+jkK/heioHvpaTxewnl3v3/+h/t+9/+9Q2060v5v1v/+3/Bdym9dxMspZfv8P/9FwRP6f37/h6cLQ62KfXftvm//j//09+IIu7fhBLuvaR7LxXkb0Rp53MZ5yrrXOX+298IunGIlN43/gFsHBJsHApsHBrsFgacLQM2Lg82Dvovuk1YsE04sE14sE0EsE1E8H1HAmfLgm0qiLaJDLaJAraJCraJBraJDr7vGOBsObBNxQCfjaXdZ2F5917BvVcM8mys5Hyu7FxVnKtqgM/GmGDjWGDj2GDjOGDjuGC3eOBsZbBxNVF/8cE2CcA2CcE2frBNIvB9JwZnq4Btqou2SQK2SQq2SQa2SQ62SQG+75TgbFWwTY0An42V3GdhNfde3b3XCPJsrOl8ruVctZ2rToDPxlRg49Rg4zRg47Rg43Rgt/TgbC2wcV1RfxnANhnBNpnANpnBNlnA950VnK0Ntqkn2iYb2CY72CYH2CYn2CYX+L5zg7N1wDb1A3w21nSfhXXdez33Xj/Is7GB87mhczVyrsYBPhvzgI3zgo3zgY3zg40LgN0KgrMNwcZNRP0VAtsUBtsUAdsUBdsUI/9zKnC2EdimqWibEmCbkmCbUmCb0mCbMuR/hgHONgbbNAvw2djAfRY2ce9N3XuzIM/G5s7nFs7V0rlaBfhsLAc2Lg82rgA2rgg2rkT++2RwtgXYuLWovypgm6pgm2pgm+pgmxrg+64JzrYE27QRbVMLbFMbbFMHbFMXbFMPfN/1wdlWYJu2AT4bm7vPwtbuvY17bxvk2djO+dzeuTo4V8cAn40NwMYNwcaNwMaNwcZNwG5Nwdn2YONOov6agW2ag21agG1agm1age+7NTjbAWzTWbRNG7BNW7BNO7BNe7BNB/B9dyRnwTZdAnw2tnOfhZ3ce2f33iXIs7Gr87mbc3V3rh4BPhs7gY07g427gI27go27gd26g7PdwMY9Rf31ANv0BNv0Atv0Btv0Ad93X7Ij2KaXaJt+YJv+YJsBYJuBYJtB4PseDM72ANv0DvDZ2NV9FvZ0773ce+8gz8Y+zue+ztXPufoH+GwcAjYeCjYeBjYeDjYeAXYbSVoFGw8Q9TcKbDMabDMGbDMWbDMOfN/jwdl+YJuBom0mgG0mgm0mgW0mg22mgO97KjjbH2wzKMBnYx/3WTjAvQ9074OCPBsHO5+HONdQ5xoW4LNxGth4Oth4Bth4Jth4FthtNjg7BGw8XNTfHLDNXLDNPLDNfLDNAvB9LwRnh4JtRoi2WQS2WQy2WQK2WQq2WQa+7x/B2WFgm5EBPhsHu8/C4e59hHsfGeTZOMr5PNq5xjjX2ACfjcvBxivAxivBxj+BjVeB3VaDs6PBxuNE/a0B2/wMtlkLtlkHtlkPvu8N4OwYsM140Ta/gG1+Bdv8Brb5HWyzEXzff4CzY8E2EwJ8No5yn4Xj3Pt49z4hyLNxovN5knNNdq4pAT4b/wQbbwIbbwYbbwEbbwW7bQNnJ4GNp4r62w622QG22Qm22QW22Q2+7z3g7GSwzTTRNnvBNvvANvvBNgfANgfB930InJ0Ctpke4LNxovssnOrep7n36UGejTOczzOda5ZzzQ7w2XgYbHwEbHwUbHwMbHwc7HYCnJ0JNp4j6u8k2OYU2OY02OYM2OYs+L7PgbOzwDZzRducB9tcANtcBNtcAttcBt/3FfI/twLbzAvw2TjDfRbOce9z3fu8IM/G+c7nBc610LkWBfhsvAo2vgY2vg42vgE2vgl2uwXOLgAbLxb1dxtscwdscxdscw9scx983w/I/2wSbLNEtM1DsM0jsM1jsM0TsM1T8H0/A2cXgW2WBvhsnO8+Cxe79yXufWmQZ+My5/OPzrXcuVYE+Gx8DjZ+ATZ+CTZ+BTZ+DXZ7Q/7nz2DjlaL+3oJt3oFt3oNtPoBtPoLv+xM4uxxs85Nom89gm7/ANl/ANl/BNt/A9+1L5f3sCrDNqgCfjcvcZ+FK9/6Te18V5Nm42vm8xrl+dq61AT4bv0vlfeNgqbxvHDyV942/T+V94xBgtx/A2TVg43Wi/kKCbUKBbUKDbcKAbcKC7zscOPsz2Ga9aJvwYJsIYJuIYJtIYJvI4PuOAs6uBdtsCPDZuNp9Fq5z7+vd+4Ygz8ZfnM+/OtdvzvV7gM/GqGDjaGDj6GDjGGDjmGC3WODsr2DjjaL+YoNt4oBt4oJt4oFt4oPvOwE4+xvY5g/RNgnBNn6wTSKwTWKwTRLwfScFZ38H2/wZ4LPxF/dZuNG9/+He/wzybNzkfN7sXFuca2uAz8ZkYOPkYOMUYOOUYONUYLfU4OxmsPE2UX9pwDZpwTbpwDbpwTYZwPedEZzdArbZLtomE9gmM9gmC9gmK9gmG/i+s4OzW8E2OwJ8Nm5yn4Xb3Pt2974jyLNxp/N5l3Ptdq49AT4bc4CNc4KNc4GNc4ON84Dd8oKzu8DGe0X95QPb5AfbFADbFATbFALfd2FwdjfYZp9omyJgm6Jgm2Jgm+JgmxLg+y4Jzu4B2+wP8Nm4030W7nXv+9z7/iDPxgPO54POdci5Dgf4bCwFNi4NNi4DNi4LNi4HdisPzh4EGx8R9VcBbFMRbFMJbFMZbFMFfN9VwdlDYJujom2qgW2qg21qgG1qgm1qge+7Njh7GGxzLMBn4wH3WXjEvR9178eCPBuPO59PONdJ5zoV4LOxDti4Lti4Hti4Pti4AditITh7Amx8WtRfI7BNY7BNE7BNU7BNM/B9NwdnT4Jtzoi2aQG2aQm2aQW2aQ22aQO+77bg7CmwzdkAn43H3Wfhafd+xr2fDfJsPOd8Pu9cF5zrYoDPxnZg4/Zg4w5g445g405gt87g7Hmw8SVRf13ANl3BNt3ANt3BNj3A990TnL0Atrks2qYX2KY32KYP2KYv2KYf+L77g7MXwTZXAnw2nnOfhZfc+2X3fiXIs/Gq8/mac113rhsBPhsHgI0Hgo0HgY0Hg42HgN2GgrPXwMY3Rf0NA9sMB9uMANuMBNuMAt/3aHD2OtjmlmibMWCbsWCbcWCb8WCbCeD7ngjO3gDb3A7w2XjVfRbedO+33PvtIM/GO87nu851z7nuB/hsnAQ2ngw2ngI2ngo2ngZ2mw7O3gUbPxD1NwNsMxNsMwtsMxtsMwd833PB2Xtgm4eibeaBbeaDbRaAbRaCbRaB73sxOHsfbPMowGfjHfdZ+MC9P3Tvj4I8Gx87n58411Pnehbgs3EJ2Hgp2HgZ2PhHsPFysNsKcPYJ2Pi5qL+VYJufwDarwDarwTZrwPf9Mzj7FGzzQrTNWrDNOrDNerDNBrDNL+D7/hWcfQa2eRngs/Gx+yx87t5fuPeXQZ6Nr5zPr53rjXO9DfDZ+BvY+Hew8Uaw8R9g4z/BbpvA2ddg43ei/jaDbbaAbbaCbbaBbbaD73sHOPsGbPNetM1OsM0usM1usM0esM1e8H3vA2ffgm0+BPhsfOU+C9+59/fu/UOQZ+NH5/Mn5/rsXH8F+GzcDzY+ADY+CDY+BDY+DHY7As5+Aht/EfV3FGxzDGxzHGxzAmxzkvzvN8HZz2Cbr6JtToNtzoBtzoJtzoFtzpP/3Rc4+xfY5luAz8aP7rPwi3v/6t6/BXk2+iY5/2/OFcy5gk/6139YuvFFsPElsPFlsPEVsPFV8r9fAWf//j7/8+w/bfz9JE1/18E2N8A2N8E2t8A2t8H3fQecDQa2CSHa5i7Y5h7Y5j7Y5gHY5iH4vh+Bs8HBNj+Abf6nZ+N/PPd8/6+/v+8h3Pvf/77/eS6k8zmUc4V2rjABPhsfg42fgI2fgo2fgY2fg91egLOhwMZhRf29BNu8Atu8Btu8Adu8Bd/3O3A2NNgmnGib92CbD2Cbj2CbT2Cbz+RdEJwNA7YJH+CzMaT7LAzr3sO59/BBno0RnM8RnSuSc0X+b8/G4O7d/68E3//2ry/ge4gIvocoot/oV/Ab/QZ+o77U3n+j36X2ef6NBkvt/fsODs5GAttEFW3zfWrv24RI7X2bH8A2IcE2ocD3HRqcjQy2iRbg8yOC+7yI4t6juvdoQZ4f0Z3PMZwrpnPFCvDdKgzYOCzYOBzYODzYOALYLSI4GwNsHFvUXySwTWSwTRSwTVSwTTTwfUcHZ2OCbeKItokBtokJtokFtokNtokDvu+44GwssE3cAJ+N0d1nYWz3Hse9xw3ybIznfI7vXAmcK2GAz8Z4YOP4YOMEYOOEYGM/2C0ROBsfbOwX9ZcYbJMEbJMUbJMMbJMcfN8pwNkEYJtEom1Sgm1SgW1Sg23SgG3Sgu87HTibEGyTOMBnYzz3Weh374nce+Igz8YkzuekzpXMuZIH+GxMDzbOADbOCDbOBDbODHbLAs4mBRunEPWXFWyTDWyTHWyTA2yTE3zfucDZZGCblKJtcoNt8oBt8oJt8oFt8oPvuwA4mxxskyrAZ2MS91mYwr2ndO+pgjwbUzuf0zhXWudKF+CzsSDYuBDYuDDYuAjYuCjYrRg4mwZsnF7UX3GwTQmwTUmwTSmwTWnwfZcBZ9OCbTKItikLtikHtikPtqkAtqkIvu9K5B0TbJMxwGdjavdZmN69Z3DvGYM8GzM5nzM7Vxbnyhrgs7Ey2LgK2Lgq2Lga2Lg62K0GOJsZbJxN1F9NsE0tsE1tsE0dsE1d8H3XI+//YJvsom3qg20agG0agm0agW0ag++7CTibFWyTI8BnYyb3WZjNvWd37zmCPBtzOp9zOVdu58oT4LOxKdi4Gdi4Odi4Bdi4JditFfnv8cDGeUX9tQbbtAHbtAXbtAPbtAffdwdwNjfYJp9om45gm05gm85gmy5gm67g++4GzuYB2+QP8NmY030W5nXv+dx7/iDPxgLO54LOVci5Cgf4bOwONu4BNu4JNu4FNu4NdusDzhYEGxcR9dcXbNMPbNMfbDMAbDMQfN+DwNlCYJuiom0Gg22GgG2Ggm2GgW2Gg+97BDhbGGxTLMBnYwH3WVjEvRd178WCPBuLO59LOFdJ5yoV4LNxJNh4FNh4NNh4DNh4LNhtHDhbAmxcWtTfeLDNBLDNRLDNJLDNZPB9TwFnS4Jtyoi2mQq2mQa2mQ62mQG2mQm+71ngbCmwTdkAn43F3Wdhafdexr2XDfJsLOd8Lu9cFZyrYoDPxtlg4zlg47lg43lg4/lgtwXgbHmwcSVRfwvBNovANovBNkvANkvB970MnK0Atqks2uZHsM1ysM0KsM1KsM1P4PteBc5WBNtUCfDZWM59FlZy75Xde5Ugz8aqzudqzlXduWoE+GxcDTZeAzb+GWy8Fmy8Duy2HpytBjauKepvA9jmF7DNr2Cb38A2v4PveyM4Wx1sU0u0zR9gmz/BNpvANpvBNlvA972V/O87wTa1A3w2VnWfhTXdey33XjvIs7GO87muc9VzrvoBPhu3gY23g413gI13go13gd12g7N1wcYNRP3tAdvsBdvsA9vsB9scAN/3QfK/0wbbNBRtcwhscxhscwRscxRscwx838fB2fpgm0YBPhvruM/CBu69oXtvFOTZ2Nj53MS5mjpXswCfjSfAxifBxqfAxqfBxmfAbmfJ/90C2Li5qL9zYJvzYJsLYJuLYJtL4Pu+DM42Bdu0EG1zBWxzFWxzDWxzHWxzA3zfN8HZZmCblgE+Gxu7z8Lm7r2Fe28Z5NnYyvnc2rnaOFfbAJ+Nt8DGt8HGd8DGd8HG98Bu98HZ1mDjdqL+HoBtHoJtHoFtHoNtnoDv+yk42wZs0160zTOwzXOwzQuwzUuwzSvwfb8GZ9uCbToE+Gxs5T4L27n39u69Q5BnY0fncyfn6uxcXQJ8Nr4BG78FG78DG78HG38Au30EZzuBjbuK+vsEtvkMtvkLbPMFbPMVfN/fwNnOYJtuom18abxv810a79sES+N9m+BpvG/zfRrv33cIcLYL2KZ7gM/Gju6zsKt77+beuwd5NvZwPvd0rl7O1TvAZ+MPYOOQYONQYOPQYOMwYLew4GxPsHEfUX/hwDbhwTYRwDYRwTaRwPcdGZztBbbpK9omCtgmKtgmGtgmOtgmBvi+Y4KzvcE2/QJ8NvZwn4V93Htf994vyLOxv/N5gHMNdK5BAT4bY4GNY4ON44CN44KN44Hd4oOzA8DGg0X9JQDbJATb+ME2icA2icH3nQScHQi2GSLaJinYJhnYJjnYJgXYJiX4vlOBs4PANkMDfDb2d5+Fg937EPc+NMizcZjzebhzjXCukQE+G1ODjdOAjdOCjdOBjdOD3TKAs8PBxqNE/WUE22QC22QG22QB22QF33c2cHYE2Ga0aJvsYJscYJucYJtcYJvc4PvOA86OBNuMCfDZOMx9Fo5y76Pd+5ggz8axzudxzjXeuSYE+GzMCzbOBzbODzYuADYuCHYrBM6OAxtPFPVXGGxTBGxTFGxTDGxTHHzfJcDZ8WCbSaJtSoJtSoFtSoNtyoBtyoLvuxw4OwFsMznAZ+NY91k40b1Pcu+TgzwbpzifpzrXNOeaHuCzsTzYuALYuCLYuBLYuDLYrQo4OxVsPEPUX1WwTTWwTXWwTQ2wTU3wfdcCZ6eBbWaKtqkNtqkDtqkLtqkHtqkPvu8G4Ox0sM2sAJ+NU9xn4Qz3PtO9zwrybJztfJ7jXHOda16Az8aGYONGYOPGYOMmYOOmYLdm4OwcsPF8UX/NwTYtwDYtwTatwDatwffdBpydC7ZZINqmLdimHdimPdimA9imI/i+O4Gz88A2CwN8Ns52n4Xz3fsC974wyLNxkfN5sXMtca6lAT4bO4ONu4CNu4KNu4GNu4PdeoCzi8HGy0T99QTb9ALb9Abb9AHb9AXfdz9wdgnY5kfRNv3BNgPANgPBNoPANoPB9z0EnF0Ktlke4LNxkfssXObef3Tvy4M8G1c4n1c610/OtSrAZ+NQsPEwsPFwsPEIsPFIsNsocHYl2Hi1qL/RYJsxYJuxYJtxYJvx5H9OBc7+BLZZI9pmIthmEthmMthmCthmKvmfYYCzq8A2Pwf4bFzhPgtXu/c17v3nIM/Gtc7ndc613rk2BPhsnA42ngE2ngk2ngU2nk3++2Rwdh3Y+BdRf3PBNvPANvPBNgvANgvB970InF0PtvlVtM1isM0SsM1SsM0ysM2P4PteDs5uANv8FuCzca37LPzFvf/q3n8L8mz83fm80bn+cK4/A3w2rgAbrwQb/wQ2XgU2Xg12WwPObgQbbxL19zPYZi3YZh3YZj3YZgP4vn8BZ/8A22wWbfMr2OY3sM3vYJuNYJs/wPf9JzkLttkS4LPxd/dZuMm9b3bvW4I8G7c6n7c513bn2hHgs3ET2Hgz2HgL2Hgr2Hgb2G07OLsNbLxT1N8OsM1OsM0usM1usM0e8H3vJTuCbXaJttkHttkPtjkAtjkItjkEvu/D4OwOsM3uAJ+NW91n4U73vsu97w7ybNzjfN7rXPuca3+Az8YjYOOjYONjYOPjYOMTYLeTpFWw8QFRf6fANqfBNmfANmfBNufA930enN0Htjko2uYC2OYi2OYS2OYy2OYK+L6vgrP7wTaHAnw27nGfhQfc+0H3fijIs/Gw8/mIcx11rmMBPhuvgY2vg41vgI1vgo1vgd1ug7NHwMbHRf3dAdvcBdvcA9vcB9s8AN/3Q3D2KNjmhGibR2Cbx2CbJ2Cbp2CbZ+D7fg7OHgPbnAzw2XjYfRYed+8n3PvJIM/GU87n0851xrnOBvhsfAE2fgk2fgU2fg02fgN2ewvOngYbnxP19w5s8x5s8wFs8xFs8wl835/B2TNgm/PGbYK7d/+//kf7/rd//QX++c+Cf/4LAT4/TrnPi3Pu/bx7vxDk+XHR+XzJuS4715X/9vyI7N79Qf75ff/Hv7789+/h/zj99f/7nf2vp7/9T9/v/3Y6rfdOvkv7v+z2P5wOlvZ/3fj/czp42v/j9/DfTn+f9v/87fzL6RBpvbf6wz+dDXI65D+f/a/TobycdU+H9nb2P06H8XrWOR0WnL0Eerv633r7v/5/Qf9FOwmX1nsn4dN67yRCWu+dRASdRAKdRAadRAGdRAWdRAOdRAedxACdxASdxAKdxAa//Tjg7GXQyTVRJ3FBJ/FAJ/FBJwlAJwlBJ37QSSLQSWLQSRLQSVLQSTLQSXLQSQrQSUrw208Fzl4BnVwHnfxP728X3fe1q+79mnu/HuT97Ybz+aZz3XKu2wG+v6UGvaUBvaUFvaUDvaUHvWUAvWUEvWUCvWUGvWUBvWUFvWUDvWUHveUADeUEZ2+C3u6I/i7lAp3kBp3kAZ3kBZ3kA53kB50UAJ0UBJ0UAp0UBp0UAZ0UBZ0UA50UB7/9EuDsLdDJXVEnJUEnpUAnpUEnZUAnZUEn5UAn5UEnFUAnFUEnlUAnlUEnVUAnVUEn1cBvvzo4ext0ci/A97cb7vvaHfd+173fC/L+dt/5/MC5HjrXowDf32qA3mqC3mqB3mqD3uqA3uqC3uqB3uqD3hqA3hqC3hqB3hqD3pqA3pqChpqBsw9Ab49Ff5eag05agE5agk5agU5ag07agE7agk7agU7ag046gE46gk46gU46g066gN9+V3D2IejkiaiTbqCT7qCTHqCTnqCTXqCT3qCTPqCTvqCTfqCT/qCTAaCTgaCTQaCTweC3PwScfQQ6eRrg+9t9933tsXt/4t6fBnl/e+Z8fu5cL5zrZYDvb0NBb8NAb8NBbyNAbyNBb6NAb6NBb2NAb2NBb+NAb+NBbxNAbxNBb5NAQ5PB2eegt1eiv0tTQCdTQSfTQCfTQSczQCczQSezQCezQSdzQCdzQSfzQCfzQScLQCcLwW9/ETj7AnTyWtTJYtDJEtDJUtDJMtDJj6CT5aCTFaCTlaCTn0Anq0Anq0Ena0AnP4NO1oLf/jpw9iXo5E2A72/P3Pe1V+79tXt/E+T97a3z+Z1zvXeuDwG+v60HvW0Avf0CevsV9PYb6O130NtG0NsfoLc/QW+bQG+bQW9bQG9bQW/bQEPbwdl3oLePor9LO0AnO0Enu0Anu0Ene0Ane0En+0An+0EnB0AnB0Enh0Anh0EnR0AnR8Fv/xg4+x508knUyXHQyQnQyUnQySnQyWnQyRnQyVnQyTnQyXnQyQXQyUXQySXQyWXQyRXw278Kzn4AnXwO8P3trfu+9tG9f3Lvn4O8v/3lfP7iXF+d61uA72/XQG/XQW83QG83QW+3QG+3QW93QG93QW/3QG/3QW8PQG8PQW+PQG+PQUNPwNkvoDffZM3fpaegk2egk+egkxegk5egk1egk9egkzegk7egk3egk/egkw+gk4+gk0/gt/8ZnP0KOvlO1MlfoJMvoJOvoJNvoBNfOu+dfJfOeyfB0nnvJHg67518n857JyH+6WyQ0z/889n/Oh3Sy1n3dChvZ//jdGivZ53TYcDZb6CTYKCT/+n97S/3fe3vv0t/379z73//+/7nueB/f3auEM71w+R//YelvYVN5723cOm89xY+nffeIqTz3ltE0Fsk0Ftk0FsU0FtU0Fs00Ft00FsM0FtM0Fss0FBscPb7yd57Cyn6uxQHdBIXdBIPdBIfdJIAdJIQdOIHnSQCnSQGnSQBnSQFnSQDnSQHnaQAv/2U4GwI0EkoUSepQCepQSdpQCdpQSfpQCfpQScZQCcZQSeZQCeZQSdZQCdZQSfZQCfZwW8/Bzj7A+gkdIDvb8Hd97WQ7j2Uew8d5P0tjPM5rHOFc67wAb6/5QS95QK95Qa95QG95QW95QO95Qe9FQC9FQS9FQK9FQa9FQG9FQW9FQMNFQdnw4LeIoj+LpUAnZQEnZQCnZQGnZQBnZQFnZQDnZQHnVQAnVQEnVQCnVQGnVQBnVQFv/1q4Gw40ElEUSfVQSc1QCc1QSe1QCe1QSd1QCd1QSf1QCf1QScNQCcNQSeNQCeNQSdNwG+/KTgbHnQSKcD3tzDu+1oE9x7RvUcK8v4W2fkcxbmiOle0AN/fmoHemoPeWoDeWoLeWoHeWoPe2oDe2oLe2oHe2oPeOoDeOoLeOoHeOoOGuoCzUUBv0UV/l7qCTrqBTrqDTnqATnqCTnqBTnqDTvqATvqCTvqBTvqDTgaATgaCTgaB3/5gcDYq6CSGqJMhoJOhoJNhoJPhoJMRoJORoJNRoJPRoJMxoJOxoJNxoJPxoJMJoJOJ4Lc/CZyNBjqJGeD7W2T3fS26e4/h3mMGeX+L5XyO7VxxnCtugO9vk0FvU0BvU0Fv00Bv00FvM0BvM0Fvs0Bvs0Fvc0Bvc0Fv80Bv80FvC0BDC8HZ2KC3eKK/S4tAJ4tBJ0tAJ0tBJ8tAJz+CTpaDTlaATlaCTn4CnawCnawGnawBnfwMfvtrwdk4oJP4ok7WgU7Wg042gE5+AZ38Cjr5DXTyO+hkI+jkD9DJn6CTTaCTzaCTLaCTreC3vw2cjQs6SRDg+1ss930tnnuP794TBHl/S/j3f4ZzJXKuxAG+v20Hve0Ave0Eve0Cve0Gve0Bve0Fve0Dve0HvR0AvR0EvR0CvR0GvR0BDR0FZ/2gtySiv0vHQCfHQScnQCcnQSenQCenQSdnQCdnQSfnQCfnQScXQCcXQSeXQCeXwW//CjibCHSSVNTJVdDJNdDJddDJDdDJTdDJLdDJbdDJHdDJXdDJPdDJfdDJA9DJQ9DJI/DbfwzOJgadJAvw/S2h+76WxL0nde/Jgry/JXc+p3CulM6VKsD3tyegt6egt2egt+egtxegt5egt1egt9egtzegt7egt3egt/egtw+gt4+goU/gbArQW2rR36XPoJO/QCdfQCdfQSffQCe+9N47+S69906CpffeSfD03jv5/p/OBjkd4p/P/tfpH7ycdU+H9Hb2P06H8nrWOR0anE0JOkkj6iRMeu+dhE3vvZNw6b13Ej69904ipPfeSUTQSSTQSWTQSRTQSVTQSTTQSXTQSQzQSUzw248FzqYCnaQN8P0tufu+ltq9p3HvaYO8v6VzPqd3rgzOlTHA97fYoLc4oLe4oLd4oLf4oLcEoLeEoDc/6C0R6C0x6C0J6C0p6C0Z6C05aCgFOJse9JZJ9HcpJegkFegkNegkDegkLegkHegkPegkA+gkI+gkE+gkM+gkC+gkK+gkG/jtZwdnM4BOMos6yQE6yQk6yQU6yQ06yQM6yQs6yQc6yQ86KQA6KQg6KQQ6KQw6KQI6KQp++8XA2YygkywBvr+lc9/XMrn3zO49S5D3t6zO52zOld25cgT4/lYc9FYC9FYS9FYK9FYa9FYG9FYW9FYO9FYe9FYB9FYR9FYJ9FYZ9FYFNFQVnM0Gessp+rtUDXRSHXRSA3RSE3RSC3RSG3RSB3RSF3RSD3RSH3TSAHTSEHTSCHTSGPz2m5B3PdBJLlEnTUEnzUAnzUEnLUAnLUEnrUAnrUEnbUAnbUEn7UAn7UEnHUAnHUEnncBvvzM4mwN0kjvA97es7vtaTveey73nDvL+lsf5nNe58jlX/gDf37qA3rqC3rqB3rqD3nqA3nqC3nqB3nqD3vqA3vqC3vqB3vqD3gaA3gaChgaBs3lBbwVEf5cGg06GgE6Ggk6GgU6Gg05GgE5Ggk5GgU5Gg07GgE7Ggk7GgU7Gg04mgN/+RHA2H+ikoKiTSaCTyaCTKaCTqaCTaaCT6aCTGaCTmaCTWaCT2aCTOaCTuaCTeaCT+eC3vwCczQ86KRTg+1se932tgHsv6N4LBXl/K+x8LuJcRZ2rWIDvbwtBb4tAb4tBb0tAb0tBb8tAbz+C3paD3laA3laC3n4Cva0Cva0Gva0BDf0MzhYBvRUX/V1aCzpZBzpZDzrZADr5BXTyK+jkN9DJ76CTjaCTP0Anf4JONoFONoNOtoDf/lZwtijopISok22gk+2gkx2gk52gk12gk92gkz2gk72gk32gk/2gkwOgk4Ogk0Ogk8Pgt38EnC0GOikZ4PtbYfd9rbh7L+HeSwZ5fyvlfC7tXGWcq2yA729HQW/HQG/HQW8nQG8nQW+nQG+nQW9nQG9nQW/nQG/nQW8XQG8XQW+XQEOXwdnSoLdyor9LV0AnV0En10An10EnN0AnN0Ent0Ant0End0And0En90An90EnD0AnD8Fv/xE4WwZ0Ul7UyWPQyRPQyVPQyTPQyXPQyQvQyUvQySvQyWvQyRvQyVvQyTvQyXvQyQfw2/8IzpYFnVQI8P2tlPu+Vs69l3fvFYK8v1V0PldyrsrOVSXA97dPoLfPoLe/QG9fQG9fQW/fQG++DN57+y6D996CZfDeW/B/Ohvk9Pf/fPa/TofwctY9/YO3s/9xOqTXs87pUOBsJdBbVdHfpdAZvHcSJoP3TsJm8N5JuAzeOwmfwXsnETJ47yQi6CQS6CQy6CQK6CQq6CQa6CQ66CQG+O3HBGcrg06qiTqJBTqJDTqJAzqJCzqJBzqJDzpJADpJCDrxg04SgU4Sg06SgE6Sgk6Sgd9+cnC2CuikeoDvbxXd97Wq7r2ae68e5P2thvO5pnPVcq7aAb6/pQC9pQS9pQK9pQa9pQG9pQW9pQO9pQe9ZQC9ZQS9ZQK9ZQa9ZQG9ZQUNZQNna4Le6oj+LmUHneQAneQEneQCneQGneQBneQFneQDneQHnRQAnRQEnRQCnRQGnRQBv/2i4Gwt0EldUSfFQCfFQSclQCclQSelQCelQSdlQCdlQSflQCflQScVQCcVQSeVQCeVyTsZOFsbdFIvwPe3Gu77Wh33Xte91wvy/lbf+dzAuRo6V6MA39+qgt6qgd6qg95qgN5qgt5qgd5qg97qgN7qgt7qgd7qg94agN4agt4agYYag7MNQG+NRX+XmoBOmoJOmoFOmoNOWoBOWoJOWoFOWoNO2oBO2oJO2oFO2oNOOoBOOoLffidwtiHopImok86gky6gk66gk26gk+6gkx6gk56gk16gk96gkz6gk76gk36gk/6gkwHgtz8QnG0EOmka4Ptbffd9rbF7b+LemwZ5f2vmfG7uXC2cq2WA72+DQG+DQW9DQG9DQW/DQG/DQW8jQG8jQW+jQG+jQW9jQG9jQW/jQG/jQUMTwNnmoLdWor9LE0Enk0Ank0EnU0AnU0En00An00EnM0AnM0Ens0Ans0Enc0Anc0En88Bvfz442wJ00lrUyQLQyULQySLQyWLQyRLQyVLQyTLQyY+gk+WgkxWgk5Wgk59AJ6tAJ6vBb38NONsSdNImwPe3Zu77Wiv33tq9twny/tbW+dzOudo7V4cA399+Br2tBb2tA72tB71tAL39Anr7FfT2G+jtd9DbRtDbH6C3P0Fvm0Bvm0FDW8DZdqC3jqK/S1tBJ9tAJ9tBJztAJztBJ7tAJ7tBJ3tAJ3tBJ/tAJ/tBJwdAJwdBJ4fAb/8wONsedNJJ1MkR0MlR0Mkx0Mlx0MkJ0MlJ0Mkp0Mlp0MkZ0MlZ0Mk50Ml50MkF0MlF8Nu/BM52AJ10DvD9ra37vtbRvXdy752DvL91cT53da5uztU9wPe3y6C3K6C3q6C3a6C366C3G6C3m6C3W6C326C3O6C3u6C3e6C3+6C3B6Chh+BsV9BbD9HfpUegk8egkyegk6egk2egk+egkxegk5egk1egk9egkzegk7egk3egk/fgt/8BnO0GOulp7CSEe/f/i+h//9dH0Mkn0Mln8L10B99LrwD/Xndx/z73cO893XuvIH+vezuf+zhXX+fqF+Df67/A9/sFfL9fwXPoG3gO+TJ6fw59l9H7cyhYRu/PoeAZvT+Hvs/o/TkU4p/OBjn9wz+f/a/TIb2cdU+H8nb2P06H9nrWOR0GnO0Deusv+nsdNqP3TsJl9N5J+IzeO4mQ0XsnEUEnkUAnkUEnUUAnUUEn0UAn0UEnMUAnMUEnscBvPzY42xd0MkDUSRzQSVzQSTzQSXzQSQLQSULQiR90kgh0khh0kgR0khR0kgx0khx0kgL89lOCs/1AJwMDfH/r7b6v9XfvA9z7wCDvb4Ocz4Oda4hzDQ3w/S0V6C016C0N6C0t6C0d6C096C0D6C0j6C0T6C0z6C0L6C0r6C0b6C07aCgHODsY9DZM9HcpJ+gkF+gkN+gkD+gkL+gkH+gkP+ikAOikIOikEOikMOikCOikKOikGPjtFwdnh4BOhos6KQE6KQk6KQU6KQ06KQM6KQs6KQc6KQ86qQA6qQg6qQQ6qQw6qQI6qQp++9XA2aGgkxEBvr8Nct/Xhrn34e59RJD3t5HO51HONdq5xgT4/lYd9FYD9FYT9FYL9FYb9FYH9FYX9FYP9FYf9NYA9NYQ9NYI9NYY9NYENNQUnB0Fehsr+rvUDHTSHHTSAnTSEnTSCnTSGnTSBnTSFnTSDnTSHnTSAXTSEXTSCXTSGfz2u4Czo0En40SddAWddAOddAed9ACd9ASd9AKd9Aad9AGd9AWd9AOd9AedDACdDASdDCL/PT44OwZ0Mj7A97eR7vvaWPc+zr2PD/L+NsH5PNG5JjnX5ADf34aA3oaC3oaB3oaD3kaA3kaC3kaB3kaD3saA3saC3saB3saD3iaA3iaChiaBsxNBb1NEf5cmg06mgE6mgk6mgU6mg05mgE5mgk5mgU5mg07mgE7mgk7mgU7mg04WgN/+QtIU6GSqqJNFoJPFoJMloJOloJNloJMfQSfLQScrQCcrQSc/gU5WgU5Wg07WgE5+Br/9teDsZNDJtADf3ya472tT3PtU9z4tyPvbdOfzDOea6VyzAnx/Wwd6Ww962wB6+wX09ivo7TfQ2++gt42gtz9Ab3+C3jaB3jaD3raA3raChraBszNAb7NFf5e2g052gE52gk52gU52g072gE72gk72gU72g04OgE4Ogk4OgU4Og06OgN/+UXB2JuhkjqiTY6CT46CTE6CTk6CTU6CT06CTM6CTs6CTc6CT86CTC6CTi6CTS6CTy+C3fwWcnQU6mRvg+9t0931ttnuf497nBnl/m+d8nu9cC5xrYYDvb1dBb9dAb9dBbzdAbzdBb7dAb7dBb3dAb3dBb/dAb/dBbw9Abw9Bb49AQ4/B2fmgt0Wiv0tPQCdPQSfPQCfPQScvQCcvQSevQCevQSdvQCdvQSfvQCfvQScfQCcfwW//Ezi7AHSyWNTJZ9DJX6CTL6CTr6CTb6ATXybvnXyXyXsnwTJ57yR4Ju+dfP9PZ4OcDvHPZ//r9A9ezrqnQ3o7+x+nQ3k965wODc4uBJ0sCfD9bZ77vrbIvS9270uCvL8tdT4vc64fnWt5gO9vYTJ57y1sJu+9hcvkvbfwmbz3FiGT994igt4igd4ig96igN6igt6igd6ig95igN5igoZigbPLQG8rRH+XYoNO4oBO4oJO4oFO4oNOEoBOEoJO/KCTRKCTxKCTJKCTpKCTZKCT5OC3nwKc/RF0slLUSUrQSSrQSWrQSRrQSVrQSTrQSXrQSQbQSUbQSSbQSWbQSRbQSVbQSTbw288Ozi4HnfwU4PvbUvd9bYV7X+nefwry/rbK+bzaudY4188Bvr/lAL3lBL3lAr3lBr3lAb3lBb3lA73lB70VAL0VBL0VAr0VBr0VAb0VBQ0VA2dXg97Wiv4uFQedlACdlASdlAKdlAadlAGdlAWdlAOdlAedVACdVASdVAKdVAadVAG//arg7BrQyTpRJ9VAJ9VBJzVAJzVBJ7VAJ7VBJ3VAJ3VBJ/VAJ/VBJw1AJw1BJ41AJ43Bb78JOPsz6GR9gO9vq9z3tbXufZ17Xx/k/W2D8/kX5/rVuX4L8P2tKeitGeitOeitBeitJeitFeitNeitDeitLeitHeitPeitA+itI+itE2ioMzj7C+jtd9HfpS6gk66gk26gk+6gkx6gk56gk16gk96gkz6gk76gk36gk/6gkwGgk4Hgtz8InP0VdLJR1Mlg0MkQ0MlQ0Mkw0Mlw0MkI0MlI0Mko0Mlo0MkY0MlY0Mk40Ml40MkE8NufCM7+Bjr5I8D3tw3u+9rv7n2je/8jyPvbn87nTc612bm2BPj+Ngn0Nhn0NgX0NhX0Ng30Nh30NgP0NhP0Ngv0Nhv0Ngf0Nhf0Ng/0Nh80tACc3QR62yr6u7QQdLIIdLIYdLIEdLIUdLIMdPIj6GQ56GQF6GQl6OQn0Mkq0Mlq0Mka8j8rAGc3g062iTpZCzpZBzpZDzrZADr5BXTyK+jkN9DJ76CTjaCTP0Anf4JONoFONoNOtoDf/lZwdgvoZHuA729/uu9rW937Nve+Pcj72w7n807n2uVcuwN8f9sGetsOetsBetsJetsFetsNetsDetsLetsHetsPejsAejsIejsEejsMGjoCzu4Eve0R/V06Cjo5Bjo5Djo5ATo5CTo5BTo5DTo5Azo5Czo5Bzo5Dzq5ADq5CDq5BH77l8HZXaCTvaJOroBOroJOroFOroNOboBOboJOboFOboNO7oBO7oJO7oFO7oNOHoBOHoLf/iNwdjfoZF+A72873Pe1Pe59r3vfF+T9bb/z+YBzHXSuQwG+vz0GvT0BvT0FvT0DvT0Hvb0Avb0Evb0Cvb0Gvb0Bvb0Fvb0Dvb0HvX0ADX0EZw+A3g6L/i59Ap18Bp38BTr5Ajr5Cjr5BjrxZfbeyXeZvXcSLLP3ToL/09kgp7//57P/dTqEl7Pu6R+8nf2P0yG9nnVOhwJnD4JOjog6CZ3ZeydhMnvvJGxm752Ey+y9k/CZvXcSIbP3TiKCTiKBTiKDTqKATqKCTqKBTqKDTmKA335McPYQ6ORogO9v+933tcPu/Yh7Pxrk/e2Y8/m4c51wrpMBvr/FAr3FBr3FAb3FBb3FA73FB70lAL0lBL35QW+JQG+JQW9JQG9JQW/JQEPJwdnjoLdTor9LKUAnKUEnqUAnqUEnaUAnaUEn6UAn6UEnGUAnGUEnmUAnmUEnWUAnWcFvPxs4ewJ0clrUSXbQSQ7QSU7QSS7QSW7QSR7QSV7QST7QSX7QSQHQSUHQSSHQSWHQSRHw2y8Kzp4EnZwJ8P3tmPu+dsq9n3bvZ4K8v511Pp9zrvPOdSHA97dioLfioLcSoLeSoLdSoLfSoLcyoLeyoLdyoLfyoLcKoLeKoLdKoLfKoKEq4Ow50NtF0d+lqqCTaqCT6qCTGqCTmqCTWqCT2qCTOqCTuqCTeqCT+qCTBqCThqCTRuC33xicPQ86uSTqpAnopCnopBnopDnopAXopCXopBXopDXopA3opC3opB3opD3opAPopCP47XcCZy+ATi4H+P521n1fu+jeL7n3y0He3644n6861zXnuh7g+1tn0FsX0FtX0Fs30Ft30FsP0FtP0Fsv0Ftv0Fsf0Ftf0Fs/0Ft/0NsA0NBAcPYq6O2G6O/SINDJYNDJENDJUNDJMNDJcNDJCNDJSNDJKNDJaNDJGNDJWNDJONDJePDbnwDOXgOd3BR1MhF0Mgl0Mhl0MgV0MhV0Mg10Mh10MgN0MhN0Mgt0Mht0Mgd0Mhd0Mg/89ueDs9dBJ7cCfH+74r6v3XDvN937rSDvb7edz3ec665z3Qvw/W0B6G0h6G0R6G0x6G0J6G0p6G0Z6O1H0Nty0NsK0NtK0NtPoLdVoLfVoKE14Owd0Nt90d+ln0Ena0En60An60EnG0Anv4BOfgWd/AY6+R10shF08gfo5E/QySbQyWbw298Czt4FnTwQdbIVdLINdLIddLIDdLITdLILdLIbdLIHdLIXdLIPdLIfdHIAdHIQdHII/PYPg7P3QCcPA3x/u+2+r9137w/c+8Mg72+PnM+PneuJcz0N8P3tCOjtKOjtGOjtOOjtBOjtJOjtFOjtNOjtDOjtLOjtHOjtPOjtAujtImjoEjj7GPT2TPR36TLo5Aro5Cro5Bro5Dro5Abo5Cbo5Bbo5Dbo5A7o5C7o5B7o5D7o5AH47T8EZ5+ATp6LOnkEOnkMOnkCOnkKOnkGOnkOOnkBOnkJOnkFOnkNOnkDOnkLOnkHOnkPfvsfwNmnoJMXAb6/PXLf15659+fu/UWQ97eXzudXzvXaud4E+P72EfT2CfT2GfT2F+jtC+jtK+jtG+jNl8V7b99l8d5bsH86G+R08H8++1+nv/dy1j0dwtvZ/zj9g9ezzumQ4Owr0Ntb0d+lUFm8dxI6i/dOwmTx3knYLN47CZfFeyfhs3jvJEIW751EBJ1EAp1EBp1EAZ1EBZ1EA51EB7/9GODsa9DJO1EnMUEnsUAnsUEncUAncUEn8UAn8UEnCUAnCUEnftBJItBJYtBJEtBJUvDbTwbOvgGdvA/w/e2l+7721r2/c+/vg7y/fXA+f3SuT871OcD3t+SgtxSgt5Sgt1Sgt9SgtzSgt7Sgt3Sgt/Sgtwygt4ygt0ygt8ygtyygoazg7EfQ21+iv0vZQCfZQSc5QCc5QSe5QCe5QSd5QCd5QSf5QCf5QScFQCcFQSeFQCeFwW+/CDj7CXTyRdRJUdBJMdBJcdBJCdBJSdBJKdBJadBJGdBJWdBJOdBJedBJBdBJRdBJJfDbrwzOfgadfA3w/e2D+772l3v/4t6/Bnl/+/b3O9sU5//duYJN+dd/WNpbFdBbVdBbNdBbddBbDdBbTdBbLdBbbdBbHdBbXdBbPdBbfdBbA9BbQ9BQI3D279/2f579p96CT9H8XWoMOmkCOmkKOmkGOmkOOmkBOmkJOmkFOmkNOmkDOmkLOmkHOmkPOukAfvsdwdnvQCffizrpBDrpDDrpAjrpCjrpBjrpDjrpATrpCTrpBTrpDTrpAzrpCzrpBzrpD377A8DZYKCTEKCT/+n97Zv7vvb336W/79+797//ff/z3A/O55DOFcq5Qgf4/jYQ9DYI9DYY9DYE9DYU9DYM9DYc9DYC9DYS9DYK9DYa9DYG9DYW9DYONDQenA0Jegsj+rs0AXQyEXQyCXQyGXQyBXQyFXQyDXQyHXQyA3QyE3QyC3QyG3QyB3QyF/z254GzoUAnYUWdzAedLACdLASdLAKdLAadLAGdLAWdLAOd/Ag6WQ46WQE6WQk6+Ql0sgr89leDs6FBJ+ECfH/7wX1fC+Pew7r3cEHe38I7nyM4V0TnihTg+9sa0NvPoLe1oLd1oLf1oLcNoLdfQG+/gt5+A739DnrbCHr7A/T2J+htE2hoMzgbAfQWWfR3aQvoZCvoZBvoZDvoZAfoZCfoZBfoZDfoZA/oZC/oZB/oZD/o5ADo5CD47R8CZyOCTqKIOjkMOjkCOjkKOjkGOjkOOjkBOjkJOjkFOjkNOjkDOjkLOjkHOjkPOrkAfvsXwdlIoJOoAb6/hXff1yK79yjuPWqQ97dozufozhXDuWIG+P52CfR2GfR2BfR2FfR2DfR2HfR2A/R2E/R2C/R2G/R2B/R2F/R2D/R2HzT0AJyNDnqLJfq79BB08gh08hh08gR08hR08gx08hx08gJ08hJ08gp08hp08gZ08hZ08g789t+DszFAJ7GNnYRw7/5/Ef3v//oAOvkIOvkEvpeY4HuJE+Df62ju3+dY7j22e48T5O91XOdzPOeK71wJ/tvf61Du3f+vBN//9q/P4Bnw1//xnf33/4IvoL+vnrb4f/8F38Buvqzez8YDGyf8bxv/X/+foP+i23yX1fs2wbJ63yZ4Vu/bfJ/V+zYhwPf9AzgbH2zjF20TEmwTCmwTGmwTBmwTFnzf4cDZBGCbRGCb/+nZGNd9FiZ07373nijIszGx8zmJcyV1rmQBPhvDg40jgI0jgo0jgY0jg92igLNJwMbJRf1FBdtEA9tEB9vEANvEBN93LHA2KdgmhWib2GCbOGCbuGCbeGCb+OR5B84mA9ukDPDZmNh9FiZ37ynce8ogz8ZUzufUzpXGudIG+GxMCDb2g40TgY0Tg42TkKbA2dRg43Si/pKBbZKDbVKAbVKCbVKR7xucTQO2SS/aJg3YJi3YJh3YJj3YJgP4vjOCs2nBNhkCfDamcp+F6dx7eveeIcizMaPzOZNzZXauLAE+GzOBjTODjbOAjbOCjbOB3bKDs5nAxllF/eUA2+QE2+QC2+QG2+QB33decDYz2CabaJt8YJv8YJsCYJuCYJtC4PsuDM5mAdtkD/DZmNF9FmZ179nce/Ygz8YczueczpXLuXIH+GwsAjYuCjYuBjYuDjYuAXYrCc7mBBvnEfVXCmxTGmxTBmxTFmxTDnzf5cHZXGCbvKJtKoBtKoJtKoFtKoNtqoDvuyo4mxtsky/AZ2MO91mYx73nde/5gjwb8zufCzhXQecqFOCzsRrYuDrYuAbYuCbYuBbYrTY4WwBsXFjUXx2wTV2wTT2wTX2wTQPwfTcEZwuCbYqItmkEtmkMtmkCtmkKtmkGvu/m4GwhsE3RAJ+N+d1nYWH3XsS9Fw3ybCzmfC7uXCWcq2SAz8YWYOOWYONWYOPWYOM2YLe24GxxsHEpUX/twDbtwTYdwDYdwTadwPfdGZwtAbYpLdqmC9imK9imG9imO9imB/i+e5L/3gxsUybAZ2Mx91lYyr2Xdu9lgjwbyzqfyzlXeeeqEOCzsRfYuDfYuA/YuC/YuB/YrT84Ww5sXFHU3wCwzUCwzSCwzWCwzRDwfQ8l//032KaSaJthYJvhYJsRYJuRYJtR4PseDc5WANtUDvDZWNZ9FlZ075Xce+Ugz8YqzueqzlXNuaoH+GwcAzYeCzYeBzYeDzaeAHabSP5nLGDjGqL+JoFtJoNtpoBtpoJtpoHvezo4Ww1sU1O0zQywzUywzSywzWywzRzwfc8FZ6uDbWoF+Gys4j4La7j3mu69VpBnY23ncx3nqutc9QJ8Ns4DG88HGy8AGy8EGy8Cuy0GZ+uAjeuL+lsCtlkKtlkGtvkRbLMcfN8rwNm6YJsGom1Wgm1+AtusAtusBtusAd/3z+BsPbBNwwCfjbXdZ2F9997AvTcM8mxs5Hxu7FxNnKtpgM/GtWDjdWDj9WDjDWDjX8Buv4KzjcHGzUT9/Qa2+R1ssxFs8wfY5k/wfW8CZ5uAbZqLttkMttkCttkKttkGttkOvu8d4GxTsE2LAJ+NjdxnYTP33ty9twjybGzpfG7lXK2dq02Az8adYONdYOPdYOM9YOO9YLd94GwrsHFbUX/7wTYHwDYHwTaHwDaHwfd9BJxtDbZpJ9rmKNjmGNjmONjmBNjmJPi+T4GzbcA27QN8NrZ0n4Vt3Xs7994+yLOxg/O5o3N1cq7OAT4bT4ONz4CNz4KNz4GNz4PdLoCzHcHGXUT9XQTbXALbXAbbXAHbXAXf9zVwthPYpqtom+tgmxtgm5tgm1tgm9vg+75D/u8NwDbdAnw2dnCfhV3ce1f33i3Is7G787mHc/V0rl4BPhvvgo3vgY3vg40fgI0fgt0egbM9wMa9Rf09Bts8Ads8Bds8A9s8B9/3C/J/UwK26SPa5iXY5hXY5jXY5g3Y5i34vt+Bs73ANn0DfDZ2d5+Fvd17H/feN8izsZ/zub9zDXCugQE+G9+DjT+AjT+CjT+BjT+D3f4i//c+YONBov6+gG2+gm2+gW182bxv81027993MHB2ANhmsGib4Nm8b/N9Nu/bhMjmfZsfwDYhwfcdCpwdCLYZEuCzsZ/7LBzk3ge79yFBno1Dnc/DnGu4c40I8NkYGmwcBmwcFmwcDmwcHuwWAZwdBjYeKeovItgmEtgmMtgmCtgmKvi+o4Gzw8E2o0TbRAfbxADbxATbxALbxAbfdxxwdgTYZnSAz8ah7rNwpHsf5d5HB3k2jnE+j3Wucc41PsBnY1ywcTywcXywcQKwcUKwmx+cHQs2niDqLxHYJjHYJgnYJinYJhn4vpODs+PANhNF26QA26QE26QC26QG26QB33dacHY82GZSgM/GMe6zcIJ7n+jeJwV5Nk52Pk9xrqnONS3AZ2M6sHF6sHEGsHFGsHEmsFtmcHYK2Hi6qL8sYJusYJtsYJvsYJsc4PvOCc5OBdvMEG2TC2yTG2yTB2yTF2yTD3zf+cHZaWCbmQE+Gye7z8Lp7n2Ge58Z5Nk4y/k827nmONfcAJ+NBcDGBcHGhcDGhcHGRcBuRcHZ2WDjeaL+ioFtioNtSoBtSoJtSoHvuzQ4OwdsM1+0TRmwTVmwTTmwTXmwTQXwfVcEZ+eCbRYE+Gyc5T4L57n3+e59QZBn40Ln8yLnWuxcSwJ8NlYCG1cGG1cBG1cFG1cDu1UHZxeBjZeK+qsBtqkJtqkFtqkNtqkDvu+64OxisM0y0Tb1wDb1wTYNwDYNwTaNwPfdGJxdArb5McBn40L3WbjUvS9z7z8GeTYudz6vcK6VzvVTgM/GJmDjpmDjZmDj5mDjFmC3luDsCrDxKlF/rcA2rcE2bcA2bcE27cD33R6cXQm2WS3apgPYpiPYphPYpjPYpgv4vruCsz+BbdYE+Gxc7j4LV7n31e59TZBn48/O57XOtc651gf4bOwGNu4ONu4BNu4JNu4FdusNzq4FG28Q9dcHbNMXbNMPbNMfbDOA/N9+gLPrwDa/iLYZBLYZDLYZArYZCrYZRv7vAsDZ9WCbXwN8Nv7sPgs3uPdf3PuvQZ6Nvzmff3eujc71R4DPxhFg45Fg41Fg49Fg4zHkf/cMzv4ONv5T1N84sM14sM0EsM1EsM0k8H1PBmc3gm02ibaZAraZCraZBraZDraZAb7vmeDsH2CbzQE+G39zn4V/uvdN7n1zkGfjFufzVufa5lzbA3w2zgIbzwYbzwEbzwUbzwO7zQdnt4KNd4j6WwC2WQi2WQS2WQy2WQK+76Xg7DawzU7RNsvANj+CbZaDbVaAbVaS/z4ZnN0OttkV4LNxi/ss3OHed7r3XUGejbudz3uca69z7Qvw2bgKbLwabLwGbPwz2Hgt+e/FwNk9YOP9ov7Wg202gG1+Adv8Crb5jbyng7N7wTYHRNtsBNv8Abb5E2yzCWyzGXzfW8DZfWCbgwE+G3e7z8L97v2Aez8Y5Nl4yPl82LmOONfRAJ+NW8HG28DG28HGO8DGO8Fuu8DZw2DjY6L+doNt9oBt9oJt9oFt9oPv+wA4ewRsc1y0zUGwzSGwzWGwzRGwzVHwfR8DZ4+CbU4E+Gw85D4Lj7n34+79RJBn40nn8ynnOu1cZwJ8Nh4HG58AG58EG58CG58Gu50BZ0+Bjc+K+jsLtjkHtjkPtrkAtrkIvu9L4OxpsM050TaXwTZXwDZXwTbXwDbXwfd9gzQGtjkf4LPxpPssPOvez7n380GejReczxed65JzXQ7w2XgTbHwLbHwbbHwHbHwX7HYPnL0INr4i6u8+2OYB2OYh2OYR2OYx+L6fkOco2OaqaJunYJtnYJvnYJsXYJuX4Pt+Bc5eBttcC/DZeMF9Fl5x71fd+7Ugz8brzucbznXTuW4F+Gx8DTZ+AzZ+CzZ+BzZ+D3b7QP5Wgo1vG/sL7t79//of7fvf/vUR/PPfBP/8d0TPj0/gt/UZ/Lb+Ar+tL+C39RV839/A2Vtgm7sBPj+uu8+L2+79jnu/G+T5cc/5fN+5HjjXwwCfH77s3jf+Lrv3jYNl975x8H86G+S/4HtPZ//ff0EIcPY+2PiRqL8fwDYhwTahwDahwTZhwPcdFpx9ALZ5LNomHNgmPNgmAtgmItgmEvi+I4OzD8E2TwJ8Nt5zn4WP3Ptj9/4kyLPxqfP5mXM9d64XAT4bo4CNo4KNo4GNo4ONY4DdYoKzz8DGL0X9xQLbxAbbxAHbxAXbxAPfd3xw9jnY5pVomwRgm4RgGz/YJhHYJjH4vpOAsy/ANq8DfDY+dZ+FL937K/f+Osiz8Y3z+a1zvXOu9wE+G5OCjZOBjZODjVOAjVOC3VKBs2/Bxh9E/aUG26QB26QF26QD26QH33cGcPYd2OajaJuMYJtMYJvMYJssYJus4PvOBs6+B9t8CvDZ+MZ9Fn5w7x/d+6cgz8bPzue/nOuLc30N8NmYHWycA2ycE2ycC2ycG+yWB5z9C2z8TdRfXrBNPrBNfrBNAbBNQfB9FwJnv4BtfFM12xQG2xQB2xQF2xQD2xQH33cJcPYr2OY7sM3/9Gz87D4Lv7n3v7f+zv33/c9zwZzPwf/+/+9cIab+6z8s3bgk2LgU2Lg02LgM2Lgs2K0cOBt8qveNfxD1Vx5sUwFsUxFsUwlsUxl831XA2e/BNiFF21QF21QD21QH29QA29QE33ct8j/TB9uECvDZGMx9Fv7g3kO691BBno2hnc9hnCusc4UL8NlYG2xcB2xcF2xcD2xcH+zWAJwNAzYOL+qvIdimEdimMdimCdimKfi+m5H/vQ3YJoJom+ZgmxZgm5Zgm1Zgm9bg+24DzoYD20QM8NkY2n0WhnfvEdx7xCDPxkjO58jOFcW5ogb4bGwLNm4HNm4PNu4ANu4IdutE/ndzYONoov46g226gG26gm26gW26g++7BzgbBWwTXbRNT7BNL7BNb7BNH7BNX/B99wNno4JtYgT4bIzkPgujuffo7j1GkGdjTOdzLOeK7VxxAnw29gcbDwAbDwQbDwIbDwa7DQFnY4GN44r6Gwq2GQa2GQ62GQG2GQm+71HgbGywTTzRNqPBNmPANmPBNuPANuPB9z0BnI0Dtokf4LMxpvssjOve47n3+EGejQmczwn//s9xrkQBPhsngo0ngY0ng42ngI2ngt2mgbMJwcaJRf1NB9vMANvMBNvMAtvMBt/3HHDWD7ZJItpmLthmHthmPthmAdhmIfi+F4GzicA2SQN8NiZwn4WJ3XsS9540yLMxmfM5uXOlcK6UAT4bF4ONl4CNl4KNl4GNfwS7LQdnk4ONU4n6WwG2WQm2+Qlsswpssxp832vA2RRgm9SibX4G26wF26wD26wH22wA3/cv4GxKsE2aAJ+NydxnYSr3ntq9pwnybEzrfE7nXOmdK0OAz8Zfwca/gY1/BxtvBBv/AXb7E5xNBzbOKOpvE9hmM9hmC9hmK9hmG/i+t4Oz6cE2mUTb7ADb7ATb7ALb7Abb7AHf915wNgPYJnOAz8a07rMwo3vP5N4zB3k2ZnE+Z3WubM6VPcBn4z6w8X6w8QGw8UGw8SGw22FwNivYOIeovyNgm6Ngm2Ngm+NgmxPg+z4JzmYD2+QUbXMKbHMabHMGbHMWbHMOfN/nwdnsYJtcAT4bs7jPwhzuPad7zxXk2Zjb+ZzHufI6V74An40XwMYXwcaXwMaXwcZXwG5Xwdk8YOP8ov6ugW2ug21ugG1ugm1uge/7NjibF2xTQLTNHbDNXbDNPbDNfbDNA/B9PwRn84FtCgb4bMztPgvzu/cC7r1gkGdjIedzYecq4lxFA3w2PgIbPwYbPwEbPwUbPwO7PQdnC4ONi4n6ewG2eQm2eQW2eQ22eQO+77fgbBGwTXHRNu/ANu/BNh/ANh/BNp/A9/0ZnC0KtikR4LOxkPssLObei7v3EkGejSWdz6Wcq7RzlQnw2fgX2PgL2Pgr2Pgb2NiXw/tu34GzpcDGZUX9BcvhfZvgObxv830O79uEyOF9mx/A9x0SnC0Ntikn2iYU2CY02CYM2CYs2CYc+L7Dg7NlwDblA3w2lnSfhWXdezn3Xj7Is7GC87mic1VyrsoBPhsjgI0jgo0jgY0jg42jgN2igrMVwcZVRP1FA9tEB9vEANvEBNvEAt93bHC2EtimqmibOGCbuGCbeGCb+GCbBOD7TgjOVgbbVAvw2VjBfRZWce9V3Xu1IM/G6s7nGs5V07lqBfhs9IONE4GNE4ONk4CNk4LdkoGzNcDGtUX9JQfbpADbpATbpALbpAbfdxpwtibYpo5om7Rgm3Rgm/Rgmwxgm4zg+84EztYC29QN8NlY3X0W1nbvddx73SDPxnrO5/rO1cC5Ggb4bMwMNs4CNs4KNs4GNs4OdssBztYHGzcS9ZcTbJMLbJMbbJMHbJMXfN/5wNkGYJvGom3yg20KgG0Kgm0KgW0Kg++7CDjbEGzTJMBnYz33WdjIvTd2702CPBubOp+bOVdz52oR4LOxKNi4GNi4ONi4BNi4JPmfIYKzzcDGLUX9lQbblAHblAXblAPblAffdwVwtjnYppVom4pgm0pgm8pgmypgm6rg+64GzrYA27QO8NnY1H0WtnTvrdx76yDPxjbO57bO1c652gf4bKwONq4BNq4JNq4FNq4NdqsDzrYFG3cQ9VcXbFMPbFMfbNMAbNMQfN+NwNl2YJuOom0ag22agG2agm2agW2ak+cdONsebNMpwGdjG/dZ2MG9d3TvnYI8Gzs7n7s4V1fn6hbgs7El2LgV2Lg12LgN2LgtaQqc7QI27i7qrz3YpgPYpiPYphPYpjP5vsHZrmCbHqJtuoJtuoFtuoNteoBteoLvuxc42w1s0zPAZ2Nn91nY3b33cO89gzwbezmfeztXH+fqG+CzsTfYuA/YuC/YuB/YuD/YbQA42xts3E/U30CwzSCwzWCwzRCwzVDwfQ8DZ/uAbfqLthkOthkBthkJthkFthkNvu8x4GxfsM2AAJ+NvdxnYT/33t+9DwjybBzofB7kXIOda0iAz8axYONxYOPxYOMJYOOJYLdJ4OwgsPFQUX+TwTZTwDZTwTbTwDbTwfc9A5wdDLYZJtpmJthmFthmNthmDthmLvi+54GzQ8A2wwN8Ng50n4VD3fsw9z48yLNxhPN5pHONcq7RAT4b54ONF4CNF4KNF4GNF4PdloCzI8HGY0T9LQXbLAPb/Ai2WQ62WQG+75Xg7CiwzVjRNj+BbVaBbVaDbdaAbX4G3/dacHY02GZcgM/GEe6zcIx7H+vexwV5No53Pk9wronONSnAZ+M6sPF6sPEGsPEvYONfwW6/gbMTwMaTRf39DrbZCLb5A2zzJ9hmE/i+N4OzE8E2U0TbbAHbbAXbbAPbbAfb7ADf907y35uBbaYG+Gwc7z4LJ7v3Ke59apBn4zTn83TnmuFcMwN8Nu4CG+8GG+8BG+8FG+8Du+0HZ6eDjWeJ+jsAtjkItjkEtjkMtjkCvu+j5L//BtvMFm1zDGxzHGxzAmxzEmxzCnzfp8HZmWCbOQE+G6e5z8JZ7n22e58T5Nk41/k8z7nmO9eCAJ+NZ8DGZ8HG58DG58HGF8BuF8n/jAVsvFDU3yWwzWWwzRWwzVWwzTXwfV8HZ+eDbRaJtrkBtrkJtrkFtrkNtrkDvu+74OwCsM3iAJ+Nc91n4UL3vsi9Lw7ybFzifF7qXMuc68cAn433wMb3wcYPwMYPwcaPwG6PwdmlYOPlov6egG2egm2egW2eg21egO/7JTi7DGyzQrTNK7DNa7DNG7DNW7DNO/B9vwdnfwTbrAzw2bjEfRYud+8r3PvKIM/Gn5zPq5xrtXOt+W/PxuDu3f+vBN//9q8P4HtYBb6HnwP8Hn5y3T+799XufU2Q72Gt83mdc613rg1T/+d/n7Xu//s6977evW8I8u/zi/P5V+f6zbl+n/r//6/9+19+n7fvZt3U//9/RtD/un/6njZO9fyfYfrn+vvff6Phn+uPf/M/19///n8Y/rn+/Df/c/397/+n4Z9r07/5n+vvf/9Nhn+uzf/mf66///03G/65tvyb/7n+/vffYvjn2vpv/uf6+99/q+Gfa9u/+Z/ru0j/7/kVDP7XBYvk3bD932z4+59/u8EQHBh2CAw7DIbvgWGnwLDTYAgBDLsEhl0Gww/AsFtg2G0whASGPQLDHoMhFDDsFRj2GgyhgWGfwLDPYAgDDPsFhv0GQ1hgOCAwHDAYwgHDQYHhoMEQHhgOCQyHDIYIwHBYYDhsMEQEhiMCwxGDIRIwHBUYjhoMkYHhmMBwzGCIAgzHBYbjBkNUYDghMJwwGKIBw0mB4aTBEB0YTgkMpwyGGMBwWmA4bTDEBIYzAsMZgyEWMJwVGM4aDLGB4ZzAcM5giAMM5wWG8wZDXGC4IDBcMBjiAcNFgeGiwRAfGC4JDJcMhgTAcFlguGwwJASGKwLDFYPBDwxXBYarBkMiYLgmMFwzGBIDw3WB4brBkAQYbggMNwyGpMBwU2C4aTAkA4ZbAsMtgyE5MNwWGG4bDCmA4Y7AcMdgSAkMdwWGuwZDKmC4JzDcMxhSA8N9geG+wZAGGB4IDA8MhrTA8FBgeGgwpAOGRwLDI4MhPTA8FhgeGwwZgOGJwPDEYMgIDE8FhqcGQyZgeCYwPDMYMgPDc4HhucGQBRheCAwvDIaswPBSYHhpMGQDhlcCwyuDITswvBYYXhsMOYDhjcDwxmDICQxvBYa3BkMuYHgnMLwzGHIDw3uB4b3BkAcYPggMHwyGvMDwUWD4aDDkA4ZPAsMngyE/MHwWGD4bDAWA4S+B4S+DoSAwfBEYvhgMhYDhq8Dw1WAoDAzfBIZvBkMRYPBN+/cb/v7PoIaiwPCdwPCdwVAMGIIJDMEMhuLAEFxgCG4wlACG7wWG7w2GksAQQmAIYTCUAoYfBIYfDIbSwBBSYAhpMJQBhlACQyiDoSwwhBYYQhsM5YAhjMAQxmAoDwxhBYawBkMFYAgnMIQzGCoCQ3iBIbzBUAkYIggMEQyGysAQUWCIaDBUAYZIAkMkg6EqMEQWGCIbDNWAIYrAEMVgqA4MUQWGqAZDDWCIJjBEMxhqAkN0gSG6wVALGGIIDDEMhtrAEFNgiGkw1AGGWAJDLIOhLjDEFhhiGwz1gCGOwBDHYKgPDHEFhrgGQwNgiCcwxDMYGgJDfIEhvsHQCBgSCAwJDIbGwJBQYEhoMDQBBr/A4DcYmgJDIoEhkcHQDBgSCwyJDYbmwJBEYEhiMLQAhqQCQ1KDoSUwJBMYkhkMrYAhucCQ3GBoDQwpBIYUBkMbYEgpMKQ0GNoCQyqBIZXB0A4YUgsMqQ2G9sCQRmBIYzB0AIa0AkNag6EjMKQTGNIZDJ2AIb3AkN5g6AwMGQSGDAZDF2DIKDBkNBi6AkMmgSGTwdANGDILDJkNhu7AkEVgyGIw9ACGrAJDVoOhJzBkExiyGQy9gCG7wJDdYOgNDDkEhhwGQx9gyCkw5DQY+gJDLoEhl8HQDxhyCwy5DYb+wJBHYMhjMAwAhrwCQ16DYSAw5BMY8hkMg4Ahv8CQ32AYDAwFBIYCBsMQYCgoMBQ0GIYCQyGBoZDBMAwYCgsMhQ2G4cBQRGAoYjCMAIaiAkNRg2EkMBQTGIoZDKOAobjAUNxgGA0MJQSGEgbDGGAoKTCUNBjGAkMpgaGUwTAOGEoLDKUNhvHAUEZgKGMwTACGsgJDWYNhIjCUExjKGQyTgKG8wFDeYJgMDBUEhgoGwxRgqCgwVDQYpgJDJYGhksEwDRgqCwyVDYbpwFBFYKhiMMwAhqoCQ1WDYSYwVBMYqhkMs4ChusBQ3WCYDQw1BIYaBsMcYKgpMNQ0GOYCQy2BoZbBMA8YagsMtQ2G+cBQR2CoYzAsAIa6AkNdg2EhMNQTGOoZDIuAob7AUN9gWAwMDQSGBgbDEmBoKDA0NBiWAkMjgaGRwbAMGBoLDI0Nhh+BoYnA0MRgWA4MTQWGpgbDCmBoJjA0MxhWAkNzgaG5wfATMLQQGFoYDKuAoaXA0NJgWA0MrQSGVgbDGmBoLTC0Nhh+BoY2AkMbg2EtMLQVGNoaDOuAoZ3A0M5gWA8M7QWG9gbDBmDoIDB0MBh+AYaOAkNHg+FXYOgkMHQyGH4Dhs4CQ2eD4Xdg6CIwdDEYNgJDV4Ghq8HwBzB0Exi6GQx/AkN3gaG7wbAJGHoIDD0Mhs3A0FNg6GkwbAGGXgJDL4NhKzD0Fhh6GwzbgKGPwNDHYNgODH0Fhr4Gww5g6Ccw9DMYdgJDf4Ghv8GwCxgGCAwDDIbdwDBQYBhoMOwBhkECwyCDYS8wDBYYBhsM+4BhiMAwxGDYDwxDBYahBsMBYBgmMAwzGA4Cw3CBYbjBcAgYRggMIwyGw8AwUmAYaTAcAYZRAsMog+EoMIwWGEYbDMeAYYzAMMZgOA4MYwWGsQbDCWAYJzCMMxhOAsN4gWG8wXAKGCYIDBMMhtPAMFFgmGgwnAGGSQLDJIPhLDBMFhgmGwzngGGKwDDFYDgPDFMFhqkGwwVgmCYwTDMYLgLDdIFhusFwCRhmCAwzDIbLwDBTYJhpMFwBhlkCwyyD4SowzBYYZhsM14BhjsAwx2C4DgxzBYa5BsMNYJgnMMwzGG4Cw3yBYb7BcAsYFggMCwyG28CwUGBYaDDcAYZFAsMig+EuMCwWGBYbDPeAYYnAsMRguA8MSwWGpQbDA2BYJjAsMxgeAsOPAsOPBsMjYFguMCw3GB4DwwqBYYXB8AQYVgoMKw2Gp8Dwk8Dwk8HwDBhWCQyrDIbnwLBaYFhtMLwAhjUCwxqD4SUw/Cww/GwwvAKGtQLDWoPhNTCsExjWGQxvgGG9wLDeYHgLDBsEhg0Gwztg+EVg+MVgeA8MvwoMvxoMH4DhN4HhN4PhIzD8LjD8bjB8AoaNAsNGg+EzMPwhMPxhMPwFDH8KDH8aDF+AYZPAsMlg+AoMmwWGzQbDN2DYIjBsMRh8kb0btgoMWw2G74Bhm8CwzWAIBgzbBYbtBkNwYNghMOwwGL4Hhp0Cw06DIQQw7BIYdhkMPwDDboFht8EQEhj2CAx7DIZQwLBXYNhrMIQGhn0Cwz6DIQww7BcY9hsMYYHhgMBwwGAIBwwHBYaDBkN4YDgkMBwyGCIAw2GB4bDBEBEYjggMRwyGSMBwVGA4ajBEBoZjAsMxgyEKMBwXGI4bDFGB4YTAcMJgiAYMJwWGkwZDdGA4JTCcMhhiAMNpgeG0wRATGM4IDGcMhljAcFZgOGswxAaGcwLDOYMhDjCcFxjOGwxxgeGCwHDBYIgHDBcFhosGQ3xguCQwXDIYEgDDZYHhssGQEBiuCAxXDAY/MFwVGK4aDImA4ZrAcM1gSAwM1wWG6wZDEmC4ITDcMBiSAsNNgeGmwZAMGG4JDLcMhuTAcFtguG0wpACGOwLDHYMhJTDcFRjuGgypgOGewHDPYEgNDPcFhvsGQxpgeCAwPDAY0gLDQ4HhocGQDhgeCQyPDIb0wPBYYHhsMGQAhicCwxODISMwPBUYnhoMmYDhmcDwzGDIDAzPBYbnBkMWYHghMLwwGLICw0uB4aXBkA0YXgkMrwyG7MDwWmB4bTDkAIY3AsMbgyEnMLwVGN4aDLmA4Z3A8M5gyA0M7wWG9wZDHmD4IDB8MBjyAsNHgeGjwZAPGD4JDJ8MhvzA8Flg+GwwFACGvwSGvwyGgsDwRWD4YjAUAoavAsNXg6EwMHwTGL4ZDEWAwTf932/4+z+DGooCw3cCw3cGQzFgCCYwBDMYigNDcIEhuMFQAhi+Fxi+NxhKAkMIgSGEwVAKGH4QGH4wGEoDQ0iBIaTBUAYYQgkMoQyGssAQWmAIbTCUA4YwAkMYg6E8MIQVGMIaDBWAIZzAEM5gqAgM4QWG8AZDJWCIIDBEMBgqA0NEgSGiwVAFGCIJDJEMhqrAEFlgiGwwVAOGKAJDFIOhOjBEFRiiGgw1gCGawBDNYKgJDNEFhugGQy1giCEwxDAYagNDTIEhpsFQBxhiCQyxDIa6wBBbYIhtMNQDhjgCQxyDoT4wxBUY4hoMDYAhnsAQz2BoCAzxBYb4BkMjYEggMCQwGBoDQ0KBIaHB0AQY/AKD32BoCgyJBIZEBkMzYEgsMCQ2GJoDQxKBIYnB0AIYkgoMSQ2GlsCQTGBIZjC0AobkAkNyg6E1MKQQGFIYDG2AIaXAkNJgaAsMqQSGVAZDO2BILTCkNhjaA0MagSGNwdABGNIKDGkNho7AkE5gSGcwdAKG9AJDeoOhMzBkEBgyGAxdgCGjwJDRYOgKDJkEhkwGQzdgyCwwZDYYugNDFoEhi8HQAxiyCgxZDYaewJBNYMhmMPQChuwCQ3aDoTcw5BAYchgMfYAhp8CQ02DoCwy5BIZcBkM/YMgtMOQ2GPoDQx6BIY/BMAAY8goMeQ2GgcCQT2DIZzAMAob8AkN+g2EwMBQQGAoYDEOAoaDAUNBgGAoMhQSGQgbDMGAoLDAUNhiGA0MRgaGIwTACGIoKDEUNhpHAUExgKGYwjAKG4gJDcYNhNDCUEBhKGAxjgKGkwFDSYBgLDKUEhlIGwzhgKC0wlDYYxgNDGYGhjMEwARjKCgxlDYaJwFBOYChnMEwChvICQ3mDYTIwVBAYKhgMU4ChosBQ0WCYCgyVBIZKBsM0YKgsMFQ2GKYDQxWBoYrBMAMYqgoMVQ2GmcBQTWCoZjDMAobqAkN1g2E2MNQQGGoYDHOAoabAUNNgmAsMtQSGWgbDPGCoLTDUNhjmA0MdgaGOwbAAGOoKDHUNhoXAUE9gqGcwLAKG+gJDfYNhMTA0EBgaGAxLgKGhwNDQYFgKDI0EhkYGwzJgaCwwNDYYfgSGJgJDE4NhOTA0FRiaGgwrgKGZwNDMYFgJDM0FhuYGw0/A0EJgaGEwrAKGlgJDS4NhNTC0EhhaGQxrgKG1wNDaYPgZGNoIDG0MhrXA0FZgaGswrAOGdgJDO4NhPTC0FxjaGwwbgKGDwNDBYPgFGDoKDB0Nhl+BoZPA0Mlg+A0YOgsMnQ2G34Ghi8DQxWDYCAxdBYauBsMfwNBNYOhmMPwJDN0Fhu4GwyZg6CEw9DAYNgNDT4Ghp8GwBRh6CQy9DIatwNBbYOhtMGwDhj4CQx+DYTsw9BUY+hoMO4Chn8DQz2DYCQz9BYb+BsMuYBggMAwwGHYDw0CBYaDBsAcYBgkMgwyGvcAwWGAYbDDsA4YhAsMQg2E/MAwVGIYaDAeAYZjAMMxgOAgMwwWG4QbDIWAYITCMMBgOA8NIgWGkwXAEGEYJDKMMhqPAMFpgGG0wHAOGMQLDGIPhODCMFRjGGgwngGGcwDDOYDgJDOMFhvEGwylgmCAwTDAYTgPDRIFhosFwBhgmCQyTDIazwDBZYJhsMJwDhikCwxSD4TwwTBUYphoMF4BhmsAwzWC4CAzTBYbpBsMlYJghMMwwGC4Dw0yBYabBcAUYZgkMswyGq8AwW2CYbTBcA4Y5AsMcg+E6MMwVGOYaDDeAYZ7AMM9guAkM8wWG+QbDLWBYIDAsMBhuA8NCgWGhwXAHGBYJDIsMhrvAsFhgWGww3AOGJQLDEoPhPjAsFRiWGgwPgGGZwLDMYHgIDD8KDD8aDI+AYbnAsNxgeAwMKwSGFQbDE2BYKTCsNBieAsNPAsNPBsMzYFglMKwyGJ4Dw2qBYbXB8AIY1ggMawyGl8Dws8Dws8HwChjWCgxrDYbXwLBOYFhnMLwBhvUCw3qD4S0wbBAYNhgM74DhF4HhF4PhPTD8KjD8ajB8AIbfBIbfDIaPwPC7wPC7wfAJGDYKDBsNhs/A8IfA8IfB8Bcw/Ckw/GkwfAGGTQLDJoPhKzBsFhg2GwzfgGHLv9nwXTTnfWkqNwSL5t2wVbDDVsMOwYFhm8CwzWD4Hhi2CwzbDYYQwLBDYNhhMPwADDsFhp0GQ0hg2CUw7DIYQgHDboFht8EQGhj2CAx7DIYwwLBXYNhrMIQFhn0Cwz6DIRww7BcY9hsM4YHhgMBwwGCIAAwHBYaDBkNEYDgkMBwyGCIBw2GB4bDBEBkYjggMRwyGKMBwVGA4ajBEBYZjAsMxgyEaMBwXGI4bDNGB4YTAcMJgiAEMJwWGkwZDTGA4JTCcMhhiAcNpgeG0wRAbGM4IDGcMhjjAcFZgOGswxAWGcwLDOYMhHjCcFxjOGwzxgeGCwHDBYEgADBcFhosGQ0JguCQwXDIY/MBwWWC4bDAkAoYrAsMVgyExMFwVGK4aDEmA4ZrAcM1gSAoM1wWG6wZDMmC4ITDcMBiSA8NNgeGmwZACGG4JDLcMhpTAcFtguG0wpAKGOwLDHYMhNTDcFRjuGgxpgOGewHDPYEgLDPcFhvsGQzpgeCAwPDAY0gPDQ4HhocGQARgeCQyPDIaMwPBYYHhsMGQChicCwxODITMwPBUYnhoMWYDhmcDwzGDICgzPBYbnBkM2YHghMLwwGLIDw0uB4aXBkAMYXgkMrwyGnMDwWmB4bTDkAoY3AsMbgyE3MLwVGN4aDHmA4Z3A8M5gyAsM7wWG9wZDPmD4IDB8MBjyA8NHgeGjwVAAGD4JDJ8MhoLA8Flg+GwwFAKGvwSGvwyGwsDwRWD4YjAUAYavAsNXg6EoMHwTGL4ZDMWAwTfj32/4+z+DGooDw3cCw3cGQwlgCCYwBDMYSgJDcIEhuMFQChi+Fxi+NxhKA0MIgSGEwVAGGH4QGH4wGMoCQ0iBIaTBUA4YQgkMoQyG8sAQWmAIbTBUAIYwAkMYg6EiMIQVGMIaDJWAIZzAEM5gqAwM4QWG8AZDFWCIIDBEMBiqAkNEgSGiwVANGCIJDJEMhurAEFlgiGww1ACGKAJDFIOhJjBEFRiiGgy1gCGawBDNYKgNDNEFhugGQx1giCEwxDAY6gJDTIEhpsFQDxhiCQyxDIb6wBBbYIhtMDQAhjgCQxyDoSEwxBUY4hoMjYAhnsAQz2BoDAzxBYb4BkMTYEggMCQwGJoCQ0KBIaHB0AwY/AKD32BoDgyJBIZEBkMLYEgsMCQ2GFoCQxKBIYnB0AoYkgoMSQ2G1sCQTGBIZjC0AYbkAkNyg6EtMKQQGFIYDO2AIaXAkNJgaA8MqQSGVAZDB2BILTCkNhg6AkMagSGNwdAJGNIKDGkNhs7AkE5gSGcwdAGG9AJDeoOhKzBkEBgyGAzdgCGjwJDRYOgODJkEhkwGQw9gyCwwZDYYegJDFoEhi8HQCxiyCgxZDYbewJBNYMhmMPQBhuwCQ3aDoS8w5BAYchgM/YAhp8CQ02DoDwy5BIZcBsMAYMgtMOQ2GAYCQx6BIY/BMAgY8goMeQ2GwcCQT2DIZzAMAYb8AkN+g2EoMBQQGAoYDMOAoaDAUNBgGA4MhQSGQgbDCGAoLDAUNhhGAkMRgaGIwTAKGIoKDEUNhtHAUExgKGYwjAGG4gJDcYNhLDCUEBhKGAzjgKGkwFDSYBgPDKUEhlIGwwRgKC0wlDYYJgJDGYGhjMEwCRjKCgxlDYbJwFBOYChnMEwBhvICQ3mDYSowVBAYKhgM04ChosBQ0WCYDgyVBIZKBsMMYKgsMFQ2GGYCQxWBoYrBMAsYqgoMVQ2G2cBQTWCoZjDMAYbqAkN1g2EuMNQQGGoYDPOAoabAUNNgmA8MtQSGWgbDAmCoLTDUNhgWAkMdgaGOwbAIGOoKDHUNhsXAUE9gqGcwLAGG+gJDfYNhKTA0EBgaGAzLgKGhwNDQYPgRGBoJDI0MhuXA0FhgaGwwrACGJgJDE4NhJTA0FRiaGgw/AUMzgaGZwbAKGJoLDM0NhtXA0EJgaGEwrAGGlgJDS4PhZ2BoJTC0MhjWAkNrgaG1wbAOGNoIDG0MhvXA0FZgaGswbACGdgJDO4PhF2BoLzC0Nxh+BYYOAkMHg+E3YOgoMHQ0GH4Hhk4CQyeDYSMwdBYYOhsMfwBDF4Ghi8HwJzB0FRi6GgybgKGbwNDNYNgMDN0Fhu4GwxZg6CEw9DAYtgJDT4Ghp8GwDRh6CQy9DIbtwNBbYOhtMOwAhj4CQx+DYScw9BUY+hoMu4Chn8DQz2DYDQz9BYb+BsMeYBggMAwwGPYCw0CBYaDBsA8YBgkMgwyG/cAwWGAYbDAcAIYhAsMQg+EgMAwVGIYaDIeAYZjAMMxgOAwMwwWG4QbDEWAYITCMMBiOAsNIgWGkwXAMGEYJDKMMhuPAMFpgGG0wnACGMQLDGIPhJDCMFRjGGgyngGGcwDDOYDgNDOMFhvEGwxlgmCAwTDAYzgLDRIFhosFwDhgmCQyTDIbzwDBZYJhsMFwAhikCwxSD4SIwTBUYphoMl4BhmsAwzWC4DAzTBYbpBsMVYJghMMwwGK4Cw0yBYabBcA0YZgkMswyG68AwW2CYbTDcAIY5AsMcg+EmMMwVGOYaDLeAYZ7AMM9guA0M8wWG+QbDHWBYIDAsMBjuAsNCgWGhwXAPGBYJDIsMhvvAsFhgWGwwPACGJQLDEoPhITAsFRiWGgyPgGGZwLDMYHgMDD8KDD8aDE+AYbnAsNxgeAoMKwSGFQbDM2BYKTCsNBieA8NPAsNPBsMLYFglMKwyGF4Cw2qBYbXB8AoY1ggMawyG18Dws8Dws8HwBhjWCgxrDYa3wLBOYFhnMLwDhvUCw3qD4T0wbBAYNhgMH4DhF4HhF4PhIzD8KjD8ajB8AobfBIbfDIbPwPC7wPC7wfAXMGwUGDYaDF+A4Q+B4Q+D4Ssw/Ckw/GkwfAOGTQLDJoPBF927YbPAsNlg+A4YtggMWwyGYMCwVWDYajAEB4ZtAsM2g+F7YNguMGw3GEIAww6BYYfB8AMw7BQYdhoMIYFhl8Cwy2AIBQy7BYbdBkNoYNgjMOwxGMIAw16BYa/BEBYY9gkM+wyGcMCwX2DYbzCEB4YDAsMBgyECMBwUGA4aDBGB4ZDAcMhgiAQMhwWGwwZDZGA4IjAcMRiiAMNRgeGowRAVGI4JDMcMhmjAcFxgOG4wRAeGEwLDCYMhBjCcFBhOGgwxgeGUwHDKYIgFDKcFhtMGQ2xgOCMwnDEY4gDDWYHhrMEQFxjOCQznDIZ4wHBeYDhvMMQHhgsCwwWDIQEwXBQYLhoMCYHhksBwyWDwA8NlgeGywZAIGK4IDFcMhsTAcFVguGowJAGGawLDNYMhKTBcFxiuGwzJgOGGwHDDYEgODDcFhpsGQwpguCUw3DIYUgLDbYHhtsGQChjuCAx3DIbUwHBXYLhrMKQBhnsCwz2DIS0w3BcY7hsM6YDhgcDwwGBIDwwPBYaHBkMGYHgkMDwyGDICw2OB4bHBkAkYnggMTwyGzMDwVGB4ajBkAYZnAsMzgyErMDwXGJ4bDNmA4YXA8MJgyA4MLwWGlwZDDmB4JTC8MhhyAsNrgeG1wZALGN4IDG8MhtzA8FZgeGsw5AGGdwLDO4MhLzC8FxjeGwz5gOGDwPDBYMgPDB8Fho8GQwFg+CQwfDIYCgLDZ4Hhs8FQCBj+Ehj+MhgKA8MXgeGLwVAEGL4KDF8NhqLA8E1g+GYwFAMG38x/v+Hv/wxqKA4M3wkM3xkMJYAhmMAQzGAoCQzBBYbgBkMpYPheYPjeYCgNDCEEhhAGQxlg+EFg+MFgKAsMIQWGkAZDOWAIJTCEMhjKA0NogSG0wVABGMIIDGEMhorAEFZgCGswVAKGcAJDOIOhMjCEFxjCGwxVgCGCwBDBYKgKDBEFhogGQzVgiCQwRDIYqgNDZIEhssFQAxiiCAxRDIaawBBVYIhqMNQChmgCQzSDoTYwRBcYohsMdYAhhsAQw2CoCwwxBYaYBkM9YIglMMQyGOoDQ2yBIbbB0AAY4ggMcQyGhsAQV2CIazA0AoZ4AkM8g6ExMMQXGOIbDE2AIYHAkMBgaAoMCQWGhAZDM2DwCwx+g6E5MCQSGBIZDC2AIbHAkNhgaAkMSQSGJAZDK2BIKjAkNRhaA0MygSGZwdAGGJILDMkNhrbAkEJgSGEwtAOGlAJDSoOhPTCkEhhSGQwdgCG1wJDaYOgIDGkEhjQGQydgSCswpDUYOgNDOoEhncHQBRjSCwzpDYauwJBBYMhgMHQDhowCQ0aDoTswZBIYMhkMPYAhs8CQ2WDoCQxZBIYsBkMvYMgqMGQ1GHoDQzaBIZvB0AcYsgsM2Q2GvsCQQ2DIYTD0A4acAkNOg6E/MOQSGHIZDAOAIbfAkNtgGAgMeQSGPAbDIGDIKzDkNRgGA0M+gSGfwTAEGPILDPkNhqHAUEBgKGAwDAOGggJDQYNhODAUEhgKGQwjgKGwwFDYYBgJDEUEhiIGwyhgKCowFDUYRgNDMYGhmMEwBhiKCwzFDYaxwFBCYChhMIwDhpICQ0mDYTwwlBIYShkME4ChtMBQ2mCYCAxlBIYyBsMkYCgrMJQ1GCYDQzmBoZzBMAUYygsM5Q2GqcBQQWCoYDBMA4aKAkNFg2E6MFQSGCoZDDOAobLAUNlgmAkMVQSGKgbDLGCoKjBUNRhmA0M1gaGawTAHGKoLDNUNhrnAUENgqGEwzAOGmgJDTYNhPjDUEhhqGQwLgKG2wFDbYFgIDHUEhjoGwyJgqCsw1DUYFgNDPYGhnsGwBBjqCwz1DYalwNBAYGhgMCwDhoYCQ0OD4UdgaCQwNDIYlgNDY4GhscGwAhiaCAxNDIaVwNBUYGhqMPwEDM0EhmYGwypgaC4wNDcYVgNDC4GhhcGwBhhaCgwtDYafgaGVwNDKYFgLDK0FhtYGwzpgaCMwtDEY1gNDW4GhrcGwARjaCQztDIZfgKG9wNDeYPgVGDoIDB0Mht+AoaPA0NFg+B0YOgkMnQyGjcDQWWDobDD8AQxdBIYuBsOfwNBVYOhqMGwChm4CQzeDYTMwdBcYuhsMW4Chh8DQw2DYCgw9BYaeBsM2YOglMPQyGLYDQ2+BobfBsAMY+ggMfQyGncDQV2DoazDsAoZ+AkM/g2E3MPQXGPobDHuAYYDAMMBg2AsMAwWGgQbDPmAYJDAMMhj2A8NggWGwwXAAGIYIDEMMhoPAMFRgGGowHAKGYQLDMIPhMDAMFxiGGwxHgGGEwDDCYDgKDCMFhpEGwzFgGCUwjDIYjgPDaIFhtMFwAhjGCAxjDIaTwDBWYBhrMJwChnECwziD4TQwjBcYxhsMZ4BhgsAwwWA4CwwTBYaJBsM5YJgkMEwyGM4Dw2SBYbLBcAEYpggMUwyGi8AwVWCYajBcAoZpAsM0g+EyMEwXGKYbDFeAYYbAMMNguAoMMwWGmQbDNWCYJTDMMhiuA8NsgWG2wXADGOYIDHMMhpvAMFdgmGsw3AKGeQLDPIPhNjDMFxjmGwx3gGGBwLDAYLgLDAsFhoUGwz1gWCQwLDIY7gPDYoFhscHwABiWCAxLDIaHwLBUYFhqMDwChmUCwzKD4TEw/Cgw/GgwPAGG5QLDcoPhKTCsEBhWGAzPgGGlwLDSYHgODD8JDD8ZDC+AYZXAsMpgeAkMqwWG1QbDK2BYIzCsMRheA8PPAsPPBsMbYFgrMKw1GN4CwzqBYZ3B8A4Y1gsM6w2G98CwQWDYYDB8AIZfBIZfDIaPwPCrwPCrwfAJGH4TGH4zGD4Dw+8Cw+8Gw1/AsFFg2GgwfAGGPwSGPwyGr8Dwp8Dwp8HwDRg2/ZsN3yVw/k5P5YZgCbwbNgt22GzYITgwbBEYthgM3wPDVoFhq8EQAhi2CQzbDIYfgGG7wLDdYAgJDDsEhh0GQyhg2Ckw7DQYQgPDLoFhl8EQBhh2Cwy7DYawwLBHYNhjMIQDhr0Cw16DITww7BMY9hkMEYBhv8Cw32CICAwHBIYDBkMkYDgoMBw0GCIDwyGB4ZDBEAUYDgsMhw2GqMBwRGA4YjBEA4ajAsNRgyE6MBwTGI4ZDDGA4bjAcNxgiAkMJwSGEwZDLGA4KTCcNBhiA8MpgeGUwRAHGE4LDKcNhrjAcEZgOGMwxAOGswLDWYMhPjCcExjOGQwJgOG8wHDeYEgIDBcEhgsGgx8YLgoMFw2GRMBwSWC4ZDAkBobLAsNlgyEJMFwRGK4YDEmB4arAcNVgSAYM1wSGawZDcmC4LjBcNxhSAMMNgeGGwZASGG4KDDcNhlTAcEtguGUwpAaG2wLDbYMhDTDcERjuGAxpgeGuwHDXYEgHDPcEhnsGQ3pguC8w3DcYMgDDA4HhgcGQERgeCgwPDYZMwPBIYHhkMGQGhscCw2ODIQswPBEYnhgMWYHhqcDw1GDIBgzPBIZnBkN2YHguMDw3GHIAwwuB4YXBkBMYXgoMLw2GXMDwSmB4ZTDkBobXAsNrgyEPMLwRGN4YDHmB4a3A8NZgyAcM7wSGdwZDfmB4LzC8NxgKAMMHgeGDwVAQGD4KDB8NhkLA8Elg+GQwFAaGzwLDZ4OhCDD8JTD8ZTAUBYYvAsMXg6EYMHwVGL4aDMWB4ZvA8M1gKAEMvln/fsPf/xnUUBIYvhMYvjMYSgFDMIEhmMFQGhiCCwzBDYYywPC9wPC9wVAWGEIIDCEMhnLA8IPA8IPBUB4YQgoMIQ2GCsAQSmAIZTBUBIbQAkNog6ESMIQRGMIYDJWBIazAENZgqAIM4QSGcAZDVWAILzCENxiqAUMEgSGCwVAdGCIKDBENhhrAEElgiGQw1ASGyAJDZIOhFjBEERiiGAy1gSGqwBDVYKgDDNEEhmgGQ11giC4wRDcY6gFDDIEhhsFQHxhiCgwxDYYGwBBLYIhlMDQEhtgCQ2yDoREwxBEY4hgMjYEhrsAQ12BoAgzxBIZ4BkNTYIgvMMQ3GJoBQwKBIYHB0BwYEgoMCQ2GFsDgFxj8BkNLYEgkMCQyGFoBQ2KBIbHB0BoYkggMSQyGNsCQVGBIajC0BYZkAkMyg6EdMCQXGJIbDO2BIYXAkMJg6AAMKQWGlAZDR2BIJTCkMhg6AUNqgSG1wdAZGNIIDGkMhi7AkFZgSGswdAWGdAJDOoOhGzCkFxjSGwzdgSGDwJDBYOgBDBkFhowGQ09gyCQwZDIYegFDZoEhs8HQGxiyCAxZDIY+wJBVYMhqMPQFhmwCQzaDoR8wZBcYshsM/YEhh8CQw2AYAAw5BYacBsNAYMglMOQyGAYBQ26BIbfBMBgY8ggMeQyGIcCQV2DIazAMBYZ8AkM+g2EYMOQXGPIbDMOBoYDAUMBgGAEMBQWGggbDSGAoJDAUMhhGAUNhgaGwwTAaGIoIDEUMhjHAUFRgKGowjAWGYgJDMYNhHDAUFxiKGwzjgaGEwFDCYJgADCUFhpIGw0RgKCUwlDIYJgFDaYGhtMEwGRjKCAxlDIYpwFBWYChrMEwFhnICQzmDYRowlBcYyhsM04GhgsBQwWCYAQwVBYaKBsNMYKgkMFQyGGYBQ2WBobLBMBsYqggMVQyGOcBQVWCoajDMBYZqAkM1g2EeMFQXGKobDPOBoYbAUMNgWAAMNQWGmgbDQmCoJTDUMhgWAUNtgaG2wbAYGOoIDHUMhiXAUFdgqGswLAWGegJDPYNhGTDUFxjqGww/AkMDgaGBwbAcGBoKDA0NhhXA0EhgaGQwrASGxgJDY4PhJ2BoIjA0MRhWAUNTgaGpwbAaGJoJDM0MhjXA0FxgaG4w/AwMLQSGFgbDWmBoKTC0NBjWAUMrgaGVwbAeGFoLDK0Nhg3A0EZgaGMw/AIMbQWGtgbDr8DQTmBoZzD8BgztBYb2BsPvwNBBYOhgMGwEho4CQ0eD4Q9g6CQwdDIY/gSGzgJDZ4NhEzB0ERi6GAybgaGrwNDVYNgCDN0Ehm4Gw1Zg6C4wdDcYtgFDD4Ghh8GwHRh6Cgw9DYYdwNBLYOhlMOwEht4CQ2+DYRcw9BEY+hgMu4Ghr8DQ12DYAwz9BIZ+BsNeYOgvMPQ3GPYBwwCBYYDBsB8YBgoMAw2GA8AwSGAYZDAcBIbBAsNgg+EQMAwRGIYYDIeBYajAMNRgOAIMwwSGYQbDUWAYLjAMNxiOAcMIgWGEwXAcGEYKDCMNhhPAMEpgGGUwnASG0QLDaIPhFDCMERjGGAyngWGswDDWYDgDDOMEhnEGw1lgGC8wjDcYzgHDBIFhgsFwHhgmCgwTDYYLwDBJYJhkMFwEhskCw2SD4RIwTBEYphgMl4FhqsAw1WC4AgzTBIZpBsNVYJguMEw3GK4BwwyBYYbBcB0YZgoMMw2GG8AwS2CYZTDcBIbZAsNsg+EWMMwRGOYYDLeBYa7AMNdguAMM8wSGeQbDXWCYLzDMNxjuAcMCgWGBwXAfGBYKDAsNhgfAsEhgWGQwPASGxQLDYoPhETAsERiWGAyPgWGpwLDUYHgCDMsEhmUGw1Ng+FFg+NFgeAYMywWG5QbDc2BYITCsMBheAMNKgWGlwfASGH4SGH4yGF4BwyqBYZXB8BoYVgsMqw2GN8CwRmBYYzC8BYafBYafDYZ3wLBWYFhrMLwHhnUCwzqD4QMwrBcY1hsMH4Fhg8CwwWD4BAy/CAy/GAyfgeFXgeFXg+EvYPhNYPjNYPgCDL8LDL8bDF+BYaPAsNFg+AYMfwgMfxgMvoTeDX8KDH8aDN8BwyaBYZPBEAwYNgsMmw2G4MCwRWDYYjB8DwxbBYatBkMIYNgmMGwzGH4Ahu0Cw3aDISQw7BAYdhgMoYBhp8Cw02AIDQy7BIZdBkMYYNgtMOw2GMICwx6BYY/BEA4Y9goMew2G8MCwT2DYZzBEAIb9AsN+gyEiMBwQGA4YDJGA4aDAcNBgiAwMhwSGQwZDFGA4LDAcNhiiAsMRgeGIwRANGI4KDEcNhujAcExgOGYwxACG4wLDcYMhJjCcEBhOGAyxgOGkwHDSYIgNDKcEhlMGQxxgOC0wnDYY4gLDGYHhjMEQDxjOCgxnDYb4wHBOYDhnMCQAhvMCw3mDISEwXBAYLhgMfmC4KDBcNBgSAcMlgeGSwZAYGC4LDJcNhiTAcEVguGIwJAWGqwLDVYMhGTBcExiuGQzJgeG6wHDdYEgBDDcEhhsGQ0pguCkw3DQYUgHDLYHhlsGQGhhuCwy3DYY0wHBHYLhjMKQFhrsCw12DIR0w3BMY7hkM6YHhvsBw32DIAAwPBIYHBkNGYHgoMDw0GDIBwyOB4ZHBkBkYHgsMjw2GLMDwRGB4YjBkBYanAsNTgyEbMDwTGJ4ZDNmB4bnA8NxgyAEMLwSGFwZDTmB4KTC8NBhyAcMrgeGVwZAbGF4LDK8NhjzA8EZgeGMw5AWGtwLDW4MhHzC8ExjeGQz5geG9wPDeYCgADB8Ehg8GQ0Fg+CgwfDQYCgHDJ4Hhk8FQGBg+CwyfDYYiwPCXwPCXwVAUGL4IDF8MhmLA8FVg+GowFAeGbwLDN4OhBDD4Zv/7DX//Z1BDSWD4TmD4zmAoBQzBBIZgBkNpYAguMAQ3GMoAw/cCw/cGQ1lgCCEwhDAYygHDDwLDDwZDeWAIKTCENBgqAEMogSGUwVARGEILDKENhkrAEEZgCGMwVAaGsAJDWIOhCjCEExjCGQxVgSG8wBDeYKgGDBEEhggGQ3VgiCgwRDQYagBDJIEhksFQExgiCwyRDYZawBBFYIhiMNQGhqgCQ1SDoQ4wRBMYohkMdYEhusAQ3WCoBwwxBIYYBkN9YIgpMMQ0GBoAQyyBIZbB0BAYYgsMsQ2GRsAQR2CIYzA0Boa4AkNcg6EJMMQTGOIZDE2BIb7AEN9gaAYMCQSGBAZDc2BIKDAkNBhaAINfYPAbDC2BIZHAkMhgaAUMiQWGxAZDa2BIIjAkMRjaAENSgSGpwdAWGJIJDMkMhnbAkFxgSG4wtAeGFAJDCoOhAzCkFBhSGgwdgSGVwJDKYOgEDKkFhtQGQ2dgSCMwpDEYugBDWoEhrcHQFRjSCQzpDIZuwJBeYEhvMHQHhgwCQwaDoQcwZBQYMhoMPYEhk8CQyWDoBQyZBYbMBkNvYMgiMGQxGPoAQ1aBIavB0BcYsgkM2QyGfsCQXWDIbjD0B4YcAkMOg2EAMOQUGHIaDAOBIZfAkMtgGAQMuQWG3AbDYGDIIzDkMRiGAENegSGvwTAUGPIJDPkMhmHAkF9gyG8wDAeGAgJDAYNhBDAUFBgKGgwjgaGQwFDIYBgFDIUFhsIGw2hgKCIwFDEYxgBDUYGhqMEwFhiKCQzFDIZxwFBcYChuMIwHhhICQwmDYQIwlBQYShoME4GhlMBQymCYBAylBYbSBsNkYCgjMJQxGKYAQ1mBoazBMBUYygkM5QyGacBQXmAobzBMB4YKAkMFg2EGMFQUGCoaDDOBoZLAUMlgmAUMlQWGygbDbGCoIjBUMRjmAENVgaGqwTAXGKoJDNUMhnnAUF1gqG4wzAeGGgJDDYNhATDUFBhqGgwLgaGWwFDLYFgEDLUFhtoGw2JgqCMw1DEYlgBDXYGhrsGwFBjqCQz1DIZlwFBfYKhvMPwIDA0EhgYGw3JgaCgwNDQYVgBDI4GhkcGwEhgaCwyNDYafgKGJwNDEYFgFDE0FhqYGw2pgaCYwNDMY1gBDc4GhucHwMzC0EBhaGAxrgaGlwNDSYFgHDK0EhlYGw3pgaC0wtDYYNgBDG4GhjcHwCzC0FRjaGgy/AkM7gaGdwfAbMLQXGNobDL8DQweBoYPBsBEYOgoMHQ2GP4Chk8DQyWD4Exg6CwydDYZNwNBFYOhiMGwGhq4CQ1eDYQswdBMYuhkMW4Ghu8DQ3WDYBgw9BIYeBsN2YOgpMPQ0GHYAQy+BoZfBsBMYegsMvQ2GXcDQR2DoYzDsBoa+AkNfg2EPMPQTGPoZDHuBob/A0N9g2AcMAwSGAQbDfmAYKDAMNBgOAMMggWGQwXAQGAYLDIMNhkPAMERgGGIwHAaGoQLDUIPhCDAMExiGGQxHgWG4wDDcYDgGDCMEhhEGw3FgGCkwjDQYTgDDKIFhlMFwEhhGCwyjDYZTwDBGYBhjMJwGhrECw1iD4QwwjBMYxhkMZ4FhvMAw3mA4BwwTBIYJBsN5YJgoMEw0GC4AwySBYZLBcBEYJgsMkw2GS8AwRWCYYjBcBoapAsNUg+EKMEwTGKYZDFeBYbrAMN1guAYMMwSGGQbDdWCYKTDMNBhuAMMsgWGWwXATGGYLDLMNhlvAMEdgmGMw3AaGuQLDXIPhDjDMExjmGQx3gWG+wDDfYLgHDAsEhgUGw31gWCgwLDQYHgDDIoFhkcHwEBgWCwyLDYZHwLBEYFhiMDwGhqUCw1KD4QkwLBMYlhkMT4HhR4HhR4PhGTAsFxiWGwzPgWGFwLDCYHgBDCsFhpUGw0tg+Elg+MlgeAUMqwSGVQbDa2BYLTCsNhjeAMMagWGNwfAWGH4WGH42GN4Bw1qBYa3B8B4Y1gkM6wyGD8CwXmBYbzB8BIYNAsMGg+ETMPwiMPxiMHwGhl8Fhl8Nhr+A4TeB4TeD4Qsw/C4w/G4wfAWGjQLDRoPhGzD88W82/H3+bwc1BPN5N/wp2OFPww7Bfd4NmwSGTQbD9z7vhs0Cw2aDIYTPu2GLwLDFYPjB592wVWDYajCE9Hk3bBMYthkMoXzeDdsFhu0GQ2ifd8MOgWGHwRDG592wU2DYaTCE9Xk37BIYdhkM4XzeDbsFht0GQ3ifd8MegWGPwRDB592wV2DYazBE9Hk37BMY9hkMkXzeDfsFhv0GQ2Sfd8MBgeGAwRDF591wUGA4aDBE9Xk3HBIYDhkM0XzeDYcFhsMGQ3Sfd8MRgeGIwRDD591wVGA4ajDE9Hk3HBMYjhkMsXzeDccFhuMGQ2yfd8MJgeGEwRDH591wUmA4aTDE9Xk3nBIYThkM8XzeDacFhtMGQ3yfd8MZgeGMwZDA591wVmA4azAk9Hk3nBMYzhkMfp93w3mB4bzBkMjn3XBBYLhgMCT2eTdcFBguGgxJfN4NlwSGSwZDUp93w2WB4bLBkMzn3XBFYLhiMCT3eTdcFRiuGgwpfN4N1wSGawZDSp93w3WB4brBkMrn3XBDYLhhMKT2eTfcFBhuGgxpfN4NtwSGWwZDWp93w22B4bbBkM7n3XBHYLhjMKT3eTfcFRjuGgwZfN4N9wSGewZDRp93w32B4b7BkMnn3fBAYHhgMGT2eTc8FBgeGgxZfN4NjwSGRwZDVp93w2OB4bHBkM3n3fBEYHhiMGT3eTc8FRieGgw5fN4NzwSGZwZDTp93w3OB4bnBkMvn3fBCYHhhMOT2eTe8FBheGgx5fN4NrwSGVwZDXp93w2uB4bXBkM/n3fBGYHhjMOT3eTe8FRjeGgwFfN4N7wSGdwZDQZ93w3uB4b3BUMjn3fBBYPhgMBT2eTd8FBg+GgxFfN4NnwSGTwZDUZ93w2eB4bPBUMzn3fCXwPCXwVDc593wRWD4YjCU8Hk3fBUYvhoMJX3eDd8Ehm8GQymfd4Nvzr/f8Pd/BjWU9nk3fCcwfGcwlPF5NwQTGIIZDGV93g3BBYbgBkM5n3fD9wLD9wZDeZ93QwiBIYTBUMHn3fCDwPCDwVDR590QUmAIaTBU8nk3hBIYQhkMlX3eDaEFhtAGQxWfd0MYgSGMwVDV590QVmAIazBU83k3hBMYwhkM1X3eDeEFhvAGQw2fd0MEgSGCwVDT590QUWCIaDDU8nk3RBIYIhkMtX3eDZEFhsgGQx2fd0MUgSGKwVDX590QVWCIajDU83k3RBMYohkM9X3eDdEFhugGQwOfd0MMgSGGwdDQ590QU2CIaTA08nk3xBIYYhkMjX3eDbEFhtgGQxOfd0McgSGOwdDU590QV2CIazA083k3xBMY4hkMzX3eDfEFhvgGQwufd0MCgSGBwdDS592QUGBIaDC08nk3+AUGv8HQ2ufdkEhgSGQwtPF5NyQWGBIbDG193g1JBIYkBkM7n3dDUoEhqcHQ3ufdkExgSGYwdPB5NyQXGJIbDB193g0pBIYUBkMnn3dDSoEhpcHQ2efdkEpgSGUwdPF5N6QWGFIbDF193g1pBIY0BkM3n3dDWoEhrcHQ3efdkE5gSGcw9PB5N6QXGNIbDD193g0ZBIYMBkMvn3dDRoEho8HQ2+fdkElgyGQw9PF5N2QWGDIbDH193g1ZBIYsBkM/n3dDVoEhq8HQ3+fdkE1gyGYwDPB5N2QXGLIbDAN93g05BIYcBsMgn3dDToEhp8Ew2OfdkEtgyGUwDPF5N+QWGHIbDEN93g15BIY8BsMwn3dDXoEhr8Ew3OfdkE9gyGcwjPB5N+QXGPIbDCN93g0FBIYCBsMon3dDQYGhoMEw2ufdUEhgKGQwjPF5NxQWGAobDGN93g1FBIYiBsM4n3dDUYGhqMEw3ufdUExgKGYwTPB5NxQXGIobDBN93g0lBIYSBsMkn3dDSYGhpMEw2efdUEpgKGUwTPF5N5QWGEobDFN93g1lBIYyBsM0n3dDWYGhrMEw3efdUE5gKGcwzPB5N5QXGMobDDN93g0VBIYKBsMsn3dDRYGhosEw2+fdUElgqGQwzPF5N1QWGCobDHN93g1VBIYqBsM8n3dDVYGhqsEw3+fdUE1gqGYwLPB5N1QXGKobDAt93g01BIYaBsMin3dDTYGhpsGw2OfdUEtgqGUwLPF5N9QWGGobDEt93g11BIY6BsMyn3dDXYGhrsHwo8+7oZ7AUM9gWO7zbqgvMNQ3GFb4vBsaCAwNDIaVPu+GhgJDQ4PhJ593QyOBoZHBsMrn3dBYYGhsMKz2eTc0ERiaGAxrfN4NTQWGpgbDzz7vhmYCQzODYa3Pu6G5wNDcYFjn825oITC0MBjW+7wbWgoMLQ2GDT7vhlYCQyuD4Refd0NrgaG1wfCrz7uhjcDQxmD4zefd0FZgaGsw/O7zbmgnMLQzGDb6vBvaCwztDYY/fN4NHQSGDgbDnz7vho4CQ0eDYZPPu6GTwNDJYNjs827oLDB0Nhi2+LwbuggMXQyGrT7vhq4CQ1eDYZvPu6GbwNDNYNju827oLjB0Nxh2+LwbeggMPQyGnT7vhp4CQ0+DYZfPu6GXwNDLYNjt827oLTD0Nhj2+Lwb+ggMfQyGvT7vhr4CQ1+DYZ/Pu6GfwNDPYNjv827oLzD0NxgO+LwbBggMAwyGgz7vhoECw0CD4ZDPu2GQwDDIYDjs824YLDAMNhiO+LwbhggMQwyGoz7vhqECw1CD4ZjPu2GYwDDMYDju824YLjAMNxhO+LwbRggMIwyGkz7vhpECw0iD4ZTPu2GUwDDKYDjt824YLTCMNhjO+LwbxggMYwyGsz7vhrECw1iD4ZzPu2GcwDDOYDjv824YLzCMNxgu+LwbJggMEwyGiz7vhokCw0SD4ZLPu2GSwDDJYLjs826YLDBMNhiu+LwbpggMUwyGqz7vhqkCw1SD4ZrPu2GawDDNYLju826YLjBMNxhu+LwbZggMMwyGmz7vhpkCw0yD4ZbPu2GWwDDLYLjt826YLTDMNhju+Lwb5ggMcwyGuz7vhrkCw1yD4Z7Pu2GewDDPYLjv826YLzDMNxge+LwbFggMCwyGhz7vhoUCw0KD4ZHPu2GRwLDIYHjs825YLDAsNhie+LwblggMSwyGpz7vhqUCw1KD4ZnPu2GZwLDMYHju8274UWD40WB44fNuWC4wLDcYXvq8G1YIDCsMhlc+74aVAsNKg+G1z7vhJ4HhJ4Phjc+7YZXAsMpgeOvzblgtMKw2GN75vBvWCAxrDIb3Pu+GnwWGnw2GDz7vhrUCw1qD4aPPu2GdwLDOYPjk825YLzCsNxg++7wbNggMGwyGv3zeDb8IDL8YDF983g2/Cgy/Ggxffd4NvwkMvxkM33zeDb8LDL8bDH//B/3n2X8ybBQYNhoM3wHDHwLDHwZDMGD4U2D402AIDgybBIZNBsP3wLBZYNhsMIQAhi0CwxaD4Qdg2CowbDUYQgLDNoFhm8EQChi2CwzbDYbQwLBDYNhhMIQBhp0Cw06DISww7BIYdhkM4YBht8Cw22AIDwx7BIY9BkMEYNgrMOw1GCICwz6BYZ/BEAkY9gsM+w2GyMBwQGA4YDBEAYaDAsNBgyEqMBwSGA4ZDNGA4bDAcNhgiA4MRwSGIwZDDGA4KjAcNRhiAsMxgeGYwRALGI4LDMcNhtjAcEJgOGEwxAGGkwLDSYMhLjCcEhhOGQzxgOG0wHDaYIgPDGcEhjMGQwJgOCswnDUYEgLDOYHhnMHgB4bzAsN5gyERMFwQGC4YDImB4aLAcNFgSAIMlwSGSwZDUmC4LDBcNhiSAcMVgeGKwZAcGK4KDFcNhhTAcE1guGYwpASG6wLDdYMhFTDcEBhuGAypgeGmwHDTYEgDDLcEhlsGQ1pguC0w3DYY0gHDHYHhjsGQHhjuCgx3DYYMwHBPYLhnMGQEhvsCw32DIRMwPBAYHhgMmYHhocDw0GDIAgyPBIZHBkNWYHgsMDw2GLIBwxOB4YnBkB0YngoMTw2GHMDwTGB4ZjDkBIbnAsNzgyEXMLwQGF4YDLmB4aXA8NJgyAMMrwSGVwZDXmB4LTC8NhjyAcMbgeGNwZAfGN4KDG8NhgLA8E5geGcwFASG9wLDe4OhEDB8EBg+GAyFgeGjwPDRYCgCDJ8Ehk8GQ1Fg+CwwfDYYigHDXwLDXwZDcWD4IjB8MRhKAMNXgeGrwVASGL4JDN8MhlLA4Jv77zf8/Z9BDaWB4TuB4TuDoQwwBBMYghkMZYEhuMAQ3GAoBwzfCwzfGwzlgSGEwBDCYKgADD8IDD8YDBWBIaTAENJgqAQMoQSGUAZDZWAILTCENhiqAEMYgSGMwVAVGMIKDGENhmrAEE5gCGcwVAeG8AJDeIOhBjBEEBgiGAw1gSGiwBDRYKgFDJEEhkgGQ21giCwwRDYY6gBDFIEhisFQFxiiCgxRDYZ6wBBNYIhmMNQHhugCQ3SDoQEwxBAYYhgMDYEhpsAQ02BoBAyxBIZYBkNjYIgtMMQ2GJoAQxyBIY7B0BQY4goMcQ2GZsAQT2CIZzA0B4b4AkN8g6EFMCQQGBIYDC2BIaHAkNBgaAUMfoHBbzC0BoZEAkMig6ENMCQWGBIbDG2BIYnAkMRgaAcMSQWGpAZDe2BIJjAkMxg6AENygSG5wdARGFIIDCkMhk7AkFJgSGkwdAaGVAJDKoOhCzCkFhhSGwxdgSGNwJDGYOgGDGkFhrQGQ3dgSCcwpDMYegBDeoEhvcHQExgyCAwZDIZewJBRYMhoMPQGhkwCQyaDoQ8wZBYYMhsMfYEhi8CQxWDoBwxZBYasBkN/YMgmMGQzGAYAQ3aBIbvBMBAYcggMOQyGQcCQU2DIaTAMBoZcAkMug2EIMOQWGHIbDEOBIY/AkMdgGAYMeQWGvAbDcGDIJzDkMxhGAEN+gSG/wTASGAoIDAUMhlHAUFBgKGgwjAaGQgJDIYNhDDAUFhgKGwxjgaGIwFDEYBgHDEUFhqIGw3hgKCYwFDMYJgBDcYGhuMEwERhKCAwlDIZJwFBSYChpMEwGhlICQymDYQowlBYYShsMU4GhjMBQxmCYBgxlBYayBsN0YCgnMJQzGGYAQ3mBobzBMBMYKggMFQyGWcBQUWCoaDDMBoZKAkMlg2EOMFQWGCobDHOBoYrAUMVgmAcMVQWGqgbDfGCoJjBUMxgWAEN1gaG6wbAQGGoIDDUMhkXAUFNgqGkwLAaGWgJDLYNhCTDUFhhqGwxLgaGOwFDHYFgGDHUFhroGw4/AUE9gqGcwLAeG+gJDfYNhBTA0EBgaGAwrgaGhwNDQYPgJGBoJDI0MhlXA0FhgaGwwrAaGJgJDE4NhDTA0FRiaGgw/A0MzgaGZwbAWGJoLDM0NhnXA0EJgaGEwrAeGlgJDS4NhAzC0EhhaGQy/AENrgaG1wfArMLQRGNoYDL8BQ1uBoa3B8DswtBMY2hkMG4GhvcDQ3mD4Axg6CAwdDIY/gaGjwNDRYNgEDJ0Ehk4Gw2Zg6CwwdDYYtgBDF4Ghi8GwFRi6CgxdDYZtwNBNYOhmMGwHhu4CQ3eDYQcw9BAYehgMO4Ghp8DQ02DYBQy9BIZeBsNuYOgtMPQ2GPYAQx+BoY/BsBcY+goMfQ2GfcDQT2DoZzDsB4b+AkN/g+EAMAwQGAYYDAeBYaDAMNBgOAQMgwSGQQbDYWAYLDAMNhiOAMMQgWGIwXAUGIYKDEMNhmPAMExgGGYwHAeG4QLDcIPhBDCMEBhGGAwngWGkwDDSYDgFDKMEhlEGw2lgGC0wjDYYzgDDGIFhjMFwFhjGCgxjDYZzwDBOYBhnMJwHhvECw3iD4QIwTBAYJhgMF4FhosAw0WC4BAyTBIZJBsNlYJgsMEw2GK4AwxSBYYrBcBUYpgoMUw2Ga8AwTWCYZjBcB4bpAsN0g+EGMMwQGGYYDDeBYabAMNNguAUMswSGWQbDbWCYLTDMNhjuAMMcgWGOwXAXGOYKDHMNhnvAME9gmGcw3AeG+QLDfIPhATAsEBgWGAwPgWGhwLDQYHgEDIsEhkUGw2NgWCwwLDYYngDDEoFhicHwFBiWCgxLDYZnwLBMYFhmMDwHhh8Fhh8NhhfAsFxgWG4wvASGFQLDCoPhFTCsFBhWGgyvgeEngeEng+ENMKwSGFYZDG+BYbXAsNpgeAcMawSGNQbDe2D4WWD42WD4AAxrBYa1BsNHYFgnMKwzGD4Bw3qBYb3B8BkYNggMGwyGv4DhF4HhF4PhCzD8KjD8ajB8BYbfBIbfDIZvwPD7v9nwnXPwbwc1BPN7N2wU7LDRsENwv3fDHwLDHwbD937vhj8Fhj8NhhB+74ZNAsMmg+EHv3fDZoFhs8EQ0u/dsEVg2GIwhPJ7N2wVGLYaDKH93g3bBIZtBkMYv3fDdoFhu8EQ1u/dsENg2GEwhPN7N+wUGHYaDOH93g27BIZdBkMEv3fDboFht8EQ0e/dsEdg2GMwRPJ7N+wVGPYaDJH93g37BIZ9BkMUv3fDfoFhv8EQ1e/dcEBgOGAwRPN7NxwUGA4aDNH93g2HBIZDBkMMv3fDYYHhsMEQ0+/dcERgOGIwxPJ7NxwVGI4aDLH93g3HBIZjBkMcv3fDcYHhuMEQ1+/dcEJgOGEwxPN7N5wUGE4aDPH93g2nBIZTBkMCv3fDaYHhtMGQ0O/dcEZgOGMw+P3eDWcFhrMGQyK/d8M5geGcwZDY791wXmA4bzAk8Xs3XBAYLhgMSf3eDRcFhosGQzK/d8MlgeGSwZDc791wWWC4bDCk8Hs3XBEYrhgMKf3eDVcFhqsGQyq/d8M1geGawZDa791wXWC4bjCk8Xs33BAYbhgMaf3eDTcFhpsGQzq/d8MtgeGWwZDe791wW2C4bTBk8Hs33BEY7hgMGf3eDXcFhrsGQya/d8M9geGewZDZ791wX2C4bzBk8Xs3PBAYHhgMWf3eDQ8FhocGQza/d8MjgeGRwZDd793wWGB4bDDk8Hs3PBEYnhgMOf3eDU8FhqcGQy6/d8MzgeGZwZDb793wXGB4bjDk8Xs3vBAYXhgMef3eDS8FhpcGQz6/d8MrgeGVwZDf793wWmB4bTAU8Hs3vBEY3hgMBf3eDW8FhrcGQyG/d8M7geGdwVDY793wXmB4bzAU8Xs3fBAYPhgMRf3eDR8Fho8GQzG/d8MngeGTwVDc793wWWD4bDCU8Hs3/CUw/GUwlPR7N3wRGL4YDKX83g1fBYavBkNpv3fDN4Hhm8FQxu/d4Jv37zf8/Z9BDWX93g3fCQzfGQzl/N4NwQSGYAZDeb93Q3CBIbjBUMHv3fC9wPC9wVDR790QQmAIYTBU8ns3/CAw/GAwVPZ7N4QUGEIaDFX83g2hBIZQBkNVv3dDaIEhtMFQze/dEEZgCGMwVPd7N4QVGMIaDDX83g3hBIZwBkNNv3dDeIEhvMFQy+/dEEFgiGAw1PZ7N0QUGCIaDHX83g2RBIZIBkNdv3dDZIEhssFQz+/dEEVgiGIw1Pd7N0QVGKIaDA383g3RBIZoBkNDv3dDdIEhusHQyO/dEENgiGEwNPZ7N8QUGGIaDE383g2xBIZYBkNTv3dDbIEhtsHQzO/dEEdgiGMwNPd7N8QVGOIaDC383g3xBIZ4BkNLv3dDfIEhvsHQyu/dkEBgSGAwtPZ7NyQUGBIaDG383g1+gcFvMLT1ezckEhgSGQzt/N4NiQWGxAZDe793QxKBIYnB0MHv3ZBUYEhqMHT0ezckExiSGQyd/N4NyQWG5AZDZ793QwqBIYXB0MXv3ZBSYEhpMHT1ezekEhhSGQzd/N4NqQWG1AZDd793QxqBIY3B0MPv3ZBWYEhrMPT0ezekExjSGQy9/N4N6QWG9AZDb793QwaBIYPB0Mfv3ZBRYMhoMPT1ezdkEhgyGQz9/N4NmQWGzAZDf793QxaBIYvBMMDv3ZBVYMhqMAz0ezdkExiyGQyD/N4N2QWG7AbDYL93Qw6BIYfBMMTv3ZBTYMhpMAz1ezfkEhhyGQzD/N4NuQWG3AbDcL93Qx6BIY/BMMLv3ZBXYMhrMIz0ezfkExjyGQyj/N4N+QWG/AbDaL93QwGBoYDBMMbv3VBQYChoMIz1ezcUEhgKGQzj/N4NhQWGwgbDeL93QxGBoYjBMMHv3VBUYChqMEz0ezcUExiKGQyT/N4NxQWG4gbDZL93QwmBoYTBMMXv3VBSYChpMEz1ezeUEhhKGQzT/N4NpQWG0gbDdL93QxmBoYzBMMPv3VBWYChrMMz0ezeUExjKGQyz/N4N5QWG8gbDbL93QwWBoYLBMMfv3VBRYKhoMMz1ezdUEhgqGQzz/N4NlQWGygbDfL93QxWBoYrBsMDv3VBVYKhqMCz0ezdUExiqGQyL/N4N1QWG6gbDYr93Qw2BoYbBsMTv3VBTYKhpMCz1ezfUEhhqGQzL/N4NtQWG2gbDj37vhjoCQx2DYbnfu6GuwFDXYFjh926oJzDUMxhW+r0b6gsM9Q2Gn/zeDQ0EhgYGwyq/d0NDgaGhwbDa793QSGBoZDCs8Xs3NBYYGhsMP/u9G5oIDE0MhrV+74amAkNTg2Gd37uhmcDQzGBY7/duaC4wNDcYNvi9G1oIDC0Mhl/83g0tBYaWBsOvfu+GVgJDK4PhN793Q2uBobXB8Lvfu6GNwNDGYNjo925oKzC0NRj+8Hs3tBMY2hkMf/q9G9oLDO0Nhk1+74YOAkMHg2Gz37uho8DQ0WDY4vdu6CQwdDIYtvq9GzoLDJ0Nhm1+74YuAkMXg2G737uhq8DQ1WDY4fdu6CYwdDMYdvq9G7oLDN0Nhl1+74YeAkMPg2G337uhp8DQ02DY4/du6CUw9DIY9vq9G3oLDL0Nhn1+74Y+AkMfg2G/37uhr8DQ12A44Pdu6Ccw9DMYDvq9G/oLDP0NhkN+74YBAsMAg+Gw37thoMAw0GA44vduGCQwDDIYjvq9GwYLDIMNhmN+74YhAsMQg+G437thqMAw1GA44fduGCYwDDMYTvq9G4YLDMMNhlN+74YRAsMIg+G037thpMAw0mA44/duGCUwjDIYzvq9G0YLDKMNhnN+74YxAsMYg+G837thrMAw1mC44PduGCcwjDMYLvq9G8YLDOMNhkt+74YJAsMEg+Gy37thosAw0WC44vdumCQwTDIYrvq9GyYLDJMNhmt+74YpAsMUg+G637thqsAw1WC44fdumCYwTDMYbvq9G6YLDNMNhlt+74YZAsMMg+G237thpsAw02C44/dumCUwzDIY7vq9G2YLDLMNhnt+74Y5AsMcg+G+37thrsAw12B44PdumCcwzDMYHvq9G+YLDPMNhkd+74YFAsMCg+Gx37thocCw0GB44vduWCQwLDIYnvq9GxYLDIsNhmd+74YlAsMSg+G537thqcCw1GB44fduWCYwLDMYXvq9G34UGH40GF75vRuWCwzLDYbXfu+GFQLDCoPhjd+7YaXAsNJgeOv3bvhJYPjJYHjn925YJTCsMhje+70bVgsMqw2GD37vhjUCwxqD4aPfu+FngeFng+GT37thrcCw1mD47PduWCcwrDMY/vJ7N6wXGNYbDF/83g0bBIYNBsNXv3fDLwLDLwbDN793w68Cw68Ggy+Rd8NvAsNvBsN3wPC7wPC7wRAMGDYKDBsNhuDA8IfA8IfB8D0w/Ckw/GkwhACGTQLDJoPhB2DYLDBsNhhCAsMWgWGLwRAKGLYKDFsNhtDAsE1g2GYwhAGG7QLDdoMhLDDsEBh2GAzhgGGnwLDTYAgPDLsEhl0GQwRg2C0w7DYYIgLDHoFhj8EQCRj2Cgx7DYbIwLBPYNhnMEQBhv0Cw36DISowHBAYDhgM0YDhoMBw0GCIDgyHBIZDBkMMYDgsMBw2GGICwxGB4YjBEAsYjgoMRw2G2MBwTGA4ZjDEAYbjAsNxgyEuMJwQGE4YDPGA4aTAcNJgiA8MpwSGUwZDAmA4LTCcNhgSAsMZgeGMweAHhrMCw1mDIREwnBMYzhkMiYHhvMBw3mBIAgwXBIYLBkNSYLgoMFw0GJIBwyWB4ZLBkBwYLgsMlw2GFMBwRWC4YjCkBIarAsNVgyEVMFwTGK4ZDKmB4brAcN1gSAMMNwSGGwZDWmC4KTDcNBjSAcMtgeGWwZAeGG4LDLcNhgzAcEdguGMwZASGuwLDXYMhEzDcExjuGQyZgeG+wHDfYMgCDA8EhgcGQ1ZgeCgwPDQYsgHDI4HhkcGQHRgeCwyPDYYcwPBEYHhiMOQEhqcCw1ODIRcwPBMYnhkMuYHhucDw3GDIAwwvBIYXBkNeYHgpMLw0GPIBwyuB4ZXBkB8YXgsMrw2GAsDwRmB4YzAUBIa3AsNbg6EQMLwTGN4ZDIWB4b3A8N5gKAIMHwSGDwZDUWD4KDB8NBiKAcMngeGTwVAcGD4LDJ8NhhLA8JfA8JfBUBIYvggMXwyGUsDwVWD4ajCUBoZvAsM3g6EMMPjm//sNf/9nUENZYPhOYPjOYCgHDMEEhmAGQ3lgCC4wBDcYKgDD9wLD9wZDRWAIITCEMBgqAcMPAsMPBkNlYAgpMIQ0GKoAQyiBIZTBUBUYQgsMoQ2GasAQRmAIYzBUB4awAkNYg6EGMIQTGMIZDDWBIbzAEN5gqAUMEQSGCAZDbWCIKDBENBjqAEMkgSGSwVAXGCILDJENhnrAEEVgiGIw1AeGqAJDVIOhATBEExiiGQwNgSG6wBDdYGgEDDEEhhgGQ2NgiCkwxDQYmgBDLIEhlsHQFBhiCwyxDYZmwBBHYIhjMDQHhrgCQ1yDoQUwxBMY4hkMLYEhvsAQ32BoBQwJBIYEBkNrYEgoMCQ0GNoAg19g8BsMbYEhkcCQyGBoBwyJBYbEBkN7YEgiMCQxGDoAQ1KBIanB0BEYkgkMyQyGTsCQXGBIbjB0BoYUAkMKg6ELMKQUGFIaDF2BIZXAkMpg6AYMqQWG1AZDd2BIIzCkMRh6AENagSGtwdATGNIJDOkMhl7AkF5gSG8w9AaGDAJDBoOhDzBkFBgyGgx9gSGTwJDJYOgHDJkFhswGQ39gyCIwZDEYBgBDVoEhq8EwEBiyCQzZDIZBwJBdYMhuMAwGhhwCQw6DYQgw5BQYchoMQ4Ehl8CQy2AYBgy5BYbcBsNwYMgjMOQxGEYAQ16BIa/BMBIY8gkM+QyGUcCQX2DIbzCMBoYCAkMBg2EMMBQUGAoaDGOBoZDAUMhgGAcMhQWGwgbDeGAoIjAUMRgmAENRgaGowTARGIoJDMUMhknAUFxgKG4wTAaGEgJDCYNhCjCUFBhKGgxTgaGUwFDKYJgGDKUFhtIGw3RgKCMwlDEYZgBDWYGhrMEwExjKCQzlDIZZwFBeYChvMMwGhgoCQwWDYQ4wVBQYKhoMc4GhksBQyWCYBwyVBYbKBsN8YKgiMFQxGBYAQ1WBoarBsBAYqgkM1QyGRcBQXWCobjAsBoYaAkMNg2EJMNQUGGoaDEuBoZbAUMtgWAYMtQWG2gbDj8BQR2CoYzAsB4a6AkNdg2EFMNQTGOoZDCuBob7AUN9g+AkYGggMDQyGVcDQUGBoaDCsBoZGAkMjg2ENMDQWGBobDD8DQxOBoYnBsBYYmgoMTQ2GdcDQTGBoZjCsB4bmAkNzg2EDMLQQGFoYDL8AQ0uBoaXB8CswtBIYWhkMvwFDa4GhtcHwOzC0ERjaGAwbgaGtwNDWYPgDGNoJDO0Mhj+Bob3A0N5g2AQMHQSGDgbDZmDoKDB0NBi2AEMngaGTwbAVGDoLDJ0Nhm3A0EVg6GIwbAeGrgJDV4NhBzB0Exi6GQw7gaG7wNDdYNgFDD0Ehh4Gw25g6Ckw9DQY9gBDL4Ghl8GwFxh6Cwy9DYZ9wNBHYOhjMOwHhr4CQ1+D4QAw9BMY+hkMB4Ghv8DQ32A4BAwDBIYBBsNhYBgoMAw0GI4AwyCBYZDBcBQYBgsMgw2GY8AwRGAYYjAcB4ahAsNQg+EEMAwTGIYZDCeBYbjAMNxgOAUMIwSGEQbDaWAYKTCMNBjOAMMogWGUwXAWGEYLDKMNhnPAMEZgGGMwnAeGsQLDWIPhAjCMExjGGQwXgWG8wDDeYLgEDBMEhgkGw2VgmCgwTDQYrgDDJIFhksFwFRgmCwyTDYZrwDBFYJhiMFwHhqkCw1SD4QYwTBMYphkMN4FhusAw3WC4BQwzBIYZBsNtYJgpMMw0GO4AwyyBYZbBcBcYZgsMsw2Ge8AwR2CYYzDcB4a5AsNcg+EBMMwTGOYZDA+BYb7AMN9geAQMCwSGBQbDY2BYKDAsNBieAMMigWGRwfAUGP5/vPdTEGtd24ZtPsu2bdu2bVuPbSzbNrNs27Zt27b6S1f1TndV/+95VeVKVfbmzDmOcY/MSqYZDNMEwyNgmG4wTBcMj4FhhsEwQzA8AYaZBsNMwfAUGGYZDLMEwzNgmG0wzBYMz4FhjsEwRzC8AIa5BsNcwfASGOYZDPMEwytgmG8wzBcMr4FhgcGwQDC8AYaFBsNCwfAWGBYZDIsEwztgWGwwLBYM74FhicGwRDB8AIalBsNSwfARGJYZDMsEwydgWG4wLBcMn4FhhcGwQjB8kfZ/N6w0GFYKhjDAsMpgWCUYwgLDaoNhtWAIBwxrDIY1giE8MKw1GNYKhgjAsM5gWCcYIgLDeoNhvWCIBAwbDIYNgiEyMGw0GDYKhijAsMlg2CQYogLDZoNhs2CIBgxbDIYtgiE6MGw1GLYKhhjAsM1g2CYYYgLDdoNhu2CIBQw7DIYdgiE2MOw0GHYKhjjAsMtg2CUY4gLDboNht2CIBwx7DIY9giE+MOw1GPYKhgTAsM9g2CcYEgLDfoNhv2BIBAwHDIYDgiExMBw0GA4KhiTAcMhgOCQYkgLDYYPhsGBIBgxHDIYjgiE5MBw1GI4KhhTAcMxgOCYYUgLDcYPhuGBIBQwnDIYTgiE1MJw0GE4KhjTAcMpgOCUY0gLDaYPhtGBIBwxnDIYzgiE9MJw1GM4KhgzAcM5gOCcYMgLDeYPhvGDIBAwXDIYLgiEzMFw0GC4KhizAcMlguCQYsgLDZYPhsmDIBgxXDIYrgiE7MFw1GK4KhhzAcM1guCYYcgLDdYPhumDIBQw3DIYbgiE3MNw0GG4KhjzAcMtguCUY8gLDbYPhtmDIBwx3DIY7giE/MNw1GO4KhgLAcM9guCcYCgLDfYPhvmAoBAwPDIYHgqEwMDw0GB4KhiLA8MhgeCQYigLDY4PhsWAoBgxPDIYngqE4MDw1GJ4KhhLA8MxgeCYYSgLDc4PhuWAoBQwvDIYXgqE0MLw0GF4KhjLA8MpgeCUYygLDa4PhtWAoBwxvDIY3gqE8MLw1GN4KhgrA8M5geCcYKgLDe4PhvWCoBAwfDIYPgqEyMHw0GD4KhirA8Mlg+CQYqgLDZ4Phs2CoBgxfTAm9IdighurAEMZgCCMYagBDWIMhrGCoCQzhDIZwgqEWMIQ3GMILhtrAEMFgiCAY6gBDRIMhomCoCwyRDIZIgqEeMEQ2GCILhvrAEMVgiCIYGgBDVIMhqmBoCAzRDIZogqERMEQ3GKILhsbAEMNgiCEYmgBDTIMhpmBoCgyxDIZYgqEZMMQ2GGILhubAEMdgiCMYWgBDXIMhrmBoCQzxDIZ4gqEVMMQ3GOILhtbAkMBgSCAY2gBDQoMhoWBoCwyJDIZEgqEdMCQ2GBILhvbAkMRgSCIYOgBDUoMhqWD4EhiSGQzJBMNXwJDcYEguGL4GhhQGQwrB8A0wpDQYUgqGb4EhlcGQSjB8BwypDYbUguF7YEhjMKQRDD8AQ1qDIa1g+BEY0hkM6QTDT8CQ3mBILxh+BoYMBkMGwfALMGQ0GDIKhl+BIZPBkEkw/AYMmQ2GzILhd2DIYjBkEQx/AENWgyGrYPgTGLIZDNkEw1/AkN1gyC4Y/gaGHAZDDsHwDzDkNBhyCoZ/gSGXwZBLMPwHDLkNhtyCoSMw5DEY8giGTsCQ12DIKxg6A0M+gyGfYOgCDPkNhvyCoSswFDAYCgiGbsBQ0GAoKBi6A0Mhg6GQYOgBDIUNhsKCoScwFDEYigiGXsBQ1GAoKhh6A0Mxg6GYYOgDDMUNhuKCoS8wlDAYSgiGfsBQ0mAoKRj6A0Mpg6GUYBgADKUNhtKCYSAwlDEYygiGQcBQ1mAoKxgGA0M5g6GcYBgCDOUNhvKCYSgwVDAYKgiGYcBQ0WCoKBiGA0Mlg6GSYBgBDJUNhsqCYSQwVDEYqgiGUcBQ1WCoKhhGA0M1g6GaYBgDDNUNhuqCYSww1DAYagiGccBQ02CoKRjGA0Mtg6GWYJgADLUNhtqCYSIw1DEY6giGScBQ12CoKxgmA0M9g6GeYJgCDPUNhvqCIQAMDQyGBoJhKjA0NBgaCoZpwNDIYGgkGKYDQ2ODobFgmAEMTQyGJoJhJjA0NRiaCoZZwNDMYGgmGGYDQ3ODoblgmAMMLQyGFoJhLjC0NBhaCoZ5wNDKYGglGOYDQ2uDobVgWAAMbQyGNoJhITC0NRjaCoZFwNDOYGgnGBYDQ3uDob1gWAIMHQyGDoJhKTB8aTB8KRiWAcNXBsNXgmE5MHxtMHwtGFYAwzcGwzeCYSUwfGswfCsYVgHDdwbDd4JhNTB8bzB8LxjWAMMPBsMPgmEtMPxoMPwoGNYBw08Gw0+CYT0w/Gww/CwYNgDDLwbDL4JhIzD8ajD8Khg2AcNvBsNvgmEzMPxuMPwuGLYAwx8Gwx+CYSsw/Gkw/CkYtgHDXwbDX4JhOzD8bTD8LRh2AMM/BsM/gmEnMPxrMPwrGHYBw38Gw3+CYTcwdDQYOgqGPcDQyWDoJBj2AkNng6GzYNgHDF0Mhi6CYT8wdDUYugqGA8DQzWDoJhgOAkN3g6G7YDgEDD0Mhh6C4TAw9DQYegqGI8DQy2DoJRiOAkNvg6G3YDgGDH0Mhj6C4Tgw9DUY+gqGE8DQz2DoJxhOAkN/g6G/YDgFDAMMhgGC4TQwDDQYBgqGM8AwyGAYJBjOAsNgg2GwYDgHDEMMhiGC4TwwDDUYhgqGC8AwzGAYJhguAsNwg2G4YLgEDCMMhhGC4TIwjDQYRgqGK8AwymAYJRiuAsNog2G0YLgGDGMMhjGC4TowjDUYxgqGG8AwzmAYJxhuAsN4g2G8YLgFDBMMhgmC4TYwTDQYJgqGO8AwyWCYJBjuAsNkg2GyYLgHDFMMhimC4T4wBAyGgGB4AAxTDYapguEhMEwzGKYJhkfAMN1gmC4YHgPDDINhhmB4AgwzDYaZguEpMMwyGGYJhmfAMNtgmC0YngPDHINhjmB4AQxzDYa5guElMMwzGOYJhlfAMN9gmC8YXgPDAoNhgWB4AwwLDYaFguEtMCwyGBYJhnfAsNhgWCwY3gPDEoNhiWD4AAxLDYalguEjMCwzGJYJhk/AsNxgWC4YPgPDCoNhhWD4It3/blhpMKwUDGGAYZXBsEowhAWG1QbDasEQDhjWGAxrBEN4YFhrMKwVDBGAYZ3BsE4wRASG9QbDesEQCRg2GAwbBENkYNhoMGwUDFGAYZPBsEkwRAWGzQbDZsEQDRi2GAxbBEN0YNhqMGwVDDGAYZvBsE0wxASG7QbDdsEQCxh2GAw7BENsYNhpMOwUDHGAYZfBsEswxAWG3QbDbsEQDxj2GAx7BEN8YNhrMOwVDAmAYZ/BsE8wJASG/QbDfsGQCBgOGAwHBENiYDhoMBwUDEmA4ZDBcEgwJAWGwwbDYcGQDBiOGAxHBENyYDhqMBwVDCmA4ZjBcEwwpASG4wbDccGQChhOGAwnBENqYDhpMJwUDGmA4ZTBcEowpAWG0wbDacGQDhjOGAxnBEN6YDhrMJwVDBmA4ZzBcE4wZASG8wbDecGQCRguGAwXBENmYLhoMFwUDFmA4ZLBcEkwZAWGywbDZcGQDRiuGAxXBEN2YLhqMFwVDDmA4ZrBcE0w5ASG6wbDdcGQCxhuGAw3BENuYLhpMNwUDHmA4ZbBcEsw5AWG2wbDbcGQDxjuGAx3BEN+YLhrMNwVDAWA4Z7BcE8wFASG+wbDfcFQCBgeGAwPBENhYHhoMDwUDEWA4ZHB8EgwFAWGxwbDY8FQDBieGAxPBENxYHhqMDwVDCWA4ZnB8EwwlASG5wbDc8FQChheGAwvBENpYHhpMLwUDGWA4ZXB8EowlAWG1wbDa8FQDhjeGAxvBEN5YHhrMLwVDBWA4Z3B8E4wVASG9wbDe8FQCRg+GAwfBENlYPhoMHwUDFWA4ZPB8EkwVAWGzwbDZ8FQDRi+CITeEGxQQ3VgCBMIvSHYoIYawBA2EHpDsEENNYEhXCD0hmCDGmoBQ/hA6A3BBjXUBoYIgdAbgg1qqAMMEQOhNwQb1FAXGCIFQm8INqihHjBEDoTeEGxQQ31giBIIvSHYoIYGwBA1EHpDsEENDYEhWiD0hmCDGhoBQ/RA6A3BBjU0BoYYgdAbgg1qaAIMMQOhNwQb1NAUGGIFQm8INqihGTDEDoTeEGxQQ3NgiBMIvSHYoIYWwBA3EHpDsEENLYEhXiD0hmCDGloBQ/xA6A3BBjW0BoYEgdAbgg1qaAMMCQOhNwQb1NAWGBIFQm8INqihHTAkDoTeEGxQQ3tgSBIIvSHYoIYOwJA0EHpDsEENXwJDskDoDcEGNXwFDMkDoTcEG9TwNTCkCITeEGxQwzfAkDIQekOwQQ3fAkOqQOgNwQY1fAcMqQOhNwQb1PA9MKQJhN4QbFDDD8CQNhB6Q7BBDT8CQ7pA6A3BBjX8BAzpA6E3BBvU8DMwZAiE3hBsUMMvwJAxEHpDsEENvwJDpkDoDcEGNfwGDJkDoTcEG9TwOzBkCYTeEGxQwx/AkDUQekOwQQ1/AkO2QOgNwQY1/AUM2QOhNwQb1PA3MOQIhN4QbFDDP8CQMxB6Q7BBDf8CQ65A6A3BBjX8Bwy5A6E3BBvU0BEY8gRCbwg2qKETMOQNhN4QbFBDZ2DIFwi9Idighi7AkD8QekOwQQ1dgaFAIPSGYIMaugFDwUDoDcEGNXQHhkKB0BuCDWroAQyFA6E3BBvU0BMYigRCbwg2qKEXMBQNhN4QbFBDb2AoFgi9Idighj7AUDwQekOwQQ19gaFEIPSGYIMa+gFDyUDoDcEGNfQHhlKB0BuCDWoYAAylA6E3BBvUMBAYygRCbwg2qGEQMJQNhN4QbFDDYGAoFwi9IdighiHAUD4QekOwQQ1DgaFCIPSGYIMahgFDxUDoDcEGNQwHhkqB0BuCDWoYAQyVA6E3BBvUMBIYqgRCbwg2qGEUMFQNhN4QbFDDaGCoFgi9IdighjHAUD0QekOwQQ1jgaFGIPSGYIMaxgFDzUDoDcEGNYwHhlqB0BuCDWqYAAy1A6E3BBvUMBEY6gRCbwg2qGESMNQNhN4QbFDDZGCoFwi9IdighinAUD8QekOwQQ0BYGgQCL0h2KCGqcDQMBB6Q7BBDdOAoVEg9IZggxqmA0PjQOgNwQY1zACGJoHQG4INapgJDE0DoTcEG9QwCxiaBUJvCDaoYTYwNA+E3hBsUMMcYGgRCL0h2KCGucDQMhB6Q7BBDfOAoVUg9IZggxrmA0PrQOgNwQY1LACGNoHQG4INalgIDG0DoTcEG9SwCBjaBUJvCDaoYTEwtA+E3hBsUMMSYOgQCL0h2KCGpcDwZSD0hmCDGpYBw1eB0BuCDWpYDgxfB0JvCDaoYQUwfBMIvSHYoIaVwPBtIPSGYIMaVgHDd4HQG4INalgNDN8HQm8INqhhDTD8EAi9IdighrXA8GMg9IZggxrWAcNPgdAbgg1qWA8MPwdCbwg2qGEDMPwSCL0h2KCGjcDwayD0hmCDGjYBw2+B0BuCDWrYDAy/B0JvCDaoYQsw/BEIvSHYoIatwPBnIPSGYIMatgHDX4HQG4INatgODH8HQm8INqhhBzD8Ewi9Idighp3A8G8g9IZggxp2AcN/gdAbgg1q2A0MHQOhNwQb1LAHGDoFQm8INqhhLzB0DoTeEGxQwz5g6BIIvSHYoIb9wNA1EHpDsEENB4ChWyD0hmCDGg4CQ/dA6A3BBjUcAoYegdAbgg1qOAwMPQOhNwQb1HAEGHoFQm8INqjhKDD0DoTeEGxQwzFg6BMIvSHYoIbjwNA3EHpDsEENJ4ChXyD0hmCDGk4CQ/9A6A3BBjWcAoYBgdAbgg1qOA0MAwOhNwQb1HAGGAYFQm8INqjhLDAMDoTeEGxQwzlgGBIIvSHYoIbzwDA0EHpDsEENF4BhWCD0hmCDGi4Cw/BA6A3BBjVcAoYRgdAbgg1quAwMIwOhNwQb1HAFGEYFQm8INqjhKjCMDoTeEGxQwzVgGBMIvSHYoIbrwDA2EHpDsEENN4BhXCD0hmCDGm4Cw/hA6A3BBjXcAoYJgdAbgg1quA0MEwOhNwQb1HAHGCYFQm8INqjhLjBMDoTeEGxQwz1gmBIIvSHYoIb7wBAIhN4QbFDDA2CYGgi9IdighofAMC0QekOwQQ2PgGF6IPSGYIMaHgPDjEDoDcEGNTwBhpmB0BuCDWp4CgyzAqE3BBvU8AwYZgdCbwg2qOE5MMwJhN4QbFDDC2CYGwi9IdighpfAMC8QekOwQQ2vgGF+IPSGYIMaXgPDgkDoDcEGNbwBhoWB0BuCDWp4CwyLAqE3BBvU8A4YFgdCbwg2qOE9MCwJhN4QbFDDB2BYGgi9Idigho/AsCwQekOwQQ2fgGF5ILSGz5n+7yyN5IYvMv/vhhWB0M8h2KCGMMCwMhB6Q7BBDWGBYVUg9IZggxrCAcPqQOgNwQY1hAeGNYHQG4INaogADGsDoTcEG9QQERjWBUJvCDaoIRIwrA+E3hBsUENkYNgQCL0h2KCGKMCwMRB6Q7BBDVGBYVMg9IZggxqiAcPmQOgNwQY1RAeGLYHQG4INaogBDFsDoTcEG9QQExi2BUJvCDaoIRYwbA+E3hBsUENsYNgRCL0h2KCGOMCwMxB6Q7BBDXGBYVcg9IZggxriAcPuQOgNwQY1xAeGPYHQG4INakgADHsDoTcEG9SQEBj2BUJvCDaoIREw7A+E3hBsUENiYDgQCL0h2KCGJMBwMBB6Q7BBDUmB4VAg9IZggxqSAcPhQOgNwQY1JAeGI4HQG4INakgBDEcDoTcEG9SQEhiOBUJvCDaoIRUwHA+E3hBsUENqYDgRCL0h2KCGNMBwMhB6Q7BBDWmB4VQg9IZggxrSAcPpQOgNwQY1pAeGM4HQG4INasgADGcDoTcEG9SQERjOBUJvCDaoIRMwnA+E3hBsUENmYLgQCL0h2KCGLMBwMRB6Q7BBDVmB4VIg9IZggxqyAcPlQOgNwQY1ZAeGK4HQG4INasgBDFcDoTcEG9SQExiuBUJvCDaoIRcwXA+E3hBsUENuYLgRCL0h2KCGPMBwMxB6Q7BBDXmB4VYg9IZggxryAcPtQOgNwQY15AeGO4HQG4INaigADHcDoTcEG9RQEBjuBUJvCDaooRAw3A+E3hBsUENhYHgQCL0h2KCGIsDwMBB6Q7BBDUWB4VEg9IZggxqKAcPjQOgNwQY1FAeGJ4HQG4INaigBDE8DoTcEG9RQEhieBUJvCDaooRQwPA+E3hBsUENpYHgRCL0h2KCGMsDwMhB6Q7BBDWWB4VUg9IZggxrKAcPrQOgNwQY1lAeGN4HQG4INaqgADG8DoTcEG9RQERjeBUJvCDaooRIwvA+E3hBsUENlYPgQCL0h2KCGKsDwMRB6Q7BBDVWB4VMg9IZggxqqAcPnQOgNwQY1VAeGL6aG3hBsUEMNYAhjMIQRDDWBIazBEFYw1AKGcAZDOMFQGxjCGwzhBUMdYIhgMEQQDHWBIaLBEFEw1AOGSAZDJMFQHxgiGwyRBUMDYIhiMEQRDA2BIarBEFUwNAKGaAZDNMHQGBiiGwzRBUMTYIhhMMQQDE2BIabBEFMwNAOGWAZDLMHQHBhiGwyxBUMLYIhjMMQRDC2BIa7BEFcwtAKGeAZDPMHQGhjiGwzxBUMbYEhgMCQQDG2BIaHBkFAwtAOGRAZDIsHQHhgSGwyJBUMHYEhiMCQRDF8CQ1KDIalg+AoYkhkMyQTD18CQ3GBILhi+AYYUBkMKwfAtMKQ0GFIKhu+AIZXBkEowfA8MqQ2G1ILhB2BIYzCkEQw/AkNagyGtYPgJGNIZDOkEw8/AkN5gSC8YfgGGDAZDBsHwKzBkNBgyCobfgCGTwZBJMPwODJkNhsyC4Q9gyGIwZBEMfwJDVoMhq2D4CxiyGQzZBMPfwJDdYMguGP4BhhwGQw7B8C8w5DQYcgqG/4Ahl8GQSzB0BIbcBkNuwdAJGPIYDHkEQ2dgyGsw5BUMXYAhn8GQTzB0BYb8BkN+wdANGAoYDAUEQ3dgKGgwFBQMPYChkMFQSDD0BIbCBkNhwdALGIoYDEUEQ29gKGowFBUMfYChmMFQTDD0BYbiBkNxwdAPGEoYDCUEQ39gKGkwlBQMA4ChlMFQSjAMBIbSBkNpwTAIGMoYDGUEw2BgKGswlBUMQ4ChnMFQTjAMBYbyBkN5wTAMGCoYDBUEw3BgqGgwVBQMI4ChksFQSTCMBIbKBkNlwTAKGKoYDFUEw2hgqGowVBUMY4ChmsFQTTCMBYbqBkN1wTAOGGoYDDUEw3hgqGkw1BQME4ChlsFQSzBMBIbaBkNtwTAJGOoYDHUEw2RgqGsw1BUMU4ChnsFQTzAEgKG+wVBfMEwFhgYGQwPBMA0YGhoMDQXDdGBoZDA0EgwzgKGxwdBYMMwEhiYGQxPBMAsYmhoMTQXDbGBoZjA0EwxzgKG5wdBcMMwFhhYGQwvBMA8YWhoMLQXDfGBoZTC0EgwLgKG1wdBaMCwEhjYGQxvBsAgY2hoMbQXDYmBoZzC0EwxLgKG9wdBeMCwFhg4GQwfBsAwYvjQYvhQMy4HhK4PhK8GwAhi+Nhi+FgwrgeEbg+EbwbAKGL41GL4VDKuB4TuD4TvBsAYYvjcYvhcMa4HhB4PhB8GwDhh+NBh+FAzrgeEng+EnwbABGH42GH4WDBuB4ReD4RfBsAkYfjUYfhUMm4HhN4PhN8GwBRh+Nxh+FwxbgeEPg+EPwbANGP40GP4UDNuB4S+D4S/BsAMY/jYY/hYMO4HhH4PhH8GwCxj+NRj+FQy7geE/g+E/wbAHGDoaDB0Fw15g6GQwdBIM+4Chs8HQWTDsB4YuBkMXwXAAGLoaDF0Fw0Fg6GYwdBMMh4Chu8HQXTAcBoYeBkMPwXAEGHoaDD0Fw1Fg6GUw9BIMx4Cht8HQWzAcB4Y+BkMfwXACGPoaDH0Fw0lg6Gcw9BMMp4Chv8HQXzCcBoYBBsMAwXAGGAYaDAMFw1lgGGQwDBIM54BhsMEwWDCcB4YhBsMQwXABGIYaDEMFw0VgGGYwDBMMl4BhuMEwXDBcBoYRBsMIwXAFGEYaDCMFw1VgGGUwjBIM14BhtMEwWjBcB4YxBsMYwXADGMYaDGMFw01gGGcwjBMMt4BhvMEwXjDcBoYJBsMEwXAHGCYaDBMFw11gmGQwTBIM94BhssEwWTDcB4YpBsMUwfAAGAIGQ0AwPASGqQbDVMHwCBimGQzTBMNjYJhuMEwXDE+AYYbBMEMwPAWGmQbDTMHwDBhmGQyzBMNzYJhtMMwWDC+AYY7BMEcwvASGuQbDXMHwChjmGQzzBMNrYJhvMMwXDG+AYYHBsEAwvAWGhQbDQsHwDhgWGQyLBMN7YFhsMCwWDB+AYYnBsEQwfASGpQbDUsHwCRiWGQzLBMNnYFhuMCwXDF9k+d8NKwyGFYIhDDCsNBhWCoawwLDKYFglGMIBw2qDYbVgCA8MawyGNYIhAjCsNRjWCoaIwLDOYFgnGCIBw3qDYb1giAwMGwyGDYIhCjBsNBg2CoaowLDJYNgkGKIBw2aDYbNgiA4MWwyGLYIhBjBsNRi2CoaYwLDNYNgmGGIBw3aDYbtgiA0MOwyGHYIhDjDsNBh2Coa4wLDLYNglGOIBw26DYbdgiA8MewyGPYIhATDsNRj2CoaEwLDPYNgnGBIBw36DYb9gSAwMBwyGA4IhCTAcNBgOCoakwHDIYDgkGJIBw2GD4bBgSA4MRwyGI4IhBTAcNRiOCoaUwHDMYDgmGFIBw3GD4bhgSA0MJwyGE4IhDTCcNBhOCoa0wHDKYDglGNIBw2mD4bRgSA8MZwyGM4IhAzCcNRjOCoaMwHDOYDgnGDIBw3mD4bxgyAwMFwyGC4IhCzBcNBguCoaswHDJYLgkGLIBw2WD4bJgyA4MVwyGK4IhBzBcNRiuCoacwHDNYLgmGHIBw3WD4bpgyA0MNwyGG4IhDzDcNBhuCoa8wHDLYLglGPIBw22D4bZgyA8MdwyGO4KhADDcNRjuCoaCwHDPYLgnGAoBw32D4b5gKAwMDwyGB4KhCDA8NBgeCoaiwPDIYHgkGIoBw2OD4bFgKA4MTwyGJ4KhBDA8NRieCoaSwPDMYHgmGEoBw3OD4blgKA0MLwyGF4KhDDC8NBheCoaywPDKYHglGMoBw2uD4bVgKA8MbwyGN4KhAjC8NRjeCoaKwPDOYHgnGCoBw3uD4b1gqAwMHwyGD4KhCjB8NBg+CoaqwPDJYPgkGKoBw2eD4bNgqA4MX0wLvSHYoIYawBDGYAgjGGoCQ1iDIaxgqAUM4QyGcIKhNjCENxjCC4Y6wBDBYIggGOoCQ0SDIaJgqAcMkQyGSIKhPjBENhgiC4YGwBDFYIgiGBoCQ1SDIapgaAQM0QyGaIKhMTBENxiiC4YmwBDDYIghGJoCQ0yDIaZgaAYMsQyGWIKhOTDENhhiC4YWwBDHYIgjGFoCQ1yDIa5gaAUM8QyGeIKhNTDENxjiC4Y2wJDAYEggGNoCQ0KDIaFgaAcMiQyGRIKhPTAkNhgSC4YOwJDEYEgiGL4EhqQGQ1LB8BUwJDMYkgmGr4EhucGQXDB8AwwpDIYUguFbYEhpMKQUDN8BQyqDIZVg+B4YUhsMqQXDD8CQxmBIIxh+BIa0BkNawfATMKQzGNIJhp+BIb3BkF4w/AIMGQyGDILhV2DIaDBkFAy/AUMmgyGTYPgdGDIbDJkFwx/AkMVgyCIY/gSGrAZDVsHwFzBkMxiyCYa/gSG7wZBdMPwDDDkMhhyC4V9gyGkw5BQM/wFDLoMhl2DoCAy5DYbcgqETMOQxGPIIhs7AkNdgyCsYugBDPoMhn2DoCgz5DYb8gqEbMBQwGAoIhu7AUNBgKCgYegBDIYOhkGDoCQyFDYbCgqEXMBQxGIoIht7AUNRgKCoY+gBDMYOhmGDoCwzFDYbigqEfMJQwGEoIhv7AUNJgKCkYBgBDKYOhlGAYCAylDYbSgmEQMJQxGMoIhsHAUNZgKCsYhgBDOYOhnGAYCgzlDYbygmEYMFQwGCoIhuHAUNFgqCgYRgBDJYOhkmAYCQyVDYbKgmEUMFQxGKoIhtHAUNVgqCoYxgBDNYOhmmAYCwzVDYbqgmEcMNQwGGoIhvHAUNNgqCkYJgBDLYOhlmCYCAy1DYbagmESMNQxGOoIhsnAUNdgqCsYpgBDPYOhnmAIAEN9g6G+YJgKDA0MhgaCYRowNDQYGgqG6cDQyGBoJBhmAENjg6GxYJgJDE0MhiaCYRYwNDUYmgqG2cDQzGBoJhjmAENzg6G5YJgLDC0MhhaCYR4wtDQYWgqG+cDQymBoJRgWAENrg6G1YFgIDG0MhjaCYREwtDUY2gqGxcDQzmBoJxiWAEN7g6G9YFgKDB0Mhg6CYRkwfGkwfCkYlgPDVwbDV4JhBTB8bTB8LRhWAsM3BsM3gmEVMHxrMHwrGFYDw3cGw3eCYQ0wfG8wfC8Y1gLDDwbDD4JhHTD8aDD8KBjWA8NPBsNPgmEDMPxsMPwsGDYCwy8Gwy+CYRMw/Gow/CoYNgPDbwbDb4JhCzD8bjD8Lhi2AsMfBsMfgmEbMPxpMPwpGLYDw18Gw1+CYQcw/G0w/C0YdgLDPwbDP4JhFzD8azD8Kxh2A8N/BsN/gmEPMHQ0GDoKhr3A0Mlg6CQY9gFDZ4Ohs2DYDwxdDIYuguEAMHQ1GLoKhoPA0M1g6CYYDgFDd4Ohu2A4DAw9DIYeguEIMPQ0GHoKhqPA0Mtg6CUYjgFDb4Oht2A4Dgx9DIY+guEEMPQ1GPoKhpPA0M9g6CcYTgFDf4Ohv2A4DQwDDIYBguEMMAw0GAYKhrPAMMhgGCQYzgHDYINhsGA4DwxDDIYhguECMAw1GIYKhovAMMxgGCYYLgHDcINhuGC4DAwjDIYRguEKMIw0GEYKhqvAMMpgGCUYrgHDaINhtGC4DgxjDIYxguEGMIw1GMYKhpvAMM5gGCcYbgHDeINhvGC4DQwTDIYJguEOMEw0GCYKhrvAMMlgmCQY7gHDZINhsmC4DwxTDIYpguEBMAQMhoBgeAgMUw2GqYLhETBMMximCYbHwDDdYJguGJ4AwwyDYYZgeAoMMw2GmYLhGTDMMhhmCYbnwDDbYJgtGF4AwxyDYY5geAkMcw2GuYLhFTDMMxjmCYbXwDDfYJgvGN4AwwKDYYFgeAsMCw2GhYLhHTAsMhgWCYb3wLDYYFgsGD4Aw5IQG8Ik/L/GSG4Im/B/Nyw1zGGpMIdwwLDMYFgmGMIDw3KDYblgiAAMKwyGFYIhIjCsNBhWCoZIwLDKYFglGCIDw2qDYbVgiAIMawyGNYIhKjCsNRjWCoZowLDOYFgnGKIDw3qDYb1giAEMGwyGDYIhJjBsNBg2CoZYwLDJYNgkGGIDw2aDYbNgiAMMWwyGLYIhLjBsNRi2CoZ4wLDNYNgmGOIDw3aDYbtgSAAMOwyGHYIhITDsNBh2CoZEwLDLYNglGBIDw26DYbdgSAIMewyGPYIhKTDsNRj2CoZkwLDPYNgnGJIDw36DYb9gSAEMBwyGA4IhJTAcNBgOCoZUwHDIYDgkGFIDw2GD4bBgSAMMRwyGI4IhLTAcNRiOCoZ0wHDMYDgmGNIDw3GD4bhgyAAMJwyGE4IhIzCcNBhOCoZMwHDKYDglGDIDw2mD4bRgyAIMZwyGM4IhKzCcNRjOCoZswHDOYDgnGLIDw3mD4bxgyAEMFwyGC4IhJzBcNBguCoZcwHDJYLgkGHIDw2WD4bJgyAMMVwyGK4IhLzBcNRiuCoZ8wHDNYLgmGPIDw3WD4bpgKAAMNwyGG4KhIDDcNBhuCoZCwHDLYLglGAoDw22D4bZgKAIMdwyGO4KhKDDcNRjuCoZiwHDPYLgnGIoDw32D4b5gKAEMDwyGB4KhJDA8NBgeCoZSwPDIYHgkGEoDw2OD4bFgKAMMTwyGJ4KhLDA8NRieCoZywPDMYHgmGMoDw3OD4blgqAAMLwyGF4KhIjC8NBheCoZKwPDKYHglGCoDw2uD4bVgqAIMbwyGN4KhKjC8NRjeCoZqwPDOYHgnGKoDw3uD4b1gqAEMHwyGD4KhJjB8NBg+CoZawPDJYPgkGGoDw2eD4bNgqAMMX0wPvSHYoIa6wBDGYAgjGOoBQ1iDIaxgqA8M4QyGcIKhATCENxjCC4aGwBDBYIggGBoBQ0SDIaJgaAwMkQyGSIKhCTBENhgiC4amwBDFYIgiGJoBQ1SDIapgaA4M0QyGaIKhBTBENxiiC4aWwBDDYIghGFoBQ0yDIaZgaA0MsQyGWIKhDTDENhhiC4a2wBDHYIgjGNoBQ1yDIa5gaA8M8QyGeIKhAzDENxjiC4YvgSGBwZBAMHwFDAkNhoSC4WtgSGQwJBIM3wBDYoMhsWD4FhiSGAxJBMN3wJDUYEgqGL4HhmQGQzLB8AMwJDcYkguGH4EhhcGQQjD8BAwpDYaUguFnYEhlMKQSDL8AQ2qDIbVg+BUY0hgMaQTDb8CQ1mBIKxh+B4Z0BkM6wfAHMKQ3GNILhj+BIYPBkEEw/AUMGQ2GjILhb2DIZDBkEgz/AENmgyGzYPgXGLIYDFkEw3/AkNVgyCoYOgJDNoMhm2DoBAzZDYbsgqEzMOQwGHIIhi7AkNNgyCkYugJDLoMhl2DoBgy5DYbcgqE7MOQxGPIIhh7AkNdgyCsYegJDPoMhn2DoBQz5DYb8gqE3MBQwGAoIhj7AUNBgKCgY+gJDIYOhkGDoBwyFDYbCgqE/MBQxGIoIhgHAUNRgKCoYBgJDMYOhmGAYBAzFDYbigmEwMJQwGEoIhiHAUNJgKCkYhgJDKYOhlGAYBgylDYbSgmE4MJQxGMoIhhHAUNZgKCsYRgJDOYOhnGAYBQzlDYbygmE0MFQwGCoIhjHAUNFgqCgYxgJDJYOhkmAYBwyVDYbKgmE8MFQxGKoIhgnAUNVgqCoYJgJDNYOhmmCYBAzVDYbqgmEyMNQwGGoIhinAUNNgqCkYAsBQy2CoJRimAkNtg6G2YJgGDHUMhjqCYTow1DUY6gqGGcBQz2CoJxhmAkN9g6G+YJgFDA0MhgaCYTYwNDQYGgqGOcDQyGBoJBjmAkNjg6GxYJgHDE0MhiaCYT4wNDUYmgqGBcDQzGBoJhgWAkNzg6G5YFgEDC0MhhaCYTEwtDQYWgqGJcDQymBoJRiWAkNrg6G1YFgGDG0MhjaCYTkwtDUY2gqGFcDQzmBoJxhWAkN7g6G9YFgFDB0Mhg6CYTUwfGkwfCkY1gDDVwbDV4JhLTB8bTB8LRjWAcM3BsM3gmE9MHxrMHwrGDYAw3cGw3eCYSMwfG8wfC8YNgHDDwbDD4JhMzD8aDD8KBi2AMNPBsNPgmErMPxsMPwsGLYBwy8Gwy+CYTsw/Gow/CoYdgDDbwbDb4JhJzD8bjD8Lhh2AcMfBsMfgmE3MPxpMPwpGPYAw18Gw1+CYS8w/G0w/C0Y9gHDPwbDP4JhPzD8azD8KxgOAMN/BsN/guEgMHQ0GDoKhkPA0Mlg6CQYDgNDZ4Ohs2A4AgxdDIYuguEoMHQ1GLoKhmPA0M1g6CYYjgNDd4Ohu2A4AQw9DIYeguEkMPQ0GHoKhlPA0Mtg6CUYTgNDb4Oht2A4Awx9DIY+guEsMPQ1GPoKhnPA0M9g6CcYzgNDf4Ohv2C4AAwDDIYBguEiMAw0GAYKhkvAMMhgGCQYLgPDYINhsGC4AgxDDIYhguEqMAw1GIYKhmvAMMxgGCYYrgPDcINhuGC4AQwjDIYRguEmMIw0GEYKhlvAMMpgGCUYbgPDaINhtGC4AwxjDIYxguEuMIw1GMYKhnvAMM5gGCcY7gPDeINhvGB4AAwTDIYJguEhMEw0GCYKhkfAMMlgmCQYHgPDZINhsmB4AgxTDIYpguEpMAQMhoBgeAYMUw2GqYLhOTBMMximCYYXwDDdYJguGF4CwwyDYYZgeAUMMw2GmYLhNTDMMhhmCYY3wDDbYJgtGN4CwxyDYY5geAcMcw2GuYLhPTDMMxjmCYYPwDDfYJgvGD4CwwKDYYFg+AQMCw2GhYLhMzAsMhgWCYYvEv3vhsUGw2LBEAYYlhgMSwRDWGBYajAsFQzhgGGZwbBMMIQHhuUGw3LBEAEYVhgMKwRDRGBYaTCsFAyRgGGVwbBKMEQGhtUGw2rBEAUY1hgMawRDVGBYazCsFQzRgGGdwbBOMEQHhvUGw3rBEAMYNhgMGwRDTGDYaDBsFAyxgGGTwbBJMMQGhs0Gw2bBEAcYthgMWwRDXGDYajBsFQzxgGGbwbBNMMQHhu0Gw3bBkAAYdhgMOwRDQmDYaTDsFAyJgGGXwbBLMCQGht0Gw27BkAQY9hgMewRDUmDYazDsFQzJgGGfwbBPMCQHhv0Gw37BkAIYDhgMBwRDSmA4aDAcFAypgOGQwXBIMKQGhsMGw2HBkAYYjhgMRwRDWmA4ajAcFQzpgOGYwXBMMKQHhuMGw3HBkAEYThgMJwRDRmA4aTCcFAyZgOGUwXBKMGQGhtMGw2nBkAUYzhgMZwRDVmA4azCcFQzZgOGcwXBOMGQHhvMGw3nBkAMYLhgMFwRDTmC4aDBcFAy5gOGSwXBJMOQGhssGw2XBkAcYrhgMVwRDXmC4ajBcFQz5gOGawXBNMOQHhusGw3XBUAAYbhgMNwRDQWC4aTDcFAyFgOGWwXBLMBQGhtsGw23BUAQY7hgMdwRDUWC4azDcFQzFgOGewXBPMBQHhvsGw33BUAIYHhgMDwRDSWB4aDA8FAylgOGRwfBIMJQGhscGw2PBUAYYnhgMTwRDWWB4ajA8FQzlgOGZwfBMMJQHhucGw3PBUAEYXhgMLwRDRWB4aTC8FAyVgOGVwfBKMFQGhtcGw2vBUAUY3hgMbwRDVWB4azC8FQzVgOGdwfBOMFQHhvcGw3vBUAMYPhgMHwRDTWD4aDB8FAy1gOGTwfBJMNQGhs8Gw2fBUAcYvpgRekOwQQ11gSGMwRBGMNQDhrAGQ1jBUB8YwhkM4QRDA2AIbzCEFwwNgSGCwRBBMDQChogGQ0TB0BgYIhkMkQRDE2CIbDBEFgxNgSGKwRBFMDQDhqgGQ1TB0BwYohkM0QRDC2CIbjBEFwwtgSGGwRBDMLQChpgGQ0zB0BoYYhkMsQRDG2CIbTDEFgxtgSGOwRBHMLQDhrgGQ1zB0B4Y4hkM8QRDB2CIbzDEFwxfAkMCgyGBYPgKGBIaDAkFw9fAkMhgSCQYvgGGxAZDYsHwLTAkMRiSCIbvgCGpwZBUMHwPDMkMhmSC4QdgSG4wJBcMPwJDCoMhhWD4CRhSGgwpBcPPwJDKYEglGH4BhtQGQ2rB8CswpDEY0giG34AhrcGQVjD8DgzpDIZ0guEPYEhvMKQXDH8CQwaDIYNg+AsYMhoMGQXD38CQyWDIJBj+AYbMBkNmwfAvMGQxGLIIhv+AIavBkFUwdASGbAZDNsHQCRiyGwzZBUNnYMhhMOQQDF2AIafBkFMwdAWGXAZDLsHQDRhyGwy5BUN3YMhjMOQRDD2AIa/BkFcw9ASGfAZDPsHQCxjyGwz5BUNvYChgMBQQDH2AoaDBUFAw9AWGQgZDIcHQDxgKGwyFBUN/YChiMBQRDAOAoajBUFQwDASGYgZDMcEwCBiKGwzFBcNgYChhMJQQDEOAoaTBUFIwDAWGUgZDKcEwDBhKGwylBcNwYChjMJQRDCOAoazBUFYwjASGcgZDOcEwChjKGwzlBcNoYKhgMFQQDGOAoaLBUFEwjAWGSgZDJcEwDhgqGwyVBcN4YKhiMFQRDBOAoarBUFUwTASGagZDNcEwCRiqGwzVBcNkYKhhMNQQDFOAoabBUFMwBIChlsFQSzBMBYbaBkNtwTANGOoYDHUEw3RgqGsw1BUMM4ChnsFQTzDMBIb6BkN9wTALGBoYDA0Ew2xgaGgwNBQMc4ChkcHQSDDMBYbGBkNjwTAPGJoYDE0Ew3xgaGowNBUMC4ChmcHQTDAsBIbmBkNzwbAIGFoYDC0Ew2JgaGkwtBQMS4ChlcHQSjAsBYbWBkNrwbAMGNoYDG0Ew3JgaGswtBUMK4ChncHQTjCsBIb2BkN7wbAKGDoYDB0Ew2pg+NJg+FIwrAGGrwyGrwTDWmD42mD4WjCsA4ZvDIZvBMN6YPjWYPhWMGwAhu8Mhu8Ew0Zg+N5g+F4wbAKGHwyGHwTDZmD40WD4UTBsAYafDIafBMNWYPjZYPhZMGwDhl8Mhl8Ew3Zg+NVg+FUw7ACG3wyG3wTDTmD43WD4XTDsAoY/DIY/BMNuYPjTYPhTMOwBhr8Mhr8Ew15g+Ntg+Fsw7AOGfwyGfwTDfmD412D4VzAcAIb/DIb/BMNBYOhoMHQUDIeAoZPB0EkwHAaGzgZDZ8FwBBi6GAxdBMNRYOhqMHQVDMeAoZvB0E0wHAeG7gZDd8FwAhh6GAw9BMNJYOhpMPQUDKeAoZfB0EswnAaG3gZDb8FwBhj6GAx9BMNZYOhrMPQVDOeAoZ/B0E8wnAeG/gZDf8FwARgGGAwDBMNFYBhoMAwUDJeAYZDBMEgwXAaGwQbDYMFwBRiGGAxDBMNVYBhqMAwVDNeAYZjBMEwwXAeG4QbDcMFwAxhGGAwjBMNNYBhpMIwUDLeAYZTBMEow3AaG0QbDaMFwBxjGGAxjBMNdYBhrMIwVDPeAYZzBME4w3AeG8QbDeMHwABgmGAwTBMNDYJhoMEwUDI+AYZLBMEkwPAaGyQbDZMHwBBimGAxTBMNTYAgYDAHB8AwYphoMUwXDc2CYZjBMEwwvgGG6wTBdMLwEhhkGwwzB8AoYZhoMMwXDa2CYZTDMEgxvgGG2wTBbMLwFhjkGwxzB8A4Y5hoMcwXDe2CYZzDMEwwfgGG+wTBfMHwEhgUGwwLB8AkYFhoMCwXDZ2BYZDCsmsgNwRv+P9f+PxkWGwwbRguGuP+7YYnBsGSa8J3O8r8blobYsOn/DMH3//d9/0/rWjYDzOwLvq4wkf9vb0fyvQ0b+X83LDecj+XCsyYcMKwwGFYIhvDAsNJgWCkYIgDDKsczXzBEBIbVBsNqwRAJGNYYDGsEQ2RgWGswrBUMUYBhncGwTjBEBYb1BsN6wRANGDY4fscJhujAsNFg2CgYYgDDJoNhk2CICQybDYbNgiEWMGwxGLYIhtjAsNVg2CoY4gDDNoNhm2CICwzbDYbtgiEeMOwwGHYIhvjAsNNg2CkYEgDDLoNhl2BICAy7DYbdgiERMOwxGPYIhsTAsNdg2CsYkgDDPoNhn2BICgz7DYb9giEZMBwwGA4IhuTAcNBgOCgYUgDDIYPhkGBICQyHDYbDgiEVMBwxGI4IhtTAcNRgOCoY0gDDMYPhmGBICwzHDYbjgiEdMJwwGE4IhvTAcNJgOCkYMgDDKYPhlGDICAynDYbTgiETMJwxGM4IhszAcNZgOCsYsgDDOYPhnGDICgznDYbzgiEbMFwwGC4IhuzAcNFguCgYcgDDJYPhkmDICQyXDYbLgiEXMFwxGK4IhtzAcNVguCoY8gDDNYPhmmDICwzXDYbrgiEfMNwwGG4IhvzAcNNguCkYCgDDLYPhlmAoCAy3DYbbgqEQMNwxGO4IhsLAcNdguCsYigDDPYPhnmAoCgz3DYb7gqEYMDwwGB4IhuLA8NBgeCgYSgDDI4PhkWAoCQyPDYbHgqEUMDwxGJ4IhtLA8NRgeCoYygDDM4PhmWAoCwzPDYbngqEcMLwwGF4IhvLA8NJgeCkYKgDDK4PhlWCoCAyvDYbXgqESMLwxGN4IhsrA8NZgeCsYqgDDO4PhnWCoCgzvDYb3gqEaMHwwGD4IhurA8NFg+CgYagDDJ4Phk2CoCQyfDYbPgqEWMHwxM/SGYIMaagNDGIMhjGCoAwxhDYawgqEuMIQzGMIJhnrAEN5gCC8Y6gNDBIMhgmBoAAwRDYaIgqEhMEQyGCIJhkbAENlgiCwYGgNDFIMhimBoAgxRDYaogqEpMEQzGKIJhmbAEN1giC4YmgNDDIMhhmBoAQwxDYaYgqElMMQyGGIJhlbAENtgiC0YWgNDHIMhjmBoAwxxDYa4gqEtMMQzGOIJhnbAEN9giC8Y2gNDAoMhgWDoAAwJDYaEguFLYEhkMCQSDF8BQ2KDIbFg+BoYkhgMSQTDN8CQ1GBIKhi+BYZkBkMywfAdMCQ3GJILhu+BIYXBkEIw/AAMKQ2GlILhR2BIZTCkEgw/AUNqgyG1YPgZGNIYDGkEwy/AkNZgSCsYfgWGdAZDOsHwGzCkNxjSC4bfgSGDwZBBMPwBDBkNhoyC4U9gyGQwZBIMfwFDZoMhs2D4GxiyGAxZBMM/wJDVYMgqGP4FhmwGQzbB8B8wZDcYsguGjsCQw2DIIRg6AUNOgyGnYOgMDLkMhlyCoQsw5DYYcguGrsCQx2DIIxi6AUNegyGvYOgODPkMhnyCoQcw5DcY8guGnsBQwGAoIBh6AUNBg6GgYOgNDIUMhkKCoQ8wFDYYCguGvsBQxGAoIhj6AUNRg6GoYOgPDMUMhmKCYQAwFDcYiguGgcBQwmAoIRgGAUNJg6GkYBgMDKUMhlKCYQgwlDYYSguGocBQxmAoIxiGAUNZg6GsYBgODOUMhnKCYQQwlDcYyguGkcBQwWCoIBhGAUNFg6GiYBgNDJUMhkqCYQwwVDYYKguGscBQxWCoIhjGAUNVg6GqYBgPDNUMhmqCYQIwVDcYqguGicBQw2CoIRgmAUNNg6GmYJgMDLUMhlqCYQow1DYYaguGADDUMRjqCIapwFDXYKgrGKYBQz2DoZ5gmA4M9Q2G+oJhBjA0MBgaCIaZwNDQYGgoGGYBQyODoZFgmA0MjQ2GxoJhDjA0MRiaCIa5wNDUYGgqGOYBQzODoZlgmA8MzQ2G5oJhATC0MBhaCIaFwNDSYGgpGBYBQyuDoZVgWAwMrQ2G1oJhCTC0MRjaCIalwNDWYGgrGJYBQzuDoZ1gWA4M7Q2G9oJhBTB0MBg6CIaVwPClwfClYFgFDF8ZDF8JhtXA8LXB8LVgWAMM3xgM3wiGtcDwrcHwrWBYBwzfGQzfCYb1wPC9wfC9YNgADD8YDD8Iho3A8KPB8KNg2AQMPxkMPwmGzcDws8Hws2DYAgy/GAy/CIatwPCrwfCrYNgGDL8ZDL8Jhu3A8LvB8Ltg2AEMfxgMfwiGncDwp8Hwp2DYBQx/GQx/CYbdwPC3wfC3YNgDDP8YDP8Ihr3A8K/B8K9g2AcM/xkM/wmG/cDQ0WDoKBgOAEMng6GTYDgIDJ0Nhs6C4RAwdDEYugiGw8DQ1WDoKhiOAEM3g6GbYDgKDN0Nhu6C4Rgw9DAYegiG48DQ02DoKRhOAEMvg6GXYDgJDL0Nht6C4RQw9DEY+giG08DQ12DoKxjOAEM/g6GfYDgLDP0Nhv6C4RwwDDAYBgiG88Aw0GAYKBguAMMgg2GQYLgIDIMNhsGC4RIwDDEYhgiGy8Aw1GAYKhiuAMMwg2GYYLgKDMMNhuGC4RowjDAYRgiG68Aw0mAYKRhuAMMog2GUYLgJDKMNhtGC4RYwjDEYxgiG28Aw1mAYKxjuAMM4g2GcYLgLDOMNhvGC4R4wTDAYJgiG+8Aw0WCYKBgeAMMkg2GSYHgIDJMNhsmC4REwTDEYpgiGx8AQMBgCguEJMEw1GKYKhqfAMM1gmCYYngHDdINhumB4DgwzDIYZguEFMMw0GGYKhpfAMMtgmCUYXgHDbINhtmB4DQxzDIY5guENMMw1GOYKhrfAMM9gmCcY3gHDfINhvmB4DwwLDIYFguEDMCw0GBYKho/AsMhgWCQYPgHDYoNhsWD4DAxLDIYlguGLKP+7YanBsFQwhAGGZQbDMsEQFhiWGwzLBUM4YFhhMKwQDOGBYaXBsFIwRACGVQbDKsEQERhWGwyrBUMkYFhjMKwRDJGBYa3BsFYwRAGGdQbDOsEQFRjWGwzrBUM0YNhgMGwQDNGBYaPBsFEwxACGTQbDJsEQExg2GwybBUMsYNhiMGwRDLGBYavBsFUwxAGGbQbDNsEQFxi2GwzbBUM8YNhhMOwQDPGBYafBsFMwJACGXQbDLsGQEBh2Gwy7BUMiYNhjMOwRDImBYa/BsFcwJAGGfQbDPsGQFBj2Gwz7BUMyYDhgMBwQDMmB4aDBcFAwpACGQwbDIcGQEhgOGwyHBUMqYDhiMBwRDKmB4ajBcFQwpAGGYwbDMcGQFhiOGwzHBUM6YDhhMJwQDOmB4aTBcFIwZACGUwbDKcGQERhOGwynBUMmYDhjMJwRDJmB4azBcFYwZAGGcwbDOcGQFRjOGwznBUM2YLhgMFwQDNmB4aLBcFEw5ACGSwbDJcGQExguGwyXBUMuYLhiMFwRDLmB4arBcFUw5AGGawbDNcGQFxiuGwzXBUM+YLhhMNwQDPmB4abBcFMwFACGWwbDLcFQEBhuGwy3BUMhYLhjMNwRDIWB4a7BcFcwFAGGewbDPcFQFBjuGwz3BUMxYHhgMDwQDMWB4aHB8FAwlACGRwbDI8FQEhgeGwyPBUMpYHhiMDwRDKWB4anB8FQwlAGGZwbDM8FQFhieGwzPBUM5YHhhMLwQDOWB4aXB8FIwVACGVwbDK8FQERheGwyvBUMlYHhjMLwRDJWB4a3B8FYwVAGGdwbDO8FQFRjeGwzvBUM1YPhgMHwQDNWB4aPB8FEw1ACGTwbDJ8FQExg+GwyfBUMtYPhiVugNwQY11AaGMAZDGMFQBxjCGgxhBUNdYAhnMIQTDPWAIbzBEF4w1AeGCAZDBMHQABgiGgwRBUNDYIhkMEQSDI2AIbLBEFkwNAaGKAZDFMHQBBiiGgxRBUNTYIhmMEQTDM2AIbrBEF0wNAeGGAZDDMHQAhhiGgwxBUNLYIhlMMQSDK2AIbbBEFswtAaGOAZDHMHQBhjiGgxxBUNbYIhnMMQTDO2AIb7BEF8wtAeGBAZDAsHQARgSGgwJBcOXwJDIYEgkGL4ChsQGQ2LB8DUwJDEYkgiGb4AhqcGQVDB8CwzJDIZkguE7YEhuMCQXDN8DQwqDIYVg+AEYUhoMKQXDj8CQymBIJRh+AobUBkNqwfAzMKQxGNIIhl+AIa3BkFYw/AoM6QyGdILhN2BIbzCkFwy/A0MGgyGDYPgDGDIaDBkFw5/AkMlgyCQY/gKGzAZDZsHwNzBkMRiyCIZ/gCGrwZBVMPwLDNkMhmyC4T9gyG4wZBcMHYEhh8GQQzB0AoacBkNOwdAZGHIZDLkEQxdgyG0w5BYMXYEhj8GQRzB0A4a8BkNewdAdGPIZDPkEQw9gyG8w5BcMPYGhgMFQQDD0AoaCBkNBwdAbGAoZDIUEQx9gKGwwFBYMfYGhiMFQRDD0A4aiBkNRwdAfGIoZDMUEwwBgKG4wFBcMA4GhhMFQQjAMAoaSBkNJwTAYGEoZDKUEwxBgKG0wlBYMQ4GhjMFQRjAMA4ayBkNZwTAcGMoZDOUEwwhgKG8wlBcMI4GhgsFQQTCMAoaKBkNFwTAaGCoZDJUEwxhgqGwwVBYMY4GhisFQRTCMA4aqBkNVwTAeGKoZDNUEwwRgqG4wVBcME4GhhsFQQzBMAoaaBkNNwTAZGGoZDLUEwxRgqG0w1BYMAWCoYzDUEQxTgaGuwVBXMEwDhnoGQz3BMB0Y6hsM9QXDDGBoYDA0EAwzgaGhwdBQMMwChkYGQyPBMBsYGhsMjQXDHGBoYjA0EQxzgaGpwdBUMMwDhmYGQzPBMB8YmhsMzQXDAmBoYTC0EAwLgaGlwdBSMCwChlYGQyvBsBgYWhsMrQXDEmBoYzC0EQxLgaGtwdBWMCwDhnYGQzvBsBwY2hsM7QXDCmDoYDB0EAwrgeFLg+FLwbAKGL4yGL4SDKuB4WuD4WvBsAYYvjEYvhEMa4HhW4PhW8GwDhi+Mxi+EwzrgeF7g+F7wbABGH4wGH4QDBuB4UeD4UfBsAkYfjIYfhIMm4HhZ4PhZ8GwBRh+MRh+EQxbgeFXg+FXwbANGH4zGH4TDNuB4XeD4XfBsAMY/jAY/hAMO4HhT4PhT8GwCxj+Mhj+Egy7geFvg+FvwbAHGP4xGP4RDHuB4V+D4V/BsA8Y/jMY/hMM+4Gho8HQUTAcAIZOBkMnwXAQGDobDJ0FwyFg6GIwdBEMh4Ghq8HQVTAcAYZuBkM3wXAUGLobDN0FwzFg6GEw9BAMx4Ghp8HQUzCcAIZeBkMvwXASGHobDL0Fwylg6GMw9BEMp4Ghr8HQVzCcAYZ+BkM/wXAWGPobDP0FwzlgGGAwDBAM54FhoMEwUDBcAIZBBsMgwXARGAYbDIMFwyVgGGIwDBEMl4FhqMEwVDBcAYZhBsMwwXAVGIYbDMMFwzVgGGEwjBAM14FhpMEwUjDcAIZRBsMowXATGEYbDKMFwy1gGGMwjBEMt4FhrMEwVjDcAYZxBsM4wXAXGMYbDOMFwz1gmGAwTBAM94FhosEwUTA8AIZJBsMkwfAQGCYbDJMFwyNgmGIwTBEMj4EhYDAEBMMTYJhqMEwVDE+BYZrBME0wPAOG6QbDdMHwHBhmGAwzBMMLYJhpMMwUDC+BYZbBMEswvAKG2QbDbMHwGhjmGAxzBMMbYJhrMMwVDG+BYZ7BME8wvAOG+QbDfMHwHhgWGAwLBMMHYFhoMCwUDB+BYZHBsEgwfAKGxQbDYsHwGRiWhNgQJvz/NUZyQ9jw/7thqWEOS4U5hAOGZQbDMsEQHhiWGwzLBUMEYFhhMKwQDBGBYaXBsFIwRAKGVQbDKsEQGRhWGwyrBUMUYFhjMKwRDFGBYa3BsFYwRAOGdQbDOsEQHRjWGwzrBUMMYNhgMGwQDDGBYaPBsFEwxAKGTQbDJsEQGxg2GwybBUMcYNhiMGwRDHGBYavBsFUwxAOGbQbDNsEQHxi2GwzbBUMCYNhhMOwQDAmBYafBsFMwJAKGXQbDLsGQGBh2Gwy7BUMSYNhjMOwRDEmBYa/BsFcwJAOGfQbDPsGQHBj2Gwz7BUMKYDhgMBwQDCmB4aDBcFAwpAKGQwbDIcGQGhgOGwyHBUMaYDhiMBwRDGmB4ajBcFQwpAOGYwbDMcGQHhiOGwzHBUMGYDhhMJwQDBmB4aTBcFIwZAKGUwbDKcGQGRhOGwynBUMWYDhjMJwRDFmB4azBcFYwZAOGcwbDOcGQHRjOGwznBUMOYLhgMFwQDDmB4aLBcFEw5AKGSwbDJcGQGxguGwyXBUMeYLhiMFwRDHmB4arBcFUw5AOGawbDNcGQHxiuGwzXBUMBYLhhMNwQDAWB4abBcFMwFAKGWwbDLcFQGBhuGwy3BUMRYLhjMNwRDEWB4a7BcFcwFAOGewbDPcFQHBjuGwz3BUMJYHhgMDwQDCWB4aHB8FAwlAKGRwbDI8FQGhgeGwyPBUMZYHhiMDwRDGWB4anB8FQwlAOGZwbDM8FQHhieGwzPBUMFYHhhMLwQDBWB4aXB8FIwVAKGVwbDK8FQGRheGwyvBUMVYHhjMLwRDFWB4a3B8FYwVAOGdwbDO8FQHRjeGwzvBUMNYPhgMHwQDDWB4aPB8FEw1AKGTwbDJ8FQGxg+GwyfBUMdYPhidugNwQY11AWGMAZDGMFQDxjCGgxhBUN9YAhnMIQTDA2AIbzBEF4wNASGCAZDBMHQCBgiGgwRBUNjYIhkMEQSDE2AIbLBEFkwNAWGKAZDFMHQDBiiGgxRBUNzYIhmMEQTDC2AIbrBEF0wtASGGAZDDMHQChhiGgwxBUNrYIhlMMQSDG2AIbbBEFswtAWGOAZDHMHQDhjiGgxxBUN7YIhnMMQTDB2AIb7BEF8wfAkMCQyGBILhK2BIaDAkFAxfA0MigyGRYPgGGBIbDIkFw7fAkMRgSCIYvgOGpAZDUsHwPTAkMxiSCYYfgCG5wZBcMPwIDCkMhhSC4SdgSGkwpBQMPwNDKoMhlWD4BRhSGwypBcOvwJDGYEgjGH4DhrQGQ1rB8DswpDMY0gmGP4AhvcGQXjD8CQwZDIYMguEvYMhoMGQUDH8DQyaDIZNg+AcYMhsMmQXDv8CQxWDIIhj+A4asBkNWwdARGLIZDNkEQydgyG4wZBcMnYEhh8GQQzB0AYacBkNOwdAVGHIZDLkEQzdgyG0w5BYM3YEhj8GQRzD0AIa8BkNewdATGPIZDPkEQy9gyG8w5BcMvYGhgMFQQDD0AYaCBkNBwdAXGAoZDIUEQz9gKGwwFBYM/YGhiMFQRDAMAIaiBkNRwTAQGIoZDMUEwyBgKG4wFBcMg4GhhMFQQjAMAYaSBkNJwTAUGEoZDKUEwzBgKG0wlBYMw4GhjMFQRjCMAIayBkNZwTASGMoZDOUEwyhgKG8wlBcMo4GhgsFQQTCMAYaKBkNFwTAWGCoZDJUEwzhgqGwwVBYM44GhisFQRTBMAIaqBkNVwTARGKoZDNUEwyRgqG4wVBcMk4GhhsFQQzBMAYaaBkNNwRAAhloGQy3BMBUYahsMtQXDNGCoYzDUEQzTgaGuwVBXMMwAhnoGQz3BMBMY6hsM9QXDLGBoYDA0EAyzgaGhwdBQMMwBhkYGQyPBMBcYGhsMjQXDPGBoYjA0EQzzgaGpwdBUMCwAhmYGQzPBsBAYmhsMzQXDImBoYTC0EAyLgaGlwdBSMCwBhlYGQyvBsBQYWhsMrQXDMmBoYzC0EQzLgaGtwdBWMKwAhnYGQzvBsBIY2hsM7QXDKmDoYDB0EAyrgeFLg+FLwbAGGL4yGL4SDGuB4WuD4WvBsA4YvjEYvhEM64HhW4PhW8GwARi+Mxi+EwwbgeF7g+F7wbAJGH4wGH4QDJuB4UeD4UfBsAUYfjIYfhIMW4HhZ4PhZ8GwDRh+MRh+EQzbgeFXg+FXwbADGH4zGH4TDDuB4XeD4XfBsAsY/jAY/hAMu4HhT4PhT8GwBxj+Mhj+Egx7geFvg+FvwbAPGP4xGP4RDPuB4V+D4V/BcAAY/jMY/hMMB4Gho8HQUTAcAoZOBkMnwXAYGDobDJ0FwxFg6GIwdBEMR4Ghq8HQVTAcA4ZuBkM3wXAcGLobDN0Fwwlg6GEw9BAMJ4Ghp8HQUzCcAoZeBkMvwXAaGHobDL0Fwxlg6GMw9BEMZ4Ghr8HQVzCcA4Z+BkM/wXAeGPobDP0FwwVgGGAwDBAMF4FhoMEwUDBcAoZBBsMgwXAZGAYbDIMFwxVgGGIwDBEMV4FhqMEwVDBcA4ZhBsMwwXAdGIYbDMMFww1gGGEwjBAMN4FhpMEwUjDcAoZRBsMowXAbGEYbDKMFwx1gGGMwjBEMd4FhrMEwVjDcA4ZxBsM4wXAfGMYbDOMFwwNgmGAwTBAMD4FhosEwUTA8AoZJBsMkwfAYGCYbDJMFwxNgmGIwTBEMT4EhYDAEBMMzYJhqMEwVDM+BYZrBME0wvACG6QbDdMHwEhhmGAwzBMMrYJhpMMwUDK+BYZbBMEswvAGG2QbDbMHwFhjmGAxzBMM7YJhrMMwVDO+BYZ7BME8wfACG+QbDfMHwERgWGAwLBMMnYFhoMCwUDJ+BYZHBsEgwfBHhfzcsNhgWC4YwwLDEYFgiGMICw1KDYalgCAcMywyGZYIhPDAsNxiWC4YIwLDCYFghGCICw0qDYaVgiAQMqwyGVYIhMjCsNhhWC4YowLDGYFgjGKICw1qDYa1giAYM6wyGdYIhOjCsNxjWC4YYwLDBYNggGGICw0aDYaNgiAUMmwyGTYIhNjBsNhg2C4Y4wLDFYNgiGOICw1aDYatgiAcM2wyGbYIhPjBsNxi2C4YEwLDDYNghGBICw06DYadgSAQMuwyGXYIhMTDsNhh2C4YkwLDHYNgjGJICw16DYa9gSAYM+wyGfYIhOTDsNxj2C4YUwHDAYDggGFICw0GD4aBgSAUMhwyGQ4IhNTAcNhgOC4Y0wHDEYDgiGNICw1GD4ahgSAcMxwyGY4IhPTAcNxiOC4YMwHDCYDghGDICw0mD4aRgyAQMpwyGU4IhMzCcNhhOC4YswHDGYDgjGLICw1mD4axgyAYM5wyGc4IhOzCcNxjOC4YcwHDBYLggGHICw0WD4aJgyAUMlwyGS4IhNzBcNhguC4Y8wHDFYLgiGPICw1WD4apgyAcM1wyGa4IhPzBcNxiuC4YCwHDDYLghGAoCw02D4aZgKAQMtwyGW4KhMDDcNhhuC4YiwHDHYLgjGIoCw12D4a5gKAYM9wyGe4KhODDcNxjuC4YSwPDAYHggGEoCw0OD4aFgKAUMjwyGR4KhNDA8NhgeC4YywPDEYHgiGMoCw1OD4algKAcMzwyGZ4KhPDA8NxieC4YKwPDCYHghGCoCw0uD4aVgqAQMrwyGV4KhMjC8NhheC4YqwPDGYHgjGKoCw1uD4a1gqAYM7wyGd4KhOjC8NxjeC4YawPDBYPggGGoCw0eD4aNgqAUMnwyGT4KhNjB8Nhg+C4Y6wPDFnNAbgg1qqAsMYQyGMIKhHjCENRjCCob6wBDOYAgnGBoAQ3iDIbxgaAgMEQyGCIKhETBENBgiCobGwBDJYIgkGJoAQ2SDIbJgaAoMUQyGKIKhGTBENRiiCobmwBDNYIgmGFoAQ3SDIbpgaAkMMQyGGIKhFTDENBhiCobWwBDLYIglGNoAQ2yDIbZgaAsMcQyGOIKhHTDENRjiCob2wBDPYIgnGDoAQ3yDIb5g+BIYEhgMCQTDV8CQ0GBIKBi+BoZEBkMiwfANMCQ2GBILhm+BIYnBkEQwfAcMSQ2GpILhe2BIZjAkEww/AENygyG5YPgRGFIYDCkEw0/AkNJgSCkYfgaGVAZDKsHwCzCkNhhSC4ZfgSGNwZBGMPwGDGkNhrSC4XdgSGcwpBMMfwBDeoMhvWD4ExgyGAwZBMNfwJDRYMgoGP4GhkwGQybB8A8wZDYYMguGf4Ehi8GQRTD8BwxZDYasgqEjMGQzGLIJhk7AkN1gyC4YOgNDDoMhh2DoAgw5DYacgqErMOQyGHIJhm7AkNtgyC0YugNDHoMhj2DoAQx5DYa8gqEnMOQzGPIJhl7AkN9gyC8YegNDAYOhgGDoAwwFDYaCgqEvMBQyGAoJhn7AUNhgKCwY+gNDEYOhiGAYAAxFDYaigmEgMBQzGIoJhkHAUNxgKC4YBgNDCYOhhGAYAgwlDYaSgmEoMJQyGEoJhmHAUNpgKC0YhgNDGYOhjGAYAQxlDYaygmEkMJQzGMoJhlHAUN5gKC8YRgNDBYOhgmAYAwwVDYaKgmEsMFQyGCoJhnHAUNlgqCwYxgNDFYOhimCYAAxVDYaqgmEiMFQzGKoJhknAUN1gqC4YJgNDDYOhhmCYAgw1DYaagiEADLUMhlqCYSow1DYYaguGacBQx2CoIximA0Ndg6GuYJgBDPUMhnqCYSYw1DcY6guGWcDQwGBoIBhmA0NDg6GhYJgDDI0MhkaCYS4wNDYYGguGecDQxGBoIhjmA0NTg6GpYFgADM0MhmaCYSEwNDcYmguGRcDQwmBoIRgWA0NLg6GlYFgCDK0MhlaCYSkwtDYYWguGZcDQxmBoIxiWA0Nbg6GtYFgBDO0MhnaCYSUwtDcY2guGVcDQwWDoIBhWA8OXBsOXgmENMHxlMHwlGNYCw9cGw9eCYR0wfGMwfCMY1gPDtwbDt4JhAzB8ZzB8Jxg2AsP3BsP3gmETMPxgMPwgGDYDw48Gw4+CYQsw/GQw/CQYtgLDzwbDz4JhGzD8YjD8Ihi2A8OvBsOvgmEHMPxmMPwmGHYCw+8Gw++CYRcw/GEw/CEYdgPDnwbDn4JhDzD8ZTD8JRj2AsPfBsPfgmEfMPxjMPwjGPYDw78Gw7+C4QAw/Gcw/CcYDgJDR4Oho2A4BAydDIZOguEwMHQ2GDoLhiPA0MVg6CIYjgJDV4Ohq2A4BgzdDIZuguE4MHQ3GLoLhhPA0MNg6CEYTgJDT4Ohp2A4BQy9DIZeguE0MPQ2GHoLhjPA0Mdg6CMYzgJDX4Ohr2A4Bwz9DIZ+guE8MPQ3GPoLhgvAMMBgGCAYLgLDQINhoGC4BAyDDIZBguEyMAw2GAYLhivAMMRgGCIYrgLDUINhqGC4BgzDDIZhguE6MAw3GIYLhhvAMMJgGCEYbgLDSINhpGC4BQyjDIZRguE2MIw2GEYLhjvAMMZgGCMY7gLDWINhrGC4BwzjDIZxguE+MIw3GMYLhgfAMMFgmCAYHgLDRINhomB4BAyTDIZJguExMEw2GCYLhifAMMVgmCIYngJDwGAICIZnwDDVYJgqGJ4DwzSDYZpgeAEM0w2G6YLhJTDMMBhmCIZXwDDTYJgpGF4DwyyDYZZgeAMMsw2G2YLhLTDMMRjmCIZ3wDDXYJgrGN4DwzyDYZ5g+AAM8w2G+YLhIzAsMBgWCIZPwLDQYFgoGD4Dw6IQGz5m++KLoAPPIdv/blhsmMNiZQ7AsMRgWCIYvsj+vxuWGgxLBUMYYFhmMCwTDGGBYbnBsFwwhAOGFQbDCsEQHhhWGgwrBUMEYFhlMKwSDBGBYbXBsFowRAKGNQbDGsEQGRjWGgxrBUMUYFhnMKwTDFGBYb3BsF4wRAOGDQbDBsEQHRg2GgwbBUMMYNhkMGwSDDGBYbPBsFkwxAKGLQbDFsEQGxi2GgxbBUMcYNhmMGwTDHGBYbvBsF0wxAOGHQbDDsEQHxh2Ggw7BUMCYNhlMOwSDAmBYbfBsFswJAKGPQbDHsGQGBj2Ggx7BUMSYNhnMOwTDEmBYb/BsF8wJAOGAwbDAcGQHBgOGgwHBUMKYDhkMBwSDCmB4bDBcFgwpAKGIwbDEcGQGhiOGgxHBUMaYDhmMBwTDGmB4bjBcFwwpAOGEwbDCcGQHhhOGgwnBUMGYDhlMJwSDBmB4bTBcFowZAKGMwbDGcGQGRjOGgxnBUMWYDhnMJwTDFmB4bzBcF4wZAOGCwbDBcGQHRguGgwXBUMOYLhkMFwSDDmB4bLBcFkw5AKGKwbDFcGQGxiuGgxXBUMeYLhmMFwTDHmB4brBcF0w5AOGGwbDDcGQHxhuGgw3BUMBYLhlMNwSDAWB4bbBcFswFAKGOwbDHcFQGBjuGgx3BUMRYLhnMNwTDEWB4b7BcF8wFAOGBwbDA8FQHBgeGgwPBUMJYHhkMDwSDCWB4bHB8FgwlAKGJwbDE8FQGhieGgxPBUMZYHhmMDwTDGWB4bnB8FwwlAOGFwbDC8FQHhheGgwvBUMFYHhlMLwSDBWB4bXB8FowVAKGNwbDG8FQGRjeGgxvBUMVYHhnMLwTDFWB4b3B8F4wVAOGDwbDB8FQHRg+GgwfBUMNYPhkMHwSDDWB4bPB8Fkw1AKGL+aG3hBsUENtYAhjMIQRDHWAIazBEFYw1AWGcAZDOMFQDxjCGwzhBUN9YIhgMEQQDA2AIaLBEFEwNASGSAZDJMHQCBgiGwyRBUNjYIhiMEQRDE2AIarBEFUwNAWGaAZDNMHQDBiiGwzRBUNzYIhhMMQQDC2AIabBEFMwtASGWAZDLMHQChhiGwyxBUNrYIhjMMQRDG2AIa7BEFcwtAWGeAZDPMHQDhjiGwzxBUN7YEhgMCQQDB2AIaHBkFAwfAkMiQyGRILhK2BIbDAkFgxfA0MSgyGJYPgGGJIaDEkFw7fAkMxgSCYYvgOG5AZDcsHwPTCkMBhSCIYfgCGlwZBSMPwIDKkMhlSC4SdgSG0wpBYMPwNDGoMhjWD4BRjSGgxpBcOvwJDOYEgnGH4DhvQGQ3rB8DswZDAYMgiGP4Aho8GQUTD8CQyZDIZMguEvYMhsMGQWDH8DQxaDIYtg+AcYshoMWQXDv8CQzWDIJhj+A4bsBkN2wdARGHIYDDkEQydgyGkw5BQMnYEhl8GQSzB0AYbcBkNuwdAVGPIYDHkEQzdgyGsw5BUM3YEhn8GQTzD0AIb8BkN+wdATGAoYDAUEQy9gKGgwFBQMvYGhkMFQSDD0AYbCBkNhwdAXGIoYDEUEQz9gKGowFBUM/YGhmMFQTDAMAIbiBkNxwTAQGEoYDCUEwyBgKGkwlBQMg4GhlMFQSjAMAYbSBkNpwTAUGMoYDGUEwzBgKGswlBUMw4GhnMFQTjCMAIbyBkN5wTASGCoYDBUEwyhgqGgwVBQMo4GhksFQSTCMAYbKBkNlwTAWGKoYDFUEwzhgqGowVBUM44GhmsFQTTBMAIbqBkN1wTARGGoYDDUEwyRgqGkw1BQMk4GhlsFQSzBMAYbaBkNtwRAAhjoGQx3BMBUY6hoMdQXDNGCoZzDUEwzTgaG+wVBfMMwAhgYGQwPBMBMYGhoMDQXDLGBoZDA0EgyzgaGxwdBYMMwBhiYGQxPBMBcYmhoMTQXDPGBoZjA0EwzzgaG5wdBcMCwAhhYGQwvBsBAYWhoMLQXDImBoZTC0EgyLgaG1wdBaMCwBhjYGQxvBsBQY2hoMbQXDMmBoZzC0EwzLgaG9wdBeMKwAhg4GQwfBsBIYvjQYvhQMq4DhK4PhK8GwGhi+Nhi+FgxrgOEbg+EbwbAWGL41GL4VDOuA4TuD4TvBsB4YvjcYvhcMG4DhB4PhB8GwERh+NBh+FAybgOEng+EnwbAZGH42GH4WDFuA4ReD4RfBsBUYfjUYfhUM24DhN4PhN8GwHRh+Nxh+Fww7gOEPg+EPwbATGP40GP4UDLuA4S+D4S/BsBsY/jYY/hYMe4DhH4PhH8GwFxj+NRj+FQz7gOE/g+E/wbAfGDoaDB0FwwFg6GQwdBIMB4Ghs8HQWTAcAoYuBkMXwXAYGLoaDF0FwxFg6GYwdBMMR4Ghu8HQXTAcA4YeBkMPwXAcGHoaDD0Fwwlg6GUw9BIMJ4Ght8HQWzCcAoY+BkMfwXAaGPoaDH0Fwxlg6Gcw9BMMZ4Ghv8HQXzCcA4YBBsMAwXAeGAYaDAMFwwVgGGQwDBIMF4FhsMEwWDBcAoYhBsMQwXAZGIYaDEMFwxVgGGYwDBMMV4FhuMEwXDBcA4YRBsMIwXAdGEYaDCMFww1gGGUwjBIMN4FhtMEwWjDcAoYxBsMYwXAbGMYaDGMFwx1gGGcwjBMMd4FhvMEwXjDcA4YJBsMEwXAfGCYaDBMFwwNgmGQwTBIMD4FhssEwWTA8AoYpBsMUwfAYGAIGQ0AwPAGGqQbDVMHwFBimGQzTBMMzYJhuMEwXDM+BYYbBMEMwvACGmQbDTMHwEhhmGQyzBMMrYJhtMMwWDK+BYY7BMEcwvAGGuQbDXMHwFhjmGQzzBMM7YJhvMMwXDO+BYYHBsEAwfACGhQbDQsHwERgWGQyLBMMnYFhsMCwWDJ+BYYnBsEQwfJHjfzcsNRiWCoYwwLDMYFgmGMICw3KDYblgCAcMKwyGFYIhPDCsNBhWCoYIwLDKYFglGCICw2qDYbVgiAQMawyGNYIhMjCsNRjWCoYowLDOYFgnGKICw3qDYb1giAYMGwyGDYIhOjBsNBg2CoYYwLDJYNgkGGICw2aDYbNgiAUMWwyGLYIhNjBsNRi2CoY4wLDNYNgmGOICw3aDYbtgiAcMOwyGHYIhPjDsNBh2CoYEwLDLYNglGBICw26DYbdgSAQMewyGPYIhMTDsNRj2CoYkwLDPYNgnGJICw36DYb9gSAYMBwyGA4IhOTAcNBgOCoYUwHDIYDgkGFICw2GD4bBgSAUMRwyGI4IhNTAcNRiOCoY0wHDMYDgmGNICw3GD4bhgSAcMJwyGE4IhPTCcNBhOCoYMwHDKYDglGDICw2mD4bRgyAQMZwyGM4IhMzCcNRjOCoYswHDOYDgnGLICw3mD4bxgyAYMFwyGC4IhOzBcNBguCoYcwHDJYLgkGHICw2WD4bJgyAUMVwyGK4IhNzBcNRiuCoY8wHDNYLgmGPICw3WD4bpgyAcMNwyGG4IhPzDcNBhuCoYCwHDLYLglGAoCw22D4bZgKAQMdwyGO4KhMDDcNRjuCoYiwHDPYLgnGIoCw32D4b5gKAYMDwyGB4KhODA8NBgeCoYSwPDIYHgkGEoCw2OD4bFgKAUMTwyGJ4KhNDA8NRieCoYywPDMYHgmGMoCw3OD4blgKAcMLwyGF4KhPDC8NBheCoYKwPDKYHglGCoCw2uD4bVgqAQMbwyGN4KhMjC8NRjeCoYqwPDOYHgnGKoCw3uD4b1gqAYMHwyGD4KhOjB8NBg+CoYawPDJYPgkGGoCw2eD4bNgqAUMX8wLvSHYoIbawBDGYAgjGOoAQ1iDIaxgqAsM4QyGcIKhHjCENxjCC4b6wBDBYIggGBoAQ0SDIaJgaAgMkQyGSIKhETBENhgiC4bGwBDFYIgiGJoAQ1SDIapgaAoM0QyGaIKhGTBENxiiC4bmwBDDYIghGFoAQ0yDIaZgaAkMsQyGWIKhFTDENhhiC4bWwBDHYIgjGNoAQ1yDIa5gaAsM8QyGeIKhHTDENxjiC4b2wJDAYEggGDoAQ0KDIaFg+BIYEhkMiQTDV8CQ2GBILBi+BoYkBkMSwfANMCQ1GJIKhm+BIZnBkEwwfAcMyQ2G5ILhe2BIYTCkEAw/AENKgyGlYPgRGFIZDKkEw0/AkNpgSC0YfgaGNAZDGsHwCzCkNRjSCoZfgSGdwZBOMPwGDOkNhvSC4XdgyGAwZBAMfwBDRoMho2D4ExgyGQyZBMNfwJDZYMgsGP4GhiwGQxbB8A8wZDUYsgqGf4Ehm8GQTTD8BwzZDYbsgqEjMOQwGHIIhk7AkNNgyCkYOgNDLoMhl2DoAgy5DYbcgqErMOQxGPIIhm7AkNdgyCsYugNDPoMhn2DoAQz5DYb8gqEnMBQwGAoIhl7AUNBgKCgYegNDIYOhkGDoAwyFDYbCgqEvMBQxGIoIhn7AUNRgKCoY+gNDMYOhmGAYAAzFDYbigmEgMJQwGEoIhkHAUNJgKCkYBgNDKYOhlGAYAgylDYbSgmEoMJQxGMoIhmHAUNZgKCsYhgNDOYOhnGAYAQzlDYbygmEkMFQwGCoIhlHAUNFgqCgYRgNDJYOhkmAYAwyVDYbKgmEsMFQxGKoIhnHAUNVgqCoYxgNDNYOhmmCYAAzVDYbqgmEiMNQwGGoIhknAUNNgqCkYJgNDLYOhlmCYAgy1DYbagiEADHUMhjqCYSow1DUY6gqGacBQz2CoJximA0N9g6G+YJgBDA0MhgaCYSYwNDQYGgqGWcDQyGBoJBhmA0Njg6GxYJgDDE0MhiaCYS4wNDUYmgqGecDQzGBoJhjmA0Nzg6G5YFgADC0MhhaCYSEwtDQYWgqGRcDQymBoJRgWA0Nrg6G1YFgCDG0MhjaCYSkwtDUY2gqGZcDQzmBoJxiWA0N7g6G9YFgBDB0Mhg6CYSUwfGkwfCkYVgHDVwbDV4JhNTB8bTB8LRjWAMM3BsM3gmEtMHxrMHwrGNYBw3cGw3eCYT0wfG8wfC8YNgDDDwbDD4JhIzD8aDD8KBg2AcNPBsNPgmEzMPxsMPwsGLYAwy8Gwy+CYSsw/Gow/CoYtgHDbwbDb4JhOzD8bjD8Lhh2AMMfBsMfgmEnMPxpMPwpGHYBw18Gw1+CYTcw/G0w/C0Y9gDDPwbDP4JhLzD8azD8Kxj2AcN/BsN/gmE/MHQ0GDoKhgPA0Mlg6CQYDgJDZ4Ohs2A4BAxdDIYuguEwMHQ1GLoKhiPA0M1g6CYYjgJDd4Ohu2A4Bgw9DIYeguE4MPQ0GHoKhhPA0Mtg6CUYTgJDb4Oht2A4BQx9DIY+guE0MPQ1GPoKhjPA0M9g6CcYzgJDf4Ohv2A4BwwDDIYBguE8MAw0GAYKhgvAMMhgGCQYLgLDYINhsGC4BAxDDIYhguEyMAw1GIYKhivAMMxgGCYYrgLDcINhuGC4BgwjDIYRguE6MIw0GEYKhhvAMMpgGCUYbgLDaINhtGC4BQxjDIYxguE2MIw1GMYKhjvAMM5gGCcY7gLDeINhvGC4BwwTDIYJguE+MEw0GCYKhgfAMMlgmCQYHgLDZINhsmB4BAxTDIYpguExMAQMhoBgeAIMUw2GqYLhKTBMMximCYZnwDDdYJguGJ4DwwyDYYZgeAEMMw2GmYLhJTDMMhhmCYZXwDDbYJgtGF4DwxyDYY5geAMMcw2GuYLhLTDMMxjmCYZ3wDDfYJgvGN4DwwKDYYFg+AAMCw2GhYLhIzAsMhgWCYZPwLDYYFgsGD4DwxKDYYlg+CLn/25YajAsFQxhgGGZwbBMMIQFhuUGw3LBEA4YVhgMKwRDeGBYaTCsFAwRgGGVwbBKMEQEhtUGw2rBEAkY1hgMawRDZGBYazCsFQxRgGGdwbBOMEQFhvUGw3rBEA0YNhgMGwRDdGDYaDBsFAwxgGGTwbBJMMQEhs0Gw2bBEAsYthgMWwRDbGDYajBsFQxxgGGbwbBNMMQFhu0Gw3bBEA8YdhgMOwRDfGDYaTDsFAwJgGGXwbBLMCQEht0Gw27BkAgY9hgMewRDYmDYazDsFQxJgGGfwbBPMCQFhv0Gw37BkAwYDhgMBwRDcmA4aDAcFAwpgOGQwXBIMKQEhsMGw2HBkAoYjhgMRwRDamA4ajAcFQxpgOGYwXBMMKQFhuMGw3HBkA4YThgMJwRDemA4aTCcFAwZgOGUwXBKMGQEhtMGw2nBkAkYzhgMZwRDZmA4azCcFQxZgOGcwXBOMGQFhvMGw3nBkA0YLhgMFwRDdmC4aDBcFAw5gOGSwXBJMOQEhssGw2XBkAsYrhgMVwRDbmC4ajBcFQx5gOGawXBNMOQFhusGw3XBkA8YbhgMNwRDfmC4aTDcFAwFgOGWwXBLMBQEhtsGw23BUAgY7hgMdwRDYWC4azDcFQxFgOGewXBPMBQFhvsGw33BUAwYHhgMDwRDcWB4aDA8FAwlgOGRwfBIMJQEhscGw2PBUAoYnhgMTwRDaWB4ajA8FQxlgOGZwfBMMJQFhucGw3PBUA4YXhgMLwRDeWB4aTC8FAwVgOGVwfBKMFQEhtcGw2vBUAkY3hgMbwRDZWB4azC8FQxVgOGdwfBOMFQFhvcGw3vBUA0YPhgMHwRDdWD4aDB8FAw1gOGTwfBJMNQEhs8Gw2fBUAsYvpgfekOwQQ21gSGMwRBGMNQBhrAGQ1jBUBcYwhkM4QRDPWAIbzCEFwz1gSGCwRBBMDQAhogGQ0TB0BAYIhkMkQRDI2CIbDBEFgyNgSGKwRBFMDQBhqgGQ1TB0BQYohkM0QRDM2CIbjBEFwzNgSGGwRBDMLQAhpgGQ0zB0BIYYhkMsQRDK2CIbTDEFgytgSGOwRBHMLQBhrgGQ1zB0BYY4hkM8QRDO2CIbzDEFwztgSGBwZBAMHQAhoQGQ0LB8CUwJDIYEgmGr4AhscGQWDB8DQxJDIYkguEbYEhqMCQVDN8CQzKDIZlg+A4YkhsMyQXD98CQwmBIIRh+AIaUBkNKwfAjMKQyGFIJhp+AIbXBkFow/AwMaQyGNILhF2BIazCkFQy/AkM6gyGdYPgNGNIbDOkFw+/AkMFgyCAY/gCGjAZDRsHwJzBkMhgyCYa/gCGzwZBZMPwNDFkMhiyC4R9gyGowZBUM/wJDNoMhm2D4DxiyGwzZBUNHYMhhMOQQDJ2AIafBkFMwdAaGXAZDLsHQBRhyGwy5BUNXYMhjMOQRDN2AIa/BkFcwdAeGfAZDPsHQAxjyGwz5BUNPYChgMBQQDL2AoaDBUFAw9AaGQgZDIcHQBxgKGwyFBUNfYChiMBQRDP2AoajBUFQw9AeGYgZDMcEwABiKGwzFBcNAYChhMJQQDIOAoaTBUFIwDAaGUgZDKcEwBBhKGwylBcNQYChjMJQRDMOAoazBUFYwDAeGcgZDOcEwAhjKGwzlBcNIYKhgMFQQDKOAoaLBUFEwjAaGSgZDJcEwBhgqGwyVBcNYYKhiMFQRDOOAoarBUFUwjAeGagZDNcEwARiqGwzVBcNEYKhhMNQQDJOAoabBUFMwTAaGWgZDLcEwBRhqGwy1BUMAGOoYDHUEw1RgqGsw1BUM04ChnsFQTzBMB4b6BkN9wTADGBoYDA0Ew0xgaGgwNBQMs4ChkcHQSDDMBobGBkNjwTAHGJoYDE0Ew1xgaGowNBUM84ChmcHQTDDMB4bmBkNzwbAAGFoYDC0Ew0JgaGkwtBQMi4ChlcHQSjAsBobWBkNrwbAEGNoYDG0Ew1JgaGswtBUMy4ChncHQTjAsB4b2BkN7wbACGDoYDB0Ew0pg+NJg+FIwrAKGrwyGrwTDamD42mD4WjCsAYZvDIZvBMNaYPjWYPhWMKwDhu8Mhu8Ew3pg+N5g+F4wbACGHwyGHwTDRmD40WD4UTBsAoafDIafBMNmYPjZYPhZMGwBhl8Mhl8Ew1Zg+NVg+FUwbAOG3wyG3wTDdmD43WD4XTDsAIY/DIY/BMNOYPjTYPhTMOwChr8Mhr8Ew25g+Ntg+Fsw7AGGfwyGfwTDXmD412D4VzDsA4b/DIb/BMN+YOhoMHQUDAeAoZPB0EkwHASGzgZDZ8FwCBi6GAxdBMNhYOhqMHQVDEeAoZvB0E0wHAWG7gZDd8FwDBh6GAw9BMNxYOhpMPQUDCeAoZfB0EswnASG3gZDb8FwChj6GAx9BMNpYOhrMPQVDGeAoZ/B0E8wnAWG/gZDf8FwDhgGGAwDBMN5YBhoMAwUDBeAYZDBMEgwXASGwQbDYMFwCRiGGAxDBMNlYBhqMAwVDFeAYZjBMEwwXAWG4QbDcMFwDRhGGAwjBMN1YBhpMIwUDDeAYZTBMEow3ASG0QbDaMFwCxjGGAxjBMNtYBhrMIwVDHeAYZzBME4w3AWG8QbDeMFwDxgmGAwTBMN9YJhoMEwUDA+AYZLBMEkwPASGyQbDZMHwCBimGAxTBMNjYAgYDAHB8AQYphoMUwXDU2CYZjBMEwzPgGG6wTBdMDwHhhkGwwzB8AIYZhoMMwXDS2CYZTDMEgyvgGG2wTBbMLwGhjkGwxzB8AYY5hoMcwXDW2CYZzDMEwzvgGG+wTBfMLwHhgUGwwLB8AEYFhoMCwXDR2BYZDAsEgyfgGGxwbBYMHwGhiUGwxLB8EWu/92w1GBYKhjCAMMyg2GZYAgLDMsNhuWCIRwwrDAYVgiG8MCw0mBYKRgiAMMqg2GVYIgIDKsNhtWCIRIwrDEY1giGyMCw1mBYKxiiAMM6g2GdYIgKDOsNhvWCIRowbDAYNgiG6MCw0WDYKBhiAMMmg2GTYIgJDJsNhs2CIRYwbDEYtgiG2MCw1WDYKhjiAMM2g2GbYIgLDNsNhu2CIR4w7DAYdgiG+MCw02DYKRgSAMMug2GXYEgIDLsNht2CIREw7DEY9giGxMCw12DYKxiSAMM+g2GfYEgKDPsNhv2CIRkwHDAYDgiG5MBw0GA4KBhSAMMhg+GQYEgJDIcNhsOCIRUwHDEYjgiG1MBw1GA4KhjSAMMxg+GYYEgLDMcNhuOCIR0wnDAYTgiG9MBw0mA4KRgyAMMpg+GUYMgIDKcNhtOCIRMwnDEYzgiGzMBw1mA4KxiyAMM5g+GcYMgKDOcNhvOCIRswXDAYLgiG7MBw0WC4KBhyAMMlg+GSYMgJDJcNhsuCIRcwXDEYrgiG3MBw1WC4KhjyAMM1g+GaYMgLDNcNhuuCIR8w3DAYbgiG/MBw02C4KRgKAMMtg+GWYCgIDLcNhtuCoRAw3DEY7giGwsBw12C4KxiKAMM9g+GeYCgKDPcNhvuCoRgwPDAYHgiG4sDw0GB4KBhKAMMjg+GRYCgJDI8NhseCoRQwPDEYngiG0sDw1GB4KhjKAMMzg+GZYCgLDM8NhueCoRwwvDAYXgiG8sDw0mB4KRgqAMMrg+GVYKgIDK8NhteCoRIwvDEY3giGysDw1mB4KxiqAMM7g+GdYKgKDO8NhveCoRowfDAYPgiG6sDw0WD4KBhqAMMng+GTYKgJDJ8Nhs+CoRYwfLEg9IZggxpqA0MYgyGMYKgDDGENhrCCoS4whDMYwgmGesAQ3mAILxjqA0MEgyGCYGgADBENhoiCoSEwRDIYIgmGRsAQ2WCILBgaA0MUgyGKYGgCDFENhqiCoSkwRDMYogmGZsAQ3WCILhiaA0MMgyGGYGgBDDENhpiCoSUwxDIYYgmGVsAQ22CILRhaA0McgyGOYGgDDHENhriCoS0wxDMY4gmGdsAQ32CILxjaA0MCgyGBYOgADAkNhoSC4UtgSGQwJBIMXwFDYoMhsWD4GhiSGAxJBMM3wJDUYEgqGL4FhmQGQzLB8B0wJDcYkguG74EhhcGQQjD8AAwpDYaUguFHYEhlMKQSDD8BQ2qDIbVg+BkY0hgMaQTDL8CQ1mBIKxh+BYZ0BkM6wfAbMKQ3GNILht+BIYPBkEEw/AEMGQ2GjILhT2DIZDBkEgx/AUNmgyGzYPgbGLIYDFkEwz/AkNVgyCoY/gWGbAZDNsHwHzBkNxiyC4aOwJDDYMghGDoBQ06DIadg6AwMuQyGXIKhCzDkNhhyC4auwJDHYMgjGLoBQ16DIa9g6A4M+QyGfIKhBzDkNxjyC4aewFDAYCggGHoBQ0GDoaBg6A0MhQyGQoKhDzAUNhgKC4a+wFDEYCgiGPoBQ1GDoahg6A8MxQyGYoJhADAUNxiKC4aBwFDCYCghGAYBQ0mDoaRgGAwMpQyGUoJhCDCUNhhKC4ahwFDGYCgjGIYBQ1mDoaxgGA4M5QyGcoJhBDCUNxjKC4aRwFDBYKggGEYBQ0WDoaJgGA0MlQyGSoJhDDBUNhgqC4axwFDFYKgiGMYBQ1WDoapgGA8M1QyGaoJhAjBUNxiqC4aJwFDDYKghGCYBQ02DoaZgmAwMtQyGWoJhCjDUNhhqC4YAMNQxGOoIhqnAUNdgqCsYpgFDPYOhnmCYDgz1DYb6gmEGMDQwGBoIhpnA0NBgaCgYZgFDI4OhkWCYDQyNDYbGgmEOMDQxGJoIhrnA0NRgaCoY5gFDM4OhmWCYDwzNDYbmgmEBMLQwGFoIhoXA0NJgaCkYFgFDK4OhlWBYDAytDYbWgmEJMLQxGNoIhqXA0NZgaCsYlgFDO4OhnWBYDgztDYb2gmEFMHQwGDoIhpXA8KXB8KVgWAUMXxkMXwmG1cDwtcHwtWBYAwzfGAzfCIa1wPCtwfCtYFgHDN8ZDN8JhvXA8L3B8L1g2AAMPxgMPwiGjcDwo8Hwo2DYBAw/GQw/CYbNwPCzwfCzYNgCDL8YDL8Ihq3A8KvB8Ktg2AYMvxkMvwmG7cDwu8Hwu2DYAQx/GAx/CIadwPCnwfCnYNgFDH8ZDH8Jht3A8LfB8Ldg2AMM/xgM/wiGvcDwr8Hwr2DYBwz/GQz/CYb9wNDRYOgoGA4AQyeDoZNgOAgMnQ2GzoLhEDB0MRi6CIbDwNDVYOgqGI4AQzeDoZtgOAoM3Q2G7oLhGDD0MBh6CIbjwNDTYOgpGE4AQy+DoZdgOAkMvQ2G3oLhFDD0MRj6CIbTwNDXYOgrGM4AQz+DoZ9gOAsM/Q2G/oLhHDAMMBgGCIbzwDDQYBgoGC4AwyCDYZBguAgMgw2GwYLhEjAMMRiGCIbLwDDUYBgqGK4AwzCDYZhguAoMww2G4YLhGjCMMBhGCIbrwDDSYBgpGG4AwyiDYZRguAkMow2G0YLhFjCMMRjGCIbbwDDWYBgrGO4AwziDYZxguAsM4w2G8YLhHjBMMBgmCIb7wDDRYJgoGB4AwySDYZJgeAgMkw2GyYLhETBMMRimCIbHwBAwGAKC4QkwTDUYpgqGp8AwzWCYJhieAcN0g2G6YHgODDMMhhmC4QUwzDQYZgqGl8Awy2CYJRheAcNsg2G2YHgNDHMMhjmC4Q0wzDUY5gqGt8Awz2CYJxjeAcP8EBve5/vii6CDGj7k+98NCwxzWCDM4SMwLDQYFgqGT8CwyGBYJBg+A8Nig2GxYPgi//9uWGIwLBEMYYBhqcGwVDCEBYZlBsMywRAOGJYbDMsFQ3hgWGEwrBAMEYBhpcGwUjBEBIZVBsMqwRAJGFYbDKsFQ2RgWGMwrBEMUYBhrcGwVjBEBYZ1BsM6wRANGNYbDOsFQ3Rg2GAwbBAMMYBho8GwUTDEBIZNBsMmwRALGDYbDJsFQ2xg2GIwbBEMcYBhq8GwVTDEBYZtBsM2wRAPGLYbDNsFQ3xg2GEw7BAMCYBhp8GwUzAkBIZdBsMuwZAIGHYbDLsFQ2Jg2GMw7BEMSYBhr8GwVzAkBYZ9BsM+wZAMGPYbDPsFQ3JgOGAwHBAMKYDhoMFwUDCkBIZDBsMhwZAKGA4bDIcFQ2pgOGIwHBEMaYDhqMFwVDCkBYZjBsMxwZAOGI4bDMcFQ3pgOGEwnBAMGYDhpMFwUjBkBIZTBsMpwZAJGE4bDKcFQ2ZgOGMwnBEMWYDhrMFwVjBkBYZzBsM5wZANGM4bDOcFQ3ZguGAwXBAMOYDhosFwUTDkBIZLBsMlwZALGC4bDJcFQ25guGIwXBEMeYDhqsFwVTDkBYZrBsM1wZAPGK4bDNcFQ35guGEw3BAMBYDhpsFwUzAUBIZbBsMtwVAIGG4bDLcFQ2FguGMw3BEMRYDhrsFwVzAUBYZ7BsM9wVAMGO4bDPcFQ3FgeGAwPBAMJYDhocHwUDCUBIZHBsMjwVAKGB4bDI8FQ2lgeGIwPBEMZYDhqcHwVDCUBYZnBsMzwVAOGJ4bDM8FQ3lgeGEwvBAMFYDhpcHwUjBUBIZXBsMrwVAJGF4bDK8FQ2VgeGMwvBEMVYDhrcHwVjBUBYZ3BsM7wVANGN4bDO8FQ3Vg+GAwfBAMNYDho8HwUTDUBIZPBsMnwVALGD4bDJ8FQ21g+GJh6A3BBjXUAYYwBkMYwVAXGMIaDGEFQz1gCGcwhBMM9YEhvMEQXjA0AIYIBkMEwdAQGCIaDBEFQyNgiGQwRBIMjYEhssEQWTA0AYYoBkMUwdAUGKIaDFEFQzNgiGYwRBMMzYEhusEQXTC0AIYYBkMMwdASGGIaDDEFQytgiGUwxBIMrYEhtsEQWzC0AYY4BkMcwdAWGOIaDHEFQztgiGcwxBMM7YEhvsEQXzB0AIYEBkMCwfAlMCQ0GBIKhq+AIZHBkEgwfA0MiQ2GxILhG2BIYjAkEQzfAkNSgyGpYPgOGJIZDMkEw/fAkNxgSC4YfgCGFAZDCsHwIzCkNBhSCoafgCGVwZBKMPwMDKkNhtSC4RdgSGMwpBEMvwJDWoMhrWD4DRjSGQzpBMPvwJDeYEgvGP4AhgwGQwbB8CcwZDQYMgqGv4Ahk8GQSTD8DQyZDYbMguEfYMhiMGQRDP8CQ1aDIatg+A8YshkM2QRDR2DIbjBkFwydgCGHwZBDMHQGhpwGQ07B0AUYchkMuQRDV2DIbTDkFgzdgCGPwZBHMHQHhrwGQ17B0AMY8hkM+QRDT2DIbzDkFwy9gKGAwVBAMPQGhoIGQ0HB0AcYChkMhQRDX2AobDAUFgz9gKGIwVBEMPQHhqIGQ1HBMAAYihkMxQTDQGAobjAUFwyDgKGEwVBCMAwGhpIGQ0nBMAQYShkMpQTDUGAobTCUFgzDgKGMwVBGMAwHhrIGQ1nBMAIYyhkM5QTDSGAobzCUFwyjgKGCwVBBMIwGhooGQ0XBMAYYKhkMlQTDWGCobDBUFgzjgKGKwVBFMIwHhqoGQ1XBMAEYqhkM1QTDRGCobjBUFwyTgKGGwVBDMEwGhpoGQ03BMAUYahkMtQRDABhqGwy1BcNUYKhjMNQRDNOAoa7BUFcwTAeGegZDPcEwAxjqGwz1BcNMYGhgMDQQDLOAoaHB0FAwzAaGRgZDI8EwBxgaGwyNBcNcYGhiMDQRDPOAoanB0FQwzAeGZgZDM8GwABiaGwzNBcNCYGhhMLQQDIuAoaXB0FIwLAaGVgZDK8GwBBhaGwytBcNSYGhjMLQRDMuAoa3B0FYwLAeGdgZDO8GwAhjaGwztBcNKYOhgMHQQDKuA4UuD4UvBsBoYvjIYvhIMa4Dha4Pha8GwFhi+MRi+EQzrgOFbg+FbwbAeGL4zGL4TDBuA4XuD4XvBsBEYfjAYfhAMm4DhR4PhR8GwGRh+Mhh+EgxbgOFng+FnwbAVGH4xGH4RDNuA4VeD4VfBsB0YfjMYfhMMO4Dhd4Phd8GwExj+MBj+EAy7gOFPg+FPwbAbGP4yGP4SDHuA4W+D4W/BsBcY/jEY/hEM+4DhX4PhX8GwHxj+Mxj+EwwHgKGjwdBRMBwEhk4GQyfBcAgYOhsMnQXDYWDoYjB0EQxHgKGrwdBVMBwFhm4GQzfBcAwYuhsM3QXDcWDoYTD0EAwngKGnwdBTMJwEhl4GQy/BcAoYehsMvQXDaWDoYzD0EQxngKGvwdBXMJwFhn4GQz/BcA4Y+hsM/QXDeWAYYDAMEAwXgGGgwTBQMFwEhkEGwyDBcAkYBhsMgwXDZWAYYjAMEQxXgGGowTBUMFwFhmEGwzDBcA0YhhsMwwXDdWAYYTCMEAw3gGGkwTBSMNwEhlEGwyjBcAsYRhsMowXDbWAYYzCMEQx3gGGswTBWMNwFhnEGwzjBcA8YxhsM4wXDfWCYYDBMEAwPgGGiwTBRMDwEhkkGwyTB8AgYJhsMkwXDY2CYYjBMEQxPgCFgMAQEw1NgmGowTBUMz4BhmsEwTTA8B4bpBsN0wfACGGYYDDMEw0tgmGkwzBQMr4BhlsEwSzC8BobZBsNswfAGGOYYDHMEw1tgmGswzBUM74BhnsEwTzC8B4b5BsN8wfABGBYYDAsEw0dgWGgwLBQMn4BhkcGwSDB8BobFBsNiwfBFgf/dsMRgWCIYwgDDUoNhqWAICwzLDIZlgiEcMCw3GJYLhvDAsMJgWCEYIgDDSoNhpWCICAyrDIZVgiESMKw2GFYLhsjAsMZgWCMYogDDWoNhrWCICgzrDIZ1giEaMKw3GNYLhujAsMFg2CAYYgDDRoNho2CICQybDIZNgiEWMGw2GDYLhtjAsMVg2CIY4gDDVoNhq2CICwzbDIZtgiEeMGw3GLYLhvjAsMNg2CEYEgDDToNhp2BICAy7DIZdgiERMOw2GHYLhsTAsMdg2CMYkgDDXoNhr2BICgz7DIZ9giEZMOw3GPYLhuTAcMBgOCAYUgDDQYPhoGBICQyHDIZDgiEVMBw2GA4LhtTAcMRgOCIY0gDDUYPhqGBICwzHDIZjgiEdMBw3GI4LhvTAcMJgOCEYMgDDSYPhpGDICAynDIZTgiETMJw2GE4LhszAcMZgOCMYsgDDWYPhrGDICgznDIZzgiEbMJw3GM4LhuzAcMFguCAYcgDDRYPhomDICQyXDIZLgiEXMFw2GC4LhtzAcMVguCIY8gDDVYPhqmDICwzXDIZrgiEfMFw3GK4LhvzAcMNguCEYCgDDTYPhpmAoCAy3DIZbgqEQMNw2GG4LhsLAcMdguCMYigDDXYPhrmAoCgz3DIZ7gqEYMNw3GO4LhuLA8MBgeCAYSgDDQ4PhoWAoCQyPDIZHgqEUMDw2GB4LhtLA8MRgeCIYygDDU4PhqWAoCwzPDIZngqEcMDw3GJ4LhvLA8MJgeCEYKgDDS4PhpWCoCAyvDIZXgqESMLw2GF4LhsrA8MZgeCMYqgDDW4PhrWCoCgzvDIZ3gqEaMLw3GN4LhurA8MFg+CAYagDDR4Pho2CoCQyfDIZPgqEWMHw2GD4LhtrA8MWi0BuCDWqoAwxhDIYwgqEuMIQ1GMIKhnrAEM5gCCcY6gNDeIMhvGBoAAwRDIYIgqEhMEQ0GCIKhkbAEMlgiCQYGgNDZIMhsmBoAgxRDIYogqEpMEQ1GKIKhmbAEM1giCYYmgNDdIMhumBoAQwxDIYYgqElMMQ0GGIKhlbAEMtgiCUYWgNDbIMhtmBoAwxxDIY4gqEtMMQ1GOIKhnbAEM9giCcY2gNDfIMhvmDoAAwJDIYEguFLYEhoMCQUDF8BQyKDIZFg+BoYEhsMiQXDN8CQxGBIIhi+BYakBkNSwfAdMCQzGJIJhu+BIbnBkFww/AAMKQyGFILhR2BIaTCkFAw/AUMqgyGVYPgZGFIbDKkFwy/AkMZgSCMYfgWGtAZDWsHwGzCkMxjSCYbfgSG9wZBeMPwBDBkMhgyC4U9gyGgwZBQMfwFDJoMhk2D4GxgyGwyZBcM/wJDFYMgiGP4FhqwGQ1bB8B8wZDMYsgmGjsCQ3WDILhg6AUMOgyGHYOgMDDkNhpyCoQsw5DIYcgmGrsCQ22DILRi6AUMegyGPYOgODHkNhryCoQcw5DMY8gmGnsCQ32DILxh6AUMBg6GAYOgNDAUNhoKCoQ8wFDIYCgmGvsBQ2GAoLBj6AUMRg6GIYOgPDEUNhqKCYQAwFDMYigmGgcBQ3GAoLhgGAUMJg6GEYBgMDCUNhpKCYQgwlDIYSgmGocBQ2mAoLRiGAUMZg6GMYBgODGUNhrKCYQQwlDMYygmGkcBQ3mAoLxhGAUMFg6GCYBgNDBUNhoqCYQwwVDIYKgmGscBQ2WCoLBjGAUMVg6GKYBgPDFUNhqqCYQIwVDMYqgmGicBQ3WCoLhgmAUMNg6GGYJgMDDUNhpqCYQow1DIYagmGADDUNhhqC4apwFDHYKgjGKYBQ12Doa5gmA4M9QyGeoJhBjDUNxjqC4aZwNDAYGggGGYBQ0ODoaFgmA0MjQyGRoJhDjA0NhgaC4a5wNDEYGgiGOYBQ1ODoalgmA8MzQyGZoJhATA0NxiaC4aFwNDCYGghGBYBQ0uDoaVgWAwMrQyGVoJhCTC0NhhaC4alwNDGYGgjGJYBQ1uDoa1gWA4M7QyGdoJhBTC0NxjaC4aVwNDBYOggGFYBw5cGw5eCYTUwfGUwfCUY1gDD1wbD14JhLTB8YzB8IxjWAcO3BsO3gmE9MHxnMHwnGDYAw/cGw/eCYSMw/GAw/CAYNgHDjwbDj4JhMzD8ZDD8JBi2AMPPBsPPgmErMPxiMPwiGLYBw68Gw6+CYTsw/GYw/CYYdgDD7wbD74JhJzD8YTD8IRh2AcOfBsOfgmE3MPxlMPwlGPYAw98Gw9+CYS8w/GMw/CMY9gHDvwbDv4JhPzD8ZzD8JxgOAENHg6GjYDgIDJ0Mhk6C4RAwdDYYOguGw8DQxWDoIhiOAENXg6GrYDgKDN0Mhm6C4RgwdDcYuguG48DQw2DoIRhOAENPg6GnYDgJDL0Mhl6C4RQw9DYYeguG08DQx2DoIxjOAENfg6GvYDgLDP0Mhn6C4Rww9DcY+guG88AwwGAYIBguAMNAg2GgYLgIDIMMhkGC4RIwDDYYBguGy8AwxGAYIhiuAMNQg2GoYLgKDMMMhmGC4RowDDcYhguG68AwwmAYIRhuAMNIg2GkYLgJDKMMhlGC4RYwjDYYRguG28AwxmAYIxjuAMNYg2GsYLgLDOMMhnGC4R4wjDcYxguG+8AwwWCYIBgeAMNEg2GiYHgIDJMMhkmC4REwTDYYJguGx8AwxWCYIhieAEPAYAgIhqfAMNVgmCoYngHDNINhmmB4DgzTDYbpguEFMMwwGGYIhpfAMNNgmCkYXgHDLINhlmB4DQyzDYbZguENMMwxGBbN4YYvIv7vhrkGwxxhDm/BHOaF2BAm+hdfBB3UEDb6/26Yb5jDfGEO4YBhgcGwQDCEB4aFBsNCwRABGBY5nkuCISIwLDYYFguGSMCwxGBYIhgiA8NSg2GpYIgCDMsMhmWCISowLDcYlguGaMCwwmBYIRiiA8NKg2GlYIgBDKsMhlWCISYwrDYYVguGWMCwxmBYIxhiA8Nag2GtYIgDDOsMhnWCIS4wrDcY1guGeMCwwWDYIBjiA8NGg2GjYEgADJsMhk2CISEwbDYYNguGRMCwxWDYIhgSA8NWg2GrYEgCDNsMhm2CISkwbDcYtguGZMCww2DYIRiSA8NOg2GnYEgBDLsMhl2CISUw7DYYdguGVMCwx2DYIxhSA8Neg2GvYEgDDPsMhn2CIS0w7DcY9guGdMBwwGA4IBjSA8NBg+GgYMgADIcMhkOCISMwHDYYDguGTMBwxGA4IhgyA8NRg+GoYMgCDMcMhmOCISswHDcYjguGbMBwwmA4IRiyA8NJg+GkYMgBDKcMhlOCIScwnDYYTguGXMBwxmA4IxhyA8NZg+GsYMgDDOcMhnOCIS8wnDcYzguGfMBwwWC4IBjyA8NFg+GiYCgADJcMhkuCoSAwXDYYLguGQsBwxWC4IhgKA8NVg+GqYCgCDNcMhmuCoSgwXDcYrguGYsBww2C4IRiKA8NNg+GmYCgBDLcMhluCoSQw3DYYbguGUsBwx2C4IxhKA8Ndg+GuYCgDDPcMhnuCoSww3DcY7guGcsDwwGB4IBjKA8NDg+GhYKgADI8MhkeCoSIwPDYYHguGSsDwxGB4IhgqA8NTg+GpYKgCDM8MhmeCoSowPDcYnguGasDwwmB4IRiqA8NLg+GlYKgBDK8MhleCoSYwvDYYXguGWsDwxmB4IxhqA8Nbg+GtYKgDDO8MhneCoS4wvDcY3guGesDwwWD4IBjqA8NHg+GjYGgADJ8Mhk+CoSEwfDYYPguGRsDwxeLQG4INamgMDGEMhjCCoQkwhDUYwgqGpsAQzmAIJxiaAUN4gyG8YGgODBEMhgiCoQUwRDQYIgqGlsAQyWCIJBhaAUNkgyGyYGgNDFEMhiiCoQ0wRDUYogqGtsAQzWCIJhjaAUN0gyG6YGgPDDEMhhiCoQMwxDQYYgqGL4EhlsEQSzB8BQyxDYbYguFrYIhjMMQRDN8AQ1yDIa5g+BYY4hkM8QTDd8AQ32CILxi+B4YEBkMCwfADMCQ0GBIKhh+BIZHBkEgw/AQMiQ2GxILhZ2BIYjAkEQy/AENSgyGpYPgVGJIZDMkEw2/AkNxgSC4YfgeGFAZDCsHwBzCkNBhSCoY/gSGVwZBKMPwFDKkNhtSC4W9gSGMwpBEM/wBDWoMhrWD4FxjSGQzpBMN/wJDeYEgvGDoCQwaDIYNg6AQMGQ2GjIKhMzBkMhgyCYYuwJDZYMgsGLoCQxaDIYtg6AYMWQ2GrIKhOzBkMxiyCYYewJDdYMguGHoCQw6DIYdg6AUMOQ2GnIKhNzDkMhhyCYY+wJDbYMgtGPoCQx6DIY9g6AcMeQ2GvIKhPzDkMxjyCYYBwJDfYMgvGAYCQwGDoYBgGAQMBQ2GgoJhMDAUMhgKCYYhwFDYYCgsGIYCQxGDoYhgGAYMRQ2GooJhODAUMxiKCYYRwFDcYCguGEYCQwmDoYRgGAUMJQ2GkoJhNDCUMhhKCYYxwFDaYCgtGMYCQxmDoYxgGAcMZQ2GsoJhPDCUMxjKCYYJwFDeYCgvGCYCQwWDoYJgmAQMFQ2GioJhMjBUMhgqCYYpwFDZYKgsGALAUMVgqCIYpgJDVYOhqmCYBgzVDIZqgmE6MFQ3GKoLhhnAUMNgqCEYZgJDTYOhpmCYBQy1DIZagmE2MNQ2GGoLhjnAUMdgqCMY5gJDXYOhrmCYBwz1DIZ6gmE+MNQ3GOoLhgXA0MBgaCAYFgJDQ4OhoWBYBAyNDIZGgmExMDQ2GBoLhiXA0MRgaCIYlgJDU4OhqWBYBgzNDIZmgmE5MDQ3GJoLhhXA0MJgaCEYVgJDS4OhpWBYBQytDIZWgmE1MLQ2GFoLhjXA0MZgaCMY1gJDW4OhrWBYBwztDIZ2gmE9MLQ3GNoLhg3A0MFg6CAYNgLDlwbDl4JhEzB8ZTB8JRg2A8PXBsPXgmELMHxjMHwjGLYCw7cGw7eCYRswfGcwfCcYtgPD9wbD94JhBzD8YDD8IBh2AsOPBsOPgmEXMPxkMPwkGHYDw88Gw8+CYQ8w/GIw/CIY9gLDrwbDr4JhHzD8ZjD8Jhj2A8PvBsPvguEAMPxhMPwhGA4Cw58Gw5+C4RAw/GUw/CUYDgPD3wbD34LhCDD8YzD8IxiOAsO/BsO/guEYMPxnMPwnGI4DQ0eDoaNgOAEMnQyGToLhJDB0Nhg6C4ZTwNDFYOgiGE4DQ1eDoatgOAMM3QyGboLhLDB0Nxi6C4ZzwNDDYOghGM4DQ0+DoadguAAMvQyGXoLhIjD0Nhh6C4ZLwNDHYOgjGC4DQ1+Doa9guAIM/QyGfoLhKjD0Nxj6C4ZrwDDAYBggGK4Dw0CDYaBguAEMgwyGQYLhJjAMNhgGC4ZbwDDEYBgiGG4Dw1CDYahguAMMwwyGYYLhLjAMNxiGC4Z7wDDCYBghGO4Dw0iDYaRgeAAMowyGUYLhITCMNhhGC4ZHwDDGYBgjGB4Dw1iDYaxgeAIM4wyGcYLhKTCMNxjGC4ZnwDDBYJggGJ4Dw0SDYaJgeAEMkwyGSYLhJTBMNhgmC4ZXwDDFYJgiGF4DQ8BgCAiGN8Aw1WCYKhjeAsM0g2GaYHgHDNMNhumC4T0wzDAYZgiGD8Aw02CYKRg+AsMsg2GWYPgEDLMNhtmC4TMwzDEY5giGL2L874a5BsNcwRAGGOYZDPMEQ1hgmG8wzBcM4YBhgcGwQDCEB4aFBsNCwRABGBYZDIsEQ0RgWGwwLBYMkYBhicGwRDBEBoalBsNSwRAFGJYZDMsEQ1RgWG4wLBcM0YBhhcGwQjBEB4aVBsNKwRADGFYZDKsEQ0xgWG0wrBYMsYBhjcGwRjDEBoa1BsNawRAHGNYZDOsEQ1xgWG8wrBcM8YBhg8GwQTDEB4aNBsNGwZAAGDYZDJsEQ0Jg2GwwbBYMiYBhi8GwRTAkBoatBsNWwZAEGLYZDNsEQ1Jg2G4wbBcMyYBhh8GwQzAkB4adBsNOwZACGHYZDLsEQ0pg2G0w7BYMqYBhj8GwRzCkBoa9BsNewZAGGPYZDPsEQ1pg2G8w7BcM6YDhgMFwQDCkB4aDBsNBwZABGA4ZDIcEQ0ZgOGwwHBYMmYDhiMFwRDBkBoajBsNRwZAFGI4ZDMcEQ1ZgOG4wHBcM2YDhhMFwQjBkB4aTBsNJwZADGE4ZDKcEQ05gOG0wnBYMuYDhjMFwRjDkBoazBsNZwZAHGM4ZDOcEQ15gOG8wnBcM+YDhgsFwQTDkB4aLBsNFwVAAGC4ZDJcEQ0FguGwwXBYMhYDhisFwRTAUBoarBsNVwVAEGK4ZDNcEQ1FguG4wXBcMxYDhhsFwQzAUB4abBsNNwVACGG4ZDLcEQ0lguG0w3BYMpYDhjsFwRzCUBoa7BsNdwVAGGO4ZDPcEQ1lguG8w3BcM5YDhgcHwQDCUB4aHBsNDwVABGB4ZDI8EQ0VgeGwwPBYMlYDhicHwRDBUBoanBsNTwVAFGJ4ZDM8EQ1VgeG4wPBcM1YDhhcHwQjBUB4aXBsNLwVADGF4ZDK8EQ01geG0wvBYMtYDhjcHwRjDUBoa3BsNbwVAHGN4ZDO8EQ11geG8wvBcM9YDhg8HwQTDUB4aPBsNHwdAAGD4ZDJ8EQ0Ng+GwwfBYMjYDhiyWhNwQb1NAYGMIYDGEEQxNgCGswhBUMTYEhnMEQTjA0A4bwBkN4wdAcGCIYDBEEQwtgiGgwRBQMLYEhksEQSTC0AobIBkNkwdAaGKIYDFEEQxtgiGowRBUMbYEhmsEQTTC0A4boBkN0wdAeGGIYDDEEQwdgiGkwxBQMXwJDLIMhlmD4ChhiGwyxBcPXwBDHYIgjGL4BhrgGQ1zB8C0wxDMY4gmG74AhvsEQXzB8DwwJDIYEguEHYEhoMCQUDD8CQyKDIZFg+AkYEhsMiQXDz8CQxGBIIhh+AYakBkNSwfArMCQzGJIJht+AIbnBkFww/A4MKQyGFILhD2BIaTCkFAx/AkMqgyGVYPgLGFIbDKkFw9/AkMZgSCMY/gGGtAZDWsHwLzCkMxjSCYb/gCG9wZBeMHQEhgwGQwbB0AkYMhoMGQVDZ2DIZDBkEgxdgCGzwZBZMHQFhiwGQxbB0A0YshoMWQVDd2DIZjBkEww9gCG7wZBdMPQEhhwGQw7B0AsYchoMOQVDb2DIZTDkEgx9gCG3wZBbMPQFhjwGQx7B0A8Y8hoMeQVDf2DIZzDkEwwDgCG/wZBfMAwEhgIGQwHBMAgYChoMBQXDYGAoZDAUEgxDgKGwwVBYMAwFhiIGQxHBMAwYihoMRQXDcGAoZjAUEwwjgKG4wVBcMIwEhhIGQwnBMAoYShoMJQXDaGAoZTCUEgxjgKG0wVBaMIwFhjIGQxnBMA4YyhoMZQXDeGAoZzCUEwwTgKG8wVBeMEwEhgoGQwXBMAkYKhoMFQXDZGCoZDBUEgxTgKGywVBZMASAoYrBUEUwTAWGqgZDVcEwDRiqGQzVBMN0YKhuMFQXDDOAoYbBUEMwzASGmgZDTcEwCxhqGQy1BMNsYKhtMNQWDHOAoY7BUEcwzAWGugZDXcEwDxjqGQz1BMN8YKhvMNQXDAuAoYHB0EAwLASGhgZDQ8GwCBgaGQyNBMNiYGhsMDQWDEuAoYnB0EQwLAWGpgZDU8GwDBiaGQzNBMNyYGhuMDQXDCuAoYXB0EIwrASGlgZDS8GwChhaGQytBMNqYGhtMLQWDGuAoY3B0EYwrAWGtgZDW8GwDhjaGQztBMN6YGhvMLQXDBuAoYPB0EEwbASGLw2GLwXDJmD4ymD4SjBsBoavDYavBcMWYPjGYPhGMGwFhm8Nhm8FwzZg+M5g+E4wbAeG7w2G7wXDDmD4wWD4QTDsBIYfDYYfBcMuYPjJYPhJMOwGhp8Nhp8Fwx5g+MVg+EUw7AWGXw2GXwXDPmD4zWD4TTDsB4bfDYbfBcMBYPjDYPhDMBwEhj8Nhj8FwyFg+Mtg+EswHAaGvw2GvwXDEWD4x2D4RzAcBYZ/DYZ/BcMxYPjPYPhPMBwHho4GQ0fBcAIYOhkMnQTDSWDobDB0FgyngKGLwdBFMJwGhq4GQ1fBcAYYuhkM3QTDWWDobjB0FwzngKGHwdBDMJwHhp4GQ0/BcAEYehkMvQTDRWDobTD0FgyXgKGPwdBHMFwGhr4GQ1/BcAUY+hkM/QTDVWDobzD0FwzXgGGAwTBAMFwHhoEGw0DBcAMYBhkMgwTDTWAYbDAMFgy3gGGIwTBEMNwGhqEGw1DBcAcYhhkMwwTDXWAYbjAMFwz3gGGEwTBCMNwHhpEGw0jB8AAYRhkMowTDQ2AYbTCMFgyPgGGMwTBGMDwGhrEGw1jB8AQYxhkM4wTDU2AYbzCMFwzPgGGCwTBBMDwHhokGw0TB8AIYJhkMkwTDS2CYbDBMFgyvgGGKwTBFMLwGhoDBEBAMb4BhqsEwVTC8BYZpBsM0wfAOGKYbDNMFw3tgmGEwzBAMH4BhpsEwUzB8BIZZBsMswfAJGGYbDLMFw2dgmGMwzBEMX8T83w1zDYZ1Y/9/7/t/WtfZs2xd4f6/Pv//zyvW509X/t/rmr8AOGb8314t+t+vX/Z/18/7v+vD/+/r+n/f90XC/93wPtf/vp/z/vc5h6F7T89EmP870MH9p+c6bNj/3TvfcK7nC9/NcMCwwGBYIBjCA8NCg2GhYIgADIsMhkWCISIwLDYYFguGSMCwxGBYIhgiA8NSg2GpYIgCDMsMhmWCISowLDcYlguGaMCwwmBYIRiiA8NKg2GlYIgBDKsMhlWCISYwrDYYVguGWMCwxmBYIxhiA8Nag2GtYIgDDOsc/ykFQ1xgWG8wrBcM8YBhg8GwQTDEB4aNBsNGwZAAGDYZDJsEQ0Jg2GwwbBYMiYBhi8GwRTAkBoatBsNWwZAEGLYZDNsEQ1Jg2G4wbBcMyYBhh8GwQzAkB4adBsNOwZACGHYZDLsEQ0pg2G0w7BYMqYBhj8GwRzCkBoa9BsNewZAGGPYZDPsEQ1pg2G8w7BcM6YDhgMFwQDCkB4aDBsNBwZABGA4ZDIcEQ0ZgOGwwHBYMmYDhiMFwRDBkBoajBsNRwZAFGI4ZDMcEQ1ZgOG4wHBcM2YDhhMFwQjBkB4aTBsNJwZADGE4ZDKcEQ05gOG0wnBYMuYDhjMFwRjDkBoazBsNZwZAHGM4ZDOcEQ15gOG8wnBcM+YDhgsFwQTDkB4aLBsNFwVAAGC4ZDJcEQ0FguGwwXBYMhYDhisFwRTAUBoarBsNVwVAEGK4ZDNcEQ1FguG4wXBcMxYDhhsFwQzAUB4abBsNNwVACGG4ZDLcEQ0lguG0w3BYMpYDhjsFwRzCUBoa7BsNdwVAGGO4ZDPcEQ1lguG8w3BcM5YDhgcHwQDCUB4aHBsNDwVABGB4ZDI8EQ0VgeGwwPBYMlYDhicHwRDBUBoanBsNTwVAFGJ4ZDM8EQ9Ww/7vhucHwXDBUA4YXBsMLwVAdGF4aDC8FQw1geGUwvBIMNYHhtcHwWjDUAoY3BsMbwVAbGN4aDG8FQx1geGcwvBMMdYHhvcHwXjDUA4YPBsMHwVAfGD4aDB8FQwNg+GQwfBIMDYHhs8HwWTA0AoYvlobeEGxQQ2NgCGMwhBEMTYAhrMEQVjA0BYZwBkM4wdAMGMIbDOEFQ3NgiGAwRBAMLYAhosEQUTC0BIZIBkMkwdAKGCIbDJEFQ2tgiGIwRBEMbYAhqsEQVTC0BYZoBkM0wdAOGKIbDNEFQ3tgiGEwxBAMHYAhpsEQUzB8CQyxDIZYguErYIhtMMQWDF8DQxyDIY5g+AYY4hoMcQXDt8AQz2CIJxi+A4b4BkN8wfA9MCQwGBIIhh+AIaHBkFAw/AgMiQyGRILhJ2BIbDAkFgw/A0MSgyGJYPgFGJIaDEkFw6/AkMxgSCYYfgOG5AZDcsHwOzCkMBhSCIY/gCGlwZBSMPwJDKkMhlSC4S9gSG0wpBYMfwNDGoMhjWD4BxjSGgxpBcO/wJDOYEgnGP4DhvQGQ3rB0BEYMhgMGQRDJ2DIaDBkFAydgSGTwZBJMHQBhswGQ2bB0BUYshgMWQRDN2DIajBkFQzdgSGbwZBNMPQAhuwGQ3bB0BMYchgMOQRDL2DIaTDkFAy9gSGXwZBLMPQBhtwGQ27B0BcY8hgMeQRDP2DIazDkFQz9gSGfwZBPMAwAhvwGQ37BMBAYChgMBQTDIGAoaDAUFAyDgaGQwVBIMAwBhsIGQ2HBMBQYihgMRQTDMGAoajAUFQzDgaGYwVBMMIwAhuIGQ3HBMBIYShgMJQTDKGAoaTCUFAyjgaGUwVBKMIwBhtIGQ2nBMBYYyhgMZQTDOGAoazCUFQzjgaGcwVBOMEwAhvIGQ3nBMBEYKhgMFQTDJGCoaDBUFAyTgaGSwVBJMEwBhsoGQ2XBEACGKgZDFcEwFRiqGgxVBcM0YKhmMFQTDNOBobrBUF0wzACGGgZDDcEwExhqGgw1BcMsYKhlMNQSDLOBobbBUFswzAGGOgZDHcEwFxjqGgx1BcM8YKhnMNQTDPOBob7BUF8wLACGBgZDA8GwEBgaGgwNBcMiYGhkMDQSDIuBobHB0FgwLAGGJgZDE8GwFBiaGgxNBcMyYGhmMDQTDMuBobnB0FwwrACGFgZDC8GwEhhaGgwtBcMqYGhlMLQSDKuBobXB0FowrAGGNgZDG8GwFhjaGgxtBcM6YGhnMLQTDOuBob3B0F4wbACGDgZDB8GwERi+NBi+FAybgOErg+ErwbAZGL42GL4WDFuA4RuD4RvBsBUYvjUYvhUM24DhO4PhO8GwHRi+Nxi+Fww7gOEHg+EHwbATGH40GH4UDLuA4SeD4SfBsBsYfjYYfhYMe4DhF4PhF8GwFxh+NRh+FQz7gOE3g+E3wbAfGH43GH4XDAeA4Q+D4Q/BcBAY/jQY/hQMh4DhL4PhL8FwGBj+Nhj+FgxHgOEfg+EfwXAUGP41GP4VDMeA4T+D4T/BcBwYOhoMHQXDCWDoZDB0EgwngaGzwdBZMJwChi4GQxfBcBoYuhoMXQXDGWDoZjB0EwxngaG7wdBdMJwDhh4GQw/BcB4YehoMPQXDBWDoZTD0EgwXgaG3wdBbMFwChj4GQx/BcBkY+hoMfQXDFWDoZzD0EwxXgaG/wdBfMFwDhgEGwwDBcB0YBhoMAwXDDWAYZDAMEgw3gWGwwTBYMNwChiEGwxDBcBsYhhoMQwXDHWAYZjAMEwx3gWG4wTBcMNwDhhEGwwjBcB8YRhoMIwXDA2AYZTCMEgwPgWG0wTBaMDwChjEGwxjB8BgYxhoMYwXDE2AYZzCMEwxPgWG8wTBeMDwDhgkGwwTB8BwYJhoMEwXDC2CYZDBMEgwvgWGywTBZMLwChikGwxTB8BoYAgZDQDC8AYapBsNUwfAWGKYZDNMEwztgmG4wTBcM74FhhsEwQzB8AIaZBsNMwfARGGYZDLMEwydgmG0wzBYMn4FhjsEwRzB8Ee5/N8w1GOYKhjDAMM9gmCcYwgLDfINhvmAIBwwLDIYFgiE8MCw0GBYKhgjAsMhgWCQYIgLDYoNhsWCIBAxLDIYlgiEyMCw1GJYKhijAsMxgWCYYogLDcoNhuWCIBgwrDIYVgiE6MKw0GFYKhhjAsMpgWCUYYgLDaoNhtWCIBQxrDIY1giE2MKw1GNYKhjjAsM5gWCcY4gLDeoNhvWCIBwwbDIYNgiE+MGw0GDYKhgTAsMlg2CQYEgLDZoNhs2BIBAxbDIYtgiExMGw1GLYKhiTAsM1g2CYYkgLDdoNhu2BIBgw7DIYdgiE5MOw0GHYKhhTAsMtg2CUYUgLDboNht2BIBQx7DIY9giE1MOw1GPYKhjTAsM9g2CcY0gLDfoNhv2BIBwwHDIYDgiE9MBw0GA4KhgzAcMhgOCQYMgLDYYPhsGDIBAxHDIYjgiEzMBw1GI4KhizAcMxgOCYYsgLDcYPhuGDIBgwnDIYTgiE7MJw0GE4KhhzAcMpgOCUYcgLDaYPhtGDIBQxnDIYzgiE3MJw1GM4KhjzAcM5gOCcY8gLDeYPhvGDIBwwXDIYLgiE/MFw0GC4KhgLAcMlguCQYCgLDZYPhsmAoBAxXDIYrgqEwMFw1GK4KhiLAcM1guCYYigLDdYPhumAoBgw3DIYbgqE4MNw0GG4KhhLAcMtguCUYSgLDbYPhtmAoBQx3DIY7gqE0MNw1GO4KhjLAcM9guCcYygLDfYPhvmAoBwwPDIYHgqE8MDw0GB4KhgrA8MhgeCQYKgLDY4PhsWCoBAxPDIYngqEyMDw1GJ4KhirA8MxgeCYYqgLDc4PhuWCoBgwvDIYXgqE6MLw0GF4KhhrA8MpgeCUYagLDa4PhtWCoBQxvDIY3gqE2MLw1GN4KhjrA8M5geCcY6gLDe4PhvWCoBwwfDIYPgqE+MHw0GD4KhgbA8Mlg+CQYGgLDZ4Phs2BoBAxfLAu9IdighsbAEMZgCCMYmgBDWIMhrGBoCgzhDIZwgqEZMIQ3GMILhubAEMFgiCAYWgBDRIMhomBoCQyRDIZIgqEVMEQ2GCILhtbAEMVgiCIY2gBDVIMhqmBoCwzRDIZogqEdMEQ3GKILhvbAEMNgiCEYOgBDTIMhpmD4EhhiGQyxBMNXwBDbYIgtGL4GhjgGQxzB8A0wxDUY4gqGb4EhnsEQTzB8BwzxDYb4guF7YEhgMCQQDD8AQ0KDIaFg+BEYEhkMiQTDT8CQ2GBILBh+BoYkBkMSwfALMCQ1GJIKhl+BIZnBkEww/AYMyQ2G5ILhd2BIYTCkEAx/AENKgyGlYPgTGFIZDKkEw1/AkNpgSC0Y/gaGNAZDGsHwDzCkNRjSCoZ/gSGdwZBOMPwHDOkNhvSCoSMwZDAYMgiGTsCQ0WDIKBg6A0MmgyGTYOgCDJkNhsyCoSswZDEYsgiGbsCQ1WDIKhi6A0M2gyGbYOgBDNkNhuyCoScw5DAYcgiGXsCQ02DIKRh6A0MugyGXYOgDDLkNhtyCoS8w5DEY8giGfsCQ12DIKxj6A0M+gyGfYBgADPkNhvyCYSAwFDAYCgiGQcBQ0GAoKBgGA0Mhg6GQYBgCDIUNhsKCYSgwFDEYigiGYcBQ1GAoKhiGA0Mxg6GYYBgBDMUNhuKCYSQwlDAYSgiGUcBQ0mAoKRhGA0Mpg6GUYBgDDKUNhtKCYSwwlDEYygiGccBQ1mAoKxjGA0M5g6GcYJgADOUNhvKCYSIwVDAYKgiGScBQ0WCoKBgmA0Mlg6GSYJgCDJUNhsqCIQAMVQyGKoJhKjBUNRiqCoZpwFDNYKgmGKYDQ3WDobpgmAEMNQyGGoJhJjDUNBhqCoZZwFDLYKglGGYDQ22DobZgmAMMdQyGOoJhLjDUNRjqCoZ5wFDPYKgnGOYDQ32Dob5gWAAMDQyGBoJhITA0NBgaCoZFwNDIYGgkGBYDQ2ODobFgWAIMTQyGJoJhKTA0NRiaCoZlwNDMYGgmGJYDQ3ODoblgWAEMLQyGFoJhJTC0NBhaCoZVwNDKYGglGFYDQ2uDobVgWAMMbQyGNoJhLTC0NRjaCoZ1wNDOYGgnGNYDQ3uDob1g2AAMHQyGDoJhIzD8v3irByW6sjWKwh3btu2kk7Ttjm3btm2bHdv2iW3btp3cOm9wx6w68wlGfTX/tXcdg6GOYNgMDHUNhrqCYQsw1DMY6gmGADDUNxjqC4atwNDAYGggGLYBQ0ODoaFg2A4MjQyGRoJhBzA0NhgaC4adwNDEYGgiGHYBQ1ODoalg2A0MzQyGZoJhDzA0NxiaC4a9wNDCYGghGPYBQ0uDoaVg2A8MrQyGVoLhADC0NhhaC4aDwNDGYGgjGA4BQ1uDoa1gOAwM7QyGdoLhCDC0NxjaC4ajwNDBYOggGI4BQ0eDoaNgOA4MnQyGToLhBDB0Nhg6C4aTwNDFYOgiGE4BQ1eDoatgOA0M3QyGboLhDDB0Nxi6C4azwNDDYOghGM4BQ0+DoadgOA8MvQyGXoLhAjD0Nhh6C4aLwNDHYOgjGC4BQ1+Doa9guAwM/QyGfoLhCjD0Nxj6C4arwDDAYBggGK4Bw0CDYaBguA4MgwyGQYLhBjAMNhgGC4abwDDEYBgiGG4Bw1CDYahguA0MwwyGYYLhDjAMNxiGC4a7wDDCYBghGO4Bw0iDYaRguA8MowyGUYLhATCMNhhGC4aHwDDGYBgjGB4Bw1iDYaxgeAwM4wyGcYLhCTCMNxjGC4anwDDBYJggGJ4Bw0SDYaJgeA4MkwyGSYLhBTBMNhgmC4aXwDDFYJgiGF4Bw1SDYapgeA0M/xkM/wmGN8AwzWCYJhjeAsN0g2G6YHgHDDMMhhmC4T0wzDQYZgqGD8Awy2CYJRg+AsNsg2G2YPgEDHMMhjmC4TMwzA2x4Yv0X3wRdFBDmPT/v2GeYYd5wg5hgWG+wTBfMIQDhgUGwwLBEB4YFhoMCwVDBGBYZDAsEgwRgWGxwbBYMEQChiUGwxLBEBkYlhoMSwVDFGBYZjAsEwxRgWG5wbBcMEQDhhUGwwrBEB0YVhoMKwVDDGBYZTCsEgwxgWG1wbBaMMQChjUGwxrBEBsY1hoMawVDHGBYZzCsEwxxgWG9wbBeMMQDhg0GwwbBEB8YNhoMGwVDAmDYZDBsEgwJgWGzwbBZMCQChi0GwxbBkBgYAgZDQDAkAYatBsNWwZAUGLYZDNsEQzJg2G4wbBcMyYFhh8GwQzCkAIadBsNOwZASGHYZDLsEQypg2G0w7BYMqYFhj8GwRzCkAYa9BsNewZAWGPYZDPsEQzpg2G8w7BcM6YHhgMFwQDBkAIaDBsNBwZARGA4ZDIcEQyZgOGwwHBYMmYHhiMFwRDBkAYajBsNRwZAVGI4ZDMcEQzZgOG4wHBcM2YHhhMFwQjDkAIaTBsNJwZATGE4ZDKcEQy5gOG0wnBYMuYHhjMFwRjDkAYazBsNZwZAXGM4ZDOcEQz5gOG8wnBcMXwLDBYPhgmDIDwwXDYaLgqEAMFwyGC4JhoLAcNlguCwYvgKGKwbDFcHwNTBcNRiuCoZvgOGawXBNMHwLDNcNhuuC4TtguGEw3BAM3wPDTYPhpmD4ARhuGQy3BMOPwHDbYLgtGH4ChjsGwx3B8DMw3DUY7gqGX4DhnsFwTzD8Cgz3DYb7guE3YHhgMDwQDL8Dw0OD4aFg+AMYHhkMjwTDn8Dw2GB4LBj+AoYnBsMTwfA3MDw1GJ4Khn+A4ZnB8Eww/AsMzw2G54KhEDC8MBheCIbCwPDSYHgpGIoAwyuD4ZVgKAoMrw2G14KhGDC8MRjeCIbiwPDWYHgrGEoAwzuD4Z1gKAkM7w2G94KhFDB8MBg+CIbSwPDRYPgoGMoAwyeD4ZNgKAsMnw2Gz4KhHDB8sSL0hmCDGsoDQxiDIYxgqAAMYQ2GsIKhIjCEMxjCCYZKwBDeYAgvGCoDQwSDIYJgqAIMEQ2GiIKhKjBEMhgiCYZqwBDZYIgsGKoDQxSDIYpgqAEMUQ2GqIKhJjBEMxiiCYZawBDdYIguGGoDQwyDIYZgqAMMMQ2GmIKhLjDEMhhiCYZ6wBDbYIgtGOoDQxyDIY5gaAAMcQ2GuIKhITDEMxjiCYZGwBDfYIgvGBoDQwKDIYFgaAIMCQ2GhIKhKTAkMhgSCYZmwJDYYEgsGJoDQxKDIYlgaAEMSQ2GpIKhJTAkMxiSCYZWwJDcYEguGFoDQwqDIYVgaAMMKQ2GlIKhLTCkMhhSCYZ2wJDaYEgtGNoDQxqDIY1g6AAMaQ2GtIKhIzCkMxjSCYZOwJDeYEgvGDoDQwaDIYNg6AIMGQ2GjIKhKzBkMhgyCYZuwJDZYMgsGLoDQxaDIYtg6AEMWQ2GrIKhJzBkMxiyCYZewJDdYMguGHoDQw6DIYdg6AMMOQ2GnIKhLzDkMhhyCYZ+wJDbYMgtGPoDQx6DIY9gGAAMeQ2GvIJhIDDkMxjyCYZBwPClwfClYBgMDPkNhvyCYQgwFDAYCgiGocBQ0GAoKBiGAcNXBsNXgmE4MHxtMHwtGEYAwzcGwzeCYSQwfGswfCsYRgHDdwbDd4JhNDB8bzB8LxjGAMMPBsMPgmEsMPxoMPwoGMYBw08Gw0+CYTww/Gww/CwYJgDDLwbDL4JhIjD8ajD8KhgmAcNvBsNvgmEyMPxuMPwuGKYAwx8Gwx+CYSow/Gkw/CkY/gOGvwyGvwTDNGD422D4WzBMB4Z/DIZ/BMMMYPjXYPhXMMwEhkIGQyHBMAsYChsMhQXDbGAoYjAUEQxzgKGowVBUMMwFhmIGQzHBMA8YihsMxQXDfGAoYTCUEAwLgKGkwVBSMCwEhlIGQynBsAgYShsMpQXDYmAoYzCUEQxLgKGswVBWMCwFhnIGQznBsAwYyhsM5QXDcmCoYDBUEAwrgKGiwVBRMKwEhkoGQyXBsAoYKhsMlQXDamCoYjBUEQxrgKGqwVBVMKwFhmoGQzXBsA4YqhsM1QXDemCoYTDUEAwbgKGmwVBTMGwEhloGQy3BsAkYahsMtQXDZmCoYzDUEQxbgKGuwVBXMASAoZ7BUE8wbAWG+gZDfcGwDRgaGAwNBMN2YGhoMDQUDDuAoZHB0Egw7ASGxgZDY8GwCxiaGAxNBMNuYGhqMDQVDHuAoZnB0Eww7AWG5gZDc8GwDxhaGAwtBMN+YGhpMLQUDAeAoZXB0EowHASG1gZDa8FwCBjaGAxtBMNhYGhrMLQVDEeAoZ3B0E4wHAWG9gZDe8FwDBg6GAwdBMNxYOhoMHQUDCeAoZPB0EkwnASGzgZDZ8FwChi6GAxdBMNpYOhqMHQVDGeAoZvB0E0wnAWG7gZDd8FwDhh6GAw9BMN5YOhpMPQUDBeAoZfB0EswXASG3gZDb8FwCRj6GAx9BMNlYOhrMPQVDFeAoZ/B0E8wXAWG/gZDf8FwDRgGGAwDBMN1YBhoMAwUDDeAYZDBMEgw3ASGwQbDYMFwCxiGGAxDBMNtYBhqMAwVDHeAYZjBMEww3AWG4QbDcMFwDxhGGAwjBMN9YBhpMIwUDA+AYZTBMEowPASG0QbDaMHwCBjGGAxjBMNjYBhrMIwVDE+AYZzBME4wPAWG8QbDeMHwDBgmGAwTBMNzYJhoMEwUDC+AYZLBMEkwvASGyQbDZMHwChimGAxTBMNrYJhqMEwVDG+A4T+D4T/B8BYYphkM0wTDO2CYbjBMFwzvgWGGwTBDMHwAhpkGw0zB8BEYZhkMswTDJ2CYbTDMFgyfgWGOwTBHMHyR4f83zDUY5gqGMMAwz2CYJxjCAsN8g2G+YAgHDAsMhgWCITwwLDQYFgqGCMCwyGBYJBgiAsNig2GxYIgEDEsMhiWCITIwLDUYlgqGKMCwzGBYJhiiAsNyg2G5YIgGDCsMhhWCITowrDQYVgqGGMCwymBYJRhiAsNqg2G1YIgFDGsMhjWCITYwrDUY1gqGOMCwzmBYJxjiAsN6g2G9YIgHDBsMhg2CIT4wbDQYNgqGBMCwyWDYJBgSAsNmg2GzYEgEDFsMhi2CITEwBAyGgGBIAgxbDYatgiEpMGwzGLYJhmTAsN1g2C4YkgPDDoNhh2BIAQw7DYadgiElMOwyGHYJhlTAsNtg2C0YUgPDHoNhj2BIAwx7DYa9giEtMOwzGPYJhnTAsN9g2C8Y0gPDAYPhgGDIAAwHDYaDgiEjMBwyGA4JhkzAcNhgOCwYMgPDEYPhiGDIAgxHDYajgiErMBwzGI4JhmzAcNxgOC4YsgPDCYPhhGDIAQwnDYaTgiEnMJwyGE4JhlzAcNpgOC0YcgPDGYPhjGDIAwxnDYazgiEvMJwzGM4JhnzAcN5gOC8YvgSGCwbDBcGQHxguGgwXBUMBYLhkMFwSDAWB4bLBcFkwfAUMVwyGK4Lha2C4ajBcFQzfAMM1g+GaYPgWGK4bDNcFw3fAcMNguCEYvgeGmwbDTcHwAzDcMhhuCYYfgeG2wXBbMPwEDHcMhjuC4WdguGsw3BUMvwDDPYPhnmD4FRjuGwz3BcNvwPDAYHggGH4HhocGw0PB8AcwPDIYHgmGP4HhscHwWDD8BQxPDIYnguFvYHhqMDwVDP8AwzOD4Zlg+BcYnhsMzwVDIWB4YTC8EAyFgeGlwfBSMBQBhlcGwyvBUBQYXhsMrwVDMWB4YzC8EQzFgeGtwfBWMJQAhncGwzvBUBIY3hsM7wVDKWD4YDB8EAylgeGjwfBRMJQBhk8GwyfBUBYYPhsMnwVDOWD4YmXoDcEGNZQHhjAGQxjBUAEYwhoMYQVDRWAIZzCEEwyVgCG8wRBeMFQGhggGQwTBUAUYIhoMEQVDVWCIZDBEEgzVgCGywRBZMFQHhigGQxTBUAMYohoMUQVDTWCIZjBEEwy1gCG6wRBdMNQGhhgGQwzBUAcYYhoMMQVDXWCIZTDEEgz1gCG2wRBbMNQHhjgGQxzB0AAY4hoMcQVDQ2CIZzDEEwyNgCG+wRBfMDQGhgQGQwLB0AQYEhoMCQVDU2BIZDAkEgzNgCGxwZBYMDQHhiQGQxLB0AIYkhoMSQVDS2BIZjAkEwytgCG5wZBcMLQGhhQGQwrB0AYYUhoMKQVDW2BIZTCkEgztgCG1wZBaMLQHhjQGQxrB0AEY0hoMaQVDR2BIZzCkEwydgCG9wZBeMHQGhgwGQwbB0AUYMhoMGQVDV2DIZDBkEgzdgCGzwZBZMHQHhiwGQxbB0AMYshoMWQVDT2DIZjBkEwy9gCG7wZBdMPQGhhwGQw7B0AcYchoMOQVDX2DIZTDkEgz9gCG3wZBbMPQHhjwGQx7BMAAY8hoMeQXDQGDIZzDkEwyDgOFLg+FLwTAYGPIbDPkFwxBgKGAwFBAMQ4GhoMFQUDAMA4avDIavBMNwYPjaYPhaMIwAhm8Mhm8Ew0hg+NZg+FYwjAKG7wyG7wTDaGD43mD4XjCMAYYfDIYfBMNYYPjRYPhRMIwDhp8Mhp8Ew3hg+Nlg+FkwTACGXwyGXwTDRGD41WD4VTBMAobfDIbfBMNkYPjdYPhdMEwBhj8Mhj8Ew1Rg+NNg+FMw/AcMfxkMfwmGacDwt8Hwt2CYDgz/GAz/CIYZwPCvwfCvYJgJDIUMhkKCYRYwFDYYCguG2cBQxGAoIhjmAENRg6GoYJgLDMUMhmKCYR4wFDcYiguG+cBQwmAoIRgWAENJg6GkYFgIDKUMhlKCYREwlDYYSguGxcBQxmAoIxiWAENZg6GsYFgKDOUMhnKCYRkwlDcYyguG5cBQwWCoIBhWAENFg6GiYFgJDJUMhkqCYRUwVDYYKguG1cBQxWCoIhjWAENVg6GqYFgLDNUMhmqCYR0wVDcYqguG9cBQw2CoIRg2AENNg6GmYNgIDLUMhlqCYRMw1DYYaguGzcBQx2CoIxi2AENdg6GuYAgAQz2DoZ5g2AoM9Q2G+oJhGzA0MBgaCIbtwNDQYGgoGHYAQyODoZFg2AkMjQ2GxoJhFzA0MRiaCIbdwNDUYGgqGPYAQzODoZlg2AsMzQ2G5oJhHzC0MBhaCIb9wNDSYGgpGA4AQyuDoZVgOAgMrQ2G1oLhEDC0MRjaCIbDwNDWYGgrGI4AQzuDoZ1gOAoM7Q2G9oLhGDB0MBg6CIbjwNDRYOgoGE4AQyeDoZNgOAkMnQ2GzoLhFDB0MRi6CIbTwNDVYOgqGM4AQzeDoZtgOAsM3Q2G7oLhHDD0MBh6CIbzwNDTYOgpGC4AQy+DoZdguAgMvQ2G3oLhEjD0MRj6CIbLwNDXYOgrGK4AQz+DoZ9guAoM/Q2G/oLhGjAMMBgGCIbrwDDQYBgoGG4AwyCDYZBguAkMgw2GwYLhFjAMMRiGCIbbwDDUYBgqGO4AwzCDYZhguAsMww2G4YLhHjCMMBhGCIb7wDDSYBgpGB4AwyiDYZRgeAgMow2G0YLhETCMMRjGCIbHwDDWYBgrGJ4AwziDYZxgeAoM4w2G8YLhGTBMMBgmCIbnwDDRYJgoGF4AwySDYZJgeAkMkw2GyYLhFTBMMRimCIbXwDDVYJgqGN4Aw38Gw3+C4S0wTDMYpgmGd8Aw3WCYLhjeA8MMg2GGYPgADDMNhpmC4SMwzDIYZgmGT8Aw22CYLRg+A8Mcg2GOYPgi4/9vmGswzBUMYYBhnsEwTzCEBYb5BsN8wRAOGBYYDAsEQ3hgWGgwLBQMEYBhkcGwSDBEBIbFBsNiwRAJGJYYDEsEQ2RgWGowLBUMUYBhmcGwTDBEBYblBsNywRANGFYYDCsEQ3RgWGkwrBQMMYBhlcGwSjDEBIbVBsNqwRALGNYYDGsEQ2xgWGswrBUMcYBhncGwTjDEBYb1BsN6wRAPGDYYDBsEQ3xg2GgwbBQMCYBhk8GwSTAkBIbNBsNmwZAIGLYYDFsEQ2JgCBgMAcGQBBi2GgxbBUNSYNhmMGwTDMmAYbvBsF0wJAeGHQbDDsGQAhh2Ggw7BUNKYNhlMOwSDKmAYbfBsFswpAaGPQbDHsGQBhj2Ggx7BUNaYNhnMOwTDOmAYb/BsF8wpAeGAwbDAcGQARgOGgwHBUNGYDhkMBwSDJmA4bDBcFgwZAaGIwbDEcGQBRiOGgxHBUNWYDhmMBwTDNmA4bjBcFwwZAeGEwbDCcGQAxhOGgwnBUNOYDhlMJwSDLmA4bTBcFow5AaGMwbDGcGQBxjOGgxnBUNeYDhnMJwTDPmA4bzBcF4wfAkMFwyGC4IhPzBcNBguCoYCwHDJYLgkGAoCw2WD4bJg+AoYrhgMVwTD18Bw1WC4Khi+AYZrBsM1wfAtMFw3GK4Lhu+A4YbBcEMwfA8MNw2Gm4LhB2C4ZTDcEgw/AsNtg+G2YPgJGO4YDHcEw8/AcNdguCsYfgGGewbDPcHwKzDcNxjuC4bfgOGBwfBAMPwODA8NhoeC4Q9geGQwPBIMfwLDY4PhsWD4CxieGAxPBMPfwPDUYHgqGP4BhmcGwzPB8C8wPDcYnguGQsDwwmB4IRgKA8NLg+GlYCgCDK8MhleCoSgwvDYYXguGYsDwxmB4IxiKA8Nbg+GtYCgBDO8MhneCoSQwvDcY3guGUsDwwWD4IBhKA8NHg+GjYCgDDJ8Mhk+CoSwwfDYYPguGcsDwxarQG4INaigPDGEMhjCCoQIwhDUYwgqGisAQzmAIJxgqAUN4gyG8YKgMDBEMhgiCoQowRDQYIgqGqsAQyWCIJBiqAUNkgyGyYKgODFEMhiiCoQYwRDUYogqGmsAQzWCIJhhqAUN0gyG6YKgNDDEMhhiCoQ4wxDQYYgqGusAQy2CIJRjqAUNsgyG2YKgPDHEMhjiCoQEwxDUY4gqGhsAQz2CIJxgaAUN8gyG+YGgMDAkMhgSCoQkwJDQYEgqGpsCQyGBIJBiaAUNigyGxYGgODEkMhiSCoQUwJDUYkgqGlsCQzGBIJhhaAUNygyG5YGgNDCkMhhSCoQ0wpDQYUgqGtsCQymBIJRjaAUNqgyG1YGgPDGkMhjSCoQMwpDUY0gqGjsCQzmBIJxg6AUN6gyG9YOgMDBkMhgyCoQswZDQYMgqGrsCQyWDIJBi6AUNmgyGzYOgODFkMhiyCoQcwZDUYsgqGnsCQzWDIJhh6AUN2gyG7YOgNDDkMhhyCoQ8w5DQYcgqGvsCQy2DIJRj6AUNugyG3YOgPDHkMhjyCYQAw5DUY8gqGgcCQz2DIJxgGAcOXBsOXgmEwMOQ3GPILhiHAUMBgKCAYhgJDQYOhoGAYBgxfGQxfCYbhwPC1wfC1YBgBDN8YDN8IhpHA8K3B8K1gGAUM3xkM3wmG0cDwvcHwvWAYAww/GAw/CIaxwPCjwfCjYBgHDD8ZDD8JhvHA8LPB8LNgmAAMvxgMvwiGicDwq8Hwq2CYBAy/GQy/CYbJwPC7wfC7YJgCDH8YDH8IhqnA8KfB8Kdg+A8Y/jIY/hIM04Dhb4Phb8EwHRj+MRj+EQwzgOFfg+FfwTATGAoZDIUEwyxgKGwwFBYMs4GhiMFQRDDMAYaiBkNRwTAXGIoZDMUEwzxgKG4wFBcM84GhhMFQQjAsAIaSBkNJwbAQGEoZDKUEwyJgKG0wlBYMi4GhjMFQRjAsAYayBkNZwbAUGMoZDOUEwzJgKG8wlBcMy4GhgsFQQTCsAIaKBkNFwbASGCoZDJUEwypgqGwwVBYMq4GhisFQRTCsAYaqBkNVwbAWGKoZDNUEwzpgqG4wVBcM64GhhsFQQzBsAIaaBkNNwbARGGoZDLUEwyZgqG0w1BYMm4GhjsFQRzBsAYa6BkNdwRAAhnoGQz3BsBUY6hsM9QXDNmBoYDA0EAzbgaGhwdBQMOwAhkYGQyPBsBMYGhsMjQXDLmBoYjA0EQy7gaGpwdBUMOwBhmYGQzPBsBcYmhsMzQXDPmBoYTC0EAz7gaGlwdBSMBwAhlYGQyvBcBAYWhsMrQXDIWBoYzC0EQyHgaGtwdBWMBwBhnYGQzvBcBQY2hsM7QXDMWDoYDB0EAzHgaGjwdBRMJwAhk4GQyfBcBIYOhsMnQXDKWDoYjB0EQyngaGrwdBVMJwBhm4GQzfBcBYYuhsM3QXDOWDoYTD0EAzngaGnwdBTMFwAhl4GQy/BcBEYehsMvQXDJWDoYzD0EQyXgaGvwdBXMFwBhn4GQz/BcBUY+hsM/QXDNWAYYDAMEAzXgWGgwTBQMNwAhkEGwyDBcBMYBhsMgwXDLWAYYjAMEQy3gWGowTBUMNwBhmEGwzDBcBcYhhsMwwXDPWAYYTCMEAz3gWGkwTBSMDwAhlEGwyjB8BAYRhsMowXDI2AYYzCMEQyPgWGswTBWMDwBhnEGwzjB8BQYxhsM4wXDM2CYYDBMEAzPgWGiwTBRMLwAhkkGwyTB8BIYJhsMkwXDK2CYYjBMEQyvgWGqwTBVMLwBhv8Mhv8Ew1tgmGYwTBMM74BhusEwXTC8B4YZBsMMwfABGGYaDDMFw0dgmGUwzBIMn4BhtsEwWzB8BoY5BsMcwfBFpv/fMNdgmCsYwgDDPINhnmAICwzzDYb5giEcMCwwGBYIhvDAsNBgWCgYIgDDIoNhkWCICAyLDYbFgiESMCwxGJYIhsjAsNRgWCoYogDDMoNhmWCICgzLDYblgiEaMKwwGFYIhujAsNJgWCkYYgDDKoNhlWCICQyrDYbVgiEWMKwxGNYIhtjAsNZgWCsY4gDDOoNhnWCICwzrDYb1giEeMGwwGDYIhvjAsNFg2CgYEgDDJoNhk2BICAybDYbNgiERMGwxGLYIhsTAEDAYAoIhCTBsNRi2CoakwLDNYNgmGJIBw3aDYbtgSA4MOwyGHYIhBTDsNBh2CoaUwLDLYNglGFIBw26DYbdgSA0MewyGPYIhDTDsNRj2Coa0wLDPYNgnGNIBw36DYb9gSA8MBwyGA4IhAzAcNBgOCoaMwHDIYDgkGDIBw2GD4bBgyAwMRwyGI4IhCzAcNRiOCoaswHDMYDgmGLIBw3GD4bhgyA4MJwyGE4IhBzCcNBhOCoacwHDKYDglGHIBw2mD4bRgyA0MZwyGM4IhDzCcNRjOCoa8wHDOYDgnGPIBw3mD4bxg+BIYLhgMFwRDfmC4aDBcFAwFgOGSwXBJMBQEhssGw2XB8BUwXDEYrgiGr4HhqsFwVTB8AwzXDIZrguFbYLhuMFwXDN8Bww2D4YZg+B4YbhoMNwXDD8Bwy2C4JRh+BIbbBsNtwfATMNwxGO4Ihp+B4a7BcFcw/AIM9wyGe4LhV2C4bzDcFwy/AcMDg+GBYPgdGB4aDA8Fwx/A8MhgeCQY/gSGxwbDY8HwFzA8MRieCIa/geGpwfBUMPwDDM8MhmeC4V9geG4wPBcMhYDhhcHwQjAUBoaXBsNLwVAEGF4ZDK8EQ1FgeG0wvBYMxYDhjcHwRjAUB4a3BsNbwVACGN4ZDO8EQ0lgeG8wvBcMpYDhg8HwQTCUBoaPBsNHwVAGGD4ZDJ8EQ1lg+GwwfBYM5YDhi9WhNwQb1FAeGMIYDGEEQwVgCGswhBUMFYEhnMEQTjBUAobwBkN4wVAZGCIYDBEEQxVgiGgwRBQMVYEhksEQSTBUA4bIBkNkwVAdGKIYDFEEQw1giGowRBUMNYEhmsEQTTDUAoboBkN0wVAbGGIYDDEEQx1giGkwxBQMdYEhlsEQSzDUA4bYBkNswVAfGOIYDHEEQwNgiGswxBUMDYEhnsEQTzA0Aob4BkN8wdAYGBIYDAkEQxNgSGgwJBQMTYEhkcGQSDA0A4bEBkNiwdAcGJIYDEkEQwtgSGowJBUMLYEhmcGQTDC0AobkBkNywdAaGFIYDCkEQxtgSGkwpBQMbYEhlcGQSjC0A4bUBkNqwdAeGNIYDGkEQwdgSGswpBUMHYEhncGQTjB0Aob0BkN6wdAZGDIYDBkEQxdgyGgwZBQMXYEhk8GQSTB0A4bMBkNmwdAdGLIYDFkEQw9gyGowZBUMPYEhm8GQTTD0AobsBkN2wdAbGHIYDDkEQx9gyGkw5BQMfYEhl8GQSzD0A4bcBkNuwdAfGPIYDHkEwwBgyGsw5BUMA4Ehn8GQTzAMAoYvDYYvBcNgYMhvMOQXDEOAoYDBUEAwDAWGggZDQcEwDBi+Mhi+EgzDgeFrg+FrwTACGL4xGL4RDCOB4VuD4VvBMAoYvjMYvhMMo4Hhe4Phe8EwBhh+MBh+EAxjgeFHg+FHwTAOGH4yGH4SDOOB4WeD4WfBMAEYfjEYfhEME4HhV4PhV8EwCRh+Mxh+EwyTgeF3g+F3wTAFGP4wGP4QDFOB4U+D4U/B8B8w/GUw/CUYpgHD3wbD34JhOjD8YzD8IxhmAMO/BsO/gmEmMBQyGAoJhlnAUNhgKCwYZgNDEYOhiGCYAwxFDYaigmEuMBQzGIoJhnnAUNxgKC4Y5gNDCYOhhGBYAAwlDYaSgmEhMJQyGEoJhkXAUNpgKC0YFgNDGYOhjGBYAgxlDYaygmEpMJQzGMoJhmXAUN5gKC8YlgNDBYOhgmBYAQwVDYaKgmElMFQyGCoJhlXAUNlgqCwYVgNDFYOhimBYAwxVDYaqgmEtMFQzGKoJhnXAUN1gqC4Y1gNDDYOhhmDYAAw1DYaagmEjMNQyGGoJhk3AUNtgqC0YNgNDHYOhjmDYAgx1DYa6giEADPUMhnqCYSsw1DcY6guGbcDQwGBoIBi2A0NDg6GhYNgBDI0MhkaCYScwNDYYGguGXcDQxGBoIhh2A0NTg6GpYNgDDM0MhmaCYS8wNDcYmguGfcDQwmBoIRj2A0NLg6GlYDgADK0MhlaC4SAwtDYYWguGQ8DQxmBoIxgOA0Nbg6GtYDgCDO0MhnaC4SgwtDcY2guGY8DQwWDoIBiOA0NHg6GjYDgBDJ0Mhk6C4SQwdDYYOguGU8DQxWDoIhhOA0NXg6GrYDgDDN0Mhm6C4SwwdDcYuguGc8DQw2DoIRjOA0NPg6GnYLgADL0Mhl6C4SIw9DYYeguGS8DQx2DoIxguA0Nfg6GvYLgCDP0Mhn6C4Sow9DcY+guGa8AwwGAYIBiuA8NAg2GgYLgBDIMMhkGC4SYwDDYYBguGW8AwxGAYIhhuA8NQg2GoYLgDDMMMhmGC4S4wDDcYhguGe8AwwmAYIRjuA8NIg2GkYHgADKMMhlGC4SEwjDYYRguGR8AwxmAYIxgeA8NYg2GsYHgCDOMMhnGC4SkwjDcYxguGZ8AwwWCYIBieA8NEg2GiYHgBDJMMhkmC4SUwTDYYJguGV8AwxWCYIhheA8NUg2GqYHgDDP8ZDP8JhrfAMM1gmCYY3gHDdINhumB4DwwzDIYZguEDMMw0GGYKho/AMCvEhk9Zvvgi6KCGz1n+f8Nsww6zhR2+yPr/G+YYDHMEQxhgmGswzBUMYYFhnsEwTzCEA4b5BsN8wRAeGBYYDAsEQwRgWGgwLBQMEYFhkcGwSDBEAobFBsNiwRAZGJYYDEsEQxRgWGowLBUMUYFhmcGwTDBEA4blBsNywRAdGFYYDCsEQwxgWGkwrBQMMYFhlcGwSjDEAobVBsNqwRAbGNYYDGsEQxxgWGswrBUMcYFhncGwTjDEA4b1BsN6wRAfGDYYDBsEQwJg2GgwbBQMCYFhk8GwSTAkAobNBsNmwZAYGLYYDFsEQxJgCBgMAcGQFBi2GgxbBUMyYNhmMGwTDMmBYbvBsF0wpACGHQbDDsGQEhh2Ggw7BUMqYNhlMOwSDKmBYbfBsFswpAGGPQbDHsGQFhj2Ggx7BUM6YNhnMOwTDOmBYb/BsF8wZACGAwbDAcGQERgOGgwHBUMmYDhkMBwSDJmB4bDBcFgwZAGGIwbDEcGQFRiOGgxHBUM2YDhmMBwTDNmB4bjBcFww5ACGEwbDCcGQExhOGgwnBUMuYDhlMJwSDLmB4bTBcFow5AGGMwbDGcGQFxjOGgxnBUM+YDhnMJwTDF8Cw3mD4bxgyA8MFwyGC4KhADBcNBguCoaCwHDJYLgkGL4ChssGw2XB8DUwXDEYrgiGb4DhqsFwVTB8CwzXDIZrguE7YLhuMFwXDN8Dww2D4YZg+AEYbhoMNwXDj8Bwy2C4JRh+AobbBsNtwfAzMNwxGO4Ihl+A4a7BcFcw/AoM9wyGe4LhN2C4bzDcFwy/A8MDg+GBYPgDGB4aDA8Fw5/A8MhgeCQY/gKGxwbDY8HwNzA8MRieCIZ/gOGpwfBUMPwLDM8MhmeCoRAwPDcYnguGwsDwwmB4IRiKAMNLg+GlYCgKDK8MhleCoRgwvDYYXguG4sDwxmB4IxhKAMNbg+GtYCgJDO8MhneCoRQwvDcY3guG0sDwwWD4IBjKAMNHg+GjYCgLDJ8Mhk+CoRwwfDYYPguG8sDwxZrQG4INaqgADGEMhjCCoSIwhDUYwgqGSsAQzmAIJxgqA0N4gyG8YKgCDBEMhgiCoSowRDQYIgqGasAQyWCIJBiqA0NkgyGyYKgBDFEMhiiCoSYwRDUYogqGWsAQzWCIJhhqA0N0gyG6YKgDDDEMhhiCoS4wxDQYYgqGesAQy2CIJRjqA0NsgyG2YGgADHEMhjiCoSEwxDUY4gqGRsAQz2CIJxgaA0N8gyG+YGgCDAkMhgSCoSkwJDQYEgqGZsCQyGBIJBiaA0NigyGxYGgBDEkMhiSCoSUwJDUYkgqGVsCQzGBIJhhaA0NygyG5YGgDDCkMhhSCoS0wpDQYUgqGdsCQymBIJRjaA0NqgyG1YOgADGkMhjSCoSMwpDUY0gqGTsCQzmBIJxg6A0N6gyG9YOgCDBkMhgyCoSswZDQYMgqGbsCQyWDIJBi6A0NmgyGzYOgBDFkMhiyCoScwZDUYsgqGXsCQzWDIJhh6A0N2gyG7YOgDDDkMhhyCoS8w5DQYcgqGfsCQy2DIJRj6A0NugyG3YBgADHkMhjyCYSAw5DUY8gqGQcCQz2DIJxgGA8OXBsOXgmEIMOQ3GPILhqHAUMBgKCAYhgFDQYOhoGAYDgxfGQxfCYYRwPC1wfC1YBgJDN8YDN8IhlHA8K3B8K1gGA0M3xkM3wmGMcDwvcHwvWAYCww/GAw/CIZxwPCjwfCjYBgPDD8ZDD8JhgnA8LPB8LNgmAgMvxgMvwiGScDwq8Hwq2CYDAy/GQy/CYYpwPC7wfC7YJgKDH8YDH8Ihv+A4U+D4U/BMA0Y/jIY/hIM04Hhb4Phb8EwAxj+MRj+EQwzgeFfg+FfwTALGAoZDIUEw2xgKGwwFBYMc4ChiMFQRDDMBYaiBkNRwTAPGIoZDMUEw3xgKG4wFBcMC4ChhMFQQjAsBIaSBkNJwbAIGEoZDKUEw2JgKG0wlBYMS4ChjMFQRjAsBYayBkNZwbAMGMoZDOUEw3JgKG8wlBcMK4ChgsFQQTCsBIaKBkNFwbAKGCoZDJUEw2pgqGwwVBYMa4ChisFQRTCsBYaqBkNVwbAOGKoZDNUEw3pgqG4wVBcMG4ChhsFQQzBsBIaaBkNNwbAJGGoZDLUEw2ZgqG0w1BYMW4ChjsFQRzAEgKGuwVBXMGwFhnoGQz3BsA0Y6hsM9QXDdmBoYDA0EAw7gKGhwdBQMOwEhkYGQyPBsAsYGhsMjQXDbmBoYjA0EQx7gKGpwdBUMOwFhmYGQzPBsA8YmhsMzQXDfmBoYTC0EAwHgKGlwdBSMBwEhlYGQyvBcAgYWhsMrQXDYWBoYzC0EQxHgKGtwdBWMBwFhnYGQzvBcAwY2hsM7QXDcWDoYDB0EAwngKGjwdBRMJwEhk4GQyfBcAoYOhsMnQXDaWDoYjB0EQxngKGrwdBVMJwFhm4GQzfBcA4YuhsM3QXDeWDoYTD0EAwXgKGnwdBTMFwEhl4GQy/BcAkYehsMvQXDZWDoYzD0EQxXgKGvwdBXMFwFhn4GQz/BcA0Y+hsM/QXDdWAYYDAMEAw3gGGgwTBQMNwEhkEGwyDBcAsYBhsMgwXDbWAYYjAMEQx3gGGowTBUMNwFhmEGwzDBcA8YhhsMwwXDfWAYYTCMEAwPgGGkwTBSMDwEhlEGwyjB8AgYRhsMowXDY2AYYzCMEQxPgGGswTBWMDwFhnEGwzjB8AwYxhsM4wXDc2CYYDBMEAwvgGGiwTBRMLwEhkkGwyTB8AoYJhsMkwXDa2CYYjBMEQxvgGGqwTBVMLwFhv8Mhv8EwztgmGYwTBMM74FhusEwXTB8AIYZBsMMwfARGGYaDDMFwydgmGUwzBIMn4FhtsEwWzB8ke3/N8wxGOYIhjDAMNdgmCsYwgLDPINhnmAIBwzzDYb5giE8MCwwGBYIhgjAsNBgWCgYIgLDIoNhkWCIBAyLDYbFgiEyMCwxGJYIhijAsNRgWCoYogLDMoNhmWCIBgzLDYblgiE6MKwwGFYIhhjAsNJgWCkYYgLDKoNhlWCIBQyrDYbVgiE2MKwxGNYIhjjAsNZgWCsY4gLDOoNhnWCIBwzrDYb1giE+MGwwGDYIhgTAsNFg2CgYEgLDJoNhk2BIBAybDYbNgiExMGwxGLYIhiTAEDAYAoIhKTBsNRi2CoZkwLDNYNgmGJIDw3aDYbtgSAEMOwyGHYIhJTDsNBh2CoZUwLDLYNglGFIDw26DYbdgSAMMewyGPYIhLTDsNRj2CoZ0wLDPYNgnGNIDw36DYb9gyAAMBwyGA4IhIzAcNBgOCoZMwHDIYDgkGDIDw2GD4bBgyAIMRwyGI4IhKzAcNRiOCoZswHDMYDgmGLIDw3GD4bhgyAEMJwyGE4IhJzCcNBhOCoZcwHDKYDglGHIDw2mD4bRgyAMMZwyGM4IhLzCcNRjOCoZ8wHDOYDgnGL4EhvMGw3nBkB8YLhgMFwRDAWC4aDBcFAwFgeGSwXBJMHwFDJcNhsuC4WtguGIwXBEM3wDDVYPhqmD4FhiuGQzXBMN3wHDdYLguGL4HhhsGww3B8AMw3DQYbgqGH4HhlsFwSzD8BAy3DYbbguFnYLhjMNwRDL8Aw12D4a5g+BUY7hkM9wTDb8Bw32C4Lxh+B4YHBsMDwfAHMDw0GB4Khj+B4ZHB8Egw/AUMjw2Gx4Lhb2B4YjA8EQz/AMNTg+GpYPgXGJ4ZDM8EQyFgeG4wPBcMhYHhhcHwQjAUAYaXBsNLwVAUGF4ZDK8EQzFgeG0wvBYMxYHhjcHwRjCUAIa3BsNbwVASGN4ZDO8EQylgeG8wvBcMpYHhg8HwQTCUAYaPBsNHwVAWGD4ZDJ8EQzlg+GwwfBYM5YHhi7WhNwQb1FABGMIYDGEEQ0VgCGswhBUMlYAhnMEQTjBUBobwBkN4wVAFGCIYDBEEQ1VgiGgwRBQM1YAhksEQSTBUB4bIBkNkwVADGKIYDFEEQ01giGowRBUMtYAhmsEQTTDUBoboBkN0wVAHGGIYDDEEQ11giGkwxBQM9YAhlsEQSzDUB4bYBkNswdAAGOIYDHEEQ0NgiGswxBUMjYAhnsEQTzA0Bob4BkN8wdAEGBIYDAkEQ1NgSGgwJBQMzYAhkcGQSDA0B4bEBkNiwdACGJIYDEkEQ0tgSGowJBUMrYAhmcGQTDC0BobkBkNywdAGGFIYDCkEQ1tgSGkwpBQM7YAhlcGQSjC0B4bUBkNqwdABGNIYDGkEQ0dgSGswpBUMnYAhncGQTjB0Bob0BkN6wdAFGDIYDBkEQ1dgyGgwZBQM3YAhk8GQSTB0B4bMBkNmwdADGLIYDFkEQ09gyGowZBUMvYAhm8GQTTD0BobsBkN2wdAHGHIYDDkEQ19gyGkw5BQM/YAhl8GQSzD0B4bcBkNuwTAAGPIYDHkEw0BgyGsw5BUMg4Ahn8GQTzAMBoYvDYYvBcMQYMhvMOQXDEOBoYDBUEAwDAOGggZDQcEwHBi+Mhi+EgwjgOFrg+FrwTASGL4xGL4RDKOA4VuD4VvBMBoYvjMYvhMMY4Dhe4Phe8EwFhh+MBh+EAzjgOFHg+FHwTAeGH4yGH4SDBOA4WeD4WfBMBEYfjEYfhEMk4DhV4PhV8EwGRh+Mxh+EwxTgOF3g+F3wTAVGP4wGP4QDP8Bw58Gw5+CYRow/GUw/CUYpgPD3wbD34JhBjD8YzD8IxhmAsO/BsO/gmEWMBQyGAoJhtnAUNhgKCwY5gBDEYOhiGCYCwxFDYaigmEeMBQzGIoJhvnAUNxgKC4YFgBDCYOhhGBYCAwlDYaSgmERMJQyGEoJhsXAUNpgKC0YlgBDGYOhjGBYCgxlDYaygmEZMJQzGMoJhuXAUN5gKC8YVgBDBYOhgmBYCQwVDYaKgmEVMFQyGCoJhtXAUNlgqCwY1gBDFYOhimBYCwxVDYaqgmEdMFQzGKoJhvXAUN1gqC4YNgBDDYOhhmDYCAw1DYaagmETMNQyGGoJhs3AUNtgqC0YtgBDHYOhjmAIAENdg6GuYNgKDPUMhnqCYRsw1DcY6guG7cDQwGBoIBh2AENDg6GhYNgJDI0MhkaCYRcwNDYYGguG3cDQxGBoIhj2AENTg6GpYNgLDM0MhmaCYR8wNDcYmguG/cDQwmBoIRgOAENLg6GlYDgIDK0MhlaC4RAwtDYYWguGw8DQxmBoIxiOAENbg6GtYDgKDO0MhnaC4RgwtDcY2guG48DQwWDoIBhOAENHg6GjYDgJDJ0Mhk6C4RQwdDYYOguG08DQxWDoIhjOAENXg6GrYDgLDN0Mhm6C4RwwdDcYuguG88DQw2DoIRguAENPg6GnYLgIDL0Mhl6C4RIw9DYYeguGy8DQx2DoIxiuAENfg6GvYLgKDP0Mhn6C4Row9DcY+guG68AwwGAYIBhuAMNAg2GgYLgJDIMMhkGC4RYwDDYYBguG28AwxGAYIhjuAMNQg2GoYLgLDMMMhmGC4R4wDDcYhguG+8AwwmAYIRgeAMNIg2GkYHgIDKMMhlGC4REwjDYYRguGx8AwxmAYIxieAMNYg2GsYHgKDOMMhnGC4RkwjDcYxguG58AwwWCYIBheAMNEg2GiYHgJDJMMhkmC4RUwTDYYJguG18AwxWCYIhjeAMNUg2GqYHgLDP8ZDP8JhnfAMM1gmCYY3gPD9BAbwiT+4ouggxrCJv7/DTMMO8wQdggHDDMNhpmCITwwzDIYZgmGCMAw22CYLRgiAsMcg2GOYIgEDHMNhrmCITIwzDMY5gmGKMAw32CYLxiiAsMCg2GBYIgGDAsNhoWCITowLDIYFgmGGMCw2GBYLBhiAsMSg2GJYIgFDEsNhqWCITYwLDMYlgmGOMCw3GBYLhjiAsMKg2GFYIgHDCsNhpWCIT4wrDIYVgmGBMCw2mBYLRgSAsMag2GNYEgEDGsNhrWCITEwrDMY1gmGJMCw3mBYLxiSAsMGg2GDYEgGDBsNho2CITkwbDIYNgmGFMCw2WDYLBhSAsMWg2GLYEgFDAGDISAYUgPDVoNhq2BIAwzbDIZtgiEtMGw3GLYLhnTAsMNg2CEY0gPDToNhp2DIAAy7DIZdgiEjMOw2GHYLhkzAsMdg2CMYMgPDXoNhr2DIAgz7DIZ9giErMOw3GPYLhmzAcMBgOCAYsgPDQYPhoGDIAQyHDIZDgiEnMBw2GA4LhlzAcMRgOCIYcgPDUYPhqGDIAwzHDIZjgiEvMBw3GI4LhnzAcMJgOCEYvgSGkwbDScGQHxhOGQynBEMBYDhtMJwWDAWB4YzBcEYwfAUMZw2Gs4Lha2A4ZzCcEwzfAMN5g+G8YPgWGC4YDBcEw3fAcNFguCgYvgeGSwbDJcHwAzBcNhguC4YfgeGKwXBFMPwEDFcNhquC4WdguGYwXBMMvwDDdYPhumD4FRhuGAw3BMNvwHDTYLgpGH4HhlsGwy3B8Acw3DYYbguGP4HhjsFwRzD8BQx3DYa7guFvYLhnMNwTDP8Aw32D4b5g+BcYHhgMDwRDIWB4aDA8FAyFgeGRwfBIMBQBhscGw2PBUBQYnhgMTwRDMWB4ajA8FQzFgeGZwfBMMJQAhucGw3PBUBIYXhgMLwRDKWB4aTC8FAylgeGVwfBKMJQBhtcGw2vBUBYY3hgMbwRDOWB4azC8FQzlgeGdwfBOMFQAhvcGw3vBUBEYPhgMHwRDJWD4aDB8FAyVgeGTwfBJMFQBhs8Gw2fBUBUYvlgXekOwQQ3VgCGMwRBGMFQHhrAGQ1jBUAMYwhkM4QRDTWAIbzCEFwy1gCGCwRBBMNQGhogGQ0TBUAcYIhkMkQRDXWCIbDBEFgz1gCGKwRBFMNQHhqgGQ1TB0AAYohkM0QRDQ2CIbjBEFwyNgCGGwRBDMDQGhpgGQ0zB0AQYYhkMsQRDU2CIbTDEFgzNgCGOwRBHMDQHhrgGQ1zB0AIY4hkM8QRDS2CIbzDEFwytgCGBwZBAMLQGhoQGQ0LB0AYYEhkMiQRDW2BIbDAkFgztgCGJwZBEMLQHhqQGQ1LB0AEYkhkMyQRDR2BIbjAkFwydgCGFwZBCMHQGhpQGQ0rB0AUYUhkMqQRDV2BIbTCkFgzdgCGNwZBGMHQHhrQGQ1rB0AMY0hkM6QRDT2BIbzCkFwy9gCGDwZBBMPQGhowGQ0bB0AcYMhkMmQRDX2DIbDBkFgz9gCGLwZBFMPQHhqwGQ1bBMAAYshkM2QTDQGDIbjBkFwyDgCGHwZBDMAwGhpwGQ07BMAQYchkMuQTDUGDIbTDkFgzDgCGPwZBHMAwHhrwGQ17BMAIY8hkM+QTDSGD40mD4UjCMAob8BkN+wTAaGAoYDAUEwxhgKGgwFBQMY4HhK4PhK8EwDhi+Nhi+FgzjgeEbg+EbwTABGL41GL4VDBOB4TuD4TvBMAkYvjcYvhcMk4HhB4PhB8EwBRh+NBh+FAxTgeEng+EnwfAfMPxsMPwsGKYBwy8Gwy+CYTow/Gow/CoYZgDDbwbDb4JhJjD8bjD8LhhmAcMfBsMfgmE2MPxpMPwpGOYAw18Gw1+CYS4w/G0w/C0Y5gHDPwbDP4JhPjD8azD8KxgWAEMhg6GQYFgIDIUNhsKCYREwFDEYigiGxcBQ1GAoKhiWAEMxg6GYYFgKDMUNhuKCYRkwlDAYSgiG5cBQ0mAoKRhWAEMpg6GUYFgJDKUNhtKCYRUwlDEYygiG1cBQ1mAoKxjWAEM5g6GcYFgLDOUNhvKCYR0wVDAYKgiG9cBQ0WCoKBg2AEMlg6GSYNgIDJUNhsqCYRMwVDEYqgiGzcBQ1WCoKhi2AEM1g6GaYAgAQ3WDobpg2AoMNQyGGoJhGzDUNBhqCobtwFDLYKglGHYAQ22DobZg2AkMdQyGOoJhFzDUNRjqCobdwFDPYKgnGPYAQ32Dob5g2AsMDQyGBoJhHzA0NBgaCob9wNDIYGgkGA4AQ2ODobFgOAgMTQyGJoLhEDA0NRiaCobDwNDMYGgmGI4AQ3ODoblgOAoMLQyGFoLhGDC0NBhaCobjwNDKYGglGE4AQ2uDobVgOAkMbQyGNoLhFDC0NRjaCobTwNDOYGgnGM4AQ3uDob1gOAsMHQyGDoLhHDB0NBg6CobzwNDJYOgkGC4AQ2eDobNguAgMXQyGLoLhEjB0NRi6CobLwNDNYOgmGK4AQ3eDobtguAoMPQyGHoLhGjD0NBh6CobrwNDLYOglGG4AQ2+DobdguAkMfQyGPoLhFjD0NRj6CobbwNDPYOgnGO4AQ3+Dob9guAsMAwyGAYLhHjAMNBgGCob7wDDIYBgkGB4Aw2CDYbBgeAgMQwyGIYLhETAMNRiGCobHwDDMYBgmGJ4Aw3CDYbhgeAoMIwyGEYLhGTCMNBhGCobnwDDKYBglGF4Aw2iDYbRgeAkMYwyGMYLhFTCMNRjGCobXwDDOYBgnGN4Aw3iDYbxgeAsMEwyGCYLhHTBMNBgmCob3wDDJYJgkGD4Aw2SDYbJg+AgMUwyGKYLhEzBMNRimCobPwPCfwfCfYPgiyf9vmGYwTBMMYYBhusEwXTCEBYYZBsMMwRAOGGYaDDMFQ3hgmGUwzBIMEYBhtsEwWzBEBIY5BsMcwRAJGOYaDHMFQ2RgmGcwzBMMUYBhvsEwXzBEBYYFBsMCwRANGBYaDAsFQ3RgWGQwLBIMMYBhscGwWDDEBIYlBsMSwRALGJYaDEsFQ2xgWGYwLBMMcYBhucGwXDDEBYYVBsMKwRAPGFYaDCsFQ3xgWGUwrBIMCYBhtcGwWjAkBIY1BsMawZAIGNYaDGsFQ2JgWGcwrBMMSYBhvcGwXjAkBYYNBsMGwZAMGDYaDBsFQ3Jg2GQwbBIMKYBhs8GwWTCkBIYtBsMWwZAKGAIGQ0AwpAaGrQbDVsGQBhi2GQzbBENaYNhuMGwXDOmAYYfBsEMwpAeGnQbDTsGQARh2GQy7BENGYNhtMOwWDJmAYY/BsEcwZAaGvQbDXsGQBRj2GQz7BENWYNhvMOwXDNmA4YDBcEAwZAeGgwbDQcGQAxgOGQyHBENOYDhsMBwWDLmA4YjBcEQw5AaGowbDUcGQBxiOGQzHBENeYDhuMBwXDPmA4YTBcEIwfAkMJw2Gk4IhPzCcMhhOCYYCwHDaYDgtGAoCwxmD4Yxg+AoYzhoMZwXD18BwzmA4Jxi+AYbzBsN5wfAtMFwwGC4Ihu+A4aLBcFEwfA8MlwyGS4LhB2C4bDBcFgw/AsMVg+GKYPgJGK4aDFcFw8/AcM1guCYYfgGG6wbDdcHwKzDcMBhuCIbfgOGmwXBTMPwODLcMhluC4Q9guG0w3BYMfwLDHYPhjmD4CxjuGgx3BcPfwHDPYLgnGP4BhvsGw33B8C8wPDAYHgiGQsDw0GB4KBgKA8Mjg+GRYCgCDI8NhseCoSgwPDEYngiGYsDw1GB4KhiKA8Mzg+GZYCgBDM8NhueCoSQwvDAYXgiGUsDw0mB4KRhKA8Mrg+GVYCgDDK8NhteCoSwwvDEY3giGcsDw1mB4KxjKA8M7g+GdYKgADO8NhveCoSIwfDAYPgiGSsDw0WD4KBgqA8Mng+GTYKgCDJ8Nhs+CoSowfLE+9IZggxqqAUMYgyGMYKgODGENhrCCoQYwhDMYwgmGmsAQ3mAILxhqAUMEgyGCYKgNDBENhoiCoQ4wRDIYIgmGusAQ2WCILBjqAUMUgyGKYKgPDFENhqiCoQEwRDMYogmGhsAQ3WCILhgaAUMMgyGGYGgMDDENhpiCoQkwxDIYYgmGpsAQ22CILRiaAUMcgyGOYGgODHENhriCoQUwxDMY4gmGlsAQ32CILxhaAUMCgyGBYGgNDAkNhoSCoQ0wJDIYEgmGtsCQ2GBILBjaAUMSgyGJYGgPDEkNhqSCoQMwJDMYkgmGjsCQ3GBILhg6AUMKgyGFYOgMDCkNhpSCoQswpDIYUgmGrsCQ2mBILRi6AUMagyGNYOgODGkNhrSCoQcwpDMY0gmGnsCQ3mBILxh6AUMGgyGDYOgNDBkNhoyCoQ8wZDIYMgmGvsCQ2WDILBj6AUMWgyGLYOgPDFkNhqyCYQAwZDMYsgmGgcCQ3WDILhgGAUMOgyGHYBgMDDkNhpyCYQgw5DIYcgmGocCQ22DILRiGAUMegyGPYBgODHkNhryCYQQw5DMY8gmGkcDwpcHwpWAYBQz5DYb8gmE0MBQwGAoIhjHAUNBgKCgYxgLDVwbDV4JhHDB8bTB8LRjGA8M3BsM3gmECMHxrMHwrGCYCw3cGw3eCYRIwfG8wfC8YJgPDDwbDD4JhCjD8aDD8KBimAsNPBsNPguE/YPjZYPhZMEwDhl8Mhl8Ew3Rg+NVg+FUwzACG3wyG3wTDTGD43WD4XTDMAoY/DIY/BMNsYPjTYPhTMMwBhr8Mhr8Ew1xg+Ntg+FswzAOGfwyGfwTDfGD412D4VzAsAIZCBkMhwbAQGAobDIUFwyJgKGIwFBEMi4GhqMFQVDAsAYZiBkMxwbAUGIobDMUFwzJgKGEwlBAMy4GhpMFQUjCsAIZSBkMpwbASGEobDKUFwypgKGMwlBEMq4GhrMFQVjCsAYZyBkM5wbAWGMobDOUFwzpgqGAwVBAM64GhosFQUTBsAIZKBkMlwbARGCobDJUFwyZgqGIwVBEMm4GhqsFQVTBsAYZqBkM1wRAAhuoGQ3XBsBUYahgMNQTDNmCoaTDUFAzbgaGWwVBLMOwAhtoGQ23BsBMY6hgMdQTDLmCoazDUFQy7gaGewVBPMOwBhvoGQ33BsBcYGhgMDQTDPmBoaDA0FAz7gaGRwdBIMBwAhsYGQ2PBcBAYmhgMTQTDIWBoajA0FQyHgaGZwdBMMBwBhuYGQ3PBcBQYWhgMLQTDMWBoaTC0FAzHgaGVwdBKMJwAhtYGQ2vBcBIY2hgMbQTDKWBoazC0FQyngaGdwdBOMJwBhvYGQ3vBcBYYOhgMHQTDOWDoaDB0FAzngaGTwdBJMFwAhs4GQ2fBcBEYuhgMXQTDJWDoajB0FQyXgaGbwdBNMFwBhu4GQ3fBcBUYehgMPQTDNWDoaTD0FAzXgaGXwdBLMNwAht4GQ2/BcBMY+hgMfQTDLWDoazD0FQy3gaGfwdBPMNwBhv4GQ3/BcBcYBhgMAwTDPWAYaDAMFAz3gWGQwTBIMDwAhsEGw2DB8BAYhhgMQwTDI2AYajAMFQyPgWGYwTBMMDwBhuEGw3DB8BQYRhgMIwTDM2AYaTCMFAzPgWGUwTBKMLwAhtEGw2jB8BIYxhgMYwTDK2AYazCMFQyvgWGcwTBOMLwBhvEGw3jB8BYYJhgMEwTDO2CYaDBMFAzvgWGSwTBJMHwAhskGw2TB8BEYphgMUwTDJ2CYajBMFQyfgeE/g2Hucm74Ivz/b5hmMExfK7zpbP+/YXqIDWGifvFF0EENYaP+/4YZhh1mCO8hHDDMNBhmCobwwDDLYJglGCIAw2yDYbZgiAgMcwyGOYIhEjDMdfwfBENkYJhnMMwTDFGAYb7BMF8wRAWGBQbDAsEQDRgWGgwLBUN0YFhkMCwSDDGAYbHBsFgwxASGJQbDEsEQCxiWGgxLBUNsYFhmMCwTDHGAYbnBsFwwxAWGFQbDCsEQDxhWGgwrBUN8YFhlMKwSDAmAYbXBsFowJASGNQbDGsGQCBjWGgxrBUNiYFhnMKwTDEmAYb3BsF4wJAWGDQbDBsGQDBg2GgwbBUNyYNhkMGwSDCmAYbPBsFkwpASGLQbDFsGQChgCBkNAMKQGhq0Gw1bBkAYYthkM2wRDWmDYbjBsFwzpgGGHwbBDMKQHhp0Gw07BkAEYdhkMuwRDRmDYbTDsFgyZgGGPwbBHMGQGhr0Gw17BkAUY9hkM+wRDVmDYbzDsFwzZgOGAwXBAMGQHhoMGw0HBkAMYDhkMhwRDTmA4bDAcFgy5gOGIwXBEMOQGhqMGw1HBkAcYjhkMxwRDXmA4bjAcFwz5gOGEwXBCMHwJDCcNhpOCIT8wnDIYTgmGAsBw2mA4LRgKAsMZg+GMYPgKGM4aDGcFw9fAcM5gOCcYvgGG8wbDecHwLTBcMBguCIbvgOGiwXBRMHwPDJcMhkuC4QdguGwwXBYMPwLDFYPhimD4CRiuGgxXBcPPwHDNYLgmGH4BhusGw3XB8Csw3DAYbgiG34DhpsFwUzD8Dgy3DIZbguEPYLhtMNwWDH8Cwx2D4Y5g+AsY7hoMdwXD38Bwz2C4Jxj+AYb7BsN9wfAvMDwwGB4IhkLA8NBgeCgYCgPDI4PhkWAoAgyPDYbHgqEoMDwxGJ4IhmLA8NRgeCoYigPDM4PhmWAoAQzPDYbngqEkMLwwGF4IhlLA8NJgeCkYSgPDK4PhlWAoAwyvDYbXgqEsMLwxGN4IhnLA8NZgeCsYygPDO4PhnWCoAAzvDYb3gqEiMHwwGD4IhkrA8NFg+CgYKgPDJ4Phk2CoAgyfDYbPgqEqMHyxIfSGYIMaqgFDGIMhjGCoDgxhDYawgqEGMIQzGMIJhprAEN5gCC8YagFDBIMhgmCoDQwRDYaIgqEOMEQyGCIJhrrAENlgiCwY6gFDFIMhimCoDwxRDYaogqEBMEQzGKIJhobAEN1giC4YGgFDDIMhhmBoDAwxDYaYgqEJMMQyGGIJhqbAENtgiC0YmgFDHIMhjmBoDgxxDYa4gqEFMMQzGOIJhpbAEN9giC8YWgFDAoMhgWBoDQwJDYaEgqENMCQyGBIJhrbAkNhgSCwY2gFDEoMhiWBoDwxJDYakgqEDMCQzGJIJho7AkNxgSC4YOgFDCoMhhWDoDAwpDYaUgqELMKQyGFIJhq7AkNpgSC0YugFDGoMhjWDoDgxpDYa0gqEHMKQzGNIJhp7AkN5gSC8YegFDBoMhg2DoDQwZDYaMgqEPMGQyGDIJhr7AkNlgyCwY+gFDFoMhi2DoDwxZDYasgmEAMGQzGLIJhoHAkN1gyC4YBgFDDoMhh2AYDAw5DYacgmEIMOQyGHIJhqHAkNtgyC0YhgFDHoMhj2AYDgx5DYa8gmEEMOQzGPIJhpHA8KXB8KVgGAUM+Q2G/IJhNDAUMBgKCIYxwFDQYCgoGMYCw1cGw1eCYRwwfG0wfC0YxgPDNwbDN4JhAjB8azB8KxgmAsN3BsN3gmESMHxvMHwvGCYDww8Gww+CYQow/Ggw/CgYpgLDTwbDT4LhP2D42WD4WTBMA4ZfDIZfBMN0YPjVYPhVMMwAht8Mht8Ew0xg+N1g+F0wzAKGPwyGPwTDbGD402D4UzDMAYa/DIa/BMNcYPjbYPhbMMwDhn8Mhn8Ew3xg+Ndg+FcwLACGQgZDIcGwEBgKGwyFBcMiYChiMBQRDIuBoajBUFQwLAGGYgZDMcGwFBiKGwzFBcMyYChhMJQQDMuBoaTBUFIwrACGUgZDKcGwEhhKGwylBcMqYChjMJQRDKuBoazBUFYwrAGGcgZDOcGwFhjKGwzlBcM6YKhgMFQQDOuBoaLBUFEwbACGSgZDJcGwERgqGwyVBcMmYKhiMFQRDJuBoarBUFUwbAGGagZDNcEQAIbqBkN1wbAVGGoYDDUEwzZgqGkw1BQM24GhlsFQSzDsAIbaBkNtwbATGOoYDHUEwy5gqGsw1BUMu4GhnsFQTzDsAYb6BkN9wbAXGBoYDA0Ewz5gaGgwNBQM+4GhkcHQSDAcAIbGBkNjwXAQGJoYDE0EwyFgaGowNBUMh4GhmcHQTDAcAYbmBkNzwXAUGFoYDC0EwzFgaGkwtBQMx4GhlcHQSjCcAIbWBkNrwXASGNoYDG0EwylgaGswtBUMp4GhncHQTjCcAYb2BkN7wXAWGDoYDB0Ewzlg6GgwdBQM54Ghk8HQSTBcAIbOBkNnwXARGLoYDF0EwyVg6GowdBUMl4Ghm8HQTTBcAYbuBkN3wXAVGHoYDD0EwzVg6Gkw9BQM14Ghl8HQSzDcAIbeBkNvwXATGPoYDH0Ewy1g6Gsw9BUMt4Ghn8HQTzDcAYb+BkN/wXAXGAYYDAMEwz1gGGgwDBQM94FhkMEwSDA8AIbBBsNgwfAQGIYYDEMEwyNgGGowDBUMj4FhmMEwTDA8AYbhBsNwwfAUGEYYDCMEwzNgGGkwjBQMz4FhlMEwSjC8AIbRBsNowfASGMYYDGMEwytgGGswjBUMr4FhnMEwTjC8AYbxBsN4wfAWGCYYDBMEwztgmGgwTBQM74FhksEwSTB8AIbJBsNkwfARGKYYDFMEwydgmGowTBUMn4HhP4PhP8HwRbT/3zDNYJgmGMIAw3SDYbpgCAsMMwyGGYIhHDDMNBhmCobwwDDLYJglGCIAw2yDYbZgiAgMcwyGOYIhEjDMNRjmCobIwDDPYJgnGKIAw3yDYb5giAoMCwyGBYIhGjAsNBgWCobowLDIYFgkGGIAw2KDYbFgiAkMSwyGJYIhFjAsNRiWCobYwLDMYFgmGOIAw3KDYblgiAsMKwyGFYIhHjCsNBhWCob4wLDKYFglGBIAw2qDYbVgSAgMawyGNYIhETCsNRjWCobEwLDOYFgnGJIAw3qDYb1gSAoMGwyGDYIhGTBsNBg2CobkwLDJYNgkGFIAw2aDYbNgSAkMWwyGLYIhFTAEDIaAYEgNDFsNhq2CIQ0wbDMYtgmGtMCw3WDYLhjSAcMOg2GHYEgPDDsNhp2CIQMw7DIYdgmGjMCw22DYLRgyAcMeg2GPYMgMDHsNhr2CIQsw7DMY9gmGrMCw32DYLxiyAcMBg+GAYMgODAcNhoOCIQcwHDIYDgmGnMBw2GA4LBhyAcMRg+GIYMgNDEcNhqOCIQ8wHDMYjgmGvMBw3GA4LhjyAcMJg+GEYPgSGE4aDCcFQ35gOGUwnBIMBYDhtMFwWjAUBIYzBsMZwfAVMJw1GM4Khq+B4ZzBcE4wfAMM5w2G84LhW2C4YDBcEAzfAcNFg+GiYPgeGC4ZDJcEww/AcNlguCwYfgSGKwbDFcHwEzBcNRiuCoafgeGawXBNMPwCDNcNhuuC4VdguGEw3BAMvwHDTYPhpmD4HRhuGQy3BMMfwHDbYLgtGP4EhjsGwx3B8Bcw3DUY7gqGv4HhnsFwTzD8Awz3DYb7guFfYHhgMDwQDIWA4aHB8FAwFAaGRwbDI8FQBBgeGwyPBUNRYHhiMDwRDMWA4anB8FQwFAeGZwbDM8FQAhieGwzPBUNJYHhhMLwQDKWA4aXB8FIwlAaGVwbDK8FQBhheGwyvBUNZYHhjMLwRDOWA4a3B8FYwlAeGdwbDO8FQARjeGwzvBUNFYPhgMHwQDJWA4aPB8FEwVAaGTwbDJ8FQBRg+GwyfBUNVYPhiY+gNwQY1VAOGMAZDGMFQHRjCGgxhBUMNYAhnMIQTDDWBIbzBEF4w1AKGCAZDBMFQGxgiGgwRBUMdYIhkMEQSDHWBIbLBEFkw1AOGKAZDFMFQHxiiGgxRBUMDYIhmMEQTDA2BIbrBEF0wNAKGGAZDDMHQGBhiGgwxBUMTYIhlMMQSDE2BIbbBEFswNAOGOAZDHMHQHBjiGgxxBUMLYIhnMMQTDC2BIb7BEF8wtAKGBAZDAsHQGhgSGgwJBUMbYEhkMCQSDG2BIbHBkFgwtAOGJAZDEsHQHhiSGgxJBUMHYEhmMCQTDB2BIbnBkFwwdAKGFAZDCsHQGRhSGgwpBUMXYEhlMKQSDF2BIbXBkFowdAOGNAZDGsHQHRjSGgxpBUMPYEhnMKQTDD2BIb3BkF4w9AKGDAZDBsHQGxgyGgwZBUMfYMhkMGQSDH2BIbPBkFkw9AOGLAZDFsHQHxiyGgxZBcMAYMhmMGQTDAOBIbvBkF0wDAKGHAZDDsEwGBhyGgw5BcMQYMhlMOQSDEOBIbfBkFswDAOGPAZDHsEwHBjyGgx5BcMIYMhnMOQTDCOB4UuD4UvBMAoY8hsM+QXDaGAoYDAUEAxjgKGgwVBQMIwFhq8Mhq8Ewzhg+Npg+FowjAeGbwyGbwTDBGD41mD4VjBMBIbvDIbvBMMkYPjeYPheMEwGhh8Mhh8EwxRg+NFg+FEwTAWGnwyGnwTDf8Dws8Hws2CYBgy/GAy/CIbpwPCrwfCrYJgBDL8ZDL8JhpnA8LvB8LtgmAUMfxgMfwiG2cDwp8Hwp2CYAwx/GQx/CYa5wPC3wfC3YJgHDP8YDP8IhvnA8K/B8K9gWAAMhQyGQoJhITAUNhgKC4ZFwFDEYCgiGBYDQ1GDoahgWAIMxQyGYoJhKTAUNxiKC4ZlwFDCYCghGJYDQ0mDoaRgWAEMpQyGUoJhJTCUNhhKC4ZVwFDGYCgjGFYDQ1mDoaxgWAMM5QyGcoJhLTCUNxjKC4Z1wFDBYKggGNYDQ0WDoaJg2AAMlQyGSoJhIzBUNhgqC4ZNwFDFYKgiGDYDQ1WDoapg2AIM1QyGaoIhAAzVDYbqgmErMNQwGGoIhm3AUNNgqCkYtgNDLYOhlmDYAQy1DYbagmEnMNQxGOoIhl3AUNdgqCsYdgNDPYOhnmDYAwz1DYb6gmEvMDQwGBoIhn3A0NBgaCgY9gNDI4OhkWA4AAyNDYbGguEgMDQxGJoIhkPA0NRgaCoYDgNDM4OhmWA4AgzNDYbmguEoMLQwGFoIhmPA0NJgaCkYjgNDK4OhlWA4AQytDYbWguEkMLQxGNoIhlPA0NZgaCsYTgNDO4OhnWA4AwztDYb2guEsMHQwGDoIhnPA0NFg6CgYzgNDJ4Ohk2C4AAydDYbOguEiMHQxGLoIhkvA0NVg6CoYLgNDN4Ohm2C4AgzdDYbuguEqMPQwGHoIhmvA0NNg6CkYrgNDL4Ohl2C4AQy9DYbeguEmMPQxGPoIhlvA0Ndg6CsYbgNDP4Ohn2C4Awz9DYb+guEuMAwwGAYIhnvAMNBgGCgY7gPDIINhkGB4AAyDDYbBguEhMAwxGIYIhkfAMNRgGCoYHgPDMINhmGB4AgzDDYbhguEpMIwwGEYIhmfAMNJgGCkYngPDKINhlGB4AQyjDYbRguElMIwxGMYIhlfAMNZgGCsYXgPDOINhnGB4AwzjDYbxguEtMEwwGCYIhnfAMNFgmCgY3gPDJINhkmD4AAyTDYbJguEjMEwxGKYIhk/AMNVgmCoYPgPDfyE2hIn4xRdBBzWEjfj/G6YZdpgm7BAOGKYbDNMFQ3hgmGEwzBAMEYBhpsEwUzBEBIZZBsMswRAJGGYbDLMFQ2RgmGMwzBEMUYBhrsEwVzBEBYZ5BsM8wRANGOYbDPMFQ3RgWGAwLBAMMYBhocGwUDDEBIZFBsMiwRALGBYbDIsFQ2xgWGIwLBEMcYBhqcGwVDDEBYZlBsMywRAPGJYbDMsFQ3xgWGEwrBAMCYBhpcGwUjAkBIZVBsMqwZAIGFYbDKsFQ2JgWGMwrBEMSYBhrcGwVjAkBYZ1BsM6wZAMGNYbDOsFQ3Jg2GAwbBAMKYBho8GwUTCkBIZNBsMmwZAKGDYbDJsFQ2pg2GIwbBEMaYAhYDAEBENaYNhqMGwVDOmAYZvBsE0wpAeG7QbDdsGQARh2GAw7BENGYNhpMOwUDJmAYZfBsEswZAaG3QbDbsGQBRj2GAx7BENWYNhrMOwVDNmAYZ/BsE8wZAeG/QbDfsGQAxgOGAwHBENOYDhoMBwUDLmA4ZDBcEgw5AaGwwbDYcGQBxiOGAxHBENeYDhqMBwVDPmA4ZjBcEwwfAkMxw2G44IhPzCcMBhOCIYCwHDSYDgpGAoCwymD4ZRg+AoYThsMpwXD18BwxmA4Ixi+AYazBsNZwfAtMJwzGM4Jhu+A4bzBcF4wfA8MFwyGC4LhB2C4aDBcFAw/AsMlg+GSYPgJGC4bDJcFw8/AcMVguCIYfgGGqwbDVcHwKzBcMxiuCYbfgOG6wXBdMPwODDcMhhuC4Q9guGkw3BQMfwLDLYPhlmD4CxhuGwy3BcPfwHDHYLgjGP4BhrsGw13B8C8w3DMY7gmGQsBw32C4LxgKA8MDg+GBYCgCDA8NhoeCoSgwPDIYHgmGYsDw2GB4LBiKA8MTg+GJYCgBDE8NhqeCoSQwPDMYngmGUsDw3GB4LhhKA8MLg+GFYCgDDC8NhpeCoSwwvDIYXgmGcsDw2mB4LRjKA8Mbg+GNYKgADG8NhreCoSIwvDMY3gmGSsDw3mB4LxgqA8MHg+GDYKgCDB8Nho+CoSowfDIYPgmGasDw2WD4LBiqA8MXm0JvCDaooQYwhDEYwgiGmsAQ1mAIKxhqAUM4gyGcYKgNDOENhvCCoQ4wRDAYIgiGusAQ0WCIKBjqAUMkgyGSYKgPDJENhsiCoQEwRDEYogiGhsAQ1WCIKhgaAUM0gyGaYGgMDNENhuiCoQkwxDAYYgiGpsAQ02CIKRiaAUMsgyGWYGgODLENhtiCoQUwxDEY4giGlsAQ12CIKxhaAUM8gyGeYGgNDPENhviCoQ0wJDAYEgiGtsCQ0GBIKBjaAUMigyGRYGgPDIkNhsSCoQMwJDEYkgiGjsCQ1GBIKhg6AUMygyGZYOgMDMkNhuSCoQswpDAYUgiGrsCQ0mBIKRi6AUMqgyGVYOgODKkNhtSCoQcwpDEY0giGnsCQ1mBIKxh6AUM6gyGdYOgNDOkNhvSCoQ8wZDAYMgiGvsCQ0WDIKBj6AUMmgyGTYOgPDJkNhsyCYQAwZDEYsgiGgcCQ1WDIKhgGAUM2gyGbYBgMDNkNhuyCYQgw5DAYcgiGocCQ02DIKRiGAUMugyGXYBgODLkNhtyCYQQw5DEY8giGkcCQ12DIKxhGAUM+gyGfYBgNDF8aDF8KhjHAkN9gyC8YxgJDAYOhgGAYBwwFDYaCgmE8MHxlMHwlGCYAw9cGw9eCYSIwfGMwfCMYJgHDtwbDt4JhMjB8ZzB8JximAMP3BsP3gmEqMPxgMPwgGP4Dhh8Nhh8FwzRg+Mlg+EkwTAeGnw2GnwXDDGD4xWD4RTDMBIZfDYZfBcMsYPjNYPhNMMwGht8Nht8Fwxxg+MNg+EMwzAWGPw2GPwXDPGD4y2D4SzDMB4a/DYa/BcMCYPjHYPhHMCwEhn8Nhn8FwyJgKGQwFBIMi4GhsMFQWDAsAYYiBkMRwbAUGIoaDEUFwzJgKGYwFBMMy4GhuMFQXDCsAIYSBkMJwbASGEoaDCUFwypgKGUwlBIMq4GhtMFQWjCsAYYyBkMZwbAWGMoaDGUFwzpgKGcwlBMM64GhvMFQXjBsAIYKBkMFwbARGCoaDBUFwyZgqGQwVBIMm4GhssFQWTBsAYYqBkMVwRAAhqoGQ1XBsBUYqhkM1QTDNmCobjBUFwzbgaGGwVBDMOwAhpoGQ03BsBMYahkMtQTDLmCobTDUFgy7gaGOwVBHMOwBhroGQ13BsBcY6hkM9QTDPmCobzDUFwz7gaGBwdBAMBwAhoYGQ0PBcBAYGhkMjQTDIWBobDA0FgyHgaGJwdBEMBwBhqYGQ1PBcBQYmhkMzQTDMWBobjA0FwzHgaGFwdBCMJwAhpYGQ0vBcBIYWhkMrQTDKWBobTC0FgyngaGNwdBGMJwBhrYGQ1vBcBYY2hkM7QTDOWBobzC0FwzngaGDwdBBMFwAho4GQ0fBcBEYOhkMnQTDJWDobDB0FgyXgaGLwdBFMFwBhq4GQ1fBcBUYuhkM3QTDNWDobjB0FwzXgaGHwdBDMNwAhp4GQ0/BcBMYehkMvQTDLWDobTD0Fgy3gaGPwdBHMNwBhr4GQ1/BcBcY+hkM/QTDPWDobzD0Fwz3gWGAwTBAMDwAhoEGw0DB8BAYBhkMgwTDI2AYbDAMFgyPgWGIwTBEMDwBhqEGw1DB8BQYhhkMwwTDM2AYbjAMFwzPgWGEwTBCMLwAhpEGw0jB8BIYRhkMowTDK2AYbTCMFgyvgWGMwTBGMLwBhrEGw1jB8BYYxhkM4wTDO2AYbzCMFwzvgWGCwTBBMHwAhokGw0TB8BEYJhkMkwTDJ2CYbDBMFgyfgWGKwTBFMHwR6f83TDUYpgqGMMDwn8Hwn2AICwzTDIZpgiEcMEw3GKYLhvDAMMNgmCEYIgDDTINhpmCICAyzDIZZgiESMMw2GGYLhsjAMMdgmCMYogDDXINhrmCICgzzDIZ5giEaMMw3GOYLhujAsMBgWCAYYgDDQoNhoWCICQyLDIZFgiEWMCw2GBYLhtjAsMRgWCIY4gDDUoNhqWCICwzLDIZlgiEeMCw3GJYLhvjAsMJgWCEYEgDDSoNhpWBICAyrDIZVgiERMKw2GFYLhsTAsMZgWCMYkgDDWoNhrWBICgzrDIZ1giEZMKw3GNYLhuTAsMFg2CAYUgDDRoNho2BICQybDIZNgiEVMGw2GDYLhtTAsMVg2CIY0gBDwGAICIa0wLDVYNgqGNIBwzaDYZtgSA8M2w2G7YIhAzDsMBh2CIaMwLDTYNgpGDIBwy6DYZdgyAwMuw2G3YIhCzDsMRj2CIaswLDXYNgrGLIBwz6DYZ9gyA4M+w2G/YIhBzAcMBgOCIacwHDQYDgoGHIBwyGD4ZBgyA0Mhw2Gw4IhDzAcMRiOCIa8wHDUYDgqGPIBwzGD4Zhg+BIYjhsMxwVDfmA4YTCcEAwFgOGkwXBSMBQEhlMGwynB8BUwnDYYTguGr4HhjMFwRjB8AwxnDYazguFbYDhnMJwTDN8Bw3mD4bxg+B4YLhgMFwTDD8Bw0WC4KBh+BIZLBsMlwfATMFw2GC4Lhp+B4YrBcEUw/AIMVw2Gq4LhV2C4ZjBcEwy/AcN1g+G6YPgdGG4YDDcEwx/AcNNguCkY/gSGWwbDLcHwFzDcNhhuC4a/geGOwXBHMPwDDHcNhruC4V9guGcw3BMMhYDhvsFwXzAUBoYHBsMDwVAEGB4aDA8FQ1FgeGQwPBIMxYDhscHwWDAUB4YnBsMTwVACGJ4aDE8FQ0lgeGYwPBMMpYDhucHwXDCUBoYXBsMLwVAGGF4aDC8FQ1lgeGUwvBIM5YDhtcHwWjCUB4Y3BsMbwVABGN4aDG8FQ0VgeGcwvBMMlYDhvcHwXjBUBoYPBsMHwVAFGD4aDB8FQ1Vg+GQwfBIM1YDhs8HwWTBUB4YvNofeEGxQQw1gCGMwhBEMNYEhrMEQVjDUAoZwBkM4wVAbGMIbDOEFQx1giGAwRBAMdYEhosEQUTDUA4ZIBkMkwVAfGCIbDJEFQwNgiGIwRBEMDYEhqsEQVTA0AoZoBkM0wdAYGKIbDNEFQxNgiGEwxBAMTYEhpsEQUzA0A4ZYBkMswdAcGGIbDLEFQwtgiGMwxBEMLYEhrsEQVzC0AoZ4BkM8wdAaGOIbDPEFQxtgSGAwJBAMbYEhocGQUDC0A4ZEBkMiwdAeGBIbDIkFQwdgSGIwJBEMHYEhqcGQVDB0AoZkBkMywdAZGJIbDMkFQxdgSGEwpBAMXYEhpcGQUjB0A4ZUBkMqwdAdGFIbDKkFQw9gSGMwpBEMPYEhrcGQVjD0AoZ0BkM6wdAbGNIbDOkFQx9gyGAwZBAMfYEho8GQUTD0A4ZMBkMmwdAfGDIbDJkFwwBgyGIwZBEMA4Ehq8GQVTAMAoZsBkM2wTAYGLIbDNkFwxBgyGEw5BAMQ4Ehp8GQUzAMA4ZcBkMuwTAcGHIbDLkFwwhgyGMw5BEMI4Ehr8GQVzCMAoZ8BkM+wTAaGL40GL4UDGOAIb/BkF8wjAWGAgZDAcEwDhgKGgwFBcN4YPjKYPhKMEwAhq8Nhq8Fw0Rg+MZg+EYwTAKGbw2GbwXDZGD4zmD4TjBMAYbvDYbvBcNUYPjBYPhBMPwHDD8aDD8KhmnA8JPB8JNgmA4MPxsMPwuGGcDwi8Hwi2CYCQy/Ggy/CoZZwPCbwfCbYJgNDL8bDL8LhjnA8IfB8IdgmAsMfxoMfwqGecDwl8Hwl2CYDwx/Gwx/C4YFwPCPwfCPYFgIDP8aDP8KhkXAUMhgKCQYFgNDYYOhsGBYAgxFDIYigmEpMBQ1GIoKhmXAUMxgKCYYlgNDcYOhuGBYAQwlDIYSgmElMJQ0GEoKhlXAUMpgKCUYVgNDaYOhtGBYAwxlDIYygmEtMJQ1GMoKhnXAUM5gKCcY1gNDeYOhvGDYAAwVDIYKgmEjMFQ0GCoKhk3AUMlgqCQYNgNDZYOhsmDYAgxVDIYqgiEADFUNhqqCYSswVDMYqgmGbcBQ3WCoLhi2A0MNg6GGYNgBDDUNhpqCYScw1DIYagmGXcBQ22CoLRh2A0Mdg6GOYNgDDHUNhrqCYS8w1DMY6gmGfcBQ32CoLxj2A0MDg6GBYDgADA0NhoaC4SAwNDIYGgmGQ8DQ2GBoLBgOA0MTg6GJYDgCDE0NhqaC4SgwNDMYmgmGY8DQ3GBoLhiOA0MLg6GFYDgBDC0NhpaC4SQwtDIYWgmGU8DQ2mBoLRhOA0Mbg6GNYDgDDG0NhraC4SwwtDMY2gmGc8DQ3mBoLxjOA0MHg6GDYLgADB0Nho6C4SIwdDIYOgmGS8DQ2WDoLBguA0MXg6GLYLgCDF0Nhq6C4SowdDMYugmGa8DQ3WDoLhiuA0MPg6GHYLgBDD0Nhp6C4SYw9DIYegmGW8DQ22DoLRhuA0Mfg6GPYLgDDH0Nhr6C4S4w9DMY+gmGe8DQ32DoLxjuA8MAg2GAYHgADAMNhoGC4SEwDDIYBgmGR8Aw2GAYLBgeA8MQg2GIYHgCDEMNhqGC4SkwDDMYhgmGZ8Aw3GAYLhieA8MIg2GEYHgBDCMNhpGC4SUwjDIYRgmGV8Aw2mAYLRheA8MYg2GMYHgDDGMNhrGC4S0wjDMYxgmGd8Aw3mAYLxjeA8MEg2GCYPgADBMNhomC4SMwTDIYJgmGT8Aw2WCYLBg+A8OUEBs+5Prii6AD31Ku/98w1bDDVOWWgOE/g+E/5ZaAYZrBME0wfJH7/zdMNximC4YwwDDDYJghGMICw0yDYaZgCAcMswyGWYIhPDDMNhhmC4YIwDDHYJgjGCICw1yDYa5giAQM8wyGeYIhMjDMNxjmC4YowLDAYFggGKICw0KDYaFgiAYMiwyGRYIhOjAsNhgWC4YYwLDEYFgiGGICw1KDYalgiAUMywyGZYIhNjAsNxiWC4Y4wLDCYFghGOICw0qDYaVgiAcMqwyGVYIhPjCsNhhWC4YEwLDGYFgjGBICw1qDYa1gSAQM6wyGdYIhMTCsNxjWC4YkwLDBYNggGJICw0aDYaNgSAYMmwyGTYIhOTBsNhg2C4YUwLDFYNgiGFICQ8BgCAiGVMCw1WDYKhhSA8M2g2GbYEgDDNsNhu2CIS0w7DAYdgiGdMCw02DYKRjSA8Mug2GXYMgADLsNht2CISMw7DEY9giGTMCw12DYKxgyA8M+g2GfYMgCDPsNhv2CISswHDAYDgiGbMBw0GA4KBiyA8Mhg+GQYMgBDIcNhsOCIScwHDEYjgiGXMBw1GA4KhhyA8Mxg+GYYMgDDMcNhuOCIS8wnDAYTgiGfMBw0mA4KRi+BIZTBsMpwZAfGE4bDKcFQwFgOGMwnBEMBYHhrMFwVjB8BQznDIZzguFrYDhvMJwXDN8AwwWD4YJg+BYYLhoMFwXDd8BwyWC4JBi+B4bLBsNlwfADMFwxGK4Ihh+B4arBcFUw/AQM1wyGa4LhZ2C4bjBcFwy/AMMNg+GGYPgVGG4aDDcFw2/AcMtguCUYfgeG2wbDbcHwBzDcMRjuCIY/geGuwXBXMPwFDPcMhnuC4W9guG8w3BcM/wDDA4PhgWD4FxgeGgwPBUMhYHhkMDwSDIWB4bHB8FgwFAGGJwbDE8FQFBieGgxPBUMxYHhmMDwTDMWB4bnB8FwwlACGFwbDC8FQEhheGgwvBUMpYHhlMLwSDKWB4bXB8FowlAGGNwbDG8FQFhjeGgxvBUM5YHhnMLwTDOWB4b3B8F4wVACGDwbDB8FQERg+GgwfBUMlYPhkMHwSDJWB4bPB8FkwVAGGL7aE3hBsUENVYAhjMIQRDNWAIazBEFYwVAeGcAZDOMFQAxjCGwzhBUNNYIhgMEQQDLWAIaLBEFEw1AaGSAZDJMFQBxgiGwyRBUNdYIhiMEQRDPWAIarBEFUw1AeGaAZDNMHQABiiGwzRBUNDYIhhMMQQDI2AIabBEFMwNAaGWAZDLMHQBBhiGwyxBUNTYIhjMMQRDM2AIa7BEFcwNAeGeAZDPMHQAhjiGwzxBUNLYEhgMCQQDK2AIaHBkFAwtAaGRAZDIsHQBhgSGwyJBUNbYEhiMCQRDO2AIanBkFQwtAeGZAZDMsHQARiSGwzJBUNHYEhhMKQQDJ2AIaXBkFIwdAaGVAZDKsHQBRhSGwypBUNXYEhjMKQRDN2AIa3BkFYwdAeGdAZDOsHQAxjSGwzpBUNPYMhgMGQQDL2AIaPBkFEw9AaGTAZDJsHQBxgyGwyZBUNfYMhiMGQRDP2AIavBkFUw9AeGbAZDNsEwABiyGwzZBcNAYMhhMOQQDIOAIafBkFMwDAaGXAZDLsEwBBhyGwy5BcNQYMhjMOQRDMOAIa/BkFcwDAeGfAZDPsEwAhi+NBi+FAwjgSG/wZBfMIwChgIGQwHBMBoYChoMBQXDGGD4ymD4SjCMBYavDYavBcM4YPjGYPhGMIwHhm8Nhm8FwwRg+M5g+E4wTASG7w2G7wXDJGD4wWD4QTBMBoYfDYYfBcMUYPjJYPhJMEwFhp8Nhp8Fw3/A8IvB8ItgmAYMvxoMvwqG6cDwm8Hwm2CYAQy/Gwy/C4aZwPCHwfCHYJgFDH8aDH8KhtnA8JfB8JdgmAMMfxsMfwuGucDwj8Hwj2CYBwz/Ggz/Cob5wFDIYCgkGBYAQ2GDobBgWAgMRQyGIoJhETAUNRiKCobFwFDMYCgmGJYAQ3GDobhgWAoMJQyGEoJhGTCUNBhKCoblwFDKYCglGFYAQ2mDobRgWAkMZQyGMoJhFTCUNRjKCobVwFDOYCgnGNYAQ3mDobxgWAsMFQyGCoJhHTBUNBgqCob1wFDJYKgkGDYAQ2WDobJg2AgMVQyGKoJhEzBUNRiqCobNwFDNYKgmGLYAQ3WDobpgCABDDYOhhmDYCgw1DYaagmEbMNQyGGoJhu3AUNtgqC0YdgBDHYOhjmDYCQx1DYa6gmEXMNQzGOoJht3AUN9gqC8Y9gBDA4OhgWDYCwwNDYaGgmEfMDQyGBoJhv3A0NhgaCwYDgBDE4OhiWA4CAxNDYamguEQMDQzGJoJhsPA0NxgaC4YjgBDC4OhhWA4CgwtDYaWguEYMLQyGFoJhuPA0NpgaC0YTgBDG4OhjWA4CQxtDYa2guEUMLQzGNoJhtPA0N5gaC8YzgBDB4Ohg2A4CwwdDYaOguEcMHQyGDoJhvPA0Nlg6CwYLgBDF4Ohi2C4CAxdDYauguESMHQzGLoJhsvA0N1g6C4YrgBDD4Ohh2C4Cgw9DYaeguEaMPQyGHoJhuvA0Ntg6C0YbgBDH4Ohj2C4CQx9DYa+guEWMPQzGPoJhtvA0N9g6C8Y7gDDAINhgGC4CwwDDYaBguEeMAwyGAYJhvvAMNhgGCwYHgDDEINhiGB4CAxDDYahguERMAwzGIYJhsfAMNxgGC4YngDDCINhhGB4CgwjDYaRguEZMIwyGEYJhufAMNpgGC0YXgDDGINhjGB4CQxjDYaxguEVMIwzGMYJhtfAMN5gGC8Y3gDDBINhgmB4CwwTDYaJguEdMEwyGCYJhvfAMNlgmCwYPgDDFINhimD4CAxTDYapguETMPxnMPwnGD4DwzSDYZpg+CLP/2+YbjBMFwxhgGGGwTBDMIQFhpkGw0zBEA4YZhkMswRDeGCYbTDMFgwRgGGOwTBHMEQEhrkGw1zBEAkY5hkM8wRDZGCYbzDMFwxRgGGBwbBAMEQFhoUGw0LBEA0YFhkMiwRDdGBYbDAsFgwxgGGJwbBEMMQEhqUGw1LBEAsYlhkMywRDbGBYbjAsFwxxgGGFwbBCMMQFhpUGw0rBEA8YVhkMqwRDfGBYbTCsFgwJgGGNwbBGMCQEhrUGw1rBkAgY1hkM6wRDYmBYbzCsFwxJgGGDwbBBMCQFho0Gw0bBkAwYNhkMmwRDcmDYbDBsFgwpgGGLwbBFMKQEhoDBEBAMqYBhq8GwVTCkBoZtBsM2wZAGGLYbDNsFQ1pg2GEw7BAM6YBhp8GwUzCkB4ZdBsMuwZABGHYbDLsFQ0Zg2GMw7BEMmYBhr8GwVzBkBoZ9BsM+wZAFGPYbDPsFQ1ZgOGAwHBAM2YDhoMFwUDBkB4ZDBsMhwZADGA4bDIcFQ05gOGIwHBEMuYDhqMFwVDDkBoZjBsMxwZAHGI4bDMcFQ15gOGEwnBAM+YDhpMFwUjB8CQynDIZTgiE/MJw2GE4LhgLAcMZgOCMYCgLDWYPhrGD4ChjOGQznBMPXwHDeYDgvGL4BhgsGwwXB8C0wXDQYLgqG74DhksFwSTB8DwyXDYbLguEHYLhiMFwRDD8Cw1WD4apg+AkYrhkM1wTDz8Bw3WC4Lhh+AYYbBsMNwfArMNw0GG4Kht+A4ZbBcEsw/A4Mtw2G24LhD2C4YzDcEQx/AsNdg+GuYPgLGO4ZDPcEw9/AcN9guC8Y/gGGBwbDA8HwLzA8NBgeCoZCwPDIYHgkGAoDw2OD4bFgKAIMTwyGJ4KhKDA8NRieCoZiwPDMYHgmGIoDw3OD4blgKAEMLwyGF4KhJDC8NBheCoZSwPDKYHglGEoDw2uD4bVgKAMMbwyGN4KhLDC8NRjeCoZywPDOYHgnGMoDw3uD4b1gqAAMHwyGD4KhIjB8NBg+CoZKwPDJYPgkGCoDw2eD4bNgqAIMXwRCbwg2qKEqMIQJhN4QbFBDNWAIGwi9IdighurAEC4QekOwQQ01gCF8IPSGYIMaagJDhEDoDcEGNdQChoiB0BuCDWqoDQyRAqE3BBvUUAcYIgdCbwg2qKEuMEQJhN4QbFBDPWCIGgi9IdighvrAEC0QekOwQQ0NgCF6IPSGYIMaGgJDjEDoDcEGNTQChpiB0BuCDWpoDAyxAqE3BBvU0AQYYgdCbwg2qKEpMMQJhN4QbFBDM2CIGwi9IdighubAEC8QekOwQQ0tgCF+IPSGYIMaWgJDgkDoDcEGNbQChoSB0BuCDWpoDQyJAqE3BBvU0AYYEgdCbwg2qKEtMCQJhN4QbFBDO2BIGgi9IdighvbAkCwQekOwQQ0dgCF5IPSGYIMaOgJDikDoDcEGNXQChpSB0BuCDWroDAypAqE3BBvU0AUYUgdCbwg2qKErMKQJhN4QbFBDN2BIGwi9Idighu7AkC4QekOwQQ09gCF9IPSGYIMaegJDhkDoDcEGNfQChoyB0BuCDWroDQyZAqE3BBvU0AcYMgdCbwg2qKEvMGQJhN4QbFBDP2DIGgi9Idighv7AkC0QekOwQQ0DgCF7IPSGYIMaBgJDjkDoDcEGNQwChpyB0BuCDWoYDAy5AqE3BBvUMAQYcgdCbwg2qGEoMOQJhN4QbFDDMGDIGwi9IdighuHAkC8QekOwQQ0jgOHLQOgNwQY1jASG/IHQG4INahgFDAUCoTcEG9QwGhgKBkJvCDaoYQwwfBUIvSHYoIaxwPB1IPSGYIMaxgHDN4HQG4INahgPDN8GQm8INqhhAjB8Fwi9IdighonA8H0g9IZggxomAcMPgdAbgg1qmAwMPwZCbwg2qGEKMPwUCL0h2KCGqcDwcyD0hmCDGv4Dhl8CoTcEG9QwDRh+DYTeEGxQw3Rg+C0QekOwQQ0zgOH3QOgNwQY1zASGPwKhNwQb1DALGP4MhN4QbFDDbGD4KxB6Q7BBDXOA4e9A6A3BBjXMBYZ/AqE3BBvUMA8Y/g2E3hBsUMN8YCgUCL0h2KCGBcBQOBB6Q7BBDQuBoUgg9IZggxoWAUPRQOgNwQY1LAaGYoHQG4INalgCDMUDoTcEG9SwFBhKBEJvCDaoYRkwlAyE3hBsUMNyYCgVCL0h2KCGFcBQOhB6Q7BBDSuBoUwg9IZggxpWAUPZQOgNwQY1rAaGcoHQG4INalgDDOUDoTcEG9SwFhgqBEJvCDaoYR0wVAyE3hBsUMN6YKgUCL0h2KCGDcBQORB6Q7BBDRuBoUog9IZggxo2AUPVQOgNwQY1bAaGaoHQG4INatgCDNUDoTcEG9QQAIYagdAbgg1q2AoMNQOhNwQb1LANGGoFQm8INqhhOzDUDoTeEGxQww5gqBMIvSHYoIadwFA3EHpDsEENu4ChXiD0hmCDGnYDQ/1A6A3BBjXsAYYGgdAbgg1q2AsMDQOhNwQb1LAPGBoFQm8INqhhPzA0DoTeEGxQwwFgaBIIvSHYoIaDwNA0EHpDsEENh4ChWSD0hmCDGg4DQ/NA6A3BBjUcAYYWgdAbgg1qOAoMLQOhNwQb1HAMGFoFQm8INqjhODC0DoTeEGxQwwlgaBMIvSHYoIaTwNA2EHpDsEENp4ChXSD0hmCDGk4DQ/tA6A3BBjWcAYYOgdAbgg1qOAsMHQOhNwQb1HAOGDoFQm8INqjhPDB0DoTeEGxQwwVg6BIIvSHYoIaLwNA1EHpDsEENl4ChWyD0hmCDGi4DQ/dA6A3BBjVcAYYegdAbgg1quAoMPQOhNwQb1HANGHoFQm8INqjhOjD0DoTeEGxQww1g6BMIvSHYoIabwNA3EHpDsEENt4ChXyD0hmCDGm4DQ/9A6A3BBjXcAYYBgdAbgg1quAsMAwOhNwQb1HAPGAYFQm8INqjhPjAMDoTeEGxQwwNgGBIIvSHYoIaHwDA0EHpDsEENj4BhWCD0hmCDGh4Dw/BA6A3BBjU8AYYRgdAbgg1qeAoMIwOhNwQb1PAMGEYFQm8INqjhOTCMDoTeEGxQwwtgGBMIvSHYoIaXwDA2EHpDsEENr4BhXCD0hmCDGl4Dw/hA6A3BBjW8AYYJgdAbgg1qeAsMEwOhNwQb1PAOGCYFQm8INqjhPTBMDoTeEGxQwwdgmBIIvSHYoIaPwDA1EHpDsEENn4Dhv0DoDcEGNXwGhmmB0BuCDWr4Iu//b5geCL0h2KCGMMAwIxB6Q7BBDWGBYWYg9IZggxrCAcOsQOgNwQY1hAeG2YHQG4INaogADHMCoTcEG9QQERjmBkJvCDaoIRIwzAuE3hBsUENkYJgfCL0h2KCGKMCwIBB6Q7BBDVGBYWEg9IZggxqiAcOiQOgNwQY1RAeGxYHQG4INaogBDEsCoTcEG9QQExiWBkJvCDaoIRYwLAuE3hBsUENsYFgeCL0h2KCGOMCwIhB6Q7BBDXGBYWUg9IZggxriAcOqQOgNwQY1xAeG1YHQG4INakgADGsCoTcEG9SQEBjWBkJvCDaoIREwrAuE3hBsUENiYFgfCL0h2KCGJMCwIRB6Q7BBDUmBYWMg9IZggxqSAcOmQOgNwQY1JAeGzYHQG4INakgBDFsCoTcEG9SQEhgCgdAbgg1qSAUMWwOhNwQb1JAaGLYFQm8INqghDTBsD4TeEGxQQ1pg2BEIvSHYoIZ0wLAzEHpDsEEN6YFhVyD0hmCDGjIAw+5A6A3BBjVkBIY9gdAbgg1qyAQMewOhNwQb1JAZGPYFQm8INqghCzDsD4TeEGxQQ1ZgOBAIvSHYoIZswHAwEHpDsEEN2YHhUCD0hmCDGnIAw+FA6A3BBjXkBIYjgdAbgg1qyAUMRwOhNwQb1JAbGI4FQm8INqghDzAcD4TeEGxQQ15gOBEIvSHYoIZ8wHAyEHpDsEENXwLDqUDoDcEGNeQHhtOB0BuCDWooAAxnAqE3BBvUUBAYzgZCbwg2qOErYDgXCL0h2KCGr4HhfCD0hmCDGr4BhguB0BuCDWr4FhguBkJvCDao4TtguBQIvSHYoIbvgeFyIPSGYIMafgCGK4HQG4INavgRGK4GQm8INqjhJ2C4Fgi9Idighp+B4Xog9IZggxp+AYYbgdAbgg1q+BUYbgZCbwg2qOE3YLgVCL0h2KCG34HhdiD0hmCDGv4AhjuB0BuCDWr4ExjuBkJvCDao4S9guBcIvSHYoIa/geF+IPSGYIMa/gGGB4HQG4INavgXGB4GQm8INqihEDA8CoTeEGxQQ2FgeBwIvSHYoIYiwPAkEHpDsEENRYHhaSD0hmCDGooBw7NA6A3BBjUUB4bngdAbgg1qKAEMLwKhNwQb1FASGF4GQm8INqihFDC8CoTeEGxQQ2lgeB0IvSHYoIYywPAmEHpDsEENZYHhbSD0hmCDGsoBw7tA6A3BBjWUB4b3gdAbgg1qqAAMHwKhNwQb1FARGD4GQm8INqihEjB8CoTeEGxQQ2Vg+BwIvSHYoIYqwPDF1tAbgg1qqAoMYQyGMIKhGjCENRjCCobqwBDOYAgnGGoAQ3iDIbxgqAkMEQyGCIKhFjBENBgiCobawBDJYIgkGOoAQ2SDIbJgqAsMUQyGKIKhHjBENRiiCob6wBDNYIgmGBoAQ3SDIbpgaAgMMQyGGIKhETDENBhiCobGwBDLYIglGJoAQ2yDIbZgaAoMcQyGOIKhGTDENRjiCobmwBDPYIgnGFoAQ3yDIb5gaAkMCQyGBIKhFTAkNBgSCobWwJDIYEgkGNoAQ2KDIbFgaAsMSQyGJIKhHTAkNRiSCob2wJDMYEgmGDoAQ3KDIblg6AgMKQyGFIKhEzCkNBhSCobOwJDKYEglGLoAQ2qDIbVg6AoMaQyGNIKhGzCkNRjSCobuwJDOYEgnGHoAQ3qDIb1g6AkMGQyGDIKhFzBkNBgyCobewJDJYMgkGPoAQ2aDIbNg6AsMWQyGLIKhHzBkNRiyCob+wJDNYMgmGAYAQ3aDIbtgGAgMOQyGHIJhEDDkNBhyCobBwJDLYMglGIYAQ26DIbdgGAoMeQyGPIJhGDDkNRjyCobhwJDPYMgnGEYAw5cGw5eCYSQw5DcY8guGUcBQwGAoIBhGA0NBg6GgYBgDDF8ZDF8JhrHA8LXB8LVgGAcM3xgM3wiG8cDwrcHwrWCYAAzfGQzfCYaJwPC9wfC9YJgEDD8YDD8IhsnA8KPB8KNgmAIMPxkMPwmGqcDws8Hws2D4Dxh+MRh+EQzTgOFXg+FXwTAdGH4zGH4TDDOA4XeD4XfBMBMY/jAY/hAMs4DhT4PhT8EwGxj+Mhj+EgxzgOFvg+FvwTAXGP4xGP4RDPOA4V+D4V/BMB8YChkMhQTDAmAobDAUFgwLgaGIwVBEMCwChqIGQ1HBsBgYihkMxQTDEmAobjAUFwxLgaGEwVBCMCwDhpIGQ0nBsBwYShkMpQTDCmAobTCUFgwrgaGMwVBGMKwChrIGQ1nBsBoYyhkM5QTDGmAobzCUFwxrgaGCwVBBMKwDhooGQ0XBsB4YKhkMlQTDBmCobDBUFgwbgaGKwVBFMGwChqoGQ1XBsBkYqhkM1QTDFmCobjBUFwwBYKhhMNQQDFuBoabBUFMwbAOGWgZDLcGwHRhqGwy1BcMOYKhjMNQRDDuBoa7BUFcw7AKGegZDPcGwGxjqGwz1BcMeYGhgMDQQDHuBoaHB0FAw7AOGRgZDI8GwHxgaGwyNBcMBYGhiMDQRDAeBoanB0FQwHAKGZgZDM8FwGBiaGwzNBcMRYGhhMLQQDEeBoaXB0FIwHAOGVgZDK8FwHBhaGwytBcMJYGhjMLQRDCeBoa3B0FYwnAKGdgZDO8FwGhjaGwztBcMZYOhgMHQQDGeBoaPB0FEwnAOGTgZDJ8FwHhg6GwydBcMFYOhiMHQRDBeBoavB0FUwXAKGbgZDN8FwGRi6GwzdBcMVYOhhMPQQDFeBoafB0FMwXAOGXgZDL8FwHRh6Gwy9BcMNYOhjMPQRDDeBoa/B0Fcw3AKGfgZDP8FwGxj6Gwz9BcMdYBhgMAwQDHeBYaDBMFAw3AOGQQbDIMFwHxgGGwyDBcMDYBhiMAwRDA+BYajBMFQwPAKGYQbDMMHwGBiGGwzDBcMTYBhhMIwQDE+BYaTBMFIwPAOGUQbDKMHwHBhGGwyjBcMLYBhjMIwRDC+BYazBMFYwvAKGcQbDOMHwGhjGGwzjBcMbYJhgMEwQDG+BYaLBMFEwvAOGSQbDJMHwHhgmGwyTBcMHYJhiMEwRDB+BYarBMFUwfAKG/wyG/wTDZ2CYZjBMEwxf5Pv/DdMNhumCIQwwzDAYZgiGsMAw02CYKRjCAcMsg2GWYAgPDLMNhtmCIQIwzDEY5giGiMAw12CYKxgiAcM8g2GeYIgMDPMNhvmCIQowLDAYFgiGqMCw0GBYKBiiAcMig2GRYIgODIsNhsWCIQYwLDEYlgiGmMCw1GBYKhhiAcMyg2GZYIgNDMsNhuWCIQ4wrDAYVgiGuMCw0mBYKRjiAcMqg2GVYIgPDKsNhtWCIQEwrDEY1giGhMCw1mBYKxgSAcM6g2GdYEgMDOsNhvWCIQkwbDAYNgiGpMCw0WDYKBiSAcMmg2GTYEgODJsNhs2CIQUwbDEYtgiGlMAQMBgCgiEVMGw1GLYKhtTAsM1g2CYY0gDDdoNhu2BICww7DIYdgiEdMOw0GHYKhvTAsMtg2CUYMgDDboNht2DICAx7DIY9giETMOw1GPYKhszAsM9g2CcYsgDDfoNhv2DICgwHDIYDgiEbMBw0GA4KhuzAcMhgOCQYcgDDYYPhsGDICQxHDIYjgiEXMBw1GI4KhtzAcMxgOCYY8gDDcYPhuGDICwwnDIYTgiEfMJw0GE4Khi+B4ZTBcEow5AeG0wbDacFQABjOGAxnBENBYDhrMJwVDF8BwzmD4Zxg+BoYzhsM5wXDN8BwwWC4IBi+BYaLBsNFwfAdMFwyGC4Jhu+B4bLBcFkw/AAMVwyGK4LhR2C4ajBcFQw/AcM1g+GaYPgZGK4bDNcFwy/AcMNguCEYfgWGmwbDTcHwGzDcMhhuCYbfgeG2wXBbMPwBDHcMhjuC4U9guGsw3BUMfwHDPYPhnmD4GxjuGwz3BcM/wPDAYHggGP4FhocGw0PBUAgYHhkMjwRDYWB4bDA8FgxFgOGJwfBEMBQFhqcGw1PBUAwYnhkMzwRDcWB4bjA8FwwlgOGFwfBCMJQEhpcGw0vBUAoYXhkMrwRDaWB4bTC8FgxlgOGNwfBGMJQFhrcGw1vBUA4Y3hkM7wRDeWB4bzC8FwwVgOGDwfBBMFQEho8Gw0fBUAkYPhkMnwRDZWD4bDB8FgxVgOGLbaE3BBvUUBUYwhgMYQRDNWAIazCEFQzVgSGcwRBOMNQAhvAGQ3jBUBMYIhgMEQRDLWCIaDBEFAy1gSGSwRBJMNQBhsgGQ2TBUBcYohgMUQRDPWCIajBEFQz1gSGawRBNMDQAhugGQ3TB0BAYYhgMMQRDI2CIaTDEFAyNgSGWwRBLMDQBhtgGQ2zB0BQY4hgMcQRDM2CIazDEFQzNgSGewRBPMLQAhvgGQ3zB0BIYEhgMCQRDK2BIaDAkFAytgSGRwZBIMLQBhsQGQ2LB0BYYkhgMSQRDO2BIajAkFQztgSGZwZBMMHQAhuQGQ3LB0BEYUhgMKQRDJ2BIaTCkFAydgSGVwZBKMHQBhtQGQ2rB0BUY0hgMaQRDN2BIazCkFQzdgSGdwZBOMPQAhvQGQ3rB0BMYMhgMGQRDL2DIaDBkFAy9gSGTwZBJMPQBhswGQ2bB0BcYshgMWQRDP2DIajBkFQz9gSGbwZBNMAwAhuwGQ3bBMBAYchgMOQTDIGDIaTDkFAyDgSGXwZBLMAwBhtwGQ27BMBQY8hgMeQTDMGDIazDkFQzDgSGfwZBPMIwAhi8Nhi8Fw0hgyG8w5BcMo4ChgMFQQDCMBoaCBkNBwTAGGL4yGL4SDGOB4WuD4WvBMA4YvjEYvhEM44HhW4PhW8EwARi+Mxi+EwwTgeF7g+F7wTAJGH4wGH4QDJOB4UeD4UfBMAUYfjIYfhIMU4HhZ4PhZ8HwHzD8YjD8IhimAcOvBsOvgmE6MPxmMPwmGGYAw+8Gw++CYSYw/GEw/CEYZgHDnwbDn4JhNjD8ZTD8JRjmAMPfBsPfgmEuMPxjMPwjGOYBw78Gw7+CYT4wFDIYCgmGBcBQ2GAoLBgWAkMRg6GIYFgEDEUNhqKCYTEwFDMYigmGJcBQ3GAoLhiWAkMJg6GEYFgGDCUNhpKCYTkwlDIYSgmGFcBQ2mAoLRhWAkMZg6GMYFgFDGUNhrKCYTUwlDMYygmGNcBQ3mAoLxjWAkMFg6GCYFgHDBUNhoqCYT0wVDIYKgmGDcBQ2WCoLBg2AkMVg6GKYNgEDFUNhqqCYTMwVDMYqgmGLcBQ3WCoLhgCwFDDYKghGLYCQ02DoaZg2AYMtQyGWoJhOzDUNhhqC4YdwFDHYKgjGHYCQ12Doa5g2AUM9QyGeoJhNzDUNxjqC4Y9wNDAYGggGPYCQ0ODoaFg2AcMjQyGRoJhPzA0NhgaC4YDwNDEYGgiGA4CQ1ODoalgOAQMzQyGZoLhMDA0NxiaC4YjwNDCYGghGI4CQ0uDoaVgOAYMrQyGVoLhODC0NhhaC4YTwNDGYGgjGE4CQ1uDoa1gOAUM7QyGdoLhNDC0NxjaC4YzwNDBYOggGM4CQ0eDoaNgOAcMnQyGToLhPDB0Nhg6C4YLwNDFYOgiGC4CQ1eDoatguAQM3QyGboLhMjB0Nxi6C4YrwNDDYOghGK4CQ0+DoadguAYMvQyGXoLhOjD0Nhh6C4YbwNDHYOgjGG4CQ1+Doa9guAUM/QyGfoLhNjD0Nxj6C4Y7wDDAYBggGO4Cw0CDYaBguAcMgwyGQYLhPjAMNhgGC4YHwDDEYBgiGB4Cw1CDYahgeAQMwwyGYYLhMTAMNxiGC4YnwDDCYBghGJ4Cw0iDYaRgeAYMowyGUYLhOTCMNhhGC4YXwDDGYBgjGF4Cw1iDYaxgeAUM4wyGcYLhNTCMNxjGC4Y3wDDBYJggGN4Cw8QQG97l/+KLoIMa3uf//w2TDDtMEnb4AAyTDYbJguEjMEwxGKYIhk/AMNVgmCoYPgPDfwbDf4LhiwL/v2GawTBNMIQBhukGw3TBEBYYZhgMMwRDOGCYaTDMFAzhgWGWwTBLMEQAhtkGw2zBEBEY5hgMcwRDJGCYazDMFQyRgWGewTBPMEQBhvkGw3zBEBUYFhgMCwRDNGBYaDAsFAzRgWGRwbBIMMQAhsUGw2LBEBMYlhgMSwRDLGBYajAsFQyxgWGZwbBMMMQBhuUGw3LBEBcYVhgMKwRDPGBYaTCsFAzxgWGVwbBKMCQAhtUGw2rBkBAY1hgMawRDImBYazCsFQyJgWGdwbBOMCQBhvUGw3rBkBQYNhgMGwRDMmDYaDBsFAzJgWGTwbBJMKQAhs0Gw2bBkBIYthgMWwRDKmAIGAwBwZAaGLYaDFsFQxpg2GYwbBMMaYFhu8GwXTCkA4YdBsMOwZAeGHYaDDsFQwZg2GUw7BIMGYFht8GwWzBkAoY9BsMewZAZGPYaDHsFQxZg2Gcw7BMMWYFhv8GwXzBkA4YDBsMBwZAdGA4aDAcFQw5gOGQwHBIMOYHhsMFwWDDkAoYjBsMRwZAbGI4aDEcFQx5gOGYwHBMMeYHhuMFwXDDkA4YTBsMJwfAlMJw0GE4KhvzAcMpgOCUYCgDDaYPhtGAoCAxnDIYzguErYDhrMJwVDF8DwzmD4Zxg+AYYzhsM5wXDt8BwwWC4IBi+A4aLBsNFwfA9MFwyGC4Jhh+A4bLBcFkw/AgMVwyGK4LhJ2C4ajBcFQw/A8M1g+GaYPgFGK4bDNcFw6/AcMNguCEYfgOGmwbDTcHwOzDcMhhuCYY/gOG2wXBbMPwJDHcMhjuC4S9guGsw3BUMfwPDPYPhnmD4BxjuGwz3BcO/wPDAYHggGAoBw0OD4aFgKAwMjwyGR4KhCDA8NhgeC4aiwPDEYHgiGIoBw1OD4algKA4MzwyGZ4KhBDA8NxieC4aSwPDCYHghGEoBw0uD4aVgKA0MrwyGV4KhDDC8NhheC4aywPDGYHgjGMoBw1uD4a1gKA8M7wyGd4KhAjC8NxjeC4aKwPDBYPggGCoBw0eD4aNgqAwMnwyGT4KhCjB8Nhg+C4aqwPDF9tAbgg1qqAYMYQyGMIKhOjCENRjCCoYawBDOYAgnGGoCQ3iDIbxgqAUMEQyGCIKhNjBENBgiCoY6wBDJYIgkGOoCQ2SDIbJgqAcMUQyGKIKhPjBENRiiCoYGwBDNYIgmGBoCQ3SDIbpgaAQMMQyGGIKhMTDENBhiCoYmwBDLYIglGJoCQ2yDIbZgaAYMcQyGOIKhOTDENRjiCoYWwBDPYIgnGFoCQ3yDIb5gaAUMCQyGBIKhNTAkNBgSCoY2wJDIYEgkGNoCQ2KDIbFgaAcMSQyGJIKhPTAkNRiSCoYOwJDMYEgmGDoCQ3KDIblg6AQMKQyGFIKhMzCkNBhSCoYuwJDKYEglGLoCQ2qDIbVg6AYMaQyGNIKhOzCkNRjSCoYewJDOYEgnGHoCQ3qDIb1g6AUMGQyGDIKhNzBkNBgyCoY+wJDJYMgkGPoCQ2aDIbNg6AcMWQyGLIKhPzBkNRiyCoYBwJDNYMgmGAYCQ3aDIbtgGAQMOQyGHIJhMDDkNBhyCoYhwJDLYMglGIYCQ26DIbdgGAYMeQyGPIJhODDkNRjyCoYRwJDPYMgnGEYCw5cGw5eCYRQw5DcY8guG0cBQwGAoIBjGAENBg6GgYBgLDF8ZDF8JhnHA8LXB8LVgGA8M3xgM3wiGCcDwrcHwrWCYCAzfGQzfCYZJwPC9wfC9YJgMDD8YDD8IhinA8KPB8KNgmAoMPxkMPwmG/4DhZ4PhZ8EwDRh+MRh+EQzTgeFXg+FXwTADGH4zGH4TDDOB4XeD4XfBMAsY/jAY/hAMs4HhT4PhT8EwBxj+Mhj+EgxzgeFvg+FvwTAPGP4xGP4RDPOB4V+D4V/BsAAYChkMhQTDQmAobDAUFgyLgKGIwVBEMCwGhqIGQ1HBsAQYihkMxQTDUmAobjAUFwzLgKGEwVBCMCwHhpIGQ0nBsAIYShkMpQTDSmAobTCUFgyrgKGMwVBGMKwGhrIGQ1nBsAYYyhkM5QTDWmAobzCUFwzrgKGCwVBBMKwHhooGQ0XBsAEYKhkMlQTDRmCobDBUFgybgKGKwVBFMGwGhqoGQ1XBsAUYqhkM1QRDABiqGwzVBcNWYKhhMNQQDNuAoabBUFMwbAeGWgZDLcGwAxhqGwy1BcNOYKhjMNQRDLuAoa7BUFcw7AaGegZDPcGwBxjqGwz1BcNeYGhgMDQQDPuAoaHB0FAw7AeGRgZDI8FwABgaGwyNBcNBYGhiMDQRDIeAoanB0FQwHAaGZgZDM8FwBBiaGwzNBcNRYGhhMLQQDMeAoaXB0FIwHAeGVgZDK8FwAhhaGwytBcNJYGhjMLQRDKeAoa3B0FYwnAaGdgZDO8FwBhjaGwztBcNZYOhgMHQQDOeAoaPB0FEwnAeGTgZDJ8FwARg6GwydBcNFYOhiMHQRDJeAoavB0FUwXAaGbgZDN8FwBRi6GwzdBcNVYOhhMPQQDNeAoafB0FMwXAeGXgZDL8FwAxh6Gwy9BcNNYOhjMPQRDLeAoa/B0Fcw3AaGfgZDP8FwBxj6Gwz9BcNdYBhgMAwQDPeAYaDBMFAw3AeGQQbDIMHwABgGGwyDBcNDYBhiMAwRDI+AYajBMFQwPAaGYQbDMMHwBBiGGwzDBcNTYBhhMIwQDM+AYaTBMFIwPAeGUQbDKMHwAhhGGwyjBcNLYBhjMIwRDK+AYazBMFYwvAaGcQbDOMHwBhjGGwzjBcNbYJhgMEwQDO+AYaLBMFEwvAeGSQbDJMHwARgmGwyTBcNHYJhiMEwRDJ+AYarBMFUwfAaG/wyG/wTDFwX/f8M0g2GaYAgDDNMNhumCISwwzDAYZgiGcMAw02CYKRjCA8Msg2GWYIgADLMNhtmCISIwzDEY5giGSMAw12CYKxgiA8M8g2GeYIgCDPMNhvmCISowLDAYFgiGaMCw0GBYKBiiA8Mig2GRYIgBDIsNhsWCISYwLDEYlgiGWMCw1GBYKhhiA8Myg2GZYIgDDMsNhuWCIS4wrDAYVgiGeMCw0mBYKRjiA8Mqg2GVYEgADKsNhtWCISEwrDEY1giGRMCw1mBYKxgSA8M6g2GdYEgCDOsNhvWCISkwbDAYNgiGZMCw0WDYKBiSA8Mmg2GTYEgBDJsNhs2CISUwbDEYtgiGVMAQMBgCgiE1MGw1GLYKhjTAsM1g2CYY0gLDdoNhu2BIBww7DIYdgiE9MOw0GHYKhgzAsMtg2CUYMgLDboNht2DIBAx7DIY9giEzMOw1GPYKhizAsM9g2CcYsgLDfoNhv2DIBgwHDIYDgiE7MBw0GA4KhhzAcMhgOCQYcgLDYYPhsGDIBQxHDIYjgiE3MBw1GI4KhjzAcMxgOCYY8gLDcYPhuGDIBwwnDIYTguFLYDhpMJwUDPmB4ZTBcEowFACG0wbDacFQEBjOGAxnBMNXwHDWYDgrGL4GhnMGwznB8A0wnDcYzguGb4HhgsFwQTB8BwwXDYaLguF7YLhkMFwSDD8Aw2WD4bJg+BEYrhgMVwTDT8Bw1WC4Khh+BoZrBsM1wfALMFw3GK4Lhl+B4YbBcEMw/AYMNw2Gm4Lhd2C4ZTDcEgx/AMNtg+G2YPgTGO4YDHcEw1/AcNdguCsY/gaGewbDPcHwDzDcNxjuC4Z/geGBwfBAMBQChocGw0PBUBgYHhkMjwRDEWB4bDA8FgxFgeGJwfBEMBQDhqcGw1PBUBwYnhkMzwRDCWB4bjA8FwwlgeGFwfBCMJQChpcGw0vBUBoYXhkMrwRDGWB4bTC8FgxlgeGNwfBGMJQDhrcGw1vBUB4Y3hkM7wRDBWB4bzC8FwwVgeGDwfBBMFQCho8Gw0fBUBkYPhkMnwRDFWD4bDB8FgxVgeGLHaE3BBvUUA0YwhgMYQRDdWAIazCEFQw1gCGcwRBOMNQEhvAGQ3jBUAsYIhgMEQRDbWCIaDBEFAx1gCGSwRBJMNQFhsgGQ2TBUA8YohgMUQRDfWCIajBEFQwNgCGawRBNMDQEhugGQ3TB0AgYYhgMMQRDY2CIaTDEFAxNgCGWwRBLMDQFhtgGQ2zB0AwY4hgMcQRDc2CIazDEFQwtgCGewRBPMLQEhvgGQ3zB0AoYEhgMCQRDa2BIaDAkFAxtgCGRwZBIMLQFhsQGQ2LB0A4YkhgMSQRDe2BIajAkFQwdgCGZwZBMMHQEhuQGQ3LB0AkYUhgMKQRDZ2BIaTCkFAxdgCGVwZBKMHQFhtQGQ2rB0A0Y0hgMaQRDd2BIazCkFQw9gCGdwZBOMPQEhvQGQ3rB0AsYMhgMGQRDb2DIaDBkFAx9gCGTwZBJMPQFhswGQ2bB0A8YshgMWQRDf2DIajBkFQwDgCGbwZBNMAwEhuwGQ3bBMAgYchgMOQTDYGDIaTDkFAxDgCGXwZBLMAwFhtwGQ27BMAwY8hgMeQTDcGDIazDkFQwjgCGfwZBPMIwEhi8Nhi8FwyhgyG8w5BcMo4GhgMFQQDCMAYaCBkNBwTAWGL4yGL4SDOOA4WuD4WvBMB4YvjEYvhEME4DhW4PhW8EwERi+Mxi+EwyTgOF7g+F7wTAZGH4wGH4QDFOA4UeD4UfBMBUYfjIYfhIM/wHDzwbDz4JhGjD8YjD8IhimA8OvBsOvgmEGMPxmMPwmGGYCw+8Gw++CYRYw/GEw/CEYZgPDnwbDn4JhDjD8ZTD8JRjmAsPfBsPfgmEeMPxjMPwjGOYDw78Gw7+CYQEwFDIYCgmGhcBQ2GAoLBgWAUMRg6GIYFgMDEUNhqKCYQkwFDMYigmGpcBQ3GAoLhiWAUMJg6GEYFgODCUNhpKCYQUwlDIYSgmGlcBQ2mAoLRhWAUMZg6GMYFgNDGUNhrKCYQ0wlDMYygmGtcBQ3mAoLxjWAUMFg6GCYFgPDBUNhoqCYQMwVDIYKgmGjcBQ2WCoLBg2AUMVg6GKYNgMDFUNhqqCYQswVDMYqgmGADBUNxiqC4atwFDDYKghGLYBQ02DoaZg2A4MtQyGWoJhBzDUNhhqC4adwFDHYKgjGHYBQ12Doa5g2A0M9QyGeoJhDzDUNxjqC4a9wNDAYGggGPYBQ0ODoaFg2A8MjQyGRoLhADA0NhgaC4aDwNDEYGgiGA4BQ1ODoalgOAwMzQyGZoLhCDA0NxiaC4ajwNDCYGghGI4BQ0uDoaVgOA4MrQyGVoLhBDC0NhhaC4aTwNDGYGgjGE4BQ1uDoa1gOA0M7QyGdoLhDDC0NxjaC4azwNDBYOggGM4BQ0eDoaNgOA8MnQyGToLhAjB0Nhg6C4aLwNDFYOgiGC4BQ1eDoatguAwM3QyGboLhCjB0Nxi6C4arwNDDYOghGK4BQ0+DoadguA4MvQyGXoLhBjD0Nhh6C4abwNDHYOgjGG4BQ1+Doa9guA0M/QyGfoLhDjD0Nxj6C4a7wDDAYBggGO4Bw0CDYaBguA8MgwyGQYLhATAMNhgGC4aHwDDEYBgiGB4Bw1CDYahgeAwMwwyGYYLhCTAMNxiGC4anwDDCYBghGJ4Bw0iDYaRgeA4MowyGUYLhBTCMNhhGC4aXwDDGYBgjGF4Bw1iDYaxgeA0M4wyGKZu54YvI/79hvMEwTtjhDdhhQogNYWJ+8UXQQQ1hY/7/homGHSYKO4QDhkkGwyTBEB4YJhsMkwVDBGCY4vguCYaIwDDVYJgqGCIBw38Gw3+CITIwTDMYpgmGKMAw3WCYLhiiAsMMg2GGYIgGDDMNhpmCITowzDIYZgmGGMAw22CYLRhiAsMcg2GOYIgFDHMNhrmCITYwzDMY5gmGOMAw32CYLxjiAsMCg2GBYIgHDAsNhoWCIT4wLDIYFgmGBMCw2GBYLBgSAsMSg2GJYEgEDEsNhqWCITEwLDMYlgmGJMCw3GBYLhiSAsMKg2GFYEgGDCsNhpWCITkwrDIYVgmGFMCw2mBYLRhSAsMag2GNYEgFDGsNhrWCITUwrDMY1gmGNMCw3mBYLxjSAsMGg2GDYEgHDBsNho2CIT0wbDIYNgmGDMCw2WDYLBgyAsMWg2GLYMgEDAGDISAYMgPDVoNhq2DIAgzbDIZtgiErMGw3GLYLhmzAsMNg2CEYsgPDToNhp2DIAQy7DIZdgiEnMOw2GHYLhlzAsMdg2CMYcgPDXoNhr2DIAwz7DIZ9giEvMOw3GPYLhnzAcMBgOCAYvgSGgwbDQcGQHxgOGQyHBEMBYDhsMBwWDAWB4YjBcEQwfAUMRw2Go4Lha2A4ZjAcEwzfAMNxg+G4YPgWGE4YDCcEw3fAcNJgOCkYvgeGUwbDKcHwAzCcNhhOC4YfgeGMwXBGMPwEDGcNhrOC4WdgOGcwnBMMvwDDeYPhvGD4FRguGAwXBMNvwHDRYLgoGH4HhksGwyXB8AcwXDYYLguGP4HhisFwRTD8BQxXDYarguFvYLhmMFwTDP8Aw3WD4bpg+BcYbhgMNwRDIWC4aTDcFAyFgeGWwXBLMBQBhtsGw23BUBQY7hgMdwRDMWC4azDcFQzFgeGewXBPMJQAhvsGw33BUBIYHhgMDwRDKWB4aDA8FAylgeGRwfBIMJQBhscGw2PBUBYYnhgMTwRDOWB4ajA8FQzlgeGZwfBMMFQAhucGw3PBUBEYXhgMLwRDJWB4aTC8FAyVgeGVwfBKMFQBhtcGw2vBUBUY3hgMbwRDNWB4azC8FQzVgeGdwfBOMNQAhvcGw3vBUBMYPhgMHwRDLWD4aDB8FAy1geGTwfBJMNQBhs8Gw2fBUBcYvtgZekOwQQ31gCGMwRBGMNQHhrAGQ1jB0AAYwhkM4QRDQ2AIbzCEFwyNgCGCwRBBMDQGhogGQ0TB0AQYIhkMkQRDU2CIbDBEFgzNgCGKwRBFMDQHhqgGQ1TB0AIYohkM0QRDS2CIbjBEFwytgCGGwRBDMLQGhpgGQ0zB0AYYYhkMsQRDW2CIbTDEFgztgCGOwRBHMLQHhrgGQ1zB0AEY4hkM8QRDR2CIbzDEFwydgCGBwZBAMHQGhoQGQ0LB0AUYEhkMiQRDV2BIbDAkFgzdgCGJwZBEMHQHhqQGQ1LB0AMYkhkMyQRDT2BIbjAkFwy9gCGFwZBCMPQGhpQGQ0rB0AcYUhkMqQRDX2BIbTCkFgz9gCGNwZBGMPQHhrQGQ1rBMAAY0hkM6QTDQGBIbzCkFwyDgCGDwZBBMAwGhowGQ0bBMAQYMhkMmQTDUGDIbDBkFgzDgCGLwZBFMAwHhqwGQ1bBMAIYshkM2QTDSGDIbjBkFwyjgCGHwZBDMIwGhpwGQ07BMAYYchkMuQTDWGDIbTDkFgzjgCGPwZBHMIwHhrwGQ17BMAEY8hkM+QTDRGD40mD4UjBMAob8BkN+wTAZGAoYDAUEwxRgKGgwFBQMU4HhK4PhK8HwHzB8bTB8LRimAcM3BsM3gmE6MHxrMHwrGGYAw3cGw3eCYSYwfG8wfC8YZgHDDwbDD4JhNjD8aDD8KBjmAMNPBsNPgmEuMPxsMPwsGOYBwy8Gwy+CYT4w/Gow/CoYFgDDbwbDb4JhITD8bjD8LhgWAcMfBsMfgmExMPxpMPwpGJYAw18Gw1+CYSkw/G0w/C0YlgHDPwbDP4JhOTD8azD8KxhWAEMhg6GQYFgJDIUNhsKCYRUwFDEYigiG1cBQ1GAoKhjWAEMxg6GYYFgLDMUNhuKCYR0wlDAYSgiG9cBQ0mAoKRg2AEMpg6GUYNgIDKUNhtKCYRMwlDEYygiGzcBQ1mAoKxi2AEM5g6GcYAgAQ3mDobxg2AoMFQyGCoJhGzBUNBgqCobtwFDJYKgkGHYAQ2WDobJg2AkMVQyGKoJhFzBUNRiqCobdwFDNYKgmGPYAQ3WDobpg2AsMNQyGGoJhHzDUNBhqCob9wFDLYKglGA4AQ22DobZgOAgMdQyGOoLhEDDUNRjqCobDwFDPYKgnGI4AQ32Dob5gOAoMDQyGBoLhGDA0NBgaCobjwNDIYGgkGE4AQ2ODobFgOAkMTQyGJoLhFDA0NRiaCobTwNDMYGgmGM4AQ3ODoblgOAsMLQyGFoLhHDC0NBhaCobzwNDKYGglGC4AQ2uDobVguAgMbQyGNoLhEjC0NRjaCobLwNDOYGgnGK4AQ3uDob1guAoMHQyGDoLhGjB0NBg6CobrwNDJYOgkGG4AQ2eDobNguAkMXQyGLoLhFjB0NRi6CobbwNDNYOgmGO4AQ3eDobtguAsMPQyGHoLhHjD0NBh6Cob7wNDLYOglGB4AQ2+DobdgeAgMfQyGPoLhETD0NRj6CobHwNDPYOgnGJ4AQ3+Dob9geAoMAwyGAYLhGTAMNBgGCobnwDDIYBgkGF4Aw2CDYbBgeAkMQwyGIYLhFTAMNRiGCobXwDDMYBgmGN4Aw3CDYbhgeAsMIwyGEYLhHTCMNBhGCob3wDDKYBglGD4Aw2iDYbRg+AgMYwyGMYLhEzCMNRjGCobPwDDOYBgnGL6I9f8bxhsM4wVDGGCYYDBMEAxhgWGiwTBRMIQDhkkGwyTBEB4YJhsMkwVDBGCYYjBMEQwRgWGqwTBVMEQChv8Mhv8EQ2RgmGYwTBMMUYBhusEwXTBEBYYZBsMMwRANGGYaDDMFQ3RgmGUwzBIMMYBhtsEwWzDEBIY5BsMcwRALGOYaDHMFQ2xgmGcwzBMMcYBhvsEwXzDEBYYFBsMCwRAPGBYaDAsFQ3xgWGQwLBIMCYBhscGwWDAkBIYlBsMSwZAIGJYaDEsFQ2JgWGYwLBMMSYBhucGwXDAkBYYVBsMKwZAMGFYaDCsFQ3JgWGUwrBIMKYBhtcGwWjCkBIY1BsMawZAKGNYaDGsFQ2pgWGcwrBMMaYBhvcGwXjCkBYYNBsMGwZAOGDYaDBsFQ3pg2GQwbBIMGYBhs8GwWTBkBIYtBsMWwZAJGAIGQ0AwZAaGrQbDVsGQBRi2GQzbBENWYNhuMGwXDNmAYYfBsEMwZAeGnQbDTsGQAxh2GQy7BENOYNhtMOwWDLmAYY/BsEcw5AaGvQbDXsGQBxj2GQz7BENeYNhvMOwXDPmA4YDBcEAwfAkMBw2Gg4IhPzAcMhgOCYYCwHDYYDgsGAoCwxGD4Yhg+AoYjhoMRwXD18BwzGA4Jhi+AYbjBsNxwfAtMJwwGE4Ihu+A4aTBcFIwfA8MpwyGU4LhB2A4bTCcFgw/AsMZg+GMYPgJGM4aDGcFw8/AcM5gOCcYfgGG8wbDecHwKzBcMBguCIbfgOGiwXBRMPwODJcMhkuC4Q9guGwwXBYMfwLDFYPhimD4CxiuGgxXBcPfwHDNYLgmGP4BhusGw3XB8C8w3DAYbgiGQsBw02C4KRgKA8Mtg+GWYCgCDLcNhtuCoSgw3DEY7giGYsBw12C4KxiKA8M9g+GeYCgBDPcNhvuCoSQwPDAYHgiGUsDw0GB4KBhKA8Mjg+GRYCgDDI8NhseCoSwwPDEYngiGcsDw1GB4KhjKA8Mzg+GZYKgADM8NhueCoSIwvDAYXgiGSsDw0mB4KRgqA8Mrg+GVYKgCDK8NhteCoSowvDEY3giGasDw1mB4KxiqA8M7g+GdYKgBDO8NhveCoSYwfDAYPgiGWsDw0WD4KBhqA8Mng+GTYKgDDJ8Nhs+CoS4wfLEr9IZggxrqAUMYgyGMYKgPDGENhrCCoQEwhDMYwgmGhsAQ3mAILxgaAUMEgyGCYGgMDBENhoiCoQkwRDIYIgmGpsAQ2WCILBiaAUMUgyGKYGgODFENhqiCoQUwRDMYogmGlsAQ3WCILhhaAUMMgyGGYGgNDDENhpiCoQ0wxDIYYgmGtsAQ22CILRjaAUMcgyGOYGgPDHENhriCoQMwxDMY4gmGjsAQ32CILxg6AUMCgyGBYOgMDAkNhoSCoQswJDIYEgmGrsCQ2GBILBi6AUMSgyGJYOgODEkNhqSCoQcwJDMYkgmGnsCQ3GBILhh6AUMKgyGFYOgNDCkNhpSCoQ8wpDIYUgmGvsCQ2mBILRj6AUMagyGNYOgPDGkNhrSCYQAwpDMY0gmGgcCQ3mBILxgGAUMGgyGDYBgMDBkNhoyCYQgwZDIYMgmGocCQ2WDILBiGAUMWgyGLYBgODFkNhqyCYQQwZDMYsgmGkcCQ3WDILhhGAUMOgyGHYBgNDDkNhpyCYQww5DIYcgmGscDwP97+AkrLOvD7dVVASkSkRESku7u7u7u7u7u7u7u7QUREQERESkQERLq7+1yz9z6xz1nv/f6HtQ6udS1dfh5wvs/M/cyoM/cv/QfYkP49NkwPxYYMH2BDhvfYMCMUGzJ+gA0Z32PDzFBsyPQBNmR6jw2zQrEh8wfYkPk9NswOxYYsH2BDlvfYMCcUG7J+gA1Z32PD3FBsyPYBNmR7jw3zQrEh+wfYkP09NswPxYYcH2BDjvfYsCAUG3J+gA0532PDwlBsyPUBNuR6jw2LQrEh9wfYkPs9NiwOxYY8H2BDnvfYsCQUG/J+gA1532PD0lBsyPcBNuR7jw3LQrEh/wfYkP89NiwPxYYCH2BDgffYsCIUGwp+gA0F32PDylBsKPQBNhR6jw2rQrGh8AfYUPg9NqwOxYYiH2BDkffYsCYUG4p+gA1F32PD2lBsKPYBNhR7jw3rQrGh+AfYUPw9NqwPxYYSH2BDiffYsCEUG0p+gA0l32PDxlBsKPUBNpR6jw2bQrGh9AfYUPo9NmwOxYYyH2BDmffYsCUUG8p+gA1l32PD1lBsKPcBNpR7jw3bQrGh/AfYUP49NmwPxYYKH2BDhffYsCMUGyp+gA0V32PD96HYUOkDbKj0Hht2hmJD5Q+wofJ7bPghFBuqfIANVd5jw65QbKj6ATZUfY8NP4ZiQ7UPsKHae2zYHYoN1T/AhurvseGnUGyo8QE21HiPDXtCsaHmB9hQ8z02/ByKDbU+wIZa77Fhbyg21P4AG2q/x4Z9odhQ5wNsqPMeG/aHYkPdD7Ch7nts+CUUG+p9gA313mPDgVBsqP8BNtR/jw2/hmJDgw+wocF7bDgYig0NP8CGhu+x4bdQbGj0ATY0eo8Nh0KxofEH2ND4PTb8HooNTT7AhibvseFwKDY0/QAbmr7Hhj9CsaHZB9jQ7D02HAnFhuYfYEPz99hwNBQbWnyADS3eY8OxUGxo+QE2tHyPDcdDsaHVB9jQ6j02nAjFhtYfYEPr99jwZyg2tPkAG9q8x4aTodjQ9gNsaPseG/4KxYZ2H2BDu/fYcCoUG9p/gA3t32PD36HY0OEDbOjwHhtOh2JDxw+woeN7bPgnFBs6fYANnd5jw5lQbOj8ATZ0fo8NZ0OxocsH2NDlPTacC8WGrh9gQ9f32PBvKDZ0+wAbur3HhvOh2ND9A2zo/h4b/gvFhh4fYEOP99hwIRQben6ADT3fY8PFUGzo9QE29HqPDZdCsaH3B9jQ+z02XA7Fhj4fYEOf99hwJRQb+n6ADX3fY8PVUGzo9wE29HuPDddCsaH/B9jQ/z02XA/FhgEfYMOA99hwIxQbBn6ADQPfY8PNUGwY9AE2DHqPDbdCsWHwB9gw+D023A7FhiEfYMOQ99hwJxQbhn6ADUPfY8PdUGwY9gE2DHuPDfdCsWH4B9gw/D023A/FhhEfYMOI99jwIBQbRn6ADSPfY8PDUGwY9QE2jHqPDY9CsWH0B9gw+j02PA7FhjEfYMOY99jwJBQbxn6ADWPfY8PTUGwY9wE2jHuPDc9CsWH8B9gw/j02PA/FhgkfYMOE99jwIhQbJn6ADRPfY8PLUGyY9AE2THqPDa9CsWHyB9gw+T02vA7FhikfYMOU99jwJhQbpn6ADVPfY8PbUGyY9gE2THuPDe9CsWH6B9gw/4fQb/jos//5hhkfYMP093g/fPTF/3zDzP//bfgkRs/GvUI2bJ/5//vr/ndv1/nToXu7wv5//f4Bf0R99zr///HcLtkayo+n70Px+MUffbQgFI/f6PELPT7c//U3/qe/7qOv/+fvi5AH/g8e+388P2+T/c/fV7P+5x9DH4f2/Rrm//rzd//7h/6/3q+zfg7d+2nGvtC9n2buC9XH2//x6z6K9T/f8DLT//y5nx2K5/50KJ/7yP/Xn7/7378tg+5//N1HIc/9pvn/87c95PFrF4fuGly/9H/++A2T/++v0f+7tyfk8aH5WN7o8SvW/89//5DHr1z/P//9N0/+v78+/+9+/5DHzw7F49d57tcvDsXz47EhH/+hfo2K9D//Z3z01f/osUM2jq/9f3s9+999bL5L9P9+bPz8FZ69PR8p3OWUKdofPLqt69mrc14V2z4uVtw5qQfVahrvRWheo55n+3+O/D8/T4e8XoW8NoQ8R58SnghExNPwf1xTvsT4KAqf40umkE/XH0XjS6ITg5h4yfgo9v/5lHwUBy/1H8XlG+LxbciWj/7PtzUBCTHzo8QkISlexj9KTgpSkorUpCEt6UKeOzKQES89H2UmC1kJmZedHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBIu44+mMJVpTGcGvoz6aBazmcNc5jGfBSxkES7Rj5bgpfKjZSxnBStZxWrWsJZ1eEn6aAMb2cRmtuDLo4+2sZ0d+PLko534svqjXfzIbn5iDz7tfrQXnx4/2o+Xoo8O8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8jUvyo384w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7hHyuvOAhzziMU94yjOe84KXvOI1b3jLO0Iu/o/5hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHSGf+D/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd4R80f8xnxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vi8x0JSEgiEpOEpCQjOSlISSpSk4a0pCM9GchIJjKThaxkIzs5yEkucpOHvOQjPwUoSCEKU4SiFKM4JShJKUpThrKUozwVqEglKlOFqlSjOjWoSS1qU4e61KM+DWhIIxrThKY0ozktaEkrWtOGtrSjPR3oSCc604WudKM7PehJL3rTh770oz8DGMggBjOEoQxjOCMYyShGM4axjGM8E5jIJCYzhalMYzozmMksZjOHucxjPgtYyCIWs4SlLGM5K1jJKlazhrWsYz0b2MgmNrOFrWxjOzv4np38wC5+ZDc/sYef2cs+9vMLB/iVg/zGIX7nMH9whKMc4zgn+JOT/MUp/uY0/3CGs5zjX87zHxe4yCUuc4WrXOM6N7jJLW5zh7vc4z4PeMgjHvOEpzzjOS94ySte84a3vCPkX/g/5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneE/Me+j/mEMIQlHJ8SnghEJBKR+YwofE5UviAaXxKdGMQkFrH5ijh8TVy+IR7fEp/vSEBCEpGYJCQlGclJQUpSkZo0pCUd6clARjKRmSxkJRvZyUFOcpGbPOQlH/kpQEEKUZgiFKUYxSlBSUpRmjKUpRzlqUBFKlGZKlSlGtWpQU1qUZs61KUe9WlAQxrRmCY0pRnNaUFLWtGaNrSlHe3pQEc60ZkudKUb3elBT3rRmz70pR/9GcBABjGYIQxlGMMZwUhGMZoxjGUc45nARCYxmSlMZRrTmcFMZjGbOcxlHvNZwEIWsZglLGUZy1nBSlaxmjWsZR3r2cBGNrGZLWxlG9vZwffs5Ad28SO7+Yk9/Mxe9rGfXzjArxzkNw7xO4f5gyMc5RjHOcGfnOQvTvE3p/mHM5zlHP9ynv+4wEUucZkrXOUa17nBTW5xmzvc5R73ecBDHvGYJzzlGc95wUte8Zo3vOUdIf+h/2M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8j/5PuYTwhDWMLxKeGJQEQiEZnPiMLnROULovEl0YlBTGIRm6+Iw9fE5Rvi8S3x+Y4EJCQRiUlCUpKRnBSkJBWpSUNa0pGeDGQkE5nJQlaykZ0c5CQXuclDXvKRnwIUpBCFKUJRilGcEpSkFKUpQ1nKUZ4KVKQSlalCVapRnRrUpBa1qUNd6lGfBjSkEY1pQlOa0ZwWtKQVrWlDW9rRng50pBOd6UJXutGdHvSkF73pQ1/60Z8BDGQQgxnCUIYxnBGMZBSjGcNYxjGeCUxkEpOZwlSmMZ0ZzGQWs5nDXOYxnwUsZBGLWcJSlrGcFaxkFatZw1rWsZ4NbGQTm9nCVraxnR18z05+YBc/spuf2MPP7GUf+/mFA/zKQX7jEL9zmD84wlGOcZwT/MlJ/uIUf3OafzjDWc7xL+f5jwtc5BKXucJVrnGdG9zkFre5w13ucZ8HPOQRj3nCU57xnBe85BWvecNb3hHyP/g/5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneEfHPPx3xCGMISjk8JTwQiEonIfEYUPicqXxCNL4lODGISi9h8RRy+Ji7fEI9vic93JCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOkG/s+5hPCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfFDvreSBCQkEYlJQlKSkZwUpCQVqUlDWtKRngxkJBOZyUJWspGdHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBKTmcJUpjGdGcxkFrOZw1zmMZ8FLGQRi1nCUpaxnBWsZBWrWcNa1rGeDWxkE5vZwla2sZ0dfM9OfmAXP7Kbn9jDz+xlH/v5hQP8ykF+4xC/c5g/OMJRjnGcE/zJSf7iFH9zmn84w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7nGfBzzkEY95wlOe8ZwXvOQVr3nDW94R8k29H/MJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qr6h/2M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8QP+XlFEpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3lHyA/zfMwnhCEs4fiU8EQgIpGIzGdE4XOi8gXR+JLoxCAmsYjNV8Tha+LyDfH4lvh8RwISkojEJCEpyUhOClKSitSkIS3pSE8GMpKJzGQhK9nITg5ykovc5CEv+chPAQpSiMIUoSjFKE4JSlKK0pShLOUoTwUqUonKVKEq1ahODWpSi9rUoS71qE8DGtKIxjShKc1oTgta0orWtKEt7WhPBzrSic50oSvd6E4PetKL3vShL/3ozwAGMojBDGEowxjOCEYyitGMYSzjGM8EJjKJyUxhKtOYzgxmMovZzGEu85jPAhayiMUsYSnLWM4KVrKK1axhLetYzwY2sonNbGEr29jODr5nJz+wix/ZzU/s4Wf2so/9/MIBfuUgv3GI3znMHxzhKMc4zgn+5CR/cYq/Oc0/nOEs5/iX8/zHBS5yictc4SrXuM4NbnKL29zhLve4zwMe8ojHPOEpz3jOC17yite84S3vCPlBvo/5hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHSE/xPsxnxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vih9xzhQQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWQs68DzkzPuTM9ZAzy0PO/A45MzvkzOmQM5tDzjwOOTM45MzdkDNrQ858DTkzNeTM0ZAzO0POvAw5MzLkzMWQMwtDzvwLOTMv5My5kDPbQs48CzkzLOTMrZAzq0LOfAo5MynkzKGQM3tCzrwJOTMm5MyVkDNLQs78CDkzI+TMiZAzG0LOPAg5MyDknvsh96wPued7yD3TQ+45HnLP7pB7XofcMzrknssh9ywOuedvyD1zQ+45G3LP1pB7nobcMzTknpsh96wMuedjyD0TQ+45GHLPvpB73oXcMy7knmsh9ywLuedXyD2zQu45FXLPppB7HoX8AP/HfEIYwhKOTwlPBCISich8RhQ+JypfEI0viU4MYhKL2HxFHL4mLt8Qj2+JH3KvHxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8jNOz7mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd4TcuOdjPiEMYQnHp4QnAhGJRGQ+IwqfE5UviMaXRCcGMYlFbL4iDl8Tl2+Ix7fE5zsSkJBEJCYJSUlGclKQklSkJg1pSUd6MpCRTGQmC1nJRnZykJNc5CYPeclHfgpQkEIUpghFKUZxSlCSUpSmDGUpR3kqUJFKVKYKValGdWpQk1rUpg51qUd9GtCQRjSmCU1pRnNa0JJWtKYNbWlHezrQkU50pgtd6UZ3etCTXvSmD33pR38GMJBBDGYIQxnGcEYwklGMZgxjGcd4JjCRSUxmClOZxnRmMJNZzGYOc5nHfBawkEUsZglLWcZyVrCSVaxmDWtZx3o2sJFNbGYLW9nGdnbwPTv5gV38yG5+Yg8/s5d97OcXDvArB/mNQ/zOYf7gCEc5xnFO8Ccn+YtT/M1p/uEMZznHv5znPy5wkUtc5gpXucZ1bnCTW9zmDne5x30e8JBHPOYJT3nGc17wkle85g1veUfITbs+5hPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlneE3LDv4xghN1l1/ROWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3hNys82M+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95R8iNej/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEv8kPuKk4CEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qm7S/TGfEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+LzHQlISCISk4SkJCM5KUhJKlKThrSkIz0ZyEgmMpOFrGQjOznISS5yk4e85CM/BShIIQpThKIUozglKEkpSlOGspSjPBWoSCUqU4WqVKM6NahJLWpTh7rUoz4NaEgjGtOEpjSjOS1oSSta04a2tKM9HehIJzrTha50ozs96EkvetOHvvSjPwMYyCAGM4ShDGM4IxjJKEYzhrGMYzwTmMgkJjOFqUxjOjOYySxmM4e5zGM+C1jIIhazhKUsYzkrWMkqVrOGtaxjPRvYyCY2s4WtbGM7O/ienfzALn5kNz+xh5/Zyz728wsH+JWD/MYhfucwf3CEoxzjOCf4k5P8xSn+5jT/cIaznONfzvMfF7jIJS5zhatc4zo3uMktbnOHu9zjPg94yCMe84SnPOM5L3jJK17zhre8I+QG/R/zCWEISzg+JTwRiEgkIvMZUficqHxBNL4kOjGISSxi8xVx+Jq4fEM8viV+yHkJJCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOkMM5PuYTwhCWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3hBzM8zGfEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+KHnP9GAhKSiMQkISnJSE4KUpKK1KQhLelITwYykonMZCEr2chODnKSi9zkIS/5yE8BClKIwhShKMUoTglKUorSlKEs5ShPBSpSicpUoSrVqE4NalKL2tShLvWoTwMa0ojGNKEpzWhOC1rSita0oS3taE8HOtKJznShK93oTg960ove9KEv/ejPAAYyiMEMYSjDGM4IRjKK0YxhLOMYzwQmMonJTGEq05jODGYyi9nMYS7zmM8CFrKIxSxhKctYzgpWsorVrGEt61jPBjayic1sYSvb2M4OvmcnP7CLH9nNT+zhZ/ayj/38wgF+5SC/cYjfOcwfHOEoxzjOCf7kJH9xir85zT+c4Szn+Jfz/McFLnKJy1zhKte4zg1ucovb3OEu97jPAx7yiMc84SnPeM4LXvKK17zhLe8IOZTrYz4hDGEJx6eEJwIRiURkPiMKnxOVL4jGl0QnBjGJRWy+Ig5fE5dviMe3xOc7EpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3lHyIF8H/MJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Qg7j/JhPCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfH5jgQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWtrGdHXzPTn5gFz+ym5/Yw8/sZR/7+YUD/MpBfuMQv3OYPzjCUY5xnBP8yUn+4hR/c5p/OMNZzvEv5/mPC1zkEpe5wlWucZ0b3OQWt7nDXe5xnwc85BGPecJTnvGcF7zkFa95w1veEXIQ78d8QhjCEo5PCU8EIhKJyHxGFD4nKl8QjS+JTgxiEovYfEUcviYu3xCPb4nPdyQgIYlITBKSkozkpCAlqUhNGtKSjvRkICOZyEwWspKN7OQgJ7nITR7yko/8FKAghShMEYpSjOKUoCSlKE0ZylKO8lSgIpWoTBWqUo3q1KAmtahNHepSj/o0oCGNaEwTmtKM5rSgJa1oTRva0o72dKAjnehMF7rSje70oCe96E0f+tKP/gxgIIMYzBCGMozhjGAkoxjNGMYyjvFMYCKTmMwUpjKN6cxgJrOYzRzmMo/5LGAhi1jMEpayjOWsYCWrWM0a1rKO9WxgI5vYzBa2so3t7OB7dvIDu/iR3fzEHn5mL/vYzy8c4FcO8huH+J3D/MERjnKM45zgT07yF6f4m9P8wxnOco5/Oc9/XOAil7jMFa5yjevc4Ca3uM0d7nKP+zzgIY94zBOe8oznvOAlr3jNG97yjpBDuD/mE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd3z0neufTwhDWMLxKeGJQEQiEZnPiMLnROULovEl0YlBTGIRm6+Iw9fE5Rvi8S3x+Y4EJCQRiUlCUpKRnBSkJBWpSUNa0pGeDGQkE5nJQlaykZ0c5CQXuclDXvKRnwIUpBCFKUJRilGcEpSkFKUpQ1nKUZ4KVKQSlalCVapRnRrUpBa1qUNd6lGfBjSkEY1pQlOa0ZwWtKQVrWlDW9rRng50pBOd6UJXutGdHvSkF73pQ1/60Z8BDGQQgxnCUIYxnBGMZBSjGcNYxjGeCUxkEpOZwlSmMZ0ZzGQWs5nDXOYxnwUsZBGLWcJSlrGcFaxkFatZw1rWsZ4NbGQTm9nCVraxnR18z05+YBc/spuf2MPP7GUf+/mFA/zKQX7jEL9zmD84wlGOcZwT/MlJ/uIUf3OafzjDWc7xL+f5jwtc5BKXucJVrnGdG9zkFre5w13ucZ8HPOQRj3nCU57xnBe85BWvecNb3vFRAtc/nxCGsITjU8ITgYhEIjKfEYXPicoXRONLohODmMQiNl8Rh6+JyzfE41vi8x0JSEgiEpOEpCQjOSlISSpSk4a0pCM9GchIJjKThaxkIzs5yEkucpOHvOQjPwUoSCEKU4SiFKM4JShJKUpThrKUozwVqEglKlOFqlSjOjWoSS1qU4e61KM+DWhIIxrThKY0ozktaEkrWtOGtrSjPR3oSCc604WudKM7PehJL3rTh770oz8DGMggBjOEoQxjOCMYyShGM4axjGM8E5jIJCYzhalMYzozmMksZjOHucxjPgtYyCIWs4SlLGM5K1jJKlazhrWsYz0b2MgmNrOFrWxjOzv4np38wC5+ZDc/sYef2cs+9vMLB/iVg/zGIX7nMH9whKMc4zgn+JOT/MUp/uY0/3CGs5zjX87zHxe4yCUuc4WrXOM6N7jJLW5zh7vc4z4PeMgjHvOEpzzjOS94ySte84a3vOOjhK5/PiEMYQnHp4QnAhGJRGQ+IwqfE5UviMaXRCcGMYlFbL4iDl8Tl2+Ix7fE5zsSkJBEJCYJSUlGclKQklSkJg1pSUd6MpCRTGQmC1nJRnZykJNc5CYPeclHfgpQkEIUpghFKUZxSlCSUpSmDGUpR3kqUJFKVKYKValGdWpQk1rUpg51qUd9GtCQRjSmCU1pRnNa0JJWtKYNbWlHezrQkU50pgtd6UZ3etCTXvSmD33pR38GMJBBDGYIQxnGcEYwklGMZgxjGcd4JjCRSUxmClOZxnRmMJNZzGYOc5nHfBawkEUsZglLWcZyVrCSVaxmDWtZx3o2sJFNbGYLW9nGdnbwPTv5gV38yG5+Yg8/s5d97OcXDvArB/mNQ/zOYf7gCEc5xnFO8Ccn+YtT/M1p/uEMZznHv5znPy5wkUtc5gpXucZ1bnCTW9zmDne5x30e8JBHPOYJT3nGc17wkle85g1vecdHiVz/fEIYwhKOTwlPBCISich8RhQ+JypfEI0viU4MYhKL2HxFHL4mLt8Qj2+Jz3ckICGJSEwSkpKM5KQgJalITRrSko70ZCAjmchMFrKSjezkICe5yE0e8pKP/BSgIIUoTBGKUozilKAkpShNGcpSjvJUoCKVqEwVqlKN6tSgJrWoTR3qUo/6NKAhjWhME5rSjOa0oCWtaE0b2tKO9nSgI53oTBe60o3u9KAnvehNH/rSj/4MYCCDGMwQhjKM4YxgJKMYzRjGMo7xTGAik5jMFKYyjenMYCazmM0c5jKP+SxgIYtYzBKWsozlrGAlq1jNGtayjvVsYCOb2MwWtrKN7ezge3byA7v4kd38xB5+Zi/72M8vHOBXDvIbh/idw/zBEY5yjOOc4E9O8hen+JvT/MMZznKOfznPf1zgIpe4zBWuco3r3OAmt7jNHe5yj/s84CGPeMwTnvKM57zgJa94zRve8o6PErv++YQwhCUcnxKeCEQkEpH5jCh8TlS+IBpfEp0YxCQWsfmKOHxNXL4hHt8Sn+9IQEISkZgkJCUZyUlBSlKRmjSkJR3pyUBGMpGZLGQlG9nJQU5ykZs85CUf+SlAQQpRmCIUpRjFKUFJSlGaMpSlHOWpQEUqUZkqVKUa1alBTWpRmzrUpR71aUBDGtGYJjSlGc1pQUta0Zo2tKUd7elARzrRmS50pRvd6UFPetGbPvSlH/0ZwEAGMZghDGUYwxnBSEYxmjGMZRzjmcBEJjGZKUxlGtOZwUxmMZs5zGUe81nAQhaxmCUsZRnLWcFKVrGaNaxlHevZwEY2sZktbGUb29nB9+zkB3bxI7v5iT38zF72sZ9fOMCvHOQ3DvE7h/mDIxzlGMc5wZ+c5C9O8Ten+YcznOUc/3Ke/7jARS5xmStc5RrXucFNbnGbO9zlHvd5wEMe8ZgnPOUZz3nBS17xmje85R0fJXH98wlhCEs4PiU8EYhIJCLzGVH4nKh8QTS+JDoxiEksYvMVcfiauHxDPL4lPt+RgIQkIjFJSEoykpOClKQiNWlISzrSk4GMZCIzWchKNrKTg5zkIjd5yEs+8lOAghSiMEUoSjGKU4KSlKI0ZShLOcpTgYpUojJVqEo1qlODmtSiNnWoSz3q04CGNKIxTWhKM5rTgpa0ojVtaEs72tOBjnSiM13oSje604Oe9KI3fehLP/ozgIEMYjBDGMowhjOCkYxiNGMYyzjGM4GJTGIyU5jKNKYzg5nMYjZzmMs85rOAhSxiMUtYyjKWs4KVrGI1a1jLOtazgY1sYjNb2Mo2trOD79nJD+ziR3bzE3v4mb3sYz+/cIBfOchvHOJ3DvMHRzjKMY5zgj85yV+c4m9O8w9nOMs5/uU8/3GBi1ziMle4yjWuc4Ob3OI2d7jLPe7zgIc84jFPeMoznvOCl7ziNW94yzs+Sur65xPCEJZwfEp4IhCRSETmM6LwOVH5gmh8SXRiEJNYxOYr4vA1cfmGeHxLfL4jAQlJRGKSkJRkJCcFKUlFatKQlnSkJwMZyURmspCVbGQnBznJRW7ykJd85KcABSlEYYpQlGIUpwQlKUVpylCWcpSnAhWpRGWqUJVqVKcGNalFbepQl3rUpwENaURjmtCUZjSnBS1pRWva0JZ2tKcDHelEZ7rQlW50pwc96UVv+tCXfvRnAAMZxGCGMJRhDGcEIxnFaMYwlnGMZwITmcRkpjCVaUxnBjOZxWzmMJd5zGcBC1nEYpawlGUsZwUrWcVq1rCWdaxnAxvZxGa2sJVtbGcH37OTH9jFj+zmJ/bwM3vZx35+4QC/cpDfOMTvHOYPjnCUYxznBH9ykr84xd+c5h/OcJZz/Mt5/uMCF7nEZa5wlWtc5wY3ucVt7nCXe9znAQ95xGOe8JRnPOcFL3nFa97wlnd8lMz1zyeEISzh+JTwRCAikYjMZ0Thc6LyBdH4kujEICaxiM1XxOFr4vIN8fiW+HxHAhKSiMQkISnJSE4KUpKK1KQhLelITwYykonMZCEr2chODnKSi9zkIS/5yE8BClKIwhShKMUoTglKUorSlKEs5ShPBSpSicpUoSrVqE4NalKL2tShLvWoTwMa0ojGNKEpzWhOC1rSita0oS3taE8HOtKJznShK93oTg960ove9KEv/ejPAAYyiMEMYSjDGM4IRjKK0YxhLOMYzwQmMonJTGEq05jODGYyi9nMYS7zmM8CFrKIxSxhKctYzgpWsorVrGEt61jPBjayic1sYSvb2M4OvmcnP7CLH9nNT+zhZ/ayj/38wgF+5SC/cYjfOcwfHOEoxzjOCf7kJH9xir85zT+c4Szn+Jfz/McFLnKJy1zhKte4zg1ucovb3OEu97jPAx7yiMc84SnPeM4LXvKK17zhLe/4KLnrn08IQ1jC8SnhiUBEIhGZz4jC50TlC6LxJdGJQUxiEZuviMPXxOUb4vEt8fmOBCQkEYlJQlKSkZwUpCQVqUlDWtKRngxkJBOZyUJWspGdHOQkF7nJQ17ykZ8CFKQQhSlCUYpRnBKUpBSlKUNZylGeClSkEpWpQlWqUZ0a1KQWtalDXepRnwY0pBGNaUJTmtGcFrSkFa1pQ1va0Z4OdKQTnelCV7rRnR70pBe96UNf+tGfAQxkEIMZwlCGMZwRjGQUoxnDWMYxnglMZBKTmcJUpjGdGcxkFrOZw1zmMZ8FLGQRi1nCUpaxnBWsZBWrWcNa1rGeDWxkE5vZwla2sZ0dfM9OfmAXP7Kbn9jDz+xlH/v5hQP8ykF+4xC/c5g/OMJRjnGcE/zJSf7iFH9zmn84w1nO8S/n+Y8LXOQSl7nCVa5xnRvc5Ba3ucNd7nGfBzzkEY95wlOe8ZwXvOQVr3nDW97xUQrXP58QhrCE41PCE4GIRCIynxGFz4nKF0TjS6ITg5jEIjZfEYevics3xONb4vMdCUhIIhKThKQkIzkpSEkqUpOGtKQjPRnISCYyk4WsZCM7OchJLnKTh7zkIz8FKEghClOEohSjOCUoSSlKU4aylKM8FahIJSpThapUozo1qEktalOHutSjPg1oSCMa04SmNKM5LWhJK1rThra0oz0d6EgnOtOFrnSjOz3oSS9604e+9KM/AxjIIAYzhKEMYzgjGMkoRjOGsYxjPBOYyCQmM4WpTGM6M5jJLGYzh7nMYz4LWMgiFrOEpSxjOStYySpWs4a1rGM9G9jIJjazha1sYzs7+J6d/MAufmQ3P7GHn9nLPvbzCwf4lYP8xiF+5zB/cISjHOM4J/iTk/zFKf7mNP9whrOc41/O8x8XuMglLnOFq1zjOje4yS1uc4e73OM+D3jIIx7zhKc84zkveMkrXvOGt7zjo5Sufz4hDGEJx6eEJwIRiURkPiMKnxOVL4jGl0QnBjGJRWy+Ig5fE5dviMe3xOc7EpCQRCQmCUlJRnJSkJJUpCYNaUlHejKQkUxkJgtZyUZ2cpCTXOQmD3nJR34KUJBCFKYIRSlGcUpQklKUpgxlKUd5KlCRSlSmClWpRnVqUJNa1KYOdalHfRrQkEY0pglNaUZzWtCSVrSmDW1pR3s60JFOdKYLXelGd3rQk170pg996Ud/BjCQQQxmCEMZxnBGMJJRjGYMYxnHeCYwkUlMZgpTmcZ0ZjCTWcxmDnOZx3wWsJBFLGYJS1nGclawklWsZg1rWcd6NrCRTWxmC1vZxnZ28D07+YFd/MhufmIPP7OXfeznFw7wKwf5jUP8zmH+4AhHOcZxTvAnJ/mLU/zNaf7hDGc5x7+c5z8ucJFLXOYKV7nGdW5wk1vc5g53ucd9HvCQRzzmCU95xnNe8JJXvOYNb3nHR6lc/3xCGMISjk8JTwQiEonIfEYUPicqXxCNL4lODGISi9h8RRy+Ji7fEI9vic93JCAhiUhMEpKSjOSkICWpSE0a0pKO9GQgI5nITBayko3s5CAnuchNHvKSj/wUoCCFKEwRilKM4pSgJKUoTRnKUo7yVKAilahMFapSjerUoCa1qE0d6lKP+jSgIY1oTBOa0ozmtKAlrWhNG9rSjvZ0oCOd6EwXutKN7vSgJ73oTR/60o/+DGAggxjMEIYyjOGMYCSjGM0YxjKO8UxgIpOYzBSmMo3pzGAms5jNHOYyj/ksYCGLWMwSlrKM5axgJatYzRrWso71bGAjm9jMFrayje3s4Ht28gO7+JHd/MQefmYv+9jPLxzgVw7yG4f4ncP8wRGOcozjnOBPTvIXp/ib0/zDGc5yjn85z39c4CKXuMwVrnKN69zgJre4zR3uco/7POAhj3jME57yjOe84CWveM0b3vKOj1K7/vmEMIQlHJ8SnghEJBKR+YwofE5UviAaXxKdGMQkFrH5ijh8TVy+IR7fEp/vSEBCEpGYJCQlGclJQUpSkZo0pCUd6clARjKRmSxkJRvZyUFOcpGbPOQlH/kpQEEKUZgiFKUYxSlBSUpRmjKUpRzlqUBFKlGZKlSlGtWpQU1qUZs61KUe9WlAQxrRmCY0pRnNaUFLWtGaNrSlHe3pQEc60ZkudKUb3elBT3rRmz70pR/9GcBABjGYIQxlGMMZwUhGMZoxjGUc45nARCYxmSlMZRrTmcFMZjGbOcxlHvNZwEIWsZglLGUZy1nBSlaxmjWsZR3r2cBGNrGZLWxlG9vZwffs5Ad28SO7+Yk9/Mxe9rGfXzjArxzkNw7xO4f5gyMc5RjHOcGfnOQvTvE3p/mHM5zlHP9ynv+4wEUucZkrXOUa17nBTW5xmzvc5R73ecBDHvGYJzzlGc95wUte8Zo3vOUdH6Vx/fMJYQhLOD4lPBGISCQi8xlR+JyofEE0viQ6MYhJLGLzFXH4mrh8Qzy+JT7fkYCEJCIxSUhKMpKTgpSkIjVpSEs60pOBjGQiM1nISjayk4Oc5CI3echLPvJTgIIUojBFKEoxilOCkpSiNGUoSznKU4GKVKIyVahKNapTg5rUojZ1qEs96tOAhjSiMU1oSjOa04KWtKI1bWhLO9rTgY50ojNd6Eo3utODnvSiN33oSz/6M4CBDGIwQxjKMIYzgpGMYjRjGMs4xjOBiUxiMlOYyjSmM4OZzGI2c5jLPOazgIUsYjFLWMoylrOClaxiNWtYyzrWs4GNbGIzW9jKNrazg+/ZyQ/s4kd28xN7+Jm97GM/v3CAXznIbxzidw7zB0c4yjGOc4I/OclfnOJvTvMPZzjLOf7lPP9xgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxT3jKM57zgpe84jVveMs7Pkrr+ucTwhCWcHxKeCIQkUhE5jOi8DlR+YJofEl0YhCTWMTmK+LwNXH5hnh8S3y+IwEJSURikpCUZCQnBSlJRWrSkJZ0pCcDGclEZrKQlWxkJwc5yUVu8pCXfOSnAAUpRGGKUJRiFKcEJSlFacpQlnKUpwIVqURlqlCValSnBjWpRW3qUJd61KcBDWlEY5rQlGY0pwUtaUVr2tCWdrSnAx3pRGe60JVudKcHPelFb/rQl370ZwADGcRghjCUYQxnBCMZxWjGMJZxjGcCE5nEZKYwlWlMZwYzmcVs5jCXecxnAQtZxGKWsJRlLGcFK1nFatawlnWsZwMb2cRmtrCVbWxnB9+zkx/YxY/s5if28DN72cd+fuEAv3KQ3zjE7xzmD45wlGMc5wR/cpK/OMXfnOYfznCWc/zLef7jAhe5xGWucJVrXOcGN7nFbe5wl3vc5wEPecRjnvCUZzznBS95xWve8JZ3fJTO9c8nhCEs4fiU8EQgIpGIzGdE4XOi8gXR+JLoxCAmsYjNV8Tha+LyDfH4lvh8RwISkojEJCEpyUhOClKSitSkIS3pSE8GMpKJzGQhK9nITg5ykovc5CEv+chPAQpSiMIUoSjFKE4JSlKK0pShLOUoTwUqUonKVKEq1ahODWpSi9rUoS71qE8DGtKIxjShKc1oTgta0orWtKEt7WhPBzrSic50oSvd6E4PetKL3vShL/3ozwAGMojBDGEowxjOCEYyitGMYSzjGM8EJjKJyUxhKtOYzgxmMovZzGEu85jPAhayiMUsYSnLWM4KVrKK1axhLetYzwY2sonNbGEr29jODr5nJz+wix/ZzU/s4Wf2so/9/MIBfuUgv3GI3znMHxzhKMc4zgn+5CR/cYq/Oc0/nOEs5/iX8/zHBS5yictc4SrXuM4NbnKL29zhLve4zwMe8ojHPOEpz3jOC17yite84S3v+Ci9659PCENYwvEp4YlARCIRmc+IwudE5Qui8SXRiUFMYhGbr4jD18TlG+LxLfH5jgQkJBGJSUJSkpGcFKQkFalJQ1rSkZ4MZCQTmclCVrKRnRzkJBe5yUNe8pGfAhSkEIUpQlGKUZwSlKQUpSlDWcpRngpUpBKVqUJVqlGdGtSkFrWpQ13qUZ8GNKQRjWlCU5rRnBa0pBWtaUNb2tGeDnSkE53pQle60Z0e9KQXvelDX/rRnwEMZBCDGcJQhjGcEYxkFKMZw1jGMZ4JTGQSk5nCVKYxnRnMZBazmcNc5jGfBSxkEYtZwlKWsZwVrGQVq1nDWtaxng1sZBOb2cJWtrGdHXzPTn5gFz+ym5/Yw8/sZR/7+YUD/MpBfuMQv3OYPzjCUY5xnBP8yUn+4hR/c5p/OMNZzvEv5/mPC1zkEpe5wlWucZ0b3OQWt7nDXe5xnwc85BGPecJTnvGcF7zkFa95w1ve8VEG1z+fEIawhONTwhOBiEQiMp8Rhc+JyhdE40uiE4OYxCI2XxGHr4nLN8TjW+LzHQlISCISk4SkJCM5KUhJKlKThrSkIz0ZyEgmMpOFrGQjOznISS5yk4e85CM/BShIIQpThKIUozglKEkpSlOGspSjPBWoSCUqU4WqVKM6NahJLWpTh7rUoz4NaEgjGtOEpjSjOS1oSSta04a2tKM9HehIJzrTha50ozs96EkvetOHvvSjPwMYyCAGM4ShDGM4IxjJKEYzhrGMYzwTmMgkJjOFqUxjOjOYySxmM4e5zGM+C1jIIhazhKUsYzkrWMkqVrOGtaxjPRvYyCY2s4WtbGM7O/ienfzALn5kNz+xh5/Zyz728wsH+JWD/MYhfucwf3CEoxzjOCf4k5P8xSn+5jT/cIaznONfzvMfF7jIJS5zhatc4zo3uMktbnOHu9zjPg94yCMe84SnPOM5L3jJK17zhre846OMrn8+IQxhCcenhCcCEYlEZD4jCp8TlS+IxpdEJwYxiUVsviIOXxOXb4jHt8TnOxKQkEQkJglJSUZyUpCSVKQmDWlJR3oykJFMZCYLWclGdnKQk1zkJg95yUd+ClCQQhSmCEUpRnFKUJJSlKYMZSlHeSpQkUpUpgpVqUZ1alCTWtSmDnWpR30a0JBGNKYJTWlGc1rQkla0pg1taUd7OtCRTnSmC13pRnd60JNe9KYPfelHfwYwkEEMZghDGcZwRjCSUYxmDGMZx3gmMJFJTGYKU5nGdGYwk1nMZg5zmcd8FrCQRSxmCUtZxnJWsJJVrGYNa1nHejawkU1sZgtb2cZ2dvA9O/mBXfzIbn5iDz+zl33s5xcO8CsH+Y1D/M5h/uAIRznGcU7wJyf5i1P8zWn+4QxnOce/nOc/LnCRS1zmCle5xnVucJNb3OYOd7nHfR7wkEc85glPecZzXvCSV7zmDW95x0eZXP98QhjCEo5PCU8EIhKJyHxGFD4nKl8QjS+JTgxiEovYfEUcviYu3xCPb4nPdyQgIYlITBKSkozkpCAlqUhNGtKSjvRkICOZyEwWspKN7OQgJ7nITR7yko/8FKAghShMEYpSjOKUoCSlKE0ZylKO8lSgIpWoTBWqUo3q1KAmtahNHepSj/o0oCGNaEwTmtKM5rSgJa1oTRva0o72dKAjnehMF7rSje70oCe96E0f+tKP/gxgIIMYzBCGMozhjGAkoxjNGMYyjvFMYCKTmMwUpjKN6cxgJrOYzRzmMo/5LGAhi1jMEpayjOWsYCWrWM0a1rKO9WxgI5vYzBa2so3t7OB7dvIDu/iR3fzEHn5mL/vYzy8c4FcO8huH+J3D/MERjnKM45zgT07yF6f4m9P8wxnOco5/Oc9/XOAil7jMFa5yjevc4Ca3uM0d7nKP+zzgIY94zBOe8oznvOAlr3jNG97yjo8yu/75hDCEJRyfEp4IRCQSkfmMKHxOVL4gGl8SnRjEJBax+Yo4fE1cviEe3xKf70hAQhKRmCQkJRnJSUFKUpGaNKQlHenJQEYykZksZCUb2clBTnKRmzzkJR/5KUBBClGYIhSlGMUpQUlKUZoylKUc5alARSpRmSpUpRrVqUFNalGbOtSlHvVpQEMa0ZgmNKUZzWlBS1rRmja0pR3t6UBHOtGZLnSlG93pQU960Zs+9KUf/RnAQAYxmCEMZRjDGcFIRjGaMYxlHOOZwEQmMZkpTGUa05nBTGYxmznMZR7zWcBCFrGYJSxlGctZwUpWsZo1rGUd69nARjaxmS1sZRvb2cH37OQHdvEju/mJPfzMXvaxn184wK8c5DcO8TuH+YMjHOUYxznBn5zkL07xN6f5hzOc5Rz/cp7/uMBFLnGZK1zlGte5wU1ucZs73OUe93nAQx7xmCc85RnPecFLXvGaN7zlHR9lcf3zCWEISzg+JTwRiEgkIvMZUficqHxBNL4kOjGISSxi8xVx+Jq4fEM8viU+35GAhCQiMUlISjKSk4KUpCI1aUhLOtKTgYxkIjNZyEo2spODnOQiN3nISz7yU4CCFKIwRShKMYpTgpKUojRlKEs5ylOBilSiMlWoSjWqU4Oa1KI2dahLPerTgIY0ojFNaEozmtOClrSiNW1oSzva04GOdKIzXehKN7rTg570ojd96Es/+jOAgQxiMEMYyjCGM4KRjGI0YxjLOMYzgYlMYjJTmMo0pjODmcxiNnOYyzzms4CFLGIxS1jKMpazgpWsYjVrWMs61rOBjWxiM1vYyja2s4Pv2ckP7OJHdvMTe/iZvexjP79wgF85yG8c4ncO8wdHOMoxjnOCPznJX5zib07zD2c4yzn+5Tz/cYGLXOIyV7jKNa5zg5vc4jZ3uMs97vOAhzziMU94yjOe84KXvOI1b3jLOz7K6vrnE8IQlnB8SngiEJFIROYzovA5UfmCaHxJdGIQk1jE5ivi8DVx+YZ4fEt8viMBCUlEYpKQlGQkJwUpSUVq0pCWdKQnAxnJRGaykJVsZCcHOclFbvKQl3zkpwAFKURhilCUYhSnBCUpRWnKUJZylKcCFalEZapQlWpUpwY1qUVt6lCXetSnAQ1pRGOa0JRmNKcFLWlFa9rQlna0pwMd6URnutCVbnSnBz3pRW/60Jd+9GcAAxnEYIYwlGEMZwQjGcVoxjCWcYxnAhOZxGSmMJVpTGcGM5nFbOYwl3nMZwELWcRilrCUZSxnBStZxWrWsJZ1rGcDG9nEZrawlW1sZwffs5Mf2MWP7OYn9vAze9nHfn7hAL9ykN84xO8c5g+OcJRjHOcEf3KSvzjF35zmH85wlnP8y3n+4wIXucRlrnCVa1znBje5xW3ucJd73OcBD3nEY57wlGc85wUvecVr3vCWd3yUzfXPJ4QhLOH4lPBEICKRiMxnROFzovIF0fiS6MQgJrGIzVfE4Wvi8g3x+Jb4fEcCEpKIxCQhKclITgpSkorUpCEt6UhPBjKSicxkISvZyE4OcpKL3OQhL/nITwEKUojCFKEoxShOCUpSitKUoSzlKE8FKlKJylShKtWoTg1qUova1KEu9ahPAxrSiMY0oSnNaE4LWtKK1rShLe1oTwc60onOdKEr3ehOD3rSi970oS/96M8ABjKIwQxhKMMYzghGMorRjGEs4xjPBCYyiclMYSrTmM4MZjKL2cxhLvOYzwIWsojFLGEpy1jOClayitWsYS3rWM8GNrKJzWxhK9vYzg6+Zyc/sIsf2c1P7OFn9rKP/fzCAX7lIL9xiN85zB8c4SjHOM4J/uQkf3GKvznNP5zhLOf4l/P8xwUuconLXOEq17jODW5yi9vc4S73uM8DHvKIxzzhKc94zscf/f/+cb/c//uv/5+9boR5uwoej7zm//NxYQJauIAWPqBFDGiRA1qUgBY1oEULaNEDWsyAFjugxQlocQNavIAWP6AlCGiJAlqSgJYsoKUIaKkCWpqAli6gZQhomQJaloCWLaDlCGi5AlqegJYvoBUIaIUCWpGAViyglQhopQJamYBWLqBVCGiVAlqVgFYtoNUIaLUCWp2AVi+gNQhojQJak4DWLKC1CGitAlqbgNYuoHUIaJ0CWpeA1i2g9QhovQJan4DWL6ANCGiDAtqQgDYsoI0IaKMC2piANi6gTQhokwLalIA2LaDNCGizAtqcgDYvoC0IaIsC2pKAtiygrQhoqwLamoC2LqBtCGibAtqWgLYtoO0IaDsD2q6Atjug7QloewPa/oB2IKAdDGiHAtrhgHYkoB0LaCcC2smAdiqgnQ5oZwLauYB2PqBdCGiXAtqVgHYtoN0IaLcC2p2Adi+gPQhojwLak4D2LKC9CGivAtqbgPYuoH388f+6hQlo4QJa+IAWMaBFDmhRAlrUgBYtoEUPaDEDWuyAFiegxQ1o8QJa/ICWIKAlCmhJAlqygJYioKUKaGkCWrqAliGgZQpoWQJatoCWI6DlCmh5Alq+gFYgoBUKaEUCWrGAViKglQpoZQJauYBWIaBVCmhVAlq1gFYjoNUKaHUCWr2A1iCgNQpoTQJas4DWIqC1CmhtAlq7gNYhoHUKaF0CWreA1iOg9QpofQJav4A2IKANCmhDAtqwgDYioI0KaGMC2riANiGgTQpoUwLatIA2I6DNCmhzAtq8gLYgoC0KaEsC2rKAtiKgrQpoawLauoC2IaBtCmhbAtq2gLYjoO0MaLsC2u6Atieg7Q1o+wPagYB2MKAdCmiHA9qRgHYsoJ0IaCcD2qmAdjqgnQlo5wLa+YB2IaBdCmhXAtq1gHYjoN0KaHcC2r2A9iCgPQpoTwLas4D2IqC9CmhvAtq7gPbxJ//rFiaghQto4QNaxIAWOaBFCWhRA1q0gBY9oMUMaLEDWpyAFjegxQto8QNagoCWKKAlCWjJAlqKgJYqoKUJaOkCWoaAlimgZQlo2QJajoCWK6DlCWj5AlqBgFYooBUJaMUCWomAViqglQlo5QJahYBWKaBVCWjVAlqNgFYroNUJaPUCWoOA1iigNQlozQJai4DWKqC1CWjtAlqHgNYpoHUJaN0CWo+A1iug9Qlo/QLagIA2KKANCWjDAtqIgDYqoI0JaOMC2oSANimgTQlo0wLajIA2K6DNCWjzAtqCgLYooC0JaMsC2oqAtiqgrQlo6wLahoC2KaBtCWjbAtqOgLYzoO0KaLsD2p6Atjeg7Q9oBwLawYB2KKAdDmhHAtqxgHYioJ0MaKcC2umAdiagnQto5wPahYB2KaBdCWjXAtqNgHYroN0JaPcC2oOA9iigPQlozwLai4D2KqC9CWjvAtrHYf7XLUxACxfQwge0iAEtckCLEtCiBrRoAS16QIsZ0GIHtDgBLW5AixfQ4ge0BAEtUUBLEtCSBbQUAS1VQEsT0NIFtAwBLVNAyxLQsgW0HAEtV0DLE9DyBbQCAa1QQCsS0IoFtBIBrVRAKxPQygW0CgGtUkCrEtCqBbQaAa1WQKsT0OoFtAYBrVFAaxLQmgW0FgGtVUBrE9DaBbQOAa1TQOsS0LoFtB4BrVdA6xPQ+gW0AQFtUEAbEtCGBbQRAW1UQBsT0MYFtAkBbVJAmxLQpgW0GQFtVkCbE9DmBbQFAW1RQFsS0JYFtBUBbVVAWxPQ1gW0DQFtU0DbEtC2BbQdAW1nQNsV0HYHtD0BbW9A2x/QDgS0gwHtUEA7HNCOBLRjAe1EQDsZ0E4FtNMB7UxAOxfQzge0CwHtUkC7EtCuBbQbAe1WQLsT0O4FtAcB7VFAexLQngW0FwHtVUB7E9DeBbSPw/6vW5iAFi6ghQ9oEQNa5IAWJaBFDWjRAlr0gBYzoMUOaHECWtyAFi+gxQ9oCQJaooCWJKAlC2gpAlqqgJYmoKULaBkCWqaAliWgZQtoOQJaroCWJ6DlC2gFAlqhgFYkoBULaCUCWqmAViaglQtoFQJapYBWJaBVC2g1AlqtgFYnoNULaA0CWqOA1iSgNQtoLQJaq4DWJqC1C2gdAlqngNYloHULaD0CWq+A1ieg9QtoAwLaoIA2JKANC2gjAtqogDYmoI0LaBMC2qSANiWgTQtoMwLarIA2J6DNC2gLAtqigLYkoC0LaCsC2qqAtiagrQtoGwLapoC2JaBtC2g7AtrOgLYroO0OaHsC2t6Atj+gHQhoBwPaoYB2OKAdCWjHAtqJgHYyoJ0KaKcD2pmAdi6gnQ9oFwLapYB2JaBdC2g3AtqtgHYnoN0LaA8C2qOA9iSgPQtoLwLaq4D2JqC9C2gfh/tftzABLVxACx/QIga0yAEtSkCLGtCiBbToAS1mQIsd0OIEtLgBLV5Aix/QEgS0RAEtSUBLFtBSBLRUAS1NQEsX0DIEtEwBLUtAyxbQcgS0XAEtT0DLF9AKBLRCAa1IQCsW0EoEtFIBrUxAKxfQKgS0SgGtSkCrFtBqBLRaAa1OQKsX0BoEtEYBrUlAaxbQWgS0VgGtTUBrF9A6BLROAa1LQOsW0HoEtF4BrU9A6xfQBgS0QQFtSEAbFtBGBLRRAW1MQBsX0CYEtEkBbUpAmxbQZgS0WQFtTkCbF9AWBLRFAW1JQPt/8KVHoaAAAABo1+12Z2ZmZmZmZmZmZmZmZmbmmZmZmZmZmZmZmZmZmZmZSZIkSZIkSZIkSZIkSZIkSZIkSZIkSZIkyT72O+frfJwF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+Q/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7E/D7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7Pf/j3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yfwN/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+I7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P4E/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/Mf/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf49/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//Y7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PyG/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Md/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9Cf39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fnP/H7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P2O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//yd/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/Cf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/flP/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+xPx+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz3/69/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn8jf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB//jO/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+RP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzn/39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/cn+vf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//3O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD8xv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/vznf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/Yn9/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf357/w+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uT9zv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g//8Xf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/4n+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf35L/1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/uT8Pv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7s9/+ff7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/E3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/4rv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/iT9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P781/9/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3J/n3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf/9rv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g/Kb/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P7813+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf1J/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+e/8fv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7k/a7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4P//N3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf9J/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+W/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7k/H7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7Pf/v3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yfzN/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+O7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P5k/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/Pf/f3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf79/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//e7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4Pzm/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Ae/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW48v/g/+f/v6vAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf3N/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/++7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P7k/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/M/+P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9yf/9/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//h7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PwW/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/I9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9Kfz9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fnf/z7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P0e/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//k9/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH+Kf7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/fmf/n5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+1Py+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz//s9/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn9Lf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB//ue/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+lP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzv/j9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/en/Pf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//5e/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD8Vv99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/vyvfr+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/an8/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf353/9+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uT9Xv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g//5vf7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/qn+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf353/5+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/tT8/v9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7s//7vf7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/a3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/73v99f3D9cAC4QF4QLxoXgQnFhuHBcBC4SF4WLxsXgYnFxuHhcAi4Rl4RLxqXgUnFpuHRcBi4Tl4XLxuXgcnF5uHxcAa4QV4QrxpXgSnFluHJcBa4SV4WrxtXganF1uHpcA64R14RrxrXgWnFtuHZcB64T14XrxvXgenF9uH7cAG4QN4Qbxo3gRnFjuHHcBG4SN4Wbxs3gZnFzuHncAm4Rt4Rbxq3gVnFruHXcBm4Tt4Xbxu3gdnF7uH3cAe4Qd4Q7xp3gTnFnuHPcBe4Sd4W7xt3gbnF3uHvcA+4R94R7xr3gXnFvuHfcB+4T94X7xv3g/tT9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P783/4/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3p/73+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf/+Pv9xf3DxeAC8QF4YJxIbhQXBguHBeBi8RF4aJxMbhYXBwuHpeAS8Ql4ZJxKbhUXBouHZeBy8Rl4bJxObhcXB4uH1eAK8QV4YpxJbhSXBmuHFeBq8RV4apxNbhaXB2uHteAa8Q14ZpxLbhWXBuuHdeB68R14bpxPbheXB+uHzeAG8QN4YZxI7hR3BhuHDeBm8RN4aZxM7hZ3BxuHreAW8Qt4ZZxK7hV3BpuHbeB28Rt4bZxO7hd3B5uH3eAO8Qd4Y5xJ7hT3BnuHHeBu8Rd4a5xN7hb3B3uHveAe8Q94Z5xL7hX3BvuHfeB+8R94b5xP7g/Db/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P78n36/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf1p/P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+f//Pv9xf3DBeACcUG4YFwILhQXhgvHReAicVG4aFwMLhYXh4vHJeAScUm4ZFwKLhWXhkvHZeAycVm4bFwOLheXh8vHFeAKcUW4YlwJrhRXhivHVeAqcVW4alwNrhZXh6vHNeAacU24ZlwLrhXXhmvHdeA6cV24blwPrhfXh+vHDeAGcUO4YdwIbhQ3hhvHTeAmcVO4adwMbhY3h5vHLeAWcUu4ZdwKbhW3hlvHbeA2cVu4bdwObhe3h9vHHeAOcUe4Y9wJ7hR3hjvHXeAucVe4a9wN7hZ3h7vHPeAecU+4Z9wL7hX3hnvHfeA+cV+4b9wP7k/T7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4P/+X3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf5p/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+b/+fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P70/L7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7P/+33+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf1t/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH/+77/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P60/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/P/+P3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H96f99/uL+4cLwAXignDBuBBcKC4MF46LwEXionDRuBhcLC4OF49LwCXiknDJuBRcKi4Nl47LwGXisnDZuBxcLi4Pl48rwBXiinDFuBJcKa4MV46rwFXiqnDVuBpcLa4OV49rwDXimnDNuBZcK64N147rwHXiunDduB5cL64P148bwA3ihnDDuBHcKG4MN46bwE3ipnDTuBncLG4ON49bwC3ilnDLuBXcKm4Nt47bwG3itnDbuB3cLm4Pt487wB3ijnDHuBPcKe4Md467wF3irnDXuBvcLe4Od497wD3innDPuBfcK+4N9477wH3ivnDfuB/cn//n7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4Px2/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/L9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H96fz9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fn//37/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+5P1+/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//n9/vL+4fLgAXiAvCBeNCcKG4MFw4LgIXiYvCReNicLG4OFw8LgGXiEvCJeNScKm4NFw6LgOXicvCZeNycLm4PFw+rgBXiCvCFeNKcKW4Mlw5rgJXiavCVeNqcLW4Olw9rgHXiGvCNeNacK24Nlw7rgPXievCdeN6cL24Plw/bgA3iBvCDeNGcKO4Mdw4bgI3iZvCTeNmcLO4Odw8bgG3iFvCLeNWcKu4Ndw6bgO3idvCbeN2cLu4Pdw+7gB3iDvCHeNOcKe4M9w57gJ3ibvCXeNucLe4O9w97gH3iHvCPeNecK+4N9w77gP3ifvCfeN+cH+6f7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7v/blxy/ggIAgIHu9XpJkiRJkiRJkiRJkiRJkiRJkiRJkiRJcs4558zMzMzMTJIkSZIkSZIkSZIkSZIkSZIkydof4Pt+/a5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//6/f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J+e3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7v3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf3p/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+X9+v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H96fv9/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/fn//39/uL+4QJwgbggXDAuBBeKC8OF4yJwkbgoXDQuBheLi8PF4xJwibgkXDIuBZeKS8Ol4zJwmbgsXDYuB5eLy8Pl4wpwhbgiXDGuBFeKK8OV4ypwlbgqXDWuBleLq8PV4xpwjbgmXDOuBdeKa8O14zpwnbguXDeuB9eL68P14wZwg7gh3DBuBDeKG8ON4yZwk7gp3DRuBjeLm8PN4xZwi7gl3DJuBbeKW8Ot4zZwm7gt3DZuB7eL28Pt4w5wh7gj3DHuBHeKO8Od4y5wl7gr3DXuBneLu8Pd4x5wj7gn3DPuBfeKe8O94z5wn7gv3DfuB/en//f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J//7/f7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J+B3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7/3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wfwZ/v7+4f7gAXCAuCBeMC8GF4sJw4bgIXCQuCheNi8HF4uJw8bgEXCIuCZeMS8Gl4tJw6bgMXCYuC5eNy8Hl4vJw+bgCXCGuCFeMK8GV4spw5bgKXCWuCleNq8HV4upw9bgGXCOuCdeMa8G14tpw7bgOXCeuC9eN68H14vpw/bgB3CBuCDeMG8GN4sZw47gJ3CRuCjeNm8HN4uZw87gF3CJuCbeMW8Gt4tZw67gN3CZuC7eN28Ht4vZw+7gD3CHuCHeMO8Gd4s5w57gL3CXuCneNu8Hd4u5w97gH3CPuCfeMe8G94t5w77gP3CfuC/eN+8H9+Q+/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+DP1+f3H/cAG4QFwQLhgXggvFheHCcRG4SFwULhoXg4vFxeHicQm4RFwSLhmXgkvFpeHScRm4TFwWLhuXg8vF5eHycQW4QlwRrhhXgivFleHKcRW4SlwVrhpXg6vF1eHqcQ24RlwTrhnXgmvFteHacR24TlwXrhvXg+vF9eH6cQO4QdwQbhg3ghvFjeHGcRO4SdwUbho3g5vFzeHmcQu4RdwSbhm3glvFreHWcRu4TdwWbhu3g9vF7eH2cQe4Q9wR7hh3gjvFneHOcRe4S9wV7hp3g7vF3eHucQ+4R9wT7hn3gnvFveHecR+4T9wX7hv3g/vzH3+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf0Z/v3+4v7hAnCBuCBcMC4EF4oLw4XjInCRuChcNC4GF4uLw8XjEnCJuCRcMi4Fl4pLw6XjMnCZuCxcNi4Hl4vLw+XjCnCFuCJcMa4EV4orw5XjKnCVuCpcNa4GV4urw9XjGnCNuCZcM64F14prw7XjOnCduC5cN64H14vrw/XjBnCDuCHcMG4EN4obw43jJnCTuCncNG4GN4ubw83jFnCLuCXcMm4Ft4pbw63jNnCbuC3cNm4Ht4vbw+3jDnCHuCPcMe4Ed4o7w53jLnCXuCvcNe4Gd4u7w93jHnCPuCfcM+4F94p7w73jPnCfuC/cN+4H9+c//X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+zPy+/3F/cMF4AJxQbhgXAguFBeGC8dF4CJxUbhoXAwuFheHi8cl4BJxSbhkXAouFZeGS8dl4DJxWbhsXA4uF5eHy8cV4ApxRbhiXAmuFFeGK8dV4CpxVbhqXA2uFleHq8c14BpxTbhmXAuuFdeGa8d14DpxXbhuXA+uF9eH68cN4AZxQ7hh3AhuFDeGG8dN4CZxU7hp3AxuFjeHm8ct4BZxS7hl3ApuFbeGW8dt4DZxW7ht3A5uF7eH28cd4A5xR7hj3AnuFHeGO8dd4C5xV7hr3A3uFneHu8c94B5xT7hn3AvuFfeGe8d94D5xX7hv3A/uz3/+/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf3Z/T3+4v7hwvABeKCcMG4EFwoLgwXjovAReKicNG4GFwsLg4Xj0vAJeKScMm4FFwqLg2XjsvAZeKycNm4HFwuLg+XjyvAFeKKcMW4ElwprgxXjqvAVeKqcNW4Glwtrg5Xj2vANeKacM24Flwrrg3XjuvAdeK6cN24Hlwvrg/XjxvADeKGcMO4Edwobgw3jpvATeKmcNO4Gdwsbg43j1vALeKWcMu4Fdwqbg23jtvAbeK2cNu4Hdwubg+3jzvAHeKOcMe4E9wp7gx3jrvAXeKucNe4G9wt7g53j3vAPeKecM+4F9wr7g33jvvAfeK+cN+4H9yf//L7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe4Wd4e7xz3gHnFPuGfcC+4V94Z7x33gPnFfuG/cD+7P2O/3F/cPF4ALxAXhgnEhuFBcGC4cF4GLxEXhonExuFhcHC4el4BLxCXhknEpuFRcGi4dl4HLxGXhsnE5uFxcHi4fV4ArxBXhinEluFJcGa4cV4GrxFXhqnE1uFpcHa4e14BrxDXhmnEtuFZcG64d14HrxHXhunE9uF5cH64fN4AbxA3hhnEjuFHcGG4cN4GbxE3hpnEzuFncHG4et4BbxC3hlnEruFXcGm4dt4HbxG3htnE7uF3cHm4fd4A7xB3hjnEnuFPcGe4cd4G7xF3hrnE3uFvcHe4e94B7xD3hnnEvuFfcG+4d94H7xH3hvnE/uD//9ff7i/uHC8AF4oJwwbgQXCguDBeOi8BF4qJw0bgYXCwuDhePS8Al4pJwybgUXCouDZeOy8Bl4rJw2bgcXC4uD5ePK8AV4opwxbgSXCmuDFeOq8BV4qpw1bgaXC2uDlePa8A14ppwzbgWXCuuDdeO68B14rpw3bgeXC+uD9ePG8AN4oZww7gR3ChuDDeOm8BN4qZw07gZ3CxuDjePW8At4pZwy7gV3CpuDbeO28Bt4rZw27gd3C5uD7ePO8Ad4o5wx7gT3CnuDHeOu8Bd4q5w17gb3C3uDnePe8A94p5wz7gX3CvuDfeO+8B94r5w37gf3J/x3+8v7h8uABeIC8IF40JwobgwXDguAheJi8JF42Jwsbg4XDwuAZeIS8Il41Jwqbg0XDouA5eJy8Jl43Jwubg8XD6uAFeIK8IV40pwpbgyXDmuAleJq8JV42pwtbg6XD2uAdeIa8I141pwrbg2XDuuA9eJ68J143pwvbg+XD9uADeIG8IN40Zwo7gx3DhuAjeJm8JN42Zws7g53DxuAbeIW8It41Zwq7g13DpuA7eJ28Jt43Zwu7g93D7uAHeIO8Id405wp7gz3DnuAneJu8Jd425wt7g73D3uAfeIe8I9415wr7g33DvuA/eJ+8J9435wf/7b7/cX9w8XgAvEBeGCcSG4UFwYLhwXgYvEReGicTG4WFwcLh6XgEvEJeGScSm4VFwaLh2XgcvEZeGycTm4XFweLh9XgCvEFeGKcSW4UlwZrhxXgavEVeGqcTW4Wlwdrh7XgGvENeGacS24Vlwbrh3XgevEdeG6cT24Xlwfrh83gBvEDeGGcSO4UdwYbhw3gZvETeGmcTO4Wdwcbh63gFvELeGWcSu4Vdwabh23gdvEbeG2cTu4Xdwebh93gDvEHeGOcSe4U9wZ7hx3gbvEXeGucTe4W9wd7h73gHvEPeGecS+4V9wb7h33gfvEfeG+cT+4PxO/31/cP1wALhAXhAvGheBCcWG4cFwELhIXhYvGxeBicXG4eFwCLhGXhEvGpeBScWm4dFwGLhOXhcvG5eBycXm4fFwBrhBXhCvGleBKcWW4clwFrhJXhavG1eBqcXW4elwDrhHXhGvGteBacW24dlwHrhPXhevG9eB6cX24ftwAbhA3hBvGjeBGcWO4cdwEbhI3hZvGzeBmcXO4edwCbhG3hFvGreBWcWu4ddwGbhO3hdvG7eB2cXu4fdwB7hB3hDvGneBOcWe4c9wF7hJ3hbvG3eBucXe4e9wD7hH3hHvGveBecW+4d9wH7hP3hfvG/eD+/Pff7y/uHy4AF4gLwgXjQnChuDBcOC4CF4mLwkXjYnCxuDhcPC4Bl4hLwiXjUnCpuDRcOi4Dl4nLwmXjcnC5uDxcPq4AV4grwhXjSnCluDJcOa4CV4mrwlXjanC1uDpcPa4B14hrwjXjWnCtuDZcO64D14nrwnXjenC9uD5cP24AN4gbwg3jRnCjuDHcOG4CN4mbwk3jZnCzuDncPG4Bt4hbwi3jVnCruDXcOm4Dt4nbwm3jdnC7uD3cPu4Ad4g7wh3jTnCnuDPcOe4Cd4m7wl3jbnC3uDvcPe4B94h7wj3jXnCvuDfcO+4D94n7wn3jfnB/Jn+/v7h/uABcIC4IF4wLwYXiwnDhuAhcJC4KF42LwcXi4nDxuARcIi4Jl4xLwaXi0nDpuAxcJi4Ll43LweXi8nD5uAJcIa4IV4wrwZXiynDluApcJa4KV42rwdXi6nD1uAZcI64J14xrwbXi2nDtuA5cJ64L143rwfXi+nD9uAHcIG4IN4wbwY3ixnDjuAncJG4KN42bwc3i5nDzuAXcIm4Jt4xbwa3i1nDruA3cJm4Lt43bwe3i9nD7uAPcIe4Id4w7wZ3iznDnuAvcJe4Kd427wd3i7nD3uAfcI+4J94x7wb3i3nDvuA/cJ+4L9437wf35H7/fX9w/XAAuEBeEC8aF4EJxYbhwXAQuEheFi8bF4GJxcbh4XAIuEZeES8al4FJxabh0XAYuE5eFy8bl4HJxebh8XAGuEFeEK8aV4EpxZbhyXAWuEleFq8bV4Gpxdbh6XAOuEdeEa8a14Fpxbbh2XAeuE9eF68b14Hpxfbh+3ABuEDeEG8aN4EZxY7hx3ARuEjeFm8bN4GZxc7h53AJuEbeEW8at4FZxa7h13AZuE7eF28bt4HZxe7h93AHuEHeEO8ad4E5xZ7hz3AXuEneFu8bd4G5xd7h73APuEfeEe8a94F5xb7h33AfuE/eF+8b94P5M/X5/cf9wAbhAXBAuGBeCC8WF4cJxEbhIXBQuGheDi8XF4eJxCbhEXBIuGZeCS8Wl4dJxGbhMXBYuG5eDy8Xl4fJxBbhCXBGuGFeCK8WV4cpxFbhKXBWuGleDq8XV4epxDbhGXBOuGdeCa8W14dpxHbhOXBeuG9eD68X14fpxA7hB3BBuGDeCG8WN4cZxE7hJ3BRuGjeDm8XN4eZxC7hF3BJuGbeCW8Wt4dZxG7hN3BZuG7eD28Xt4fZxB7hD3BHuGHeCO8Wd4c5xF7hL3BXuGneDu8Xd4e5xD7hH3BPuGfeCe8W94d5xH7hP3BfuG/eD+/M/f7+/uH+4AFwgLggXjAvBheLCcOG4CFwkLgoXjYvBxeLicPG4BFwiLgmXjEvBpeLScOm4DFwmLguXjcvB5eLycPm4AlwhrghXjCvBleLKcOW4ClwlrgpXjavB1eLqcPW4BlwjrgnXjGvBteLacO24DlwnrgvXjevB9eL6cP24Adwgbgg3jBvBjeLGcOO4Cdwkbgo3jZvBzeLmcPO4Bdwibgm3jFvBreLWcOu4Ddwmbgu3jdvB7eL2cPu4A9wh7gh3jDvBneLOcOe4C9wl7gp3jbvB3eLucPe4B9wj7gn3jHvBveLecO+4D9wn7gv3jfvB/Zn+/f7i/uECcIG4IFwwLgQXigvDheMicJG4KFw0LgYXi4vDxeMScIm4JFwyLgWXikvDpeMycJm4LFw2LgeXi8vD5eMKcIW4IlwxrgRXiivDleMqcJW4Klw1rgZXi6vD1eMacI24JlwzrgXXimvDteM6cJ24Llw3rgfXi+vD9eMGcIO4IdwwbgQ3ihvDjeMmcJO4Kdw0bgY3i5vDzeMWcIu4JdwybgW3ilvDreM2cJu4Ldw2bge3i9vD7eMOcIe4I9wx7gR3ijvDneMucJe4K9w17gZ3i7vD3eMecI+4J9wz7gX3invDveM+cJ+4L9w37gf353/9fn9x/3ABuEBcEC4YF4ILxYXhwnERuEhcFC4aF4OLxcXh4nEJuERcEi4Zl4JLxaXh0nEZuExcFi4bl4PLxeXh8nEFuEJcEa4YV4IrxZXhynEVuEpcFa4aV4OrxdXh6nENuEZcE64Z14JrxbXh2nEduE5cF64b14PrxfXh+nEDuEHcEG4YN4IbxY3hxnETuEncFG4aN4Obxc3h5nELuEXcEm4Zt4Jbxa3h1nEbuE3cFm4bt4Pbxe3h9nEHuEPcEe4Yd4I7xZ3hznEXuEvcFe4ad4O7xd3h7nEPuEfcE+4Z94J7xb3h3nEfuE/cF+4b94P7M/P7/cX9wwXgAnFBuGBcCC4UF4YLx0XgInFRuGhcDC4WF4eLxyXgEnFJuGRcCi4Vl4ZLx2XgMnFZuGxcDi4Xl4fLxxXgCnFFuGJcCa4UV4Yrx1XgKnFVuGpcDa4WV4erxzXgGnFNuGZcC64V14Zrx3XgOnFduG5cD64X14frxw3gBnFDuGHcCG4UN4Ybx03gJnFTuGncDG4WN4ebxy3gFnFLuGXcCm4Vt4Zbx23gNnFbuG3cDm4Xt4fbxx3gDnFHuGPcCe4Ud4Y7x13gLnFXuGvcDe7/+N/S+SxOxDlzAA==", - "debug_symbols": "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nwL6FNinuPgprn4K+FPgn+ICqLgCKiBQgYGKi6DiKqiAQQUOKi6EiiuhAgoVWKi4GCquhgo4VOCh4oKoGH5C3z+i75/R54f0+Sl9/5i+f06fH9TnJ/X/9KP676tfDz+sz0/r+8f1/fP6/MA+P7HvH9n3z+zzQ/v3p/axUQsbta6NWtdGLWzUwkata6PWtVELG7Ue/9+EuT/Af23UwkYtbNS6NmpdG7WwUQsbta6NWtdGLWzUwkata6PWtVELG7WwUevaqHVt1MJGLWzUujZqXRu1sFELG7WujVrXRi1s1MJGre826o//PyfWdxz18eh7t+f7o+DR4qPiUfLR4tHmo82jw0fnPvqj3Y+P/hHv+2jxUfEo+WjxaPPR5hF3bO5o7mjuaO5o7mjuaO5o7mjuaO5o7jjccbjjcMfhjsMdhzsOdxzuONxxuGO4Y7hjuGO4Y7hjuGO4Y7hjuGPuHd/V1PePfmdT76PFR8Wj5KPFo81Hm0eHj947PuzU949G8GjxUfEo+WjxaPPR5tHho9yxuGNxx+KOxR2LOxZ3LO5Y3LG4Y3GHuEPcIe4Qd4g7xB3iDnGHuEPckdyR3JHckdyR3JHckdyR3EHnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50Hni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3QuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnReebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN50fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXczvXE9yxuGNxx+KOxR2LOxZ3LO5Y3LG4Y3GHuEPcIe4Qd4g7xB3iDnGHuEPckdyR3JHckdyR3JHckdyR3JHckdxR3FHcUdxR3FHcUdxR3FHcUdxR3LG5Y3PH5o7NHZs7Nnds7tjcsbljc0dzR3NHc0dzR3NHc0dzR3NHc0dzx+GOwx2HOw53HO443HG443DH4Y7DHcMdwx3DHcMdwx3DHcMdwx3DHXSOhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eGEhxMeTng44eESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uESD5d4uMTDJR4u8XCJh0s8XOLhEg+XeLjEwyUeLvFwiYdLPFzi4RIPl3i4xMMlHi7xcImHSzxc4uHyu4db+v6oefTtf8fa3x/N++i7h/v+0e8e7n20+Kh4lHy0eLT5aPPo8NG5j/7o/OOjf3T+Plp8VDxKPlo82ny0eXT4KHcs7ljcsbhjccfijsUdizsWdyzuWNwh7hB3iDvEHeIOcYe4Q9wh7hB3JHckdyR3JHckdyR3JHckdyR3JHcUdxR3FHcUdxR3FHcUdxR3FHcUd2zu2NyxuWNzx+aOzR2bOzZ3bO7Y3NHc0dzR3NHc0dzR3NHc0dzR3NHccbjjcMfhjsMdhzsOdxzuONxxuONwx3DHcMdwx3DHcMdwB50HnQedB50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedi85F56Jz0bnoXHQuOhedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedP5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/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w2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsNtPNzGw2083MbDbTzcxsPt7x5O8f1R8ejb/w7l90fNo8NH5z76o/OPj/7R+fto8VHxKPlo8Wjz0ebR4aNzH/3R+cdH/+j8fbT4qHjEHZs7Nnds7tjcsbmjuaO5o7mjuaO5o7mjuaO5o7mjueNwx+GOwx2HOw53HO443HG443DH4Y7hjuGO4Y7hjuGO4Y7hjuGO4Y65d3z3cN8/+t3DvY8WHxWPko8WjzYfbR4dPnrv+O7hPj4awaPFR8Wj5KPFo81Hm0eHj3LH4o7FHYs7Fncs7ljcsbhjccfijsUd4g5xh7hD3CHuEHeIO8Qd4g5xR3JHckdyR3IHnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzhedLzpfdL7ofNH5ovNF54vOF50vOl90vuh80fmi80Xni84XnS86X3S+6HzR+aLzReeLzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRuehcdC46F52LzkXnonPRueg86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86TzpPOk86bzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzovOi86LzofNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm86bzpvOm84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6Hzo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0nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedJ50nnSedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedF50XnRedH5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON51vOt90vul80/mm803nm843nW8633S+6XzT+abzTeebzjedbzrfdL7pfNP5pvNN55vON503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nTedN503nR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+aHzQ+eHzg+dHzo/dH7o/ND5ofND54fOD50fOj90fuj80Pmh80Pnh84PnR86P3R+6PzQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dD50PnQ+dzO57mdz3M7n+d2Ps/tfJ7b+Ty383lu5/Pczue5nc9zO5/ndj7P7Xye2/k8t/N5bufz3M7nuZ3Pczuf53Y+T3DH4o7FHYs7Fncs7ljcsbhjccfijsUd4g5xh7hD3CHuEHeIO8Qd4g5xR3JHckdyR3JHckdyR3JHckdyR3JHcUdxR3FHcUdxR3FHcUdxR3FHccfmjs0dmzs2d2zu2NyxuWNzx+aOzR3NHc0dzR3NHc0dzR3NHc0dzR3NHYc7Dncc7jjccbjjcMfhjsMdhzsOdwx3DHcMdwx3DHcMdwx3DHcMd9B50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQedB50HnQOR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjBww0ebvBwg4cbPNzg4QYPN3i4wcMNHm7wcIOHGzzc4OEGDzd4uMHDDR5u8HCDhxs83ODhBg83eLjB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vSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWtLekvSXtLWlvSXtL2lvS3pL2lrS3pL0l7S1pb0l7S9pb0t6S9pa0t6S9Je0taW9Je0vaW9LekvaWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxlhxvyfGWHG/J8ZYcb8nxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0Zb8l4S8ZbMt6S8ZaMt2S8JeMtGW/JeEvGWzLekvGWjLdkvCXjLRlvyXhLxlsy3pLxloy3ZLwl4y0ZtiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiQetiSe8G3Lty3ftnzb8m3Lty3ftnzb8m3Lty3fJt8m3ybfJt8m3ybfJt8m3ybfJt+Wvi19W/q29G3p29K3pW9L35a+LX1b+bbybeXbyreVbyvfVr6tfFv5tvJt27dt37Z92/Zt27dt37Z92/Zt27dt39a+rX1b+7b2be3b2re1b2vf1r6tfdvxbce3Hd92fNvxbce3Hd92fNvxbce3jW8b3za+bXzb+LbxbePbxreNb/OWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvSXhLwlsS3pLwloS3JLwl4S0Jb0l4S8JbEt6S8JaEtyS8JeEtCW9JeEvCWxLekvCWhLckvCXhLQlvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb8nylixvyfKWLG/J8pYsb4nda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L2G3WvYvYbda9i9ht1r2L0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b0uu9dl97rsXpfd67J7XXavy+512b2u7+61zsfD4eEfW7Lj42H44fIvkB+mf0H54fYvaD88/gVzH353rx+/4Lt7vQ+Xf4H8MP0Lyg+3f0H74fEv4Lbv7vX9BRF+uPwL5IfpX1B+uP0L2g+Pf4FvW75t+bbl25ZvW75t+bbl25ZvW75t+Tb5Nvk2+Tb5Nvk2+Tb5Nvk2+Tb5tvRt6dvSt6VvS9+Wvi19W/q29G3p28q3lW8r31a+rXxb+bbybeXbyreVb9u+bfu27du2b9u+bfu27du2b9u+bfu29m3t29q3tW9r39a+rX1b+7b2be3bjm87vu34tuPbjm87vu34tuPbvCXylshbIm+JvCXylshbIm+JvCXylshbIm9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWpLckvSXpLUlvSXpL0luS3pL0lqS3JL0l6S1Jb0l6S9Jbkt6S9JaktyS9JektSW9JekvSW5LekvSWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvSXlLyltS3pLylpS3pLwl5S0pb0l5S8pbUt6S8paUt6S8JeUtKW9JeUvKW1LekvKWlLekvCXlLSlvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaWbG/J9pZsb8n2lmxvyfaW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dq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrtX2b3K7lV2r7J7ld2r7F5l9yq7V9m9yu5Vdq+ye5Xdq+xeZfcqu1fZvcruVXavsnuV3avsXmX3KrvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9e0e02717R7TbvXtHtNu9f/j0h7N6LkRqIo6NIrAPXz37FdzpCdWgmI6LjKUTof9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7jW51+Rek3tN7vX/p21awr0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0m95rca3Kvyb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb0W91rca3Gvxb3WH/da/fcM5/+/1r+/53U+D9JZHrRzPNjv/Kcl/z74pyX/nceD63wepLM8aOd4sP+df9zr3wd/3Ot/5/HgOp8H6SwP2jkefNv+uNd/H0Q4jwfX+TxIZ3nQzvHAtmPbse3Ydmw7th3bjm3HtmPbse3adm27tl3brm3Xtmvbte3adm17tj3bnm3Ptmfbs+3Z9mx7tj3b0ra0LW1L29K2tC1tS9vStrStbCvbyrayrWwr28q2sq1sK9vatratbWvb2ra2rW1r29q2tk1LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl9L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9fS/r3taR/X0v697Wkf19L+ve1pH9h27Ht2HZsO7Yd245tx7Zj27Ht2HZtu7Zd265t17Zr27Xt2nZtu7Y9255tz7Zn27Pt2fZse7Y9255taVvalralbWlb2pa2pW1pW9pWtpVtZVvZVraVbWVb2Va2lW1tW9vWtrVtbVvb1ra1bW1b2za2jW1j29g2to1tY9vYNraNbWvb2ra2rW1r29q2tq1ta5uWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqCffa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829Nvfa3Gtzr829dmsJ99rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovzb0299rca3Ovw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cvw70O9zrc63Cv88e9dv090/nPtv17tnM82O/805K/D/605N/zeHCdz4N0lgftHA/2O/9pyb8P/mnJf+fx4Dpte7Y9255tz7ZnW9qWtqVtaVvalralbWlb2pa2lW1lW9lWtpVtZVvZVraVbWVb29a2tW1tW9vWtrVtbVvb1raNbWPb2Da2jW1j29g2to1tY9vatratbWvb2ra2rW1r29q237Y/7vXvgz/u9b/zeHCdz4N0lgftHA++bX/d698HEc7jwXU+D9JZHrRzPLDt2HZsO7Yd27QktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLWktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVkv5bs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/r6W7O9ryf6+luzva8n+vpbs72vJ/sK2Y9ux7dh2bDu2HduObce2Y9ux7dp2bbu2Xduubde2a9u17dp2bXu2Pduebc+2Z9uz7dn2bHu2PdvStrQtbUvb0ra0LW1L29K2tK1sK9vKtrKtbCvbyrayrWwr29q2tq1ta9vatratbWvb2ra2bWwb28a2sW1sG9vGtrFtbBvb1ra1bW1b29a2tW1tW9vWNi0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwt4V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udT/3en6fe/3nDOfx4DqfB+ksD9o5Hux3/teSf85wHg+u83mQzvKgneOBbce2Y9ux7dh2bDu2HduObce2Y9u17dp2bbu2Xduubde2a9u17dr2bHu2Pduebc+2Z9uz7dn2bHu2pW1pW9qWtqVtaVvalralbWlb2Va2lW1lW9lWtpVtZVvZVra1bW1b29a2tW1tW9vWtrVtbdvYNraNbWPb2Da2jW1j29g2tq1ta9vatratbWvb2ra2rW1aEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaElpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMlqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3Gtwr8G9Bvca3OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9Hu71cK+Hez3c6+FeD/d6uNfDvR7u9XCvh3s93OvhXg/3erjXw70e7vVwr4d7Pdzr4V4P93q418O9nj/udfLv2c7/f23m77nf+U9L/n3wT0v+O48H1/k8SGd50M7xYL/zn5b8++Cflvx3Hg+u83mQTtuubde2a9uz7dn2bHu2Pduebc+2Z9uz7dmWtqVtaVvalralbWlb2pa2pW1lW9lWtpVtZVvZVraVbWVb2da2tW1tW9vWtrVtbVvb1ra1bWPb2Da2jW1j29g2to1tY9vYtratbWvb2ra2rW1r29q2tu237Y97/fvgj3v97zweXOfzIJ3lQTvHg2/bH/f674MI5/HgOp8H6SwP2jke2KYlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWlJaUlpSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJa0lrSWtJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMloyWjJaMlqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJaslqyWrJasl+7Xk/r6W3N/Xkvv7WnJ/X0vu72vJ/X0tub+vJff3teT+vpbc39eS+/tacn9fS+7va8n9fS25v68l9/e15P6+ltzf15L7+1pyf2Hbse3Ydmw7th3bjm3HtmPbse3Ydm27tl3brm3Xtmvbte3adm27tj3bnm3Ptmfbs+3Z9mx7tj3bnm1pW9qWtqVtaVvalralbWlb2la2lW1lW9lWtpVtZVvZVraVbW1b29a2tW1tW9vWtrVtbVvbNraNbWPb2Da2jW1j29g2to1ta9vatratbWvb2ra2rW1rm5aEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaElhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GlJaklqSWpJaklqSWpJaklqSWpJaklqSWpJaklqSWpJagn3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVyr5d7vdzr5V4v93q518u9Xu71cq+Xe73c6+VeL/d6udfLvV7u9XKvl3u93OvlXi/3ernXy71e7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71ca+Pe33c6+NeH/f6uNfHvT7u9XGvj3t93OvjXh/3+rjXx70+7vVxr497fdzr414f9/q418e9Pu71/XGv7/f3DOf/v/bu3/M6nwfpLA/aOR7sd/7Tkn8f/NOS/87jwXU+D9JZHrRzPNjvHNvGtrFtbBvbxraxbWwb28a2tW1tW9vWtrVtbVvb1ra1bb9tf9zr3wd/3Ot/5/HgOp8H6SwP2jkefNv+uNd/H0Q4jwfX+TxIZ3nQzvHAtmPbse3Ydmw7th3bjm3HtmPbse3adm27tl3brm3Xtmvbte3adm17tj3bnm3Ptmfbs+3Z9mx7tj3b0ra0LW1L29K2tC1tS9vStrRNS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVkv2a0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbk72tJ/r6W5O9rSf6+luTva0n+vpbkL2w7th3bjm3HtmPbse3Ydmw7th3brm3Xtmvbte3adm27tl3brm3Xtmfbs+3Z9mx7tj3bnm3Ptmfbsy1tS9vStrQtbUvb0ra0LW1L28q2sq1sK9vKtrKtbCvbyrayrW1r29q2tq1ta9vatratbWvbxraxbWwb28a2sW1sG9vGtrFtbVvb1ra1bW1b29a2tW1t05LQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS3hXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfkXpN7Te41udfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNfiXot7Le61uNf6617377nf+U9L8vw9w3k8uM7nQTrLg3aOB/udf1ry98Gflvx7Hg+u83mQzvKgnbYd265t17Zr27Xt2nZtu7Zd265t17Zn27Pt2fZse7Y9255tz7Zn27MtbUvb0ra0LW1L29K2tC1tS9vKtrKtbCvbyrayrWwr28q2sq1ta9vatratbWvb2ra2rW1r28a2sW1sG9vGtrFtbBvbxraxbW1b29a2tW1tW9vWtrVtbdtv21/3un/PcB4PrvN5kM7yoJ3jwbettaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLWktaS1pLVktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS0ZLRktGS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS1ZLVktWS/lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/vpb072tJ/76W9O9rSf++lvTva0n/wrZj27Ht2HZsO7Yd245tx7Zj27Ht2nZtu7Zd265t17Zr27Xt2nZte7Y9255tz7Zn27Pt2fZse7Y929K2tC1tS9vStrQtbUvb0ra0rWwr28q2sq1sK9vKtrKtbCvb2ra2rW1r29q2tq1ta9vatrZtbBvbxraxbWwb28a2sW1sG9vWtrVtbVvb1ra1bW1b29Y2LQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktCS0JLQktOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC25WnK15GrJ1ZKrJVdLrpZcLblacrXkasnVkqslV0uullwtuVpyteRqydWSqyVXS66WXC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05LUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktKS0pLSktKS0pLSktKS0hLutbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6be23utbnX5l6bex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6Hex3udbjX4V6H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5GrJ1ZKrJVdLrpZcLblacrXkasnVkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwteVrytORpydOSpyVPS56WPC15WvK05GnJ05KnJU9LnpY8LXla8rTkacnTkqclT0ueljwtSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS1JLUktSS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSktKS0pLSkt4V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udbnX5V6Xe13udT/3+v8/wv+15J8znMeD63wepLM8aOd4sN/5X0v+OcN5PLjO50E6y4N2jge2HduObce2Y9ux7dh2bDu2HduObde2a9u17dp2bbu2Xduubde2a9uz7dn2bHu2Pduebc+2Z9uz7dmWtqVtaVvalralbWlb2pa2pW1lW9lWtpVtZVvZVraVbWVb2da2tW1tW9vWtrVtbVvb1ra1bWPb2Da2jW1j29g2to1tY9vYtratbWvb2ra2rW1r29q2tmlJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaEloSWhJaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYcLTlacrTkaMnRkqMlR0uOlhwtOVpytORoydGSoyVHS46WHC05WnK05GjJ0ZKjJUdLjpYc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19C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r6F5D9xq619C9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3WvqXlP3mrrX1L2m7jV1r6l7Td1r6l5T95q619S9pu41da+pe03da+peU/eautfUvabuNXWvqXtN3Wvq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llyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZsmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYYnutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld1r6V5L91q619K9lu61dK+ley3da+leS/dautfSvZbutXSvpXst3WvpXkv3WrrX0r2W7rV0r6V7Ld3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r0b0e3evRvR7d69G9Ht3r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r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/d6da9X93p1r1f3enWvV/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b99q619a9tu61da+te23da+teW/fautfWvbbutXWvrXtt3WvrXlv32rrX1r227rV1r617bd1r615b9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3OrrX0b2O7nV0r6N7Hd3r6F5H9zq619G9ju51dK+jex3d6+heR/c6utfRvY7udXSvo3sd3evoXkf3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6dK9P9/p0r0/3+nSvT/f6/nSv7/59Xs//X3vv73M8nw++3+d/lvzvg/8s+fdMH5Tn8cH1bB+M5/PB9+/5p3v9+8Gf7vXfM31QnscH17N9MJ7PB7+3/ele//dBhGf6oDyPD65n+2A8nw/clm5Lt6Xb0m3ptnRbui3dlm5Lt5Xbym3ltnJbua3cVm4rt5Xbym3Hbcdtx23Hbcdtx23Hbcdtx23Hbddt123Xbddt123Xbddt123Xbddt7bZ2W7ut3dZua7e129pt7bZ227ht3DZuG7eN28Zt47Zx27ht3Pbc9tz23PbcxpKPJR9LPpZ8LPlY8rHkY8nHko8lH0s+lnws+VjyseT7teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+/m15Pv5teT7+bXk+wm3pdvSbem2dFu6Ld2Wbku3pdvSbeW2clu5rdxWbiu3ldvKbeW2cttx23Hbcdtx23Hbcdtx23Hbcdtx23Xbddt123Xbddt123Xbddt123Vbu63d1m5rt7Xb2m3ttnZbu63dNm4bt43bxm3jtnHbuG3cNm4btz23Pbc9tz23Pbc9tz23Pbc9tz23fW773Pa57XPb57bPbZ/bPrd9bmNJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJlgRLgiXBkmBJsCRYEiwJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsiRZkixJliRLkiXJkmRJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhRLiiXFkmJJsaRYUiwplhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmSbOkWdIsaZY0S5olzZJmybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZYMS4Ylw5JhybBkWDIsGZY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJboXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/XSvn+71071+utdP9/rpXj/d66d7/X671///F+efJf89wzN9UJ7HB9ezfTCezwff7/OfJf89wzN9UJ7HB9ezfTCezwduS7el29Jt6bZ0W7ot3ZZuS7el28pt5bZyW7mt3FZuK7eV28pt5bbjtuO247bjtuO247bjtuO247bjtuu267brtuu267brtuu267brtuu2dlu7rd3Wbmu3tdvabe22dlu7bdw2bhu3jdvGbeO2cdu4bdw2bntue257bntue257bntue257bntu+9z2ue1z2+e2z22f2z63fW773MaSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLAmWBEuCJcGSYEmwJFgSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSZEmyJFmSLEmWJEuSJcmSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLCmWFEuKJcWSYkmxpFhSLDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksOSw5LDksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSy5LLksuSxpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmZJs6RZ0ixpljRLmiXNkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMiwZlgxLhiXDkmHJsGRYMix5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LHkseSx5LPlY8rHkY8nHko8lH0s+lnws+VjyseRjyceSjyUfSz6WfCz5WPKx5GPJx5KPJR9LPpZ8LPlY8rHkY8nHkj/d69d/n9/v8z9L/j3DMz3L83hez/YcT2tl7Vg71o61Y+1YO9aOtWPtWDvWrrVr7Vq71q61a+1au9autWutrbW1ttbW2lpba2ttra21tbE21sbaWBtrY22sjbWxNtaetWftWXvWnrVn7Vl71p61Z+2z9ln7rH3WPmuftc/aZ+2z9v1biz/d679neKZneR7P69me4/k8rYW1sBbWwlpYC2thLayFtbCW1tJaWktraS2tpbW0ltbSWlkra2WtrJW1slbWylpZK2vH2rF2rB1rx9qxdqwda8faryXxc61da9fatXatXWvX2rV2rV1rba2ttbW21tbaWltra22trY21sTbWxtpYG2tjbayNtbH2rD1rz9qz9qw9a8/as/asPWuftc/aZ+2z9ln7rH3WPmufNZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbAkWBIsCZYES4IlwZJgSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYkS5IlyZJkSbIkWZIsSZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiSbGkWFIsKZYUS4olxZJiyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJYclhyWHJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZcllyWXJZUmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWNEuaJc2SZkmzpFnSLGmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcmwZFgyLBmWDEuGJcOSYcljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyWPJY8ljyceSjyUfSz6WfCz5WPKx5GPJx5KPJR9LPpZ8LPlY8rHkY8nHko8lH0s+lnws+VjyseRjyceSjyUfSz6W6F5D9xq619C9hu41dK+hew3da+heQ/cautfQvYbuNXSvoXsN3WvoXkP3GrrX0L2G7jV0r6F7Dd1r/Ole45u/71rvs953vXu9Z73fen/e/5ny+471Xru9dnvt9trttdtrt9dur91Zu7N2Z+3O2p21O2t31u6s3Vm7s3bf2n1r963dt3bf2n1r963dt3bf2n1r91u739r91u63dr+1+63db+1+a/dbu9/vbv7pZH/fsd653rXeZ73vevd6z3q/9V67sXZj7cbajbUbazfWbqzdWLuxdmPt5trNtZtrN9durt1cu7l2c+3m2s21W2u31m6t3Vq7tXZr7dbarbVba7fW7lm7Z+2etXvW7lm7Z+2etXvW7lm7Z+3etXvX7l27d+3etXvX7l27d+3etXvXbq/dXru9dnvt9trttdtrt9dur91eu7N2Z+3O2p21O2t31u6s3Vm7s3Zn7b61+9buW7tv7b61+9buW7tv7b61+9but3a/tfut3W/tfmv3W7vf2v3W7rd2l1exvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5dZZXZ3l1lldneXWWV2d5dZZXZ3l1lld/Aub//4H25/2fV7/vWO/8791/3/+/+/8/sv6+z3rf9e71nvV+6/15/+fV7zvWO9d77ebazbWbazfXbq7dXLu1dmvt1tqttVtrt9Zurd1au7V2a+2etXvW7lm7Z+2etXvW7lm7Z+2etXvW7l27d+3etXvX7l27d+3etXvX7l27d+322u2122u3126v3V67vXZ77fba7bU7a3fW7qzdWbuzdmftztqdtTtrd9buW7tv7b61+9buW7tv7b61+9buW7tv7X5r91u739r91u63dr+1+63db+1+a/ez+6eN/n3Heud613qf9b7r3es96/3We+3G2o21G2t3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d5dZdXd3l1l1d3eXWXV3d51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9mefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1lldvefWWV2959ZZXb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPp4VT+8qh9e1Q+v6odX9cOr+uFV/fCqfnhVP7yqn5+1G2s31m6s3Vi7sXZj7cbajbUbazfWbq7dXLu5dnPt5trNtZtrN9durt1cu7V2a+3W2q21W2u31m6t3Vq7tXZr7Z61e9buWbtn7Z61e9buWbtn7Z61e9buXbt37d61e9fuXbt37d61e9fuXbt37fba7bXba7fXbq/dXru9dnvt9trttTtrd9burN1Zu7N2Z+3O2p21O2t31u5bu2/tvrX71u5bu2/tvrX71u5bu2/tfmv3W7vf2v3W7rd2v7X7rd1v7X5rd3kVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV2d5dZZXZ3l1lldneXWWV2d5dZZXZ3l1lldneXWWV2d5tfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xttfr2Wn17rb69Vt9eq2+v1bfX6ttr9e21+vZafXutvr1W316rb6/Vt9fq22v17bX69lp9e62+vVbfXqtvr9W31+rba/Xt9bdvz5+/71zvWu//dvP+fd/17vWe9X7r/Xn/8erfO9b7z+77+671Put917vXe9b7rffn/cerf+9Y77V71u5Zu2ftnrV71u5Zu2ft3rV71+5du3ft3rV71+5du3ft3rV7126v3V67vXZ77fba7bXba7fXbq/dXruzdmftztqdtTtrd9burN1Zu7N2Z+2+tfvW7lu7b+2+tfvW7lu7b+2+tfvW7rd2v7X7rd1v7X5r91u739r91u63dj+7f/v2f+9Y71zvWu+z3ne9e71nvd96r91Yu7F2Y+3G2o21G2s31m6s3Vi7sXZz7ebazbWbazfXbq7dXLu5dnPt5tqttVtrd3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dXHq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/PDq/Pzs3Zj7cbajbUbazfWbqzdWLuxdmPtxtrNtZtrN9durt1cu7l2c+3m2s21m2u31m6t3Vq7tXZr7dbarbVba7fWbq3ds3bP2j1r96zds3bP2j1r96zds3bP2r1r967du3bv2r1r967du3bv2r1r967dXru9dnvt9trttdtrt9dur91eu712Z+3O2p21O2t31u6s3Vm7s3Zn7c7afWv3rd23dt/afWv3rd23dt/afWv3rd1v7X5r91u739r91u63dr+1+63db+0ur2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5Vcurv317xd93rfdZ77vevd6z3m+9P+8/Xv17x3qv3bt279q9a/eu3bt279q9a7fXbq/dXru9dnvt9trttdtrt9dur91Zu7N2Z+3O2p21O2t31u6s3Vm7s3bf2n1r963dt3bf2n1r963dt3bf2n1r91u739r91u63dr+1+63db+1+a/dbu5/dv337v3esd653rfdZ77vevd6z3m+9126s3Vi7sXZj7cbajbUbazfWbqzdWLu5dnPt5trNtZtrN9durt1cu7l2c+3W2q21W2u31m6t3Vq7tXZr7dbarbV71u5Zu8urs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7zq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5VUvr3p51curWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8muXVLK9meTXLq1lezfJqllezvJrl1SyvZnk1y6tZXs3yapZXs7ya5dUsr2Z5NcurWV7N8mqWV7O8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vHrLq7e8esurt7x6y6u3vPrbt9f5+671Put917vXe9b7rffn/der/71jvddur91eu712e+322u2122t31u6s3Vm7s3Zn7c7anbU7a3fW7qzdt3bf2n1r963dt3bf2n1r963dt3bf2v3W7rd2v7X7rd1v7X5r91u739r91u5n92/f/u8d653rXet91vuud6/3rPdb77UbazfWbqzdWLuxdmPtxtqNtRtrN9Zurt1cu7l2c+3m2s21m2s3126u3Vy7tXZr7dbarbVba7fWbq3dWru1dmvtnrV71u5Zu2ftnrV71u5Zu2ftnrV71u5du3ftLq++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurb3n1La++5dW3vPqWV9/y6ltefcurj1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f3h1f352ftxtqNtRtrN9ZurN1Yu7F2Y+3G2o21m2s3126u3Vy7uXZz7ebazbWbazfXbq3dWru1dmvt1tqttVtrt9Zurd1au2ftnrV71u5Zu2ftnrV71u5Zu2ftnrV71+5du3ft3rV71+5du3ft3rV71+5du712e+322u2122u3126v3V67vXZ77c7anbU7a3fW7qzdWbuzdmftztqdtfvW7lu7b+2+tfvW7lu7b+2+tfvW7lu739r91u63dr+1+63db+1+a/dbu9/aXV7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLK9ieRXLq1hexfIqllexvIrlVSyvYnkVy6tYXsXyKpZXsbyK5VUsr2J5FcurWF7F8iqWV7G8iuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe5fIql1e5vMrlVS6vcnmVy6tcXuXyKpdXubzK5VUur3J5lcurXF7l8iqXV7m8yuVVLq9yeZXLq1xe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p5VcurWl7V8qqWV7W8quVVLa9qeVXLq1pe1fKqlle1vKrlVS2vanlVy6taXtXyqpZXtbyq5VUtr2p59b++ff6+a73Pet/17vWe9X7r/Xn/9ep/71jvtTtrd9burN1Zu7N2Z+3O2n1r963dt3bf2n1r963dt3bf2n1r963db+1+a/dbu9/a/dbut3a/tfut3W/tfnb/17f/7x3rnetd633W+653r/es91vvtRtrN9ZurN1Yu7F2Y+3G2o21G2s31m6u3Vy7uXZz7ebazbWbazfXbq7dXLu1dmvt1tqttVtrt9Zurd1au7V2a+2etXvW7lm7Z+2etXvW7lm7Z+2etXvW7l27d+3etXvX7l27d+3etXvX7l27d+322u21u7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6uzvDrLq7O8Osurs7w6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usuru7y6y6u7vLrLq7u8usurXl718qqXV7286uVVL696edXLq15e9fKql1e9vOrlVS+vennVy6teXvXyqpdXvbzq5dX/NWkHK7dsu3mG7yXtNKakMSSN3EswtuMEg7HNiR0Iwfce7/2vdebT+4oqeHtPo1DjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41Xj1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLVz337+fzsYh/2ZTd72Mt+3/2nV793sOku3aW7dJfu0l26S/fRfXQf3Uf30X10H91H99F93+7PffvvHexkF/uwL7vZw1423aAbdINu0A26QTfoBt2gG3STbtJNukk36SbdpJt0k27SLbpFt+gW3aJbdItu0S26RffQPXQP3UP30D10D91D99A9dC/dS/fSvXQv3Uv30r10L91Lt+k23abbdJtu0226TbfpNt2hO3Tx6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6v39ao/X6/68/WqP1+v+vP1qj9fr/rz9ao/X6/68/WqP1+v+vOhG3SDbtANukE36AbdoBt0g27STbpJN+km3aSbdJNu0k26RbfoFt2iW3SLbtEtukW36B66h+6he+geuofuoXvoHrqH7qV76V66l+6le+leupfupXvpNt2m23SbbtNtuk236Tbdpjt0h+7QHbpDd+gO3aE7dIfu0l26S3fpLt2lu3SX7tJduo/uo/voPrqP7qP76D66jy5eBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41Xg1e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8eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8WrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavHq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPr37u27t+9rCX/b77x6tfO9jJLvZhXzbdQ/fQPXQv3Uv30r10L91L99K9dC/dS7fpNt2m23SbbtNtuk236TbdoTt0h+7QHbpDd+gO3aE7dJfu0l26S3fpLt2lu3SX7tJ9dB/dR/fRfXQf3Uf30X1031+77+e+/fcOdrKLfdiX3exhL5tu0A26QTfoBt2gG3SDbtANukk36SbdpJt0k27STbpJN+kW3aJbdItu0S26RbfoFt2ie+geuofuoXvoHrqH7qF76B66l+6le+leupfupXvpXrqX7qXbdJtu0226TbfpNt2m23Sb7tAdukN36A7doTt0h+7QHbpLd+ku3aW7dJfu0l26S3fpPrqP7qP76D66j+6j++g+ungVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dX3Lc/7tsf9+2P+/bHffvjvv1x3/64b3/ctz/u2x/37Y/79sd9++O+/XHf/rhvf9y3P+7bH/ftj/v2x337+3Xf3j972e+7f7z6tYOd7GIf9mU3m27TbbpDd+gO3aE7dIfu0B26Q3foLt2lu3SX7tJdukt36S7dpfvoPrqP7qP76D66j+6j++i+393//Nv++bCDnexiH/ZlN3vYy6YbdINu0A26QTfoBt2gG3SDbtJNukk36SbdpJt0k27STbpFt+gW3aJbdItu0S26RbfoHrqH7qF76B66h+6he+geuofupXvpXrqX7qV76V66l+6le+k23abbdJtu0226TbfpNt2mO3SH7tAdukN36A7doTt0h+7SXbpLd+ku3aW7dJfu0l26j+6j++g+uo/uo/voPrqPLl4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6ePXrvn1/9h/d+fzsP7pzf/b77j+9+r2DnexiH/ZlN3vYdIfu0l26S3fpLt2lu3SX7tJduo/uo/voPrqP7qP76D66j+77dn/u23/vYCe72Id92c0e9rLpBt2gG3SDbtANukE36AbdoJt0k27STbpJN+km3aSbdJNu0S26RbfoFt2iW3SLbtEtuofuoXvoHrqH7qF76B66h+6he+leupfupXvpXrqX7qV76V66TbfpNt2m23SbbtNtunh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXbxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8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qvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8arxqvGq8WrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavBq8GrwavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavFq8WrxavHq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dX7+tVfb5e1efrVX2+XtXn61V9vl7V5+tVfb5e1efrVX2+XtXnQzfoBt2gG3SDbtANukE36AbdpPvjVf/sZBf7sC+72cNe9vvuH69+bbpFt+gW3aJbdItu0S26h+6he+geuofuoXvoHrqH7qF76V66l+6le+leupfupXvpXrpNt+k23abbdJtu0226TbfpDt2hO3SH7tAdukN36A7dobt0l+7SXbpLd+ku3aW7dJfuo/voPrqP7qP76D66j+6j+77dX/ftv3awk13sw77sZg972XSDbtANukE36AbdoBt0g27QTbp4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq1/37fuz/+je87P/6N752Yd92c0e9rLfd//p1e8d7GTTPXQP3UP30D10D91L99K9dC/dS/fSvXQv3Uv30m26TbfpNt2m23SbbtNtuk136A7doTt0h+7QHbpDd+gO3aW7dJfu0l26S3fpLt2lu3Qf3Uf30X10H91H99F9dB/d9+3+3Lf/3sFOdrEP+7KbPexl0w26QTfoBt2gG3SDbtANukE36SbdpJt0k27STbpJN+km3aJbdIsuXjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41Xg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDqfb06n69X5/P16ny+Xp3P16vz+Xp1Pl+vzufr1fl8vTqfr1fn86EbdINu0A26QTfoBt2gG3SDbtJNukk36SbdpJt0k27STbpFt+gW3aJbdItu0S26RbfoHrqH7qH7p1f9+dmHfdnNHvay33f/6dXvHexk0710L91L99K9dC/dptt0m27TbbpNt+k23abbdIfu0B26Q3foDt2hO3SH7tBdukt36S7dpbt0l+7SXbpL99F9dB/dR/fRfXQf3Uf30X3f7s99++8d7GQX+7Avu9nDXjbdoBt0g27QDbpBN+gG3aAbdJNu0k26STfpJt2km3STbtItukW36Bbdolt0i27RLbpF99A9dA9dvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6ePVz3971sw/7sps97GW/7/7x6tcOdrLpNt2m23SbbtNtukN36A7doTt0h+7QHbpDd+gu3aW7dJfu0l26S3fpLt2l++g+uo/uo/voPrqP7qP76L5v9+e+/fcOdrKLfdiX3exhL5tu0A26QTfoBt2gG3SDbtANukk36SbdpJt0k27STbpJN+kW3aJbdItu0S26RbfoFt2ie+geuofuoXvoHrqH7qF76B66l+6le+niVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVePV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPr97Xq/v5enU/X6/u5+vV/Xy9up+vV/fz9ep+vl7dz9er+/l6dT8fukE36AbdoBt0g27QDbpBN+gm3aSbdJNu0k26STfpJt2kW3SLbtEtukW36Bbdolt0i+6he+geuofuoXvoHrqH7qF76F66l+6le+leupfupXvpXrqXbtNtuk236Tbdptt0m27TbbpDd+gO3aE7dIfu0B26Q3foLt2lu3SX7tJdukt36S7dpfvoPrqP7qP76D66j+6j++jiVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4FXgVeBV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXiVeJV4lXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXhVeFV4VXh1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxSvu2y/37Zf79st9++W+/XLffrlvv9y3X+7bL/ftl/v2y3375b79ct9+uW+/3Ldf7tsv9+2X+/bLffvlvv3+um/vn33ZzR72st93/3j1awc72cWmu3SX7tJdukv30X10H91H99F9dB/dR/fRfd/ur/v2XzvYyS72YV92s4e9bLpBN+gG3aAbdINu0A26QTfoJt2km3STbtJNukk36SbdpFt0i27RLbpFt+gW3aJbdIvuoXvoHrqH7qF76B66h+6he+heupfupXvpXrqX7qV76V66l27TbbpNt+k23abbdJtu0226Q3foDt2hi1eNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV41XjVeNV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXg1eDV4NXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1eLV4tXi1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6ePXw6uHVw6uHVw+vHl49vHp49fDq4dXDq4dXD68eXj28enj18Orh1cOrh1cPrx5ePbx6X6/68/WqP1+v+vP1qj9fr/rz9ao/X6/68/WqP1+v+vP1qj8fukE36AbdoBt0g27QDbpBN+gm3aSbdJNu0k26STfpJt2kW3SLbtEtukW36Bbdolt0i+6he+geuofuoXvoHrqH7qF76F66l+6le+leupfupXvpXrqXbtNtuk236Tbdptt0m27TbbpDd+gO3aE7dIfu0B26Q3foLt2lu3R/vNqf/Ud3Pj/7j+7cn93sYS/7ffefXv3ewU52sQ+b7qP76D6679v9uW//vYOd7GIf9mU3e9jLpht0g27QDbpBN+gG3aAbdINu0k26STfpJt2km3STbtJNukW36Bbdolt0i27RLbpFt+geuofuoXvoHrqH7qF76B66h+6le+leupfupXvpXrqX7qV76Tbdptt0m27TbbpNt+k23aY7dIfu0B26Q3foDt2hO3SH7tJdukt36S5dvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrwKvAq8CrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvEq8SrxKvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8KrwqvCq8Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGrg1cHrw5eHbw6eHXw6uDVwauDVwevDl4dvDp4dfDq4NXBq4NXB68OXh28Onh18Org1cGri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1cWri1cXry5eXby6eHXx6uLVxauLVxevLl5dvLp4dfHq4tXFq4tXF68uXl28unh18eri1c99+8bP/rM7P/uP7tbPXvaf3ffH/rlv3/sf//W//J+//cs//u3f/dM//O//8t/+338+/s9//+e//7d//Jd//vX4b//3X3+/+bu//OM//dM//q+/+de//Mvf/8P/+Pe//MPf/NO//P2f7/7jv//H/wc=", - "file_map": { - "18": { - "source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This slice will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\n }\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b: [u1; 32] = exponent.to_le_bits();\n\n for i in 1..33 {\n r *= r;\n r = (b[32 - i] as Field) * (r * self) + (1 - b[32 - i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This slice will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting slice will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n }\n}\n\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(f\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(f\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(f\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n", - "path": "std/field/mod.nr" - }, - "19": { - "source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n // TODO(https://github.com/noir-lang/noir/issues/5672): Add back assert_constant on starting_index\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Same as from_field but:\n// does not assert the limbs are 128 bits\n// does not assert the decomposition does not overflow the EmbeddedCurveScalar\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal(input: [Field; N]) -> [Field; N] {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault;\n\nimpl BuildHasher for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl Default for BuildHasherDefault\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for [T]\nwhere\n T: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n", - "path": "std/hash/mod.nr" - }, - "50": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse lib::configs::default::threshold::{\n L, N, USER_DATA_ENCRYPTION_BIT_CT, USER_DATA_ENCRYPTION_BIT_E0, USER_DATA_ENCRYPTION_BIT_E1,\n USER_DATA_ENCRYPTION_BIT_K, USER_DATA_ENCRYPTION_BIT_P1, USER_DATA_ENCRYPTION_BIT_P2,\n USER_DATA_ENCRYPTION_BIT_PK, USER_DATA_ENCRYPTION_BIT_R1, USER_DATA_ENCRYPTION_BIT_R2,\n USER_DATA_ENCRYPTION_BIT_U, USER_DATA_ENCRYPTION_CONFIGS,\n};\nuse lib::core::threshold::user_data_encryption::UserDataEncryption;\nuse lib::math::polynomial::Polynomial;\n\nfn main(\n pk_commitment: pub Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e1: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n k1: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n) {\n let user_data_encryption: UserDataEncryption = UserDataEncryption::new(\n USER_DATA_ENCRYPTION_CONFIGS,\n pk_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n k1,\n r1is,\n r2is,\n p1is,\n p2is,\n );\n let is_user_data_encryption_valid = user_data_encryption.execute();\n assert(is_user_data_encryption_valid);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/bin/threshold/user_data_encryption/src/main.nr" - }, - "72": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::commitments::compute_user_data_encryption_challenge_commitment;\nuse crate::math::helpers::flatten;\nuse crate::math::polynomial::Polynomial;\n\n/// Cryptographic parameters for Greco circuit.\npub struct Configs {\n /// CRT moduli: [q_0, q_1, ..., q_{L-1}]\n pub qis: [Field; L],\n /// Scaling factors for each basis: [k0_0, k0_1, ..., k0_{L-1}]\n pub k0is: [Field; L],\n /// Bounds for public key polynomials for each CRT basis\n pub pk_bounds: [Field; L],\n /// Bounds for error polynomials (e0)\n pub e0_bound: Field,\n /// Bounds for error polynomials (e1)\n pub e1_bound: Field,\n /// Bound for secret polynomial u (ternary distribution)\n pub u_bound: Field,\n /// Lower bounds for r1 polynomials (modulus switching quotients)\n pub r1_low_bounds: [Field; L],\n /// Upper bounds for r1 polynomials (modulus switching quotients)\n pub r1_up_bounds: [Field; L],\n /// Bounds for r2 polynomials (cyclotomic reduction quotients)\n pub r2_bounds: [Field; L],\n /// Bounds for p1 polynomials (modulus switching quotients)\n pub p1_bounds: [Field; L],\n /// Bounds for p2 polynomials (cyclotomic reduction quotients)\n pub p2_bounds: [Field; L],\n /// Lower bound for k1 polynomial (scaled message)\n pub k1_low_bound: Field,\n /// Upper bound for k1 polynomial (scaled message)\n pub k1_up_bound: Field,\n}\n\nimpl Configs {\n pub fn new(\n qis: [Field; L],\n k0is: [Field; L],\n pk_bounds: [Field; L],\n e0_bound: Field,\n e1_bound: Field,\n u_bound: Field,\n r1_low_bounds: [Field; L],\n r1_up_bounds: [Field; L],\n r2_bounds: [Field; L],\n p1_bounds: [Field; L],\n p2_bounds: [Field; L],\n k1_low_bound: Field,\n k1_up_bound: Field,\n ) -> Self {\n Configs {\n qis,\n k0is,\n pk_bounds,\n e0_bound,\n e1_bound,\n u_bound,\n r1_low_bounds,\n r1_up_bounds,\n r2_bounds,\n p1_bounds,\n p2_bounds,\n k1_low_bound,\n k1_up_bound,\n }\n }\n}\n\n/// Correct User Data Encryption Circuit under Threshold public key\n///\n/// Verifies:\n/// 1. Range checks on all polynomial coefficients\n/// 2. Correct encryption: ct0i = pk0i * u + e0 + k1 * k0i + r1i * qi + r2i * cyclo\n/// and ct1i = pk1i * u + e1 + p1i * qi + p2i * cyclo\n///\n/// DISCLAIMER: Ported from Halo2 circuit by Greco paper authors @ PSE.\n/// Halo2 implementation: https://github.com/privacy-scaling-explorations/greco\npub struct UserDataEncryption {\n configs: Configs,\n pk_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n k1: Polynomial,\n r1is: [Polynomial<(2 * N) - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<(2 * N) - 1>; L],\n p2is: [Polynomial; L],\n}\n\nimpl UserDataEncryption {\n pub fn new(\n configs: Configs,\n pk_commitment: Field,\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n ct0is: [Polynomial; L],\n ct1is: [Polynomial; L],\n u: Polynomial,\n e0: Polynomial,\n e0is: [Polynomial; L],\n e0_quotients: [Polynomial; L],\n e1: Polynomial,\n k1: Polynomial,\n r1is: [Polynomial<2 * N - 1>; L],\n r2is: [Polynomial; L],\n p1is: [Polynomial<2 * N - 1>; L],\n p2is: [Polynomial; L],\n ) -> UserDataEncryption {\n UserDataEncryption {\n configs,\n pk_commitment,\n pk0is,\n pk1is,\n ct0is,\n ct1is,\n u,\n e0,\n e0is,\n e0_quotients,\n e1,\n k1,\n r1is,\n r2is,\n p1is,\n p2is,\n }\n }\n\n /// Flattens all polynomials coefficients into a single array for challenge generation.\n ///\n /// This function serializes all polynomial coefficients into a 1D array to enable\n /// the generation of random challenge values using the Fiat-Shamir transform.\n /// The coefficients are arranged in a specific order to ensure deterministic\n /// challenge generation.\n ///\n /// # Returns\n /// An array containing all polynomials coefficients in flattened form\n fn gammas_payload(self) -> Vec {\n let mut inputs = Vec::new();\n\n inputs.push(self.pk_commitment);\n\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct0is);\n inputs = flatten::<_, _, BIT_CT>(inputs, self.ct1is);\n\n // Flatten common polynomials (used across all CRT bases)\n inputs = flatten::<_, _, BIT_E0>(inputs, [self.e0]);\n inputs = flatten::<_, _, BIT_E1>(inputs, [self.e1]);\n inputs = flatten::<_, _, BIT_U>(inputs, [self.u]);\n inputs = flatten::<_, _, BIT_K>(inputs, [self.k1]);\n\n // Flatten randomness polynomials for each CRT basis\n inputs = flatten::<_, _, BIT_R1>(inputs, self.r1is);\n inputs = flatten::<_, _, BIT_R2>(inputs, self.r2is);\n inputs = flatten::<_, _, BIT_P1>(inputs, self.p1is);\n inputs = flatten::<_, _, BIT_P2>(inputs, self.p2is);\n\n inputs\n }\n\n /// Performs coefficient-wise CRT consistency check for e0 polynomial.\n ///\n /// Verifies that for each CRT basis i and each coefficient j:\n /// e0.coefficients[j] = e0is[i].coefficients[j] + e0_quotients[i].coefficients[j] * qi\n ///\n /// This ensures that e0 == e0is[i] (mod qi) for all coefficients, which is\n /// much more secure than checking equality at a single evaluation point.\n ///\n /// # Security\n /// Coefficient-wise checking prevents attacks where a malicious prover could\n /// construct different polynomials that happen to evaluate to the same value\n /// at a single challenge point.\n fn check_e0_crt_consistency(self) {\n for i in 0..L {\n // Check each coefficient satisfies the CRT relationship\n for j in 0..N {\n // Verify: e0_coeff = e0i_coeff + quotient_coeff * qi\n assert(\n self.e0.coefficients[j]\n == self.e0is[i].coefficients[j]\n + self.e0_quotients[i].coefficients[j] * self.configs.qis[i],\n );\n }\n }\n }\n\n /// Verifies the correct encryption constraints for the Greco circuit.\n ///\n /// This function implements the core zero-knowledge proof by checking:\n /// 1. Binary constraint on k1 polynomial\n /// 2. Range constraints on all polynomials coefficients\n /// 3. CRT consistency for e0 polynomial\n /// 4. Correct encryption equations\n ///\n /// The proof uses the Schwartz-Zippel lemma: if polynomial equations hold\n /// when evaluated at random points, then the polynomials are identical with\n /// high probability.\n ///\n /// # Encryption Equations\n /// For each CRT basis i:\n /// * ct0i(gamma) = pk0i(gamma) * u(gamma) + e0(gamma) + k1(gamma) * k0i + r1i(gamma) * qi + r2i(gamma) * cyclo\n /// * ct1i(gamma) = pk1i(gamma) * u(gamma) + e1(gamma) + p1i(gamma) * qi + p2i(gamma) * cyclo\n ///\n /// Where:\n /// * cyclo(gamma) = gamma^N + 1 (cyclotomic polynomial)\n /// * qi, k0i are constants from the cryptographic parameters\n /// * r1i, r2i, p1i, p2i are randomness polynomials for each i-th CRT basis.\n ///\n /// # Returns\n /// True if the encryption constraints are satisfied, false otherwise.\n pub fn execute(self) -> bool {\n // Step 1: Perform range checks on all polynomial coefficients\n self.check_range_bounds();\n\n // Step 2: Check CRT consistency for e0 polynomial\n self.check_e0_crt_consistency();\n\n // Step 3: Generate Fiat-Shamir challenges\n let gammas = self.generate_challenge();\n\n // Step 4: Verify encryption constraints using challenges\n self.verify_evaluations(gammas)\n }\n\n /// Performs range checks on all polynomial coefficients.\n ///\n /// Checks that all polynomial coefficients are within their expected bounds\n /// as specified in the `configs`. This prevents attacks where coefficients\n /// are outside the valid range, which could break the security properties\n /// of the encryption scheme.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// its expected bounds. The bounds are defined per polynomial type in the `configs`.\n fn check_range_bounds(self) {\n self.u.range_check_2bounds::(self.configs.u_bound, self.configs.u_bound);\n self.e0.range_check_2bounds::(self.configs.e0_bound, self.configs.e0_bound);\n self.e1.range_check_2bounds::(self.configs.e1_bound, self.configs.e1_bound);\n self.k1.range_check_2bounds::(self.configs.k1_up_bound, self.configs.k1_low_bound);\n\n for i in 0..L {\n self.pk0is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n self.pk1is[i].range_check_2bounds::(\n self.configs.pk_bounds[i],\n self.configs.pk_bounds[i],\n );\n\n self.r1is[i].range_check_2bounds::(\n self.configs.r1_up_bounds[i],\n self.configs.r1_low_bounds[i],\n );\n self.r2is[i].range_check_2bounds::(\n self.configs.r2_bounds[i],\n self.configs.r2_bounds[i],\n );\n\n self.p1is[i].range_check_2bounds::(\n self.configs.p1_bounds[i],\n self.configs.p1_bounds[i],\n );\n self.p2is[i].range_check_2bounds::(\n self.configs.p2_bounds[i],\n self.configs.p2_bounds[i],\n );\n }\n }\n\n /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge.\n ///\n /// This function implements the Fiat-Shamir transform for the Greco circuit:\n /// 1. First, it computes and verifies the public key commitment by absorbing\n /// all public key polynomials and squeezing a single commitment value.\n /// 2. Then, it generates challenge values by absorbing all witness values\n /// (ciphertexts, errors, randomness) and squeezing 2L challenge values.\n ///\n /// The sponge absorbs all witness values and squeezes out deterministic random\n /// field elements that will be used to evaluate polynomials for the Schwartz-Zippel lemma.\n ///\n /// # Returns\n /// Vector of challenge values [gamma_0, gamma_1, ..., gamma_{2L-1}] where:\n /// - gamma_0 is used as the primary evaluation point\n /// - gamma_1, ..., gamma_{L-1} are used for linear combination of ct0 constraints\n /// - gamma_L, ..., gamma_{2L-1} are used for linear combination of ct1 constraints\n fn generate_challenge(self) -> Vec {\n compute_user_data_encryption_challenge_commitment::(\n self.pk0is,\n self.pk1is,\n self.gammas_payload(),\n self.pk_commitment,\n )\n }\n\n /// Verifies encryption constraints using Fiat-Shamir challenges.\n ///\n /// For each CRT basis i, this function verifies that the encryption equations hold\n /// when evaluated at the challenge points. It uses the Schwartz-Zippel lemma:\n /// if polynomial equations hold when evaluated at random points, then the polynomials\n /// are identical with high probability.\n ///\n /// The verification combines all CRT bases using a linear combination with the\n /// challenge values to reduce the number of constraints while maintaining security.\n ///\n /// # Arguments\n /// * `gammas` - Vector of challenge values [gamma_0, gamma_1, ..., gamma_{2L-1}]\n /// generated by `generate_challenge()`\n ///\n /// # Returns\n /// `true` if all encryption constraints are satisfied, `false` otherwise.\n fn verify_evaluations(self, gammas: Vec) -> bool {\n let gamma = gammas.get(0);\n let cyclo_at_gamma = gamma.pow_32(N as Field) + 1;\n let u_at_gamma = self.u.eval(gamma);\n let e1_at_gamma = self.e1.eval(gamma);\n let k1_at_gamma = self.k1.eval(gamma);\n\n let mut sum = (0, 0);\n for i in 0..L {\n let pk0is_at_gamma = self.pk0is[i].eval(gamma);\n let r1i_at_gamma = self.r1is[i].eval(gamma);\n let r2i_at_gamma = self.r2is[i].eval(gamma);\n let e0is_at_gamma = self.e0is[i].eval(gamma);\n\n let pk0_u = (pk0is_at_gamma * u_at_gamma) + e0is_at_gamma;\n let mut ct0_rhs = pk0_u + (k1_at_gamma * self.configs.k0is[i]);\n ct0_rhs += r1i_at_gamma * self.configs.qis[i];\n ct0_rhs += r2i_at_gamma * cyclo_at_gamma;\n let ct0_lhs = self.ct0is[i].eval(gamma);\n let pk1is_at_gamma = self.pk1is[i].eval(gamma);\n let p1is_at_gamma = self.p1is[i].eval(gamma);\n let p2is_at_gamma = self.p2is[i].eval(gamma);\n let pk1_u = (pk1is_at_gamma * u_at_gamma) + e1_at_gamma;\n let mut ct1_rhs = pk1_u + p2is_at_gamma * cyclo_at_gamma;\n ct1_rhs += p1is_at_gamma * self.configs.qis[i];\n let ct1_lhs = self.ct1is[i].eval(gamma);\n let gamma_i = if i == 0 { 1 } else { gammas.get(i) };\n sum = (\n sum.0 + ct0_lhs * gamma_i + ct1_lhs * gammas.get(i + L),\n sum.1 + ct0_rhs * gamma_i + ct1_rhs * gammas.get(i + L),\n );\n }\n\n sum.0 == sum.1\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/core/threshold/user_data_encryption.nr" - }, - "74": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse crate::math::helpers::{compute_safe, flatten};\nuse crate::math::polynomial::Polynomial;\n\n/// DOMAIN SEPARATORS\n\n// Domain separator - \"PK\"\npub global DS_PK: [u8; 64] = [\n 0x50, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_GENERATION\"\npub global DS_PK_GENERATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_COMPUTATION\"\npub global DS_SHARE_COMPUTATION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x55, 0x54, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"SHARE_ENCRYPTION\"\npub global DS_SHARE_ENCRYPTION: [u8; 64] = [\n 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"PK_AGGREGATION\"\npub global DS_PK_AGGREGATION: [u8; 64] = [\n 0x50, 0x4b, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CIPHERTEXT\"\npub global DS_CIPHERTEXT: [u8; 64] = [\n 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"AGGREGATED_SHARES\"\npub global DS_AGGREGATED_SHARES: [u8; 64] = [\n 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45,\n 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"RECURSIVE_AGGREGATION\"\npub global DS_RECURSIVE_AGGREGATION: [u8; 64] = [\n 0x52, 0x45, 0x43, 0x55, 0x52, 0x53, 0x49, 0x56, 0x45, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47,\n 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_PK_GENERATION\"\npub global DS_CLG_PK_GENERATION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x50, 0x4b, 0x5f, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f,\n 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_ENCRYPTION\"\npub global DS_CLG_SHARE_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_USER_DATA_ENCRYPTION\"\npub global DS_CLG_USER_DATA_ENCRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x45, 0x4e,\n 0x43, 0x52, 0x59, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n// Domain separator - \"CLG_SHARE_DECRYPTION\"\npub global DS_CLG_SHARE_DECRYPTION: [u8; 64] = [\n 0x43, 0x4c, 0x47, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x5f, 0x44, 0x45, 0x43, 0x52, 0x59, 0x50,\n 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n];\n\n/// WRAPPERS\n\npub fn compute_commitments(\n payload: Vec,\n domain_separator: [u8; 64],\n io_pattern: [u32; 2],\n) -> Vec {\n compute_safe(domain_separator, payload, io_pattern)\n}\n\npub fn single_polynomial_payload(\n payload: Vec,\n input: Polynomial,\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, [input])\n}\n\npub fn multiple_polynomial_payload(\n payload: Vec,\n inputs: [Polynomial; L],\n) -> Vec {\n flatten::<_, _, BIT_POLY>(payload, inputs)\n}\n\n/// COMMITMENTS\n\npub fn compute_dkg_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_threshold_pk_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_GENERATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_share_computation_sk_commitment(\n sk: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), sk);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_computation_e_sm_commitment(\n e_sm: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), e_sm);\n compute_commitments(\n payload,\n DS_SHARE_COMPUTATION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_message(\n message: Polynomial,\n) -> Field {\n let mut payload = single_polynomial_payload::(Vec::new(), message);\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_share_encryption_commitment_from_shares(\n y: [[[Field; N_PARTIES + 1]; L]; N],\n party_idx: u32,\n mod_idx: u32,\n) -> Field {\n let mut payload = Vec::new();\n\n for coeff_idx in 0..N {\n payload.push(y[coeff_idx][mod_idx][party_idx + 1]);\n }\n\n // Include party_idx and mod_idx in the hash\n payload.push(party_idx as Field);\n payload.push(mod_idx as Field);\n\n compute_commitments(\n payload,\n DS_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_aggregated_shares_commitment(\n agg_shares: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), agg_shares);\n compute_commitments(\n payload,\n DS_AGGREGATED_SHARES,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_pk_aggregation_commitment(\n pk0: [Polynomial; L],\n pk1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), pk0);\n payload = multiple_polynomial_payload::(payload, pk1);\n\n compute_commitments(payload, DS_PK_AGGREGATION, [0x80000000 | payload.len(), 1]).get(0)\n}\n\npub fn compute_recursive_aggregation_commitment(payload: Vec) -> Field {\n compute_safe(\n DS_RECURSIVE_AGGREGATION,\n payload,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n\npub fn compute_ciphertext_commitment(\n ct0: [Polynomial; L],\n ct1: [Polynomial; L],\n) -> Field {\n let mut payload = multiple_polynomial_payload::(Vec::new(), ct0);\n payload = multiple_polynomial_payload::(payload, ct1);\n\n compute_commitments(payload, DS_CIPHERTEXT, [0x80000000 | payload.len(), 1]).get(0)\n}\n\n/// COMMITMENTS FOR CHALLENGES\n\npub fn compute_threshold_pk_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_PK_GENERATION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_share_encryption_challenge(payload: Vec) -> Vec {\n compute_commitments(\n payload,\n DS_CLG_SHARE_ENCRYPTION,\n [0x80000000 | payload.len(), 2 * L],\n )\n}\n\npub fn compute_user_data_encryption_challenge_commitment(\n pk0is: [Polynomial; L],\n pk1is: [Polynomial; L],\n gammas_payload: Vec,\n pk_commitment: Field,\n) -> Vec {\n assert(compute_pk_aggregation_commitment::(pk0is, pk1is) == pk_commitment);\n\n compute_commitments(\n gammas_payload,\n DS_CLG_USER_DATA_ENCRYPTION,\n [0x80000000 | gammas_payload.len(), 2 * L],\n )\n}\n\npub fn compute_threshold_share_decryption_challenge(payload: Vec) -> Field {\n compute_commitments(\n payload,\n DS_CLG_SHARE_DECRYPTION,\n [0x80000000 | payload.len(), 1],\n )\n .get(0)\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/commitments.nr" - }, - "75": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\n//! Helper functions for circuit construction and cryptographic operations.\nuse crate::math::polynomial::Polynomial;\nuse crate::math::safe::SafeSponge;\n\n/// Compute hex-aligned packing parameters for a given `BIT`.\n///\n/// # Purpose\n/// Returns `(nibble_bits, group)` for use by pack/flatten so layout stays consistent.\n/// - `nibble_bits`: ceil (`BIT`) to the next multiple of 4 (nibble alignment).\n/// - Examples: `BIT = 7 -> 8`, `BIT = 8 -> 8`, `BIT = 9 -> 12`, `BIT = 10 -> 12`, `BIT = 11 -> 12`,\n/// `BIT=16 -> 16`, `BIT = 17 -> 20`.\n/// - `group`: max number of encoded limbs that fit in one BN254 field element,\n/// when each limb uses an extra 4 bits (see below).\n///\n/// # Rationale\n/// - We align to nibbles so powers of two are hex-friendly and deterministic.\n/// - We reserve one extra nibble (4 bits) per stored value to lift signed\n/// coefficients into the non-negative range (e.g., store `v + 2^nibble_bits`),\n/// which implies a radix of `2^(nibble_bits + 4)`.\n///\n/// # Safety\n/// - Asserts `nibble_bits + 4 <= 254` to avoid mod-p wrap on BN254.\n/// - Ensures at least one limb fits: `group >= 1`.\nfn packing_layout() -> (u32, u32) {\n // Ceil BIT up to the next multiple of 4 (nibble alignment).\n let nibble_bits = ((BIT + 3) / 4) * 4;\n\n // Each stored limb uses an extra nibble because negative coefficients\n // will be shifted to positive, so radix = 2^(nibble_bits+4).\n assert(nibble_bits + 4 <= 254);\n\n // Maximum limbs that fit in one BN254 element without wrap.\n let group = 254 / (nibble_bits + 4);\n assert(group >= 1);\n (nibble_bits, group)\n}\n\n/// Flatten `L` polynomials into a single linear stream of packed `Field` carriers.\n///\n/// ## What this does\n/// - For each CRT limb `j` in `0..L`, it packs the coefficients of `poly[j]`\n/// with `pack::` and appends all resulting carriers to `inputs`.\n/// - The packing layout (nibble-aligned width and `group` size) is taken from\n/// `packing_layout::()` and must match what `pack` uses.\n///\n/// ## Determinism & order\n/// - Preserves a stable order: iterate `j = 0..L`, then for each `j` append\n/// carriers in ascending chunk index `i = 0..num_chunks`.\n/// - This ensures transcripts remain deterministic across runs.\n///\n/// ## Generics\n/// - `A`: polynomial degree (number of coefficients per polynomial).\n/// - `L`: number of CRT bases (polynomials).\n/// - `BIT`: per-coefficient bit bound used by the packing layout (compile-time).\n///\n/// ## Returns\n/// - The same `inputs` vector, extended with all carriers in deterministic order.\npub fn flatten(\n mut inputs: Vec,\n poly: [Polynomial; L],\n) -> Vec {\n for j in 0..L {\n // Pack its A coefficients into `num_chunks` carriers using the same BIT layout.\n let packed = pack::(poly[j].coefficients);\n\n // Append carriers in-order to `inputs` to keep a stable transcript layout.\n for i in 0..packed.len() {\n inputs.push(packed.get(i));\n }\n }\n\n // Return the extended input stream.\n inputs\n}\n\n/// Pack `A` values into a `Vec` of carriers using the shared hex-aligned layout.\n///\n/// ## What this does\n/// - Computes `(nibble_bits, group)` via `packing_layout::()`.\n/// - Encodes each value as a limb `digit = v + 2^nibble_bits` and concatenates\n/// limbs in base `radix = 2^(nibble_bits + 4)` (one extra nibble of headroom).\n/// - Packs up to `group` limbs per carrier (fits within BN254 254-bit capacity).\n/// - Pads the last, partial carrier with `digit = 2^nibble_bits` to keep a stable layout.\n///\n/// ## Determinism & order\n/// - Processes values in increasing index order and emits carriers in chunk order\n/// (`chunk = 0..num_chunks`). Padding is deterministic.\n///\n/// ## Generics\n/// - `A`: number of input values.\n/// - `BIT`: per-value bit bound; rounded up to `nibble_bits` by `packing_layout`.\n///\n/// ## Preconditions / Notes\n/// - Call with the raw coefficients whose magnitudes already satisfy the BIT bound\n/// (as enforced by the upstream range checks); `pack` performs the signed -> unsigned\n/// shift internally via `v + base`.\n/// - `group >= 1` is enforced by `packing_layout::()`.\n/// - Padding with `digit = 2^nibble_bits` encodes `zero limb` consistently.\n///\n/// ## Returns\n/// - A `Vec` where each element is a concatenation of up to `group` limbs,\n/// suitable for hashing or transcript I/O.\npub fn pack(values: [Field; A]) -> Vec {\n // Layout parameters: nibble-aligned width and limbs-per-carrier group size.\n let (nibble_bits, group) = packing_layout::();\n\n let base = 2.pow_32(nibble_bits as Field); // 2^nibble_bits\n let radix = 2.pow_32((nibble_bits + 4) as Field); // 2^(nibble_bits + 4)\n\n // Number of chunks to emit: ceil(A / group).\n let num_chunks = (A + group - 1) / group;\n let mut out = Vec::new();\n\n // Process in fixed-size chunks of `group` limbs.\n for chunk in 0..num_chunks {\n // How many real values go into this chunk.\n let remain = A - (chunk * group);\n let take = if remain < group { remain } else { group };\n\n // Build field element accumulator (big-endian concatenation in `radix`).\n let mut acc = 0;\n for i in 0..take {\n let v = values[chunk * group + i];\n acc = acc * radix + (v + base);\n }\n\n // Pad remaining limb slots with the canonical zero-limb `digit = base`.\n for _ in 0..(group - take) {\n acc = acc * radix + base;\n }\n\n out.push(acc);\n }\n out\n}\n\n/// Computes a cryptographic hash using the SAFE (Sponge API for Field Elements) protocol.\n///\n/// This is a convenience wrapper around the SAFE sponge API that handles the full\n/// lifecycle: initialization, absorption, squeezing, and finalization. It's designed\n/// for use in Fiat-Shamir challenge generation and commitment schemes within zero-knowledge circuits.\n///\n/// # Arguments\n/// * `domain_separator` - A 64-byte domain separator used to differentiate between\n/// different protocol instances and prevent cross-protocol attacks.\n/// * `inputs` - Vector of field elements to be absorbed into the sponge.\n/// * `io_pattern` - A 2-element array encoding the I/O pattern:\n/// - `io_pattern[0]`: Encoded ABSORB operation (MSB=1, lower 31 bits = length)\n/// - `io_pattern[1]`: Encoded SQUEEZE operation (MSB=0, lower 31 bits = length)\n///\n/// # Returns\n/// A vector of field elements squeezed from the sponge, with length determined by\n/// the SQUEEZE operation in the IO pattern.\npub fn compute_safe(\n domain_separator: [u8; 64],\n inputs: Vec,\n io_pattern: [u32; 2],\n) -> Vec {\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(inputs);\n let digests = sponge.squeeze();\n sponge.finish();\n\n digests\n}\n\n#[test]\nfn test_flatten() {\n // Create test polynomials\n let poly1 = Polynomial::new([1, 2, 3]); // degree 2\n let poly2 = Polynomial::new([4, -16, 6]); // degree 2\n let poly3 = Polynomial::new([-7, 8, 9]); // degree 2\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 4>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n assert(result.get(0) == 0x11121310101010101010101010101010101010101010101010101010101010);\n assert(result.get(1) == 0x14001610101010101010101010101010101010101010101010101010101010); // -16 became 00 at 0x 14 00 16,\n assert(result.get(2) == 0x09181910101010101010101010101010101010101010101010101010101010); // -7 became 09 at 0x 09 18 19(16 - 7 = 9)\n}\n\n#[test]\nfn test_flatten_big() {\n // Create test polynomials\n let poly1 = Polynomial::new([\n 1791218451968394,\n 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n 5430119342984413,\n 704811298945172,\n 8901715723925099,\n 21888242871839275222246405745257275088548364400416034343698203098124042812559,\n 21888242871839275222246405745257275088548364400416034343698200215091693880034,\n ]);\n let poly2 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698200314078269634250,\n 21888242871839275222246405745257275088548364400416034343698200967285641915872,\n 2909990636858607,\n 7896103832076587,\n 2078397209533893,\n 21888242871839275222246405745257275088548364400416034343698199792421452734531,\n 614400389245817,\n 8290314119277588,\n ]);\n let poly3 = Polynomial::new([\n 21888242871839275222246405745257275088548364400416034343698201373175279892906,\n 21888242871839275222246405745257275088548364400416034343698201087241869723721,\n 6768789983786188,\n 635797784303388,\n 7610153424227556,\n 4633893206538324,\n 2016269760615332,\n 21888242871839275222246405745257275088548364400416034343698201007080554428142,\n ]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 54>(inputs, polynomials);\n\n // Verify the flattened coefficients are in the correct positions\n // Every value shifted 1 nibble incase of negative integers\n\n // For the first index of result operation goes like this,\n\n // First four index of poly1\n // 1791218451968394,\n // 21888242871839275222246405745257275088548364400416034343698198265248580087864,\n // 21888242871839275222246405745257275088548364400416034343698200542108324633466,\n // 5430119342984413,\n\n // base + 1791218451968394 = 0x1065d1a8b8b718a\n // base - 5921327228407753 = 0xeaf69591f3b037 (negative coefficient shifted)\n // base - 3644467483862151 = 0xf30d604a3a9b79 (negative coefficient shifted)\n // base + 5430119342984413 = 0x1134aaa2e86ccdd\n assert(result.get(0) == 0x1065d1a8b8b718a0eaf69591f3b0370f30d604a3a9b791134aaa2e86ccdd);\n assert(result.get(1) == 0x1028105ab1b789411fa010339db66b0fc220f1326bc8e0f1e3f4cc1e02e1);\n assert(result.get(2) == 0x0f23dfbe7cd76c90f4901299312ddf10a569efe35acef11c0d76f005412b);\n assert(result.get(3) == 0x107624a8f605dc50f0638a368960421022ecb3cf36b7911d73ff2c27ec14);\n assert(result.get(4) == 0x0f6013a24e1b9a90f4fd2c158a08481180c2dba8af4cc10242413515171c);\n assert(result.get(5) == 0x11b0964eb898ce411076805680b85410729c962da53a40f4b44412d0f6ed);\n}\n\n#[test]\nfn test_flatten_small() {\n // Create test polynomials\n let poly1 = Polynomial::new([712345, 104857, 999999, 500001, 123, 654321, 77]);\n let poly2 = Polynomial::new([1, 524287, 888888, 23456, 34567, 765432, 0]);\n let poly3 = Polynomial::new([444444, 333333, 222222, 111111, 987654, 246810, 13579]);\n\n let polynomials = [poly1, poly2, poly3];\n\n // Initialize target array with zeros\n let mut inputs = Vec::new();\n\n // Flatten the polynomials\n let result = flatten::<_, _, 20>(inputs, polynomials);\n\n assert(result.get(0) == 0x1ade991199991f423f17a12110007b19fbf110004d100000100000100000);\n assert(result.get(1) == 0x10000117ffff1d9038105ba01087071badf8100000100000100000100000);\n assert(result.get(2) == 0x16c81c15161513640e11b2071f120613c41a10350b100000100000100000);\n}\n\n#[test]\nfn test_safe_hashing_with_safe_helper() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let digests1 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests1.len() == 1);\n assert(digests1.get(0) != 0);\n\n // Test determinism\n let digests2 = compute_safe(domain_separator, elements, io_pattern);\n\n assert(digests2.len() == 1);\n assert(digests2.get(0) != 0);\n assert(digests2.get(0) == digests1.get(0));\n}\n\n#[test]\nfn test_pack() {\n // Test pack function directly with small values\n let values = [1, 2, 3, 4];\n let packed = pack::<4, 4>(values);\n\n // With BIT=4, nibble_bits=4, group should be floor(254/(4+4)) = 31\n // So all 4 values should fit in one carrier\n assert(packed.len() >= 1);\n\n // Test with negative values\n let values_neg = [-1, 2, -3, 4];\n let packed_neg = pack::<4, 4>(values_neg);\n assert(packed_neg.len() >= 1);\n}\n\n#[test]\nfn test_pack_single_value() {\n // Test packing a single value\n let values = [42];\n let packed = pack::<1, 8>(values);\n assert(packed.len() == 1);\n assert(packed.get(0) != 0);\n}\n\n#[test]\nfn test_pack_determinism() {\n // Test that packing is deterministic\n let values = [10, 20, 30];\n let packed1 = pack::<3, 8>(values);\n let packed2 = pack::<3, 8>(values);\n\n assert(packed1.len() == packed2.len());\n for i in 0..packed1.len() {\n assert(packed1.get(i) == packed2.get(i));\n }\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/helpers.nr" - }, - "80": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse super::modulo::U128::ModU128;\n\n/// Polynomial structure representing a polynomial of degree N-1.\n///\n/// A polynomial P(X) = a_{N-1} * X^{N-1} + a_{N-2} * X^{N-2} + ... + a_1 * X + a_0\n/// is represented as an array of coefficients where coefficients[0] = a_{N-1} (highest degree)\n/// and coefficients[N-1] = a_0 (constant term).\npub struct Polynomial {\n /// Array of polynomial coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1} (highest degree term)\n /// coefficients[N-1] = constant term (degree 0)\n pub coefficients: [Field; N],\n}\n\nimpl Polynomial {\n /// Creates a new polynomial from an array of coefficients.\n ///\n /// # Arguments\n /// * `coefficients` - Array of N coefficients in descending degree order\n /// coefficients[0] = coefficient of X^{N-1}\n /// coefficients[N-1] = constant term\n ///\n /// # Returns\n /// A new Polynomial instance with the specified coefficients\n pub fn new(coefficients: [Field; N]) -> Self {\n Polynomial { coefficients }\n }\n\n /// Adds two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to add to the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients added.\n pub fn add(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] + other.coefficients[i];\n }\n\n result\n }\n\n /// Subtracts two polynomials.\n ///\n /// # Arguments\n /// * `other` - The polynomial to subtract from the current polynomial.\n ///\n /// # Returns\n /// A new polynomial with the coefficients subtracted.\n pub fn sub(self, other: Self) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] - other.coefficients[i];\n }\n\n result\n }\n\n /// Multiplies a polynomial by a scalar.\n ///\n /// # Arguments\n /// * `scalar` - The scalar to multiply the polynomial by.\n ///\n /// # Returns\n /// A new polynomial with the coefficients multiplied by the scalar.\n pub fn mul_scalar(self, scalar: Field) -> Self {\n let mut result = Self::new([0; N]);\n\n for i in 0..N {\n result.coefficients[i] = self.coefficients[i] * scalar;\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point using Horner's method.\n ///\n /// Horner's method computes P(x) = a_{N-1} * x^{N-1} + ... + a_1 * x + a_0\n /// as ((...((a_{N-1} * x + a_{N-2}) * x + a_{N-3}) * x + ...) * x + a_0)\n /// This approach require n multiplications and n additions to evaluate the polynomial.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial.\n ///\n /// # Returns\n /// The value of the polynomial at point x: P(x).\n pub fn eval(self, x: Field) -> Field {\n let mut result = self.coefficients[0];\n\n for i in 1..self.coefficients.len() {\n result = result * x + self.coefficients[i];\n }\n\n result\n }\n\n /// Evaluates the polynomial at a given point with modular reduction.\n ///\n /// This function computes `P(x) mod q` using Horner's method with intermediate\n /// modular reductions to prevent overflow. The result is guaranteed to be in\n /// the range `[0, q)`.\n ///\n /// The function performs modular reduction after each multiplication and addition\n /// to ensure the accumulator always remains in the range `[0, q)`, preventing\n /// any potential overflow issues.\n ///\n /// # Arguments\n /// * `x` - The point at which to evaluate the polynomial\n /// * `q` - The modular arithmetic context containing the modulus\n ///\n /// # Returns\n /// The value `P(x) mod q` in the range `[0, q)`\n pub fn eval_mod(self, x: Field, q: ModU128) -> Field {\n let mut acc = self.coefficients[0];\n let len = self.coefficients.len();\n\n for i in 1..len {\n acc = q.mul_mod(acc, x);\n acc = q.add(acc, self.coefficients[i]);\n }\n\n acc\n }\n\n /// Performs range checking on polynomial coefficients using asymmetric bounds.\n ///\n /// This function constrains all polynomial coefficients to be in the range [-lower_bound, upper_bound],\n /// where `lower_bound` is a non-negative magnitude.\n /// It uses a shifting technique to handle negative numbers efficiently:\n /// 1. Shifts each coefficient by adding `lower_bound`: c' = c + lower_bound\n /// 2. Checks that shifted coefficients are in [0, upper_bound + lower_bound] using bit-size assertions\n /// 3. This ensures original coefficients are in [-lower_bound, upper_bound]\n ///\n /// The function uses two bit-size checks per coefficient to ensure the value is within bounds:\n /// - `shifted_coefficient.assert_max_bit_size::()` ensures c' >= 0\n /// - `(range_size - shifted_coefficient).assert_max_bit_size::()` ensures c' <= range_size\n ///\n /// # Arguments\n /// * `upper_bound` - The upper bound for coefficient range checking\n /// * `lower_bound` - Non-negative magnitude of the negative bound\n /// Coefficients must satisfy: -lower_bound <= c <= upper_bound\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length of the total range `upper_bound + lower_bound`\n /// (choose `BIT` so `upper_bound + lower_bound < 2^BIT`). Since all checked\n /// values lie in `[0, upper_bound + lower_bound]`, they cannot exceed `BIT + 1` bits.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the specified bounds.\n pub fn range_check_2bounds(self, upper_bound: Field, lower_bound: Field) {\n let range_size = lower_bound + upper_bound;\n\n for i in 0..self.coefficients.len() {\n let shifted_coefficient = self.coefficients[i] + lower_bound;\n\n shifted_coefficient.assert_max_bit_size::();\n (range_size - shifted_coefficient).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, upper_bound).\n ///\n /// This function constrains all polynomial coefficients to be non-negative and\n /// strictly less than `upper_bound`. It uses bit-size assertions to verify that\n /// coefficients are in the valid range.\n ///\n /// The function performs two checks per coefficient:\n /// 1. `coeff.assert_max_bit_size::()` ensures `coeff >= 0` and `coeff < 2^BIT`\n /// 2. `(upper_bound - 1 - coeff).assert_max_bit_size::()` ensures `coeff < upper_bound`\n ///\n /// # Arguments\n /// * `upper_bound` - The exclusive upper bound for coefficient range checking.\n /// Coefficients must satisfy: `0 <= c < upper_bound`\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Must satisfy `upper_bound <= 2^BIT` for\n /// the range check to work correctly.\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, upper_bound)`.\n pub fn range_check_standard(self, upper_bound: Field) {\n for i in 0..self.coefficients.len() {\n let coeff = self.coefficients[i];\n // Check coeff >= 0 and coeff < 2^BIT\n coeff.assert_max_bit_size::();\n // Check coeff <= upper_bound - 1 (i.e., coeff < upper_bound)\n (upper_bound - 1 - coeff).assert_max_bit_size::();\n }\n }\n\n /// Performs range checking on polynomial coefficients for the range [0, 2^BIT).\n ///\n /// This is a specialized range check for coefficients that must be non-negative\n /// and less than a power of two. It's more efficient than `range_check_standard`\n /// when the upper bound is exactly `2^BIT` because it only needs a single\n /// bit-size assertion per coefficient.\n ///\n /// The function verifies that each coefficient satisfies:\n /// - `coeff >= 0` (implicit from bit-size check)\n /// - `coeff < 2^BIT` (enforced by `assert_max_bit_size::()`)\n ///\n /// # Generic Parameters\n /// * `BIT` - The bit-length parameter. Coefficients must satisfy: `0 <= c < 2^BIT`\n ///\n /// # Panics\n /// This function will cause the circuit to fail if any coefficient is outside\n /// the range `[0, 2^BIT)`.\n pub fn range_check_power_of_two(self) {\n for i in 0..self.coefficients.len() {\n self.coefficients[i].assert_max_bit_size::();\n }\n }\n}\n\n#[test]\nfn test_polynomial_eval() {\n let coeffs = [1, 2, 3]; // represents 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n\n let x = 2; // evaluate at x = 2\n let result = poly.eval(x);\n\n // (1 * 2^2) + (2 * 2) + 3 = 4 + 4 + 3 = 11\n assert(result == 11);\n}\n\n#[test]\nfn test_polynomial_eval_zero() {\n let coeffs = [1, -2, 1]; // x^2 - 2x + 1 = (x-1)^2\n let poly = Polynomial::new(coeffs);\n\n let x = 1; // evaluate at x = 1, should be 0\n let result = poly.eval(x);\n\n assert(result == 0);\n}\n\n#[test]\nfn test_polynomial_bounds() {\n let coeffs = [-16, 240, 242];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-240, 242]\n poly.range_check_2bounds::<8>(242, 240);\n}\n\n#[test(should_fail_with = \"assert_max_bit_size\")]\nfn test_polynomial_out_of_bounds_coefficients() {\n let coeffs = [-100];\n let poly = Polynomial::new(coeffs);\n\n // Test double bounds check - constrains to [-98, 99]\n // Should fail because -100 is out of bounds.\n poly.range_check_2bounds::<7>(99, 98);\n}\n\n#[test]\nfn test_polynomial_add() {\n let coeffs1 = [1, 2, 3]; // 1x^2 + 2x + 3\n let coeffs2 = [4, 5, 6]; // 4x^2 + 5x + 6\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.add(poly2);\n\n // Expected: (1+4)x^2 + (2+5)x + (3+6) = 5x^2 + 7x + 9\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 7);\n assert(result.coefficients[2] == 9);\n}\n\n#[test]\nfn test_polynomial_sub() {\n let coeffs1 = [5, 7, 9]; // 5x^2 + 7x + 9\n let coeffs2 = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly1 = Polynomial::new(coeffs1);\n let poly2 = Polynomial::new(coeffs2);\n\n let result = poly1.sub(poly2);\n\n // Expected: (5-1)x^2 + (7-2)x + (9-3) = 4x^2 + 5x + 6\n assert(result.coefficients[0] == 4);\n assert(result.coefficients[1] == 5);\n assert(result.coefficients[2] == 6);\n}\n\n#[test]\nfn test_polynomial_mul_scalar() {\n let coeffs = [1, 2, 3]; // 1x^2 + 2x + 3\n let poly = Polynomial::new(coeffs);\n let scalar = 5;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 5x^2 + 10x + 15\n assert(result.coefficients[0] == 5);\n assert(result.coefficients[1] == 10);\n assert(result.coefficients[2] == 15);\n}\n\n#[test]\nfn test_polynomial_mul_scalar_zero() {\n let coeffs = [1, 2, 3];\n let poly = Polynomial::new(coeffs);\n let scalar = 0;\n\n let result = poly.mul_scalar(scalar);\n\n // Expected: 0x^2 + 0x + 0 = 0\n assert(result.coefficients[0] == 0);\n assert(result.coefficients[1] == 0);\n assert(result.coefficients[2] == 0);\n}\n\n#[test]\nfn test_eval_mod_simple() {\n // Test without initial reduction - simple case\n // p(x) = x + 1 at x=5od 7\n // Expected: (5 + 1) mod 7 = 6\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 1]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 6);\n\n // Test: p(x) = 2x + 3 at x=5od 7\n // Expected: (10 + 3) mod 7 = 13 mod 7 = 6\n let poly2 = Polynomial::new([2, 3]);\n let result2 = poly2.eval_mod(5, q);\n assert(result2 == 6);\n}\n\n#[test]\nfn test_eval_mod_degree_2() {\n // p(x) = x^2 + 2x + 3 at x=5od 7\n // Using Horner's method: ((1)*5 + 2)*5 + 3 = (5+2)*5 + 3 = 7*5 + 3 = 35 + 3 = 38\n // 38 mod 7 = 3 (since 38 = 5*7 + 3)\n let q = ModU128::new(7);\n\n let poly = Polynomial::new([1, 2, 3]);\n let result = poly.eval_mod(5, q);\n assert(result == 3);\n}\n\n#[test]\nfn test_eval_mod() {\n // Test 1: Simple polynomial x^2 + 2x + 3 at x=5od 7\n // Expected: (25 + 10 + 3) mod 7 = 38 mod 7 = 3\n let q = ModU128::new(7);\n\n let poly1 = Polynomial::new([1, 2, 3]);\n let result1 = poly1.eval_mod(5, q);\n assert(result1 == 3);\n\n // Test 2: Higher degree polynomialod small prime\n // p(x) = x^3 + x^2 + x + 1 at x=2od 11\n // Expected: (8 + 4 + 2 + 1) mod 11 = 15 mod 11 = 4\n let q = ModU128::new(11);\n\n let poly2 = Polynomial::new([1, 1, 1, 1]);\n let result2 = poly2.eval_mod(2, q);\n assert(result2 == 4);\n\n // Test 3: Polynomial with larger coefficients\n // p(x) = 100x^2 + 50x + 25 at x=10od 73\n // Expected: (10000 + 500 + 25) mod 73 = 10525 mod 73 = 13\n let q = ModU128::new(73);\n\n let poly3 = Polynomial::new([100, 50, 25]);\n let result3 = poly3.eval_mod(10, q);\n assert(result3 == 13);\n\n // Test 4: Result should be less than modulus\n let poly4 = Polynomial::new([5, 3, 7]);\n let q = ModU128::new(17);\n let result4 = poly4.eval_mod(4, q);\n assert(result4 as u128 < q.get_mod_field() as u128);\n\n // Test 5: Compare with regular eval for small values\n let poly5 = Polynomial::new([1, 2, 1]);\n let x = 3;\n let q = ModU128::new(1000);\n let result5 = poly5.eval_mod(x, q);\n let expected5 = poly5.eval(x);\n assert(result5 == expected5);\n\n // Test 6: Zero polynomial\n let poly6 = Polynomial::new([0, 0, 0]);\n let q = ModU128::new(13);\n let result6 = poly6.eval_mod(100, q);\n assert(result6 == 0);\n}\n\n#[test]\nfn test_large_party_ids_scenario() {\n // Simulating party IDs in range [1, 100]\n let party_id_1 = 42;\n let party_id_2 = 73;\n let m = ModU128::new(288230376151711717); // ~58 bits\n\n // Operations that would be used in Lagrange coefficients\n let product = m.mul_mod(party_id_1, party_id_2);\n let diff = m.sub(party_id_2, party_id_1);\n\n assert(product == 3066);\n assert(diff == 31);\n}\n\n#[test]\nfn test_eval_vs_eval_mod() {\n // Compare eval and eval_mod for small values where no reduction should occur\n let poly = Polynomial::new([1, 2, 3]);\n let x = 2;\n let q = ModU128::new(1000); // Large enough that no reduction happens\n\n let result_normal = poly.eval(x);\n let result_mod = poly.eval_mod(x, q);\n\n // They should be equal: (1)*2 + 2)*2 + 3 = (2+2)*2 + 3 = 4*2 + 3 = 11\n assert(result_normal == 11);\n assert(result_mod == 11);\n}\n\n#[test]\nfn test_eval_mod_step_by_step() {\n // p(x) = x + 1 at x=5od 7\n // Step by step: acc = 1, then acc = 1*5 + 1 = 6\n let poly = Polynomial::new([1, 1]);\n\n // Manually compute\n let mut acc = 1; // coefficients[0]\n acc = acc * 5 + 1; // = 6\n assert(acc == 6);\n\n // Now with reduce_mod\n let m = ModU128::new(7);\n let reduced = m.reduce_mod(acc);\n assert(reduced == 6);\n\n // Now test the actual function\n let result = poly.eval_mod(5, m);\n assert(result == 6);\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/polynomial.nr" - }, - "81": { - "source": "// SPDX-License-Identifier: LGPL-3.0-only\n//\n// This file is provided WITHOUT ANY WARRANTY;\n// without even the implied warranty of MERCHANTABILITY\n// or FITNESS FOR A PARTICULAR PURPOSE.\n\nuse keccak256::keccak256;\nuse poseidon::poseidon2_permutation;\n\n/// SAFE (Sponge API for Field Elements)\n///\n/// This module provides a complete implementation of the SAFE API in Noir as defined in:\n/// \"SAFE (Sponge API for Field Elements) - A Toolbox for ZK Hash Applications\"\n/// see https://hackmd.io/bHgsH6mMStCVibM_wYvb2w#22-Sponge-state for more details.\n///\n/// SAFE provides a unified interface for cryptographic sponge functions that can be\n/// instantiated with various permutations to create hash functions, MACs, authenticated\n/// encryption schemes, and other cryptographic primitives for ZK proof systems.\n///\n/// This implementation follows the SAFE specification exactly, providing:\n/// - Complete API: START, ABSORB, SQUEEZE, FINISH operations.\n/// - Full security: Domain separation, tag computation, IO pattern validation.\n/// - Poseidon2 integration: Field-friendly permutation for ZK systems.\n/// - Specification compliance: All operations follow SAFE spec 2.4 exactly.\n/// - Natural API design: Variable-length inputs, automatic length detection from IO patterns.\n///\n/// # API Design\n///\n/// The API is designed for natural usage while maintaining type safety:\n/// - `absorb(input: [Field])`: Accepts variable-length arrays, no padding required.\n/// - `squeeze()`: Returns a vector with field element(s).\n/// - IO patterns automatically determine operation lengths for validation.\n\n/// Rate parameter for the sponge construction (number of field elements that can be absorbed per permutation call).\nglobal RATE: u32 = 3;\n\n/// Capacity parameter for the sponge construction (security parameter, typically 1-2 field elements).\nglobal CAPACITY: u32 = 1;\n\n/// Total state size (rate + capacity) in field elements.\nglobal STATE_SIZE: u32 = RATE + CAPACITY;\n\n/// IO Pattern encoding constants (from SAFE spec 2.3).\n///\n/// These constants are used for encoding operation types in the 32-bit word format:\n/// - MSB set to 1 for ABSORB operations\n/// - MSB set to 0 for SQUEEZE operations\n\n/// Flag for ABSORB operations (MSB = 1)\nglobal ABSORB_FLAG: u32 = 0x80000000;\n\n/// Flag for SQUEEZE operations (MSB = 0)\nglobal SQUEEZE_FLAG: u32 = 0x00000000;\n\n/// SAFE Sponge State (following spec 2.2)\n///\n/// The sponge state consists of the permutation state, tag, position counters,\n/// and IO pattern tracking as defined in the SAFE specification.\n///\n/// # Generic Parameters\n/// - `L`: The length of the IO pattern array\n///\n/// # Fields\n/// - `state`: Permutation state V in F^n (rate + capacity elements)\n/// - `tag`: Parameter tag T used for instance differentiation\n/// - `absorb_pos`: Current absorb position (<= n-c)\n/// - `squeeze_pos`: Current squeeze position (<= n-c)\n/// - `io_pattern`: Expected IO pattern for validation (encoded 32-bit words)\n/// - `io_count`: Current operation count for pattern tracking\npub struct SafeSponge {\n /// Permutation state V in F^n (rate + capacity elements).\n state: [Field; STATE_SIZE],\n /// Parameter tag T used for instance differentiation.\n tag: Field,\n /// Current absorb position (<= n-c).\n absorb_pos: u32,\n /// Current squeeze position (<= n-c).\n squeeze_pos: u32,\n /// Expected IO pattern for validation.\n io_pattern: [u32; L],\n /// Current operation count for pattern tracking (spec 2.4: io_count).\n io_count: u32,\n}\n\nimpl SafeSponge {\n /// Initializes a new SAFE sponge instance with the given IO pattern and domain separator (following spec 2.4).\n ///\n /// # Arguments\n /// - `io_pattern`: Array of 32-bit encoded operations defining the expected sequence of ABSORB/SQUEEZE calls.\n /// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n /// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n ///\n /// # Returns\n /// A new `SafeSponge` instance with initialized state\n pub fn start(io_pattern: [u32; L], domain_separator: [u8; 64]) -> SafeSponge {\n // Compute tag from IO pattern and domain separator (spec 2.3).\n let tag = compute_tag(io_pattern, domain_separator);\n\n let mut state = [0; STATE_SIZE];\n // Initialize capacity with tag (spec 2.4).\n // Add T to the first 128 bits of the state.\n state[0] = tag;\n\n SafeSponge { state, tag, absorb_pos: 0, squeeze_pos: 0, io_pattern, io_count: 0 }\n }\n\n /// Absorbs field elements into the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to absorb is automatically validated against the IO pattern.\n /// This method accepts variable-length arrays, making it natural to use without padding.\n ///\n /// # Arguments\n /// - `input`: Array of field elements to absorb (variable length, must match IO pattern)\n pub fn absorb(&mut self, input: Vec) {\n let length = input.len() as u32;\n\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_absorb = (expected_encoded_word & ABSORB_FLAG) != 0;\n let expected_length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type and length\n assert(is_expected_absorb, \"Expected ABSORB operation\");\n assert(expected_length == length, \"Length mismatch\");\n\n // Process each element naturally (no unnecessary iterations).\n for i in 0..length {\n // If absorb_pos == (n-c) then permute and reset (spec 2.4).\n if self.absorb_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.absorb_pos = 0;\n }\n\n // Add X[i] to state at absorb_pos (spec 2.4).\n // Note: absorb_pos is the rate position, not capacity position.\n self.state[self.absorb_pos + CAPACITY] =\n self.state[self.absorb_pos + CAPACITY] + input.get(i);\n self.absorb_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = ABSORB_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n\n // Force permute at start of next SQUEEZE (spec 2.4).\n self.squeeze_pos = RATE;\n }\n\n /// Extracts field elements from the sponge state, interleaving permutation calls as needed (following spec 2.4).\n ///\n /// The number of elements to squeeze is automatically determined from the IO pattern.\n pub fn squeeze(&mut self) -> Vec {\n // Validate against IO pattern.\n assert(self.io_count < L);\n\n // Parse expected operation from io_pattern (encoded word)\n let expected_encoded_word = self.io_pattern[self.io_count];\n let is_expected_squeeze = (expected_encoded_word & ABSORB_FLAG) == 0;\n let length = expected_encoded_word & 0x7FFFFFFF;\n\n // Validate operation type\n assert(is_expected_squeeze, \"Expected SQUEEZE operation\");\n\n let mut output = Vec::new();\n\n // SQUEEZE implementation following spec 2.4.\n // If length==0, loop won't execute (spec 2.4).\n for _ in 0..length {\n // If squeeze_pos==(n-c) then permute and reset (spec 2.4).\n if self.squeeze_pos == RATE {\n // n-c = RATE.\n self.state = self.permute();\n self.squeeze_pos = 0;\n self.absorb_pos = 0;\n }\n // Set Y[i] to state element at squeeze_pos (spec 2.4).\n output.push(self.state[self.squeeze_pos + CAPACITY]);\n self.squeeze_pos += 1;\n }\n\n // Verify that the encoded word matches the expected pattern.\n let encoded_word = SQUEEZE_FLAG | length;\n assert(encoded_word == expected_encoded_word);\n\n self.io_count += 1;\n output\n }\n\n /// Finalizes the sponge instance, verifying that all expected operations have been performed and clearing the internal state for security (following spec 2.4).\n ///\n /// This function is used to ensure that the sponge instance has been used correctly and to prevent information leakage.\n pub fn finish(&mut self) {\n // Check that io_count equals the length of the IO pattern expected (spec 2.4).\n assert(self.io_count == L, \"IO pattern not completed\");\n\n // Erase the state and its variables (spec 2.4).\n self.state = [0; STATE_SIZE];\n self.absorb_pos = 0;\n self.squeeze_pos = 0;\n self.io_count = 0;\n }\n\n /// Permute the state using Poseidon2 (following spec 2.4).\n ///\n /// Applies the Poseidon2 permutation to the current state.\n /// This is the core cryptographic primitive of the sponge construction.\n ///\n /// # Returns\n /// New state after permutation\n fn permute(self) -> [Field; STATE_SIZE] {\n poseidon2_permutation(self.state, STATE_SIZE)\n }\n}\n\n/// Computes a unique tag for a sponge instance based on its IO pattern and domain separator.\n/// The tag is used to ensure that distinct instances behave like distinct functions.\n///\n/// # Arguments\n/// - `io_pattern`: Array of 32-bit encoded operations defining the sponge's usage pattern.\n/// Each word has MSB=1 for ABSORB operations, MSB=0 for SQUEEZE operations.\n/// - `domain_separator`: 64-byte domain separator for cross-protocol security.\n///\n/// # Returns\n/// A field element representing the 128-bit tag.\npub fn compute_tag(io_pattern: [u32; L], domain_separator: [u8; 64]) -> Field {\n // Step 1: Parse and aggregate consecutive operations of the same type\n let mut encoded_words = [0; L]; // Support up to L operations.\n let mut word_count = 0;\n let mut current_absorb_sum = 0;\n let mut current_squeeze_sum = 0;\n let mut last_was_absorb = false;\n\n for i in 0..L {\n if io_pattern[i] > 0 {\n // Parse operation type from MSB and length from lower 31 bits\n let is_absorb = (io_pattern[i] & ABSORB_FLAG) != 0;\n let length = io_pattern[i] & 0x7FFFFFFF; // Clear MSB to get length\n\n if is_absorb {\n if last_was_absorb {\n // Aggregate consecutive ABSORB operations\n current_absorb_sum += length;\n } else {\n // Start new ABSORB sequence\n if current_squeeze_sum > 0 {\n // Flush previous SQUEEZE sequence\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n current_squeeze_sum = 0;\n }\n current_absorb_sum = length;\n }\n last_was_absorb = true;\n } else {\n if !last_was_absorb {\n // Aggregate consecutive SQUEEZE operations\n current_squeeze_sum += length;\n } else {\n // Start new SQUEEZE sequence\n if current_absorb_sum > 0 {\n // Flush previous ABSORB sequence\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n current_absorb_sum = 0;\n }\n current_squeeze_sum = length;\n }\n last_was_absorb = false;\n }\n }\n }\n\n // Flush remaining operations\n if current_absorb_sum > 0 {\n encoded_words[word_count] = ABSORB_FLAG | current_absorb_sum;\n word_count += 1;\n }\n if current_squeeze_sum > 0 {\n encoded_words[word_count] = SQUEEZE_FLAG | current_squeeze_sum;\n word_count += 1;\n }\n\n // Step 2: Serialize to byte string and append domain separator (following SAFE spec 2.3).\n // Buffer is 256 bytes: max 192 bytes for IO pattern (48 words) + 64 bytes for domain separator.\n // Note: We must use a fixed-size array because Noir's keccak256 requires [u8; N], not Vec.\n let max_io_pattern_bytes: u32 = 192; // 256 - 64 (domain separator)\n let io_pattern_bytes = word_count * 4;\n assert(\n io_pattern_bytes <= max_io_pattern_bytes,\n \"IO pattern too large: max 48 aggregated words supported\",\n );\n\n let mut input_bytes = [0u8; 256];\n let mut byte_count: u32 = 0;\n\n // Serialize encoded words to bytes (big-endian as per SAFE spec).\n // Note: Noir requires compile-time loop bounds, so we iterate over L (the array size)\n // instead of word_count (runtime value). The condition `i < word_count` ensures we only\n // process valid encoded words. This is safe because word_count <= L always holds\n // (we can have at most L encoded words from L input operations).\n for i in 0..L {\n if i < word_count {\n let word = encoded_words[i];\n input_bytes[byte_count] = (word >> 24) as u8;\n input_bytes[byte_count + 1] = (word >> 16) as u8;\n input_bytes[byte_count + 2] = (word >> 8) as u8;\n input_bytes[byte_count + 3] = word as u8;\n byte_count += 4;\n }\n }\n\n // Append full 64-byte domain separator.\n for i in 0..64 {\n input_bytes[byte_count] = domain_separator[i];\n byte_count += 1;\n }\n\n // Step 3: Hash with Keccak-256 and truncate to 128 bits.\n // Note: The SAFE spec uses SHA3-256, but we use Keccak-256 for Noir compatibility.\n // Keccak-256 differs from SHA3-256 in padding, but both provide equivalent security.\n let hash_bytes = keccak256(input_bytes, byte_count);\n\n // Convert first 128 bits (16 bytes) to field element.\n let mut tag_value: Field = 0;\n for i in 0..16 {\n tag_value = tag_value * 256 + (hash_bytes[i] as Field);\n }\n\n tag_value\n}\n\n#[test]\nfn test_safe_hashing() {\n // Verifies basic hash functionality with a simple ABSORB(3) + SQUEEZE(1) pattern.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice(&[1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_merkle_node() {\n // Verifies SAFE can be used for Merkle tree node hashing with pattern ABSORB(1) + ABSORB(1) + SQUEEZE(1).\n // Tests the ability to absorb multiple inputs before squeezing output.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let left = Vec::from_slice([123]);\n let right = Vec::from_slice([456]);\n\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(left);\n sponge.absorb(right);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(left);\n sponge2.absorb(right);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_commitment_scheme() {\n // Verifies SAFE can be used for commitment schemes with pattern ABSORB(3) + SQUEEZE(1).\n // Tests the ability to create deterministic commitments from multiple field elements.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let values = Vec::from_slice([10, 20, 30]);\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(values);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n\n // Test determinism\n let mut sponge2 = SafeSponge::start(io_pattern, domain_separator);\n sponge2.absorb(values);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output2.len() == 1);\n assert(output2.get(0) != 0);\n}\n\n#[test]\nfn test_domain_separation() {\n // Verifies that different domain separators produce different outputs for the same input.\n // This is crucial for cross-protocol security and preventing collisions between different applications.\n let elements = Vec::from_slice([1, 2, 3]);\n let domain1 = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let domain2 = [\n 0x41, 0x42, 0x43, 0x45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(3), SQUEEZE(1)\n let io_pattern = [0x80000003, 0x00000001];\n\n let mut sponge1 = SafeSponge::start(io_pattern, domain1);\n sponge1.absorb(elements);\n let output1 = sponge1.squeeze();\n sponge1.finish();\n\n let mut sponge2 = SafeSponge::start(io_pattern, domain2);\n sponge2.absorb(elements);\n let output2 = sponge2.squeeze();\n sponge2.finish();\n\n assert(output1.len() == 1);\n assert(output2.len() == 1);\n assert(output1.get(0) != output2.get(0)); // Different domain separators should produce different outputs\n}\n\n#[test]\nfn test_multiple_squeeze() {\n // Verifies that multiple field elements can be squeezed in a single operation.\n // Tests pattern ABSORB(3) + SQUEEZE(2) to ensure proper state management.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n let elements = Vec::from_slice([1, 2, 3]);\n\n // Pattern: ABSORB(3), SQUEEZE(2)\n let io_pattern = [0x80000003, 0x00000002];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(elements);\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 2);\n assert(output.get(0) != 0);\n assert(output.get(1) != 0);\n assert(output.get(0) != output.get(1)); // Different squeeze outputs should be different\n}\n\n#[test]\nfn test_zero_length_operations() {\n // Verifies that zero-length ABSORB and SQUEEZE operations are handled correctly.\n // Tests pattern ABSORB(0) + SQUEEZE(1) to ensure proper state transitions.\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Pattern: ABSORB(0), SQUEEZE(1)\n let io_pattern = [0x80000000, 0x00000001];\n let mut sponge = SafeSponge::start(io_pattern, domain_separator);\n sponge.absorb(Vec::new());\n let output = sponge.squeeze();\n sponge.finish();\n\n assert(output.len() == 1);\n assert(output.get(0) != 0);\n}\n\n#[test]\nfn test_tag_computation() {\n // Verifies the tag computation algorithm using the example from the SAFE specification.\n // Pattern: ABSORB(3), ABSORB(3), SQUEEZE(3)\n // Should aggregate to: ABSORB(6), SQUEEZE(3)\n // Encoded as: [0x80000006, 0x00000003]\n // Tests determinism and pattern differentiation.\n\n let io_pattern = [0x80000003, 0x80000003, 0x00000003];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test determinism\n let tag2 = compute_tag(io_pattern, domain_separator);\n assert(tag == tag2);\n\n // Test that different patterns produce different tags\n let io_pattern2 = [0x80000003, 0x00000003]; // ABSORB(3), SQUEEZE(3) - different pattern\n let tag3 = compute_tag(io_pattern2, domain_separator);\n assert(tag != tag3);\n}\n\n#[test]\nfn test_tag_computation_debug() {\n println(\"=== SAFE Tag Computation Debug Test ===\");\n\n // Test your specific pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\n let io_pattern = [0x80000002, 0x00000002, 0x80000002];\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n println(f\"Testing pattern: {io_pattern}\");\n println(\n f\"Expected to aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(2)\",\n );\n println(\n f\"Expected encoded words: [0x80000002, 0x00000002, 0x80000002]\",\n );\n println(\"\");\n\n let tag = compute_tag(io_pattern, domain_separator);\n\n println(f\"=== Expected Rust Output ===\");\n println(\"Pattern [2, 2, 2] (ABSORB(2), SQUEEZE(2), ABSORB(2))\");\n println(\"Domain separator: 0x41424344...\");\n println(\"Tag: 0xce3bb9ee4b2d41c42e9cdda38afe8b6a\");\n println(\"\");\n\n println(f\"=== Noir Output ===\");\n println(f\"Tag: {tag}\");\n println(\"\");\n\n println(\"Compare the tag values above with Rust script!\");\n}\n\n#[test]\nfn test_consecutive_absorb_aggregation() {\n // Test that consecutive ABSORB operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1) should aggregate to ABSORB(2), SQUEEZE(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(1) = [0x80000002, 0x00000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(2), SQUEEZE(1)\n let aggregated_pattern = [0x80000002, 0x00000001];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Consecutive ABSORB operations should aggregate to the same tag\");\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive ABSORB operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive ABSORB Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001] (ABSORB(1), ABSORB(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000002, 0x00000001] (ABSORB(2), SQUEEZE(1))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_consecutive_squeeze_aggregation() {\n // Test that consecutive SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1) should aggregate to ABSORB(1), SQUEEZE(2)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), SQUEEZE(1), SQUEEZE(1)\n let io_pattern = [0x80000001, 0x00000001, 0x00000001];\n\n // This should aggregate to: ABSORB(1), SQUEEZE(2) = [0x80000001, 0x00000002]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag ABSORB(1), SQUEEZE(2)\n let aggregated_pattern = [0x80000001, 0x00000002];\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(\n tag == aggregated_tag,\n \"Consecutive SQUEEZE operations should aggregate to the same tag\",\n );\n\n // Test that a different pattern produces a different tag\n let different_pattern = [0x80000001, 0x00000001, 0x80000001]; // ABSORB(1), SQUEEZE(1), ABSORB(1)\n let different_tag = compute_tag(different_pattern, domain_separator);\n\n // This should be different because it doesn't have consecutive SQUEEZE operations\n assert(tag != different_tag, \"Different patterns should produce different tags\");\n\n println(\"=== Consecutive SQUEEZE Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x00000001, 0x00000001] (ABSORB(1), SQUEEZE(1), SQUEEZE(1))\",\n );\n println(\n f\"Aggregated pattern: [0x80000001, 0x00000002] (ABSORB(1), SQUEEZE(2))\",\n );\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n println(f\"Different pattern tag: {different_tag}\");\n}\n\n#[test]\nfn test_mixed_consecutive_aggregation() {\n // Test that both consecutive ABSORB and SQUEEZE operations are properly aggregated\n // Pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n // Should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1)\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Test pattern: ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1)\n let io_pattern = [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001];\n\n // This should aggregate to: ABSORB(2), SQUEEZE(2), ABSORB(1) = [0x80000002, 0x00000002, 0x80000001]\n let tag = compute_tag(io_pattern, domain_separator);\n\n // Test that the aggregated pattern produces the same tag\n let aggregated_pattern = [0x80000002, 0x00000002, 0x80000001]; // ABSORB(2), SQUEEZE(2), ABSORB(1)\n let aggregated_tag = compute_tag(aggregated_pattern, domain_separator);\n\n // The tags should be identical because the patterns are equivalent after aggregation\n assert(tag == aggregated_tag, \"Mixed consecutive operations should aggregate to the same tag\");\n\n println(\"=== Mixed Consecutive Aggregation Test ===\");\n println(\n f\"Original pattern: [0x80000001, 0x80000001, 0x00000001, 0x00000001, 0x80000001]\",\n );\n println(\n f\" (ABSORB(1), ABSORB(1), SQUEEZE(1), SQUEEZE(1), ABSORB(1))\",\n );\n println(f\"Aggregated pattern: [0x80000002, 0x00000002, 0x80000001]\");\n println(f\" (ABSORB(2), SQUEEZE(2), ABSORB(1))\");\n println(f\"Original tag: {tag}\");\n println(f\"Aggregated tag: {aggregated_tag}\");\n}\n\n#[test]\nfn test_large_io_pattern() {\n let domain_separator = [\n 0x41, 0x42, 0x43, 0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0,\n ];\n\n // Create pattern with 48 alternating ABSORB(1) and SQUEEZE(1) operations\n // This is the maximum supported (48 words * 4 bytes = 192 bytes, leaving 64 for domain separator)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1; // ABSORB(1)\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1; // SQUEEZE(1)\n }\n }\n\n let tag = compute_tag(io_pattern, domain_separator);\n assert(tag != 0);\n}\n\n#[test]\nfn test_domain_separator_not_truncated() {\n // This test verifies that the domain separator is always included in the tag computation,\n // even for large IO patterns. If the domain separator were truncated, different domain\n // separators would produce the same tag for large patterns.\n\n let domain_separator_a = [\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,\n 0x41, 0x41, 0x41, 0x41,\n ]; // All 'A's\n\n let domain_separator_b = [\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,\n 0x42, 0x42, 0x42, 0x42,\n ]; // All 'B's\n\n // Create pattern with 48 alternating operations (max supported: 192 bytes of IO pattern)\n let mut io_pattern = [0u32; 48];\n for i in 0..48 {\n if i % 2 == 0 {\n io_pattern[i] = ABSORB_FLAG | 1;\n } else {\n io_pattern[i] = SQUEEZE_FLAG | 1;\n }\n }\n\n let tag_a = compute_tag(io_pattern, domain_separator_a);\n let tag_b = compute_tag(io_pattern, domain_separator_b);\n\n // Tags MUST be different because domain separators are different.\n // If they were the same, it would mean the domain separator was truncated/ignored.\n assert(tag_a != tag_b, \"Domain separator must affect tag even for large IO patterns\");\n}\n", - "path": "/home/ace/main/gnosis/enclave/circuits/lib/src/math/safe.nr" - } - }, - "expression_width": { "Bounded": { "width": 4 } } -} diff --git a/crates/zk-prover/tests/fixtures/user_data_encryption.vk b/crates/zk-prover/tests/fixtures/user_data_encryption.vk deleted file mode 100644 index 0934ae5fb94ed2f384f22af5d21f52aafb4d5fd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmajgcRw2l1Hf?!E|F0|gcJ>81~F=nh>B6GMvc}un#~?Xvj*D}Tpj^vpu7jqQ3EHqm#oP1 z^TYYmLI?^H(?PG$so*bmV8CWnk`gVNEc=^jCxofTKJc+L%2}5kdO1q5p%cb`1|<7j z@Jl~MY$v=2o2(OSzXhF`PD2QTM>%1j8n{xGY@eInSeAotKzGEDB$iBXFsvL#W*-n% z<2W&4-}t{FbrjNt5G7~wRwFyX5Q9^$CfO1l0PK$2jhmJU6`SqcW322lb4O1kZhjPu zNe;-z-=@k-mRh%5^KkpZ3_nL&s{>=h^oh)9O5+j7Lnn)}9JYMKYw&jI;UOBCL5C4F z`ayZQyOGtTVk3{O4sD+RxYJpKZMIPc(T3GNjG!*?1#r8}@&nv1$kmwJyFYK{Ge>A7 zp?fWTrhroi1z2H#*}iFnDQH$Mx4F+m`B;=m z&#WflgA-5#)C(v}pJ|nAWfqP0YpVLAGuB-Z~k5=Qa_bIeoRY`Rk`^lBOna@rUsLj1$@|iUe zZ_Zn;)@B(LD>iZ=YtLLUFrMc=jWdexcxE?FPoHYO;~{tGO9*hQ2zaZ@z`1P}c~D4Q zZ-vQHw%!})`swtyl`7|?31(=+=h+N#HVMw z5IIj3J+2wGnGAfygPJtJ4GhanmLq~73fcNQnTr@osV}lmD#O3HY7Htdpt3I+O>e9fmJ$|XDjNI`tDslpVdq4E+#fQszk;7Gj>JXPl_e*Ys*v{z}^4eXBaA3b@tlB&D-aHl>N2-3^ z;kLT#MStbmrJYf9A(PyHA0^QnHt`@DPxFQaJ806x8F#v|@#bR%rG_i1-5OuI(2p{) zFb$1DFiB_)A-(lx=8#=_F~(xI==I#gQLt3*%C;59u&3tb4b6UFcBB-_=2`mZFHk^|;FaWJud) z_3f)4EH>)&E-pUYZs4v7Z4=`yJ9uLdV+2>y|yBMZC+vB5yFhHGV5yYjtB|G-lipI)eILP33qPxb)1(7Z#-1)$9Bu66(f? z#=%LfbE>oiw^8{kMIPU^{1o9O2&AX;lx{o|l-Rzi9F{0IK^FaO2t)rPg*J*NG8udz z-#_2IQJubI9U7xG)ROa^@j0B97NT(sC)v1K@3I%xnIurK!q*cO^gxjyOP) z<+y}fryV?_*2X^nxipn~M@q3?-!I{=FHVER{}g@=mmroEDUuDXGfL|b&&%V(Nh_r! zftO^bYR#@dt@{M~BwUjb>x4R+9RXUeGO3}rT(Lyfq23a0S z0R2T_Y-r^~6+obgNQ5el=&Zd4du3bw3b34(rL|$;8RnFFSJH>Y3%`+_Olwm+N=AXu zhxGmh9;2TOgdi)85jX11CWY@R>`gu22&2LoxyCDIj^h6B<%FdNz&UFEA)NdOpWNIW zwLILWjjIvr>3>J9xFU3K|KMMMA2<*#=uuugD}eL*9@vfbEQPo5r3l Option { - if let Ok(output) = Command::new("which").arg("bb").output().await { - if output.status.success() { - let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); - if !path.is_empty() { - return Some(PathBuf::from(path)); - } - } - } - if let Ok(home) = std::env::var("HOME") { - for path in [ - format!("{}/.bb/bb", home), - format!("{}/.nargo/bin/bb", home), - format!("{}/.enclave/noir/bin/bb", home), - ] { - if std::path::Path::new(&path).exists() { - return Some(PathBuf::from(path)); - } - } - } - None -} - -async fn setup_test_prover(bb: &PathBuf) -> (ZkBackend, tempfile::TempDir) { - let target_tmp = env!("CARGO_TARGET_TMPDIR"); - let temp = TempDir::new_in(target_tmp).unwrap(); - - let temp_path = temp.path(); - let noir_dir = temp_path.join("noir"); - let bb_binary = BBPath::Default(noir_dir.join("bin").join("bb")); - let circuits_dir = noir_dir.join("circuits"); - let work_dir = noir_dir.join("work").join("test_node"); - let backend = ZkBackend::new( - bb_binary, - circuits_dir.clone(), - work_dir.clone(), - ZkConfig::default(), - ); - - fs::create_dir_all(&backend.circuits_dir).await.unwrap(); - fs::create_dir_all(backend.circuits_dir.join("vk")) - .await - .unwrap(); - fs::create_dir_all(&backend.work_dir).await.unwrap(); - fs::create_dir_all(backend.base_dir.join("bin")) - .await - .unwrap(); - - #[cfg(unix)] - std::os::unix::fs::symlink(bb, &backend.bb_binary).unwrap(); - - (backend, temp) -} +use e3_zk_helpers::{compute_share_computation_sk_commitment, compute_threshold_pk_commitment}; +use e3_zk_prover::{Provable, ZkBackend, ZkProver}; -async fn setup_circuit_fixtures(backend: &ZkBackend, circuit_path: &[&str], fixture_name: &str) { - let fixtures = fixtures_dir(); - let json_path = fixtures.join(format!("{fixture_name}.json")); - let vk_path = fixtures.join(format!("{fixture_name}.vk")); - assert!( - json_path.exists(), - "missing circuit fixture: {} (run `pnpm sync:fixtures` to copy from circuits target)", - json_path.display() - ); - assert!( - vk_path.exists(), - "missing verification key fixture: {}", - vk_path.display() - ); - let circuit_dir = circuit_path - .iter() - .fold(backend.circuits_dir.clone(), |p, seg| p.join(seg)); - fs::create_dir_all(&circuit_dir).await.unwrap(); - fs::copy(json_path, circuit_dir.join(format!("{fixture_name}.json"))) - .await - .unwrap(); - fs::copy(vk_path, circuit_dir.join(format!("{fixture_name}.vk"))) - .await - .unwrap(); -} +use crate::common::{ + extract_field, extract_field_from_end, find_bb, setup_compiled_circuit, setup_test_prover, +}; async fn setup_share_encryption_e_sm_test() -> Option<( ZkBackend, @@ -144,7 +58,7 @@ async fn setup_share_encryption_e_sm_test() -> Option<( let sd: e3_fhe_params::PresetSearchDefaults = BfvPreset::InsecureThreshold512.search_defaults().unwrap(); - setup_circuit_fixtures(&backend, &["dkg", "share_encryption"], "share_encryption").await; + setup_compiled_circuit(&backend, "dkg", "share_encryption").await; let sample = ShareEncryptionCircuitData::generate_sample( preset, @@ -184,7 +98,7 @@ async fn setup_share_encryption_sk_test() -> Option<( let sd: e3_fhe_params::PresetSearchDefaults = BfvPreset::InsecureThreshold512.search_defaults().unwrap(); - setup_circuit_fixtures(&backend, &["dkg", "share_encryption"], "share_encryption").await; + setup_compiled_circuit(&backend, "dkg", "share_encryption").await; let sample = ShareEncryptionCircuitData::generate_sample( preset, @@ -221,12 +135,7 @@ async fn setup_share_computation_sk_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures( - &backend, - &["dkg", "sk_share_computation"], - "sk_share_computation", - ) - .await; + setup_compiled_circuit(&backend, "dkg", "sk_share_computation").await; let sample = ShareComputationCircuitData::generate_sample(preset, committee, DkgInputType::SecretKey) @@ -258,12 +167,7 @@ async fn setup_share_computation_e_sm_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures( - &backend, - &["dkg", "e_sm_share_computation"], - "e_sm_share_computation", - ) - .await; + setup_compiled_circuit(&backend, "dkg", "e_sm_share_computation").await; let sample = ShareComputationCircuitData::generate_sample( preset, @@ -298,7 +202,7 @@ async fn setup_pk_generation_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures(&backend, &["threshold", "pk_generation"], "pk_generation").await; + setup_compiled_circuit(&backend, "threshold", "pk_generation").await; let sample = PkGenerationCircuitData::generate_sample(preset, committee).ok()?; let prover = ZkProver::new(&backend); @@ -328,12 +232,7 @@ async fn setup_share_decryption_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures( - &backend, - &["threshold", "share_decryption"], - "share_decryption", - ) - .await; + setup_compiled_circuit(&backend, "threshold", "share_decryption").await; let sample = ThresholdShareDecryptionCircuitData::generate_sample(preset, committee).ok()?; let prover = ZkProver::new(&backend); @@ -363,7 +262,7 @@ async fn setup_pk_aggregation_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures(&backend, &["threshold", "pk_aggregation"], "pk_aggregation").await; + setup_compiled_circuit(&backend, "threshold", "pk_aggregation").await; let sample = PkAggregationCircuitData::generate_sample(preset, committee).ok()?; let prover = ZkProver::new(&backend); @@ -393,12 +292,7 @@ async fn setup_decrypted_shares_aggregation_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures( - &backend, - &["threshold", "decrypted_shares_aggregation_bn"], - "decrypted_shares_aggregation_bn", - ) - .await; + setup_compiled_circuit(&backend, "threshold", "decrypted_shares_aggregation_bn").await; let sample = DecryptedSharesAggregationCircuitData::generate_sample(preset, committee).ok()?; let prover = ZkProver::new(&backend); @@ -427,7 +321,7 @@ async fn setup_pk_test() -> Option<( let bb = find_bb().await?; let (backend, temp) = setup_test_prover(&bb).await; - setup_circuit_fixtures(&backend, &["dkg", "pk"], "pk").await; + setup_compiled_circuit(&backend, "dkg", "pk").await; let sample = PkCircuitData::generate_sample(preset).ok()?; let prover = ZkProver::new(&backend); diff --git a/crates/zk-prover/tests/witness_tests.rs b/crates/zk-prover/tests/witness_tests.rs index 471dd929dd..472c39624d 100644 --- a/crates/zk-prover/tests/witness_tests.rs +++ b/crates/zk-prover/tests/witness_tests.rs @@ -34,15 +34,3 @@ fn test_witness_generation_wrong_sum_fails() { assert!(result.is_err()); } - -#[test] -fn test_compiled_circuit_from_fixture() { - let fixtures = fixtures_dir(); - let circuit = CompiledCircuit::from_file(&fixtures.join("pk.json")).unwrap(); - - assert!( - !circuit.abi.parameters.is_empty(), - "PkBfv circuit should have parameters" - ); - assert!(circuit.abi.parameters.len() > 0); -} diff --git a/scripts/build-circuits.ts b/scripts/build-circuits.ts index d81f825957..53f65d76a5 100644 --- a/scripts/build-circuits.ts +++ b/scripts/build-circuits.ts @@ -81,8 +81,11 @@ class NoirCircuitBuilder { return result } - if (this.options.clean && existsSync(this.options.outputDir!)) { - rmSync(this.options.outputDir!, { recursive: true }) + if (this.options.clean) { + if (existsSync(this.options.outputDir!)) { + rmSync(this.options.outputDir!, { recursive: true }) + } + this.cleanTargetDirs(circuits) } mkdirSync(this.options.outputDir!, { recursive: true }) @@ -120,6 +123,33 @@ class NoirCircuitBuilder { } } + private cleanTargetDirs(circuits: CircuitInfo[]): void { + const cleaned = new Set() + for (const circuit of circuits) { + // Clean group-level target (e.g. circuits/bin/dkg/target) + const groupTarget = join(this.circuitsDir, circuit.group, 'target') + if (!cleaned.has(groupTarget) && existsSync(groupTarget)) { + rmSync(groupTarget, { recursive: true }) + cleaned.add(groupTarget) + } + // Clean circuit-level target (e.g. circuits/bin/dkg/pk/target) + const circuitTarget = join(circuit.path, 'target') + if (!cleaned.has(circuitTarget) && existsSync(circuitTarget)) { + rmSync(circuitTarget, { recursive: true }) + cleaned.add(circuitTarget) + } + } + // Clean root-level target (circuits/bin/target) + const rootTarget = join(this.circuitsDir, 'target') + if (existsSync(rootTarget)) { + rmSync(rootTarget, { recursive: true }) + cleaned.add(rootTarget) + } + if (cleaned.size > 0) { + console.log(` 🧹 Cleaned ${cleaned.size} stale target dir(s)`) + } + } + private discoverCircuits(): CircuitInfo[] { const circuits: CircuitInfo[] = [] if (!existsSync(this.circuitsDir)) return circuits diff --git a/scripts/generate-verifiers.ts b/scripts/generate-verifiers.ts index a9ac95e07f..3b4588578a 100644 --- a/scripts/generate-verifiers.ts +++ b/scripts/generate-verifiers.ts @@ -97,6 +97,9 @@ class VerifierGenerator { return } + // Clean stale nargo build caches to prevent using outdated artifacts + this.cleanTargetDirs(circuits) + // Prepare output directory if (this.options.clean && existsSync(this.verifierDir)) { rmSync(this.verifierDir, { recursive: true }) @@ -305,6 +308,34 @@ class VerifierGenerator { return `${pascal(group)}${pascal(name)}Verifier` } + /** + * Remove all nargo target directories to prevent stale cached artifacts + * from being picked up instead of freshly compiled ones. + */ + private cleanTargetDirs(circuits: CircuitInfo[]): void { + const cleaned = new Set() + for (const circuit of circuits) { + const groupTarget = join(this.circuitsDir, circuit.group, 'target') + if (!cleaned.has(groupTarget) && existsSync(groupTarget)) { + rmSync(groupTarget, { recursive: true }) + cleaned.add(groupTarget) + } + const circuitTarget = join(circuit.path, 'target') + if (!cleaned.has(circuitTarget) && existsSync(circuitTarget)) { + rmSync(circuitTarget, { recursive: true }) + cleaned.add(circuitTarget) + } + } + const rootTarget = join(this.circuitsDir, 'target') + if (existsSync(rootTarget)) { + rmSync(rootTarget, { recursive: true }) + cleaned.add(rootTarget) + } + if (cleaned.size > 0) { + console.log(` 🧹 Cleaned ${cleaned.size} stale target dir(s)`) + } + } + private checkTool(cmd: string, name: string): void { try { execSync(cmd, { stdio: ['pipe', 'pipe', 'pipe'] }) From db0c46f93f2f77757540f4082a44fb78760ff672 Mon Sep 17 00:00:00 2001 From: ctrlc03 <93448202+ctrlc03@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:02:49 +0000 Subject: [PATCH 3/3] trigger CI --- crates/zk-prover/src/prover.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/zk-prover/src/prover.rs b/crates/zk-prover/src/prover.rs index 30f3565138..17611eeeb4 100644 --- a/crates/zk-prover/src/prover.rs +++ b/crates/zk-prover/src/prover.rs @@ -85,6 +85,8 @@ impl ZkProver { "prove", "--scheme", "ultra_honk", + "--oracle_hash", + "keccak", "-b", &circuit_path.to_string_lossy(), "-w", @@ -179,6 +181,8 @@ impl ZkProver { "verify", "--scheme", "ultra_honk", + "--oracle-hash", + "keccak", "-i", &public_inputs_path.to_string_lossy(), "-p",