Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
PlonkVerifier
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
contract PlonkVerifier {
// Omega
uint256 constant w1 = 4158865282786404163413953114870269622875596290766033564087307867933865333818;
// Scalar field size
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// [1]_1
uint256 constant G1x = 1;
uint256 constant G1y = 2;
// [1]_2
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
// Verification Key data
uint32 constant n = 4096;
uint16 constant nPublic = 70;
uint16 constant nLagrange = 70;
uint256 constant Qmx = 5632008363968866309549108312886552672446438759246321951785047131127306162551;
uint256 constant Qmy = 4674335480452642575214556538785165255605105377475229798935024178188834872407;
uint256 constant Qlx = 17510872482381644415380425620659008743526744493436632887227325703599468154077;
uint256 constant Qly = 6860449996061978897606672597541323513293402985440940938125552661002542679250;
uint256 constant Qrx = 19183821858018632428091194942668939220752937431747787518268284848427383143212;
uint256 constant Qry = 4347656548540891302929038641252674313254826702941857072022020122615328147249;
uint256 constant Qox = 9665117680788864990870208749128335589764709447275328067622256794906329153161;
uint256 constant Qoy = 19133257155017997927710413818099652299989074681528038768096341797176504301254;
uint256 constant Qcx = 20542918934572239426377571707147586390439123111781242853681265539002448920834;
uint256 constant Qcy = 3350293089372382268875142600218565393107020378630306922363080116961645944507;
uint256 constant S1x = 20974187049570957105351523213696914970209475957622175327140712507651594603833;
uint256 constant S1y = 8929224395784987835395417924643666942337749468828169979760207440696390171328;
uint256 constant S2x = 9822675317590679120954807373656628749209744039014930540750465648111358267842;
uint256 constant S2y = 7410094228733793874364736469004097890944795501371653618707857862102426857326;
uint256 constant S3x = 12783797717795818473260214178415403074408893845856224474136891027477933696656;
uint256 constant S3y = 14575094723702245964654803700620911341309941483686476182524158276767088538968;
uint256 constant k1 = 2;
uint256 constant k2 = 3;
uint256 constant X2x1 = 21831381940315734285607113342023901060522397560371972897001948545212302161822;
uint256 constant X2x2 = 17231025384763736816414546592865244497437017442647097510447326538965263639101;
uint256 constant X2y1 = 2388026358213174446665280700919698872609886601280537296205114254867301080648;
uint256 constant X2y2 = 11507326595632554467052522095592665270651932854513688777769618397986436103170;
// Proof calldata
// Byte offset of every parameter of the calldata
// Polynomial commitments
uint16 constant pA = 4 + 0;
uint16 constant pB = 4 + 64;
uint16 constant pC = 4 + 128;
uint16 constant pZ = 4 + 192;
uint16 constant pT1 = 4 + 256;
uint16 constant pT2 = 4 + 320;
uint16 constant pT3 = 4 + 384;
uint16 constant pWxi = 4 + 448;
uint16 constant pWxiw = 4 + 512;
// Opening evaluations
uint16 constant pEval_a = 4 + 576;
uint16 constant pEval_b = 4 + 608;
uint16 constant pEval_c = 4 + 640;
uint16 constant pEval_s1 = 4 + 672;
uint16 constant pEval_s2 = 4 + 704;
uint16 constant pEval_zw = 4 + 736;
// Memory data
// Challenges
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pU = 352;
uint16 constant pPI = 384;
uint16 constant pEval_r0 = 416;
uint16 constant pD = 448;
uint16 constant pF = 512;
uint16 constant pE = 576;
uint16 constant pTmp = 640;
uint16 constant pAlpha2 = 704;
uint16 constant pZh = 736;
uint16 constant pZhInv = 768;
uint16 constant pEval_l1 = 800;
uint16 constant pEval_l2 = 832;
uint16 constant pEval_l3 = 864;
uint16 constant pEval_l4 = 896;
uint16 constant pEval_l5 = 928;
uint16 constant pEval_l6 = 960;
uint16 constant pEval_l7 = 992;
uint16 constant pEval_l8 = 1024;
uint16 constant pEval_l9 = 1056;
uint16 constant pEval_l10 = 1088;
uint16 constant pEval_l11 = 1120;
uint16 constant pEval_l12 = 1152;
uint16 constant pEval_l13 = 1184;
uint16 constant pEval_l14 = 1216;
uint16 constant pEval_l15 = 1248;
uint16 constant pEval_l16 = 1280;
uint16 constant pEval_l17 = 1312;
uint16 constant pEval_l18 = 1344;
uint16 constant pEval_l19 = 1376;
uint16 constant pEval_l20 = 1408;
uint16 constant pEval_l21 = 1440;
uint16 constant pEval_l22 = 1472;
uint16 constant pEval_l23 = 1504;
uint16 constant pEval_l24 = 1536;
uint16 constant pEval_l25 = 1568;
uint16 constant pEval_l26 = 1600;
uint16 constant pEval_l27 = 1632;
uint16 constant pEval_l28 = 1664;
uint16 constant pEval_l29 = 1696;
uint16 constant pEval_l30 = 1728;
uint16 constant pEval_l31 = 1760;
uint16 constant pEval_l32 = 1792;
uint16 constant pEval_l33 = 1824;
uint16 constant pEval_l34 = 1856;
uint16 constant pEval_l35 = 1888;
uint16 constant pEval_l36 = 1920;
uint16 constant pEval_l37 = 1952;
uint16 constant pEval_l38 = 1984;
uint16 constant pEval_l39 = 2016;
uint16 constant pEval_l40 = 2048;
uint16 constant pEval_l41 = 2080;
uint16 constant pEval_l42 = 2112;
uint16 constant pEval_l43 = 2144;
uint16 constant pEval_l44 = 2176;
uint16 constant pEval_l45 = 2208;
uint16 constant pEval_l46 = 2240;
uint16 constant pEval_l47 = 2272;
uint16 constant pEval_l48 = 2304;
uint16 constant pEval_l49 = 2336;
uint16 constant pEval_l50 = 2368;
uint16 constant pEval_l51 = 2400;
uint16 constant pEval_l52 = 2432;
uint16 constant pEval_l53 = 2464;
uint16 constant pEval_l54 = 2496;
uint16 constant pEval_l55 = 2528;
uint16 constant pEval_l56 = 2560;
uint16 constant pEval_l57 = 2592;
uint16 constant pEval_l58 = 2624;
uint16 constant pEval_l59 = 2656;
uint16 constant pEval_l60 = 2688;
uint16 constant pEval_l61 = 2720;
uint16 constant pEval_l62 = 2752;
uint16 constant pEval_l63 = 2784;
uint16 constant pEval_l64 = 2816;
uint16 constant pEval_l65 = 2848;
uint16 constant pEval_l66 = 2880;
uint16 constant pEval_l67 = 2912;
uint16 constant pEval_l68 = 2944;
uint16 constant pEval_l69 = 2976;
uint16 constant pEval_l70 = 3008;
uint16 constant lastMem = 3040;
function verifyProof(uint256[24] calldata _proof, uint256[70] calldata _pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elements
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we subtract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we subtract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput() {
checkField(calldataload(pEval_a))
checkField(calldataload(pEval_b))
checkField(calldataload(pEval_c))
checkField(calldataload(pEval_s1))
checkField(calldataload(pEval_s2))
checkField(calldataload(pEval_zw))
}
function calculateChallenges(pMem, pPublic) {
let beta
let aux
let mIn := mload(0x40) // Pointer to the next free memory position
// Compute challenge.beta & challenge.gamma
mstore(mIn, Qmx)
mstore(add(mIn, 32), Qmy)
mstore(add(mIn, 64), Qlx)
mstore(add(mIn, 96), Qly)
mstore(add(mIn, 128), Qrx)
mstore(add(mIn, 160), Qry)
mstore(add(mIn, 192), Qox)
mstore(add(mIn, 224), Qoy)
mstore(add(mIn, 256), Qcx)
mstore(add(mIn, 288), Qcy)
mstore(add(mIn, 320), S1x)
mstore(add(mIn, 352), S1y)
mstore(add(mIn, 384), S2x)
mstore(add(mIn, 416), S2y)
mstore(add(mIn, 448), S3x)
mstore(add(mIn, 480), S3y)
mstore(add(mIn, 512), calldataload(add(pPublic, 0)))
mstore(add(mIn, 544), calldataload(add(pPublic, 32)))
mstore(add(mIn, 576), calldataload(add(pPublic, 64)))
mstore(add(mIn, 608), calldataload(add(pPublic, 96)))
mstore(add(mIn, 640), calldataload(add(pPublic, 128)))
mstore(add(mIn, 672), calldataload(add(pPublic, 160)))
mstore(add(mIn, 704), calldataload(add(pPublic, 192)))
mstore(add(mIn, 736), calldataload(add(pPublic, 224)))
mstore(add(mIn, 768), calldataload(add(pPublic, 256)))
mstore(add(mIn, 800), calldataload(add(pPublic, 288)))
mstore(add(mIn, 832), calldataload(add(pPublic, 320)))
mstore(add(mIn, 864), calldataload(add(pPublic, 352)))
mstore(add(mIn, 896), calldataload(add(pPublic, 384)))
mstore(add(mIn, 928), calldataload(add(pPublic, 416)))
mstore(add(mIn, 960), calldataload(add(pPublic, 448)))
mstore(add(mIn, 992), calldataload(add(pPublic, 480)))
mstore(add(mIn, 1024), calldataload(add(pPublic, 512)))
mstore(add(mIn, 1056), calldataload(add(pPublic, 544)))
mstore(add(mIn, 1088), calldataload(add(pPublic, 576)))
mstore(add(mIn, 1120), calldataload(add(pPublic, 608)))
mstore(add(mIn, 1152), calldataload(add(pPublic, 640)))
mstore(add(mIn, 1184), calldataload(add(pPublic, 672)))
mstore(add(mIn, 1216), calldataload(add(pPublic, 704)))
mstore(add(mIn, 1248), calldataload(add(pPublic, 736)))
mstore(add(mIn, 1280), calldataload(add(pPublic, 768)))
mstore(add(mIn, 1312), calldataload(add(pPublic, 800)))
mstore(add(mIn, 1344), calldataload(add(pPublic, 832)))
mstore(add(mIn, 1376), calldataload(add(pPublic, 864)))
mstore(add(mIn, 1408), calldataload(add(pPublic, 896)))
mstore(add(mIn, 1440), calldataload(add(pPublic, 928)))
mstore(add(mIn, 1472), calldataload(add(pPublic, 960)))
mstore(add(mIn, 1504), calldataload(add(pPublic, 992)))
mstore(add(mIn, 1536), calldataload(add(pPublic, 1024)))
mstore(add(mIn, 1568), calldataload(add(pPublic, 1056)))
mstore(add(mIn, 1600), calldataload(add(pPublic, 1088)))
mstore(add(mIn, 1632), calldataload(add(pPublic, 1120)))
mstore(add(mIn, 1664), calldataload(add(pPublic, 1152)))
mstore(add(mIn, 1696), calldataload(add(pPublic, 1184)))
mstore(add(mIn, 1728), calldataload(add(pPublic, 1216)))
mstore(add(mIn, 1760), calldataload(add(pPublic, 1248)))
mstore(add(mIn, 1792), calldataload(add(pPublic, 1280)))
mstore(add(mIn, 1824), calldataload(add(pPublic, 1312)))
mstore(add(mIn, 1856), calldataload(add(pPublic, 1344)))
mstore(add(mIn, 1888), calldataload(add(pPublic, 1376)))
mstore(add(mIn, 1920), calldataload(add(pPublic, 1408)))
mstore(add(mIn, 1952), calldataload(add(pPublic, 1440)))
mstore(add(mIn, 1984), calldataload(add(pPublic, 1472)))
mstore(add(mIn, 2016), calldataload(add(pPublic, 1504)))
mstore(add(mIn, 2048), calldataload(add(pPublic, 1536)))
mstore(add(mIn, 2080), calldataload(add(pPublic, 1568)))
mstore(add(mIn, 2112), calldataload(add(pPublic, 1600)))
mstore(add(mIn, 2144), calldataload(add(pPublic, 1632)))
mstore(add(mIn, 2176), calldataload(add(pPublic, 1664)))
mstore(add(mIn, 2208), calldataload(add(pPublic, 1696)))
mstore(add(mIn, 2240), calldataload(add(pPublic, 1728)))
mstore(add(mIn, 2272), calldataload(add(pPublic, 1760)))
mstore(add(mIn, 2304), calldataload(add(pPublic, 1792)))
mstore(add(mIn, 2336), calldataload(add(pPublic, 1824)))
mstore(add(mIn, 2368), calldataload(add(pPublic, 1856)))
mstore(add(mIn, 2400), calldataload(add(pPublic, 1888)))
mstore(add(mIn, 2432), calldataload(add(pPublic, 1920)))
mstore(add(mIn, 2464), calldataload(add(pPublic, 1952)))
mstore(add(mIn, 2496), calldataload(add(pPublic, 1984)))
mstore(add(mIn, 2528), calldataload(add(pPublic, 2016)))
mstore(add(mIn, 2560), calldataload(add(pPublic, 2048)))
mstore(add(mIn, 2592), calldataload(add(pPublic, 2080)))
mstore(add(mIn, 2624), calldataload(add(pPublic, 2112)))
mstore(add(mIn, 2656), calldataload(add(pPublic, 2144)))
mstore(add(mIn, 2688), calldataload(add(pPublic, 2176)))
mstore(add(mIn, 2720), calldataload(add(pPublic, 2208)))
mstore(add(mIn, 2752 ), calldataload(pA))
mstore(add(mIn, 2784 ), calldataload(add(pA, 32)))
mstore(add(mIn, 2816 ), calldataload(pB))
mstore(add(mIn, 2848 ), calldataload(add(pB, 32)))
mstore(add(mIn, 2880 ), calldataload(pC))
mstore(add(mIn, 2912 ), calldataload(add(pC, 32)))
beta := mod(keccak256(mIn, 2944), q)
mstore(add(pMem, pBeta), beta)
// challenges.gamma
mstore(add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
// challenges.alpha
mstore(mIn, mload(add(pMem, pBeta)))
mstore(add(mIn, 32), mload(add(pMem, pGamma)))
mstore(add(mIn, 64), calldataload(pZ))
mstore(add(mIn, 96), calldataload(add(pZ, 32)))
aux := mod(keccak256(mIn, 128), q)
mstore(add(pMem, pAlpha), aux)
mstore(add(pMem, pAlpha2), mulmod(aux, aux, q))
// challenges.xi
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pT1))
mstore(add(mIn, 64), calldataload(add(pT1, 32)))
mstore(add(mIn, 96), calldataload(pT2))
mstore(add(mIn, 128), calldataload(add(pT2, 32)))
mstore(add(mIn, 160), calldataload(pT3))
mstore(add(mIn, 192), calldataload(add(pT3, 32)))
aux := mod(keccak256(mIn, 224), q)
mstore( add(pMem, pXi), aux)
// challenges.v
mstore(mIn, aux)
mstore(add(mIn, 32), calldataload(pEval_a))
mstore(add(mIn, 64), calldataload(pEval_b))
mstore(add(mIn, 96), calldataload(pEval_c))
mstore(add(mIn, 128), calldataload(pEval_s1))
mstore(add(mIn, 160), calldataload(pEval_s2))
mstore(add(mIn, 192), calldataload(pEval_zw))
let v1 := mod(keccak256(mIn, 224), q)
mstore(add(pMem, pV1), v1)
// challenges.beta * challenges.xi
mstore(add(pMem, pBetaXi), mulmod(beta, aux, q))
// challenges.xi^n
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
aux:= mulmod(aux, aux, q)
mstore(add(pMem, pXin), aux)
// Zh
aux:= mod(add(sub(aux, 1), q), q)
mstore(add(pMem, pZh), aux)
mstore(add(pMem, pZhInv), aux) // We will invert later together with lagrange pols
// challenges.v^2, challenges.v^3, challenges.v^4, challenges.v^5
aux := mulmod(v1, v1, q)
mstore(add(pMem, pV2), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV3), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV4), aux)
aux := mulmod(aux, v1, q)
mstore(add(pMem, pV5), aux)
// challenges.u
mstore(mIn, calldataload(pWxi))
mstore(add(mIn, 32), calldataload(add(pWxi, 32)))
mstore(add(mIn, 64), calldataload(pWxiw))
mstore(add(mIn, 96), calldataload(add(pWxiw, 32)))
mstore(add(pMem, pU), mod(keccak256(mIn, 128), q))
}
function calculateLagrange(pMem) {
let w := 1
mstore(
add(pMem, pEval_l1),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l2),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l3),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l4),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l5),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l6),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l7),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l8),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l9),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l10),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l11),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l12),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l13),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l14),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l15),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l16),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l17),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l18),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l19),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l20),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l21),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l22),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l23),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l24),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l25),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l26),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l27),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l28),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l29),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l30),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l31),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l32),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l33),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l34),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l35),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l36),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l37),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l38),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l39),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l40),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l41),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l42),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l43),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l44),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l45),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l46),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l47),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l48),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l49),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l50),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l51),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l52),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l53),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l54),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l55),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l56),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l57),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l58),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l59),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l60),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l61),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l62),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l63),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l64),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l65),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l66),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l67),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l68),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l69),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l70),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
inverseArray(add(pMem, pZhInv), 71 )
let zh := mload(add(pMem, pZh))
w := 1
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l2),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l2)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l3),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l3)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l4),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l4)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l5),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l5)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l6),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l6)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l7),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l7)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l8),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l8)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l9),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l9)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l10),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l10)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l11),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l11)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l12),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l12)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l13),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l13)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l14),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l14)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l15),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l15)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l16),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l16)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l17),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l17)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l18),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l18)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l19),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l19)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l20),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l20)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l21),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l21)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l22),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l22)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l23),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l23)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l24),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l24)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l25),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l25)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l26),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l26)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l27),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l27)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l28),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l28)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l29),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l29)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l30),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l30)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l31),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l31)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l32),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l32)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l33),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l33)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l34),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l34)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l35),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l35)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l36),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l36)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l37),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l37)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l38),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l38)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l39),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l39)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l40),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l40)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l41),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l41)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l42),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l42)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l43),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l43)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l44),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l44)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l45),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l45)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l46),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l46)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l47),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l47)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l48),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l48)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l49),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l49)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l50),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l50)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l51),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l51)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l52),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l52)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l53),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l53)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l54),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l54)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l55),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l55)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l56),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l56)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l57),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l57)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l58),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l58)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l59),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l59)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l60),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l60)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l61),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l61)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l62),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l62)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l63),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l63)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l64),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l64)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l65),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l65)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l66),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l66)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l67),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l67)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l68),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l68)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l69),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l69)),
zh,
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l70),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l70)),
zh,
q
),
q
)
)
}
function calculatePI(pMem, pPub) {
let pl := 0
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l1)),
calldataload(add(pPub, 0)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l2)),
calldataload(add(pPub, 32)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l3)),
calldataload(add(pPub, 64)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l4)),
calldataload(add(pPub, 96)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l5)),
calldataload(add(pPub, 128)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l6)),
calldataload(add(pPub, 160)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l7)),
calldataload(add(pPub, 192)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l8)),
calldataload(add(pPub, 224)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l9)),
calldataload(add(pPub, 256)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l10)),
calldataload(add(pPub, 288)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l11)),
calldataload(add(pPub, 320)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l12)),
calldataload(add(pPub, 352)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l13)),
calldataload(add(pPub, 384)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l14)),
calldataload(add(pPub, 416)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l15)),
calldataload(add(pPub, 448)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l16)),
calldataload(add(pPub, 480)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l17)),
calldataload(add(pPub, 512)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l18)),
calldataload(add(pPub, 544)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l19)),
calldataload(add(pPub, 576)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l20)),
calldataload(add(pPub, 608)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l21)),
calldataload(add(pPub, 640)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l22)),
calldataload(add(pPub, 672)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l23)),
calldataload(add(pPub, 704)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l24)),
calldataload(add(pPub, 736)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l25)),
calldataload(add(pPub, 768)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l26)),
calldataload(add(pPub, 800)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l27)),
calldataload(add(pPub, 832)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l28)),
calldataload(add(pPub, 864)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l29)),
calldataload(add(pPub, 896)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l30)),
calldataload(add(pPub, 928)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l31)),
calldataload(add(pPub, 960)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l32)),
calldataload(add(pPub, 992)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l33)),
calldataload(add(pPub, 1024)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l34)),
calldataload(add(pPub, 1056)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l35)),
calldataload(add(pPub, 1088)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l36)),
calldataload(add(pPub, 1120)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l37)),
calldataload(add(pPub, 1152)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l38)),
calldataload(add(pPub, 1184)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l39)),
calldataload(add(pPub, 1216)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l40)),
calldataload(add(pPub, 1248)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l41)),
calldataload(add(pPub, 1280)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l42)),
calldataload(add(pPub, 1312)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l43)),
calldataload(add(pPub, 1344)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l44)),
calldataload(add(pPub, 1376)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l45)),
calldataload(add(pPub, 1408)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l46)),
calldataload(add(pPub, 1440)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l47)),
calldataload(add(pPub, 1472)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l48)),
calldataload(add(pPub, 1504)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l49)),
calldataload(add(pPub, 1536)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l50)),
calldataload(add(pPub, 1568)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l51)),
calldataload(add(pPub, 1600)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l52)),
calldataload(add(pPub, 1632)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l53)),
calldataload(add(pPub, 1664)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l54)),
calldataload(add(pPub, 1696)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l55)),
calldataload(add(pPub, 1728)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l56)),
calldataload(add(pPub, 1760)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l57)),
calldataload(add(pPub, 1792)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l58)),
calldataload(add(pPub, 1824)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l59)),
calldataload(add(pPub, 1856)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l60)),
calldataload(add(pPub, 1888)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l61)),
calldataload(add(pPub, 1920)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l62)),
calldataload(add(pPub, 1952)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l63)),
calldataload(add(pPub, 1984)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l64)),
calldataload(add(pPub, 2016)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l65)),
calldataload(add(pPub, 2048)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l66)),
calldataload(add(pPub, 2080)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l67)),
calldataload(add(pPub, 2112)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l68)),
calldataload(add(pPub, 2144)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l69)),
calldataload(add(pPub, 2176)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l70)),
calldataload(add(pPub, 2208)),
q
)
),
q
),
q
)
mstore(add(pMem, pPI), pl)
}
function calculateR0(pMem) {
let e1 := mload(add(pMem, pPI))
let e2 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha2)), q)
let e3a := addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q)
e3a := addmod(e3a, mload(add(pMem, pGamma)), q)
let e3b := addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q)
e3b := addmod(e3b, mload(add(pMem, pGamma)), q)
let e3c := addmod(
calldataload(pEval_c),
mload(add(pMem, pGamma)),
q)
let e3 := mulmod(mulmod(e3a, e3b, q), e3c, q)
e3 := mulmod(e3, calldataload(pEval_zw), q)
e3 := mulmod(e3, mload(add(pMem, pAlpha)), q)
let r0 := addmod(e1, mod(sub(q, e2), q), q)
r0 := addmod(r0, mod(sub(q, e3), q), q)
mstore(add(pMem, pEval_r0) , r0)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_setC(pR, x, y) {
mstore(pR, x)
mstore(add(pR, 32), y)
}
function g1_calldataSet(pR, pP) {
mstore(pR, calldataload(pP))
mstore(add(pR, 32), calldataload(add(pP, 32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSet(pR, pP, s) {
g1_mulSetC(pR, mload(pP), mload(add(pP, 32)), s)
}
function calculateD(pMem) {
let _pD:= add(pMem, pD)
let gamma := mload(add(pMem, pGamma))
let mIn := mload(0x40)
mstore(0x40, add(mIn, 256)) // d1, d2, d3 & d4 (4*64 bytes)
g1_setC(_pD, Qcx, Qcy)
g1_mulAccC(_pD, Qmx, Qmy, mulmod(calldataload(pEval_a), calldataload(pEval_b), q))
g1_mulAccC(_pD, Qlx, Qly, calldataload(pEval_a))
g1_mulAccC(_pD, Qrx, Qry, calldataload(pEval_b))
g1_mulAccC(_pD, Qox, Qoy, calldataload(pEval_c))
let betaxi := mload(add(pMem, pBetaXi))
let val1 := addmod(
addmod(calldataload(pEval_a), betaxi, q),
gamma, q)
let val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(betaxi, k1, q),
q), gamma, q)
let val3 := addmod(
addmod(
calldataload(pEval_c),
mulmod(betaxi, k2, q),
q), gamma, q)
let d2a := mulmod(
mulmod(mulmod(val1, val2, q), val3, q),
mload(add(pMem, pAlpha)),
q
)
let d2b := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha2)),
q
)
// We'll use mIn to save d2
g1_calldataSet(add(mIn, 192), pZ)
g1_mulSet(
mIn,
add(mIn, 192),
addmod(addmod(d2a, d2b, q), mload(add(pMem, pU)), q))
val1 := addmod(
addmod(
calldataload(pEval_a),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s1), q),
q), gamma, q)
val2 := addmod(
addmod(
calldataload(pEval_b),
mulmod(mload(add(pMem, pBeta)), calldataload(pEval_s2), q),
q), gamma, q)
val3 := mulmod(
mulmod(mload(add(pMem, pAlpha)), mload(add(pMem, pBeta)), q),
calldataload(pEval_zw), q)
// We'll use mIn + 64 to save d3
g1_mulSetC(
add(mIn, 64),
S3x,
S3y,
mulmod(mulmod(val1, val2, q), val3, q))
// We'll use mIn + 128 to save d4
g1_calldataSet(add(mIn, 128), pT1)
g1_mulAccC(add(mIn, 128), calldataload(pT2), calldataload(add(pT2, 32)), mload(add(pMem, pXin)))
let xin2 := mulmod(mload(add(pMem, pXin)), mload(add(pMem, pXin)), q)
g1_mulAccC(add(mIn, 128), calldataload(pT3), calldataload(add(pT3, 32)) , xin2)
g1_mulSetC(add(mIn, 128), mload(add(mIn, 128)), mload(add(mIn, 160)), mload(add(pMem, pZh)))
mstore(add(add(mIn, 64), 32), mod(sub(qf, mload(add(add(mIn, 64), 32))), qf))
mstore(add(mIn, 160), mod(sub(qf, mload(add(mIn, 160))), qf))
g1_acc(_pD, mIn)
g1_acc(_pD, add(mIn, 64))
g1_acc(_pD, add(mIn, 128))
}
function calculateF(pMem) {
let p := add(pMem, pF)
g1_set(p, add(pMem, pD))
g1_mulAccC(p, calldataload(pA), calldataload(add(pA, 32)), mload(add(pMem, pV1)))
g1_mulAccC(p, calldataload(pB), calldataload(add(pB, 32)), mload(add(pMem, pV2)))
g1_mulAccC(p, calldataload(pC), calldataload(add(pC, 32)), mload(add(pMem, pV3)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV4)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV5)))
}
function calculateE(pMem) {
let s := mod(sub(q, mload(add(pMem, pEval_r0))), q)
s := addmod(s, mulmod(calldataload(pEval_a), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(calldataload(pEval_b), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(calldataload(pEval_c), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s1), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(calldataload(pEval_s2), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(calldataload(pEval_zw), mload(add(pMem, pU)), q), q)
g1_mulSetC(add(pMem, pE), G1x, G1y, s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(0x40, add(mIn, 576)) // [0..383] = pairing data, [384..447] = pWxi, [448..512] = pWxiw
let _pWxi := add(mIn, 384)
let _pWxiw := add(mIn, 448)
let _aux := add(mIn, 512)
g1_calldataSet(_pWxi, pWxi)
g1_calldataSet(_pWxiw, pWxiw)
// A1
g1_mulSet(mIn, _pWxiw, mload(add(pMem, pU)))
g1_acc(mIn, _pWxi)
mstore(add(mIn, 32), mod(sub(qf, mload(add(mIn, 32))), qf))
// [X]_2
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
// B1
g1_mulSet(add(mIn, 192), _pWxi, mload(add(pMem, pXi)))
let s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulSet(_aux, _pWxiw, s)
g1_acc(add(mIn, 192), _aux)
g1_acc(add(mIn, 192), add(pMem, pF))
mstore(add(pMem, add(pE, 32)), mod(sub(qf, mload(add(pMem, add(pE, 32)))), qf))
g1_acc(add(mIn, 192), add(pMem, pE))
// [1]_2
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput()
calculateChallenges(pMem, _pubSignals)
calculateLagrange(pMem)
calculatePI(pMem, _pubSignals)
calculateR0(pMem)
calculateD(pMem)
calculateF(pMem)
calculateE(pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"viaIR": true,
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract ABI
API[{"inputs":[{"internalType":"uint256[24]","name":"_proof","type":"uint256[24]"},{"internalType":"uint256[70]","name":"_pubSignals","type":"uint256[70]"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60808060405234610016576133ce908161001c8239f35b600080fdfe600436101561000d57600080fd5b6000803560e01c63b36ccadc1461002357600080fd5b3461092357610bc03660031901126109235736610304116109235736610bc41161092357610c6060405261005961024435610a0e565b61006561026435610a0e565b61007161028435610a0e565b61007d6102a435610a0e565b6100896102c435610a0e565b6100956102e435610a0e565b6040517f0c739a90a4c08ede904b4005bb29727f6f47e86ffe9f4b0ad8d91b7293f691778152602081017f0a559483250bf77c5029a9be97616f1776b12b61d45fc30fe6577bd956cc9c579052604081017f26b6cd7727d0e2ea9b831a4df456879b7a4787927770625b91572f8456698cdd9052606081017f0f2ae08938010a69fc2ff8fc3973ac0cddb80e838afed52de963d0098fd884d29052608081017f2a69a88c4b674e5d918b7d26d134ff6cffbb1723104891e5558a34d110703b2c905260a081017f099cafb81bf75cb3b3b8043cc4a879a4395d7c21e68fe264a9a6fae0bb2e0731905260c081017f155e43437cabe7380a36dad36e811d82db73c35427d3b31b2f66a9c08cb8fe89905260e081017f2a4d0a2f38844c678569ebfa8f7efa6a35fb6bf6b462eb48360859efe64536c6905261010081017f2d6ae14ca6e1e55e808ad564dc250451c8f3bb839fb5b975d39496c9a91ec102905261012081017f076832dd56494dd4c64e39691e8822401679b6a91527bc8c85803a1dc86fdebb905261014081017f2e5ef81c197058f5dc62b9f3ead75813bd9db12098dea5b0c4d1d7aa091b4d39905261016081017f13bdc30c7f44781fe99c2834cd947c0367f5b88a250d74c20428fcaed40bbac0905261018081017f15b76fed0ac8f1d6e459da90be39d050e389c9945debfedf26a9af1ace4f51c290526101a081017f1061f6f6e767cb48b7f745a7be53721de0964d6a7c35559bb8abdcc155d82f6e90526101c081017f1c435f833d6b71739e0d200d27dca10160533269d4550a1042d02ac034b9a69090526101e081017f20393615f5c7e74249fb870fee140e74f3e47681d425cc2ef69416de40f27558905261030435610200820152610324356102208201526103443561024082015261036435610260820152610384356102808201526103a4356102a08201526103c4356102c08201526103e4356102e082015261040435610300820152610424356103208201526104443561034082015261046435610360820152610484356103808201526104a4356103a08201526104c4356103c08201526104e4356103e082015261050435610400820152610524356104208201526105443561044082015261056435610460820152610584356104808201526105a4356104a08201526105c4356104c08201526105e4356104e082015261060435610500820152610624356105208201526106443561054082015261066435610560820152610684356105808201526106a4356105a08201526106c4356105c08201526106e4356105e082015261070435610600820152610724356106208201526107443561064082015261076435610660820152610784356106808201526107a4356106a08201526107c4356106c08201526107e4356106e082015261080435610700820152610824356107208201526108443561074082015261086435610760820152610884356107808201526108a4356107a08201526108c4356107c08201526108e4356107e082015261090435610800820152610924356108208201526109443561084082015261096435610860820152610984356108808201526109a4356108a08201526109c4356108c08201526109e4356108e0820152610a0435610900820152610a2435610920820152610a4435610940820152610a6435610960820152610a8435610980820152610aa4356109a0820152610ac4356109c0820152610ae4356109e0820152610b0435610a00820152610b2435610a20820152610b4435610a40820152610b6435610a60820152610b8435610a80820152610ba435610aa0820152600435610ac0820152602435610ae0820152604435610b00820152606435610b20820152608435610b4082015260a435610b60820152610b80812060008051602061337983398151915290068060a052602060a020600080516020613379833981519152900660c05280825260c051602083015260c435604083015260e4356060830152608082206000805160206133798339815191529006806080526000805160206133798339815191528180096103405282526101043560208301526101243560408301526101443560608301526101643560808301526101843560a08301526101a43560c083015260e0822060008051602061337983398151915290068060e0528083526102443560208401526102643560408401526102843560608401526102a43560808401526102c43560a08401526102e43560c084015260e0832060008051602061337983398151915290069181836101405260008051602061337983398151915291096101205280600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980610100527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000000160008051602061337983398151915290068061036052610380526000805160206133798339815191528180098181610160526000805160206133798339815191529109818161018052600080516020613379833981519152910990816101a05260008051602061337983398151915291096101c0526101c43581526101e43560208201526102043560408201526102243560608201526080902060008051602061337983398151915290066101e0526108ec610a2f565b6108f4612358565b6108fc6127cd565b610904612d04565b61090c612ef4565b610914612fd4565b61091c613131565b8152602090f35b80fd5b600060019160008051602061337983398151915290805b61096f575060019192501161096a57600081126109575790565b6000805160206133798339815191520190565b600080fd5b8082058481029093039392909190820290038061093d565b604051610380516103a0905b610c6082106109e7576109a590610926565b91601f19918201919081015b61038083116109bf57505052565b81809160008051602061337983398151915280825188099686519009958552019201916109b1565b80600080516020613379833981519152918493945283519009906020809101920190610993565b6000805160206133798339815191521115610a2557565b6000805260206000f35b600080516020613379833981519152807f1f5912838f01a9db572cd61d1ffca58d5577bbae517f718dbc00bfb77c49078460e05182807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000830106611000096103a05282807f273278dc0301cf1ab67275428426c7b3b1427e810ab5d4d8279a8021efbd2bc7830106611000096103c05282807f2dea18ee476c9bfe044dc5dedc4bfaeb6f72bc3105247fc673d79c9a7965d11f830106611000096103e05282807f2f0e732b960386256ff5476b0fe98f3aeb3f017320a2485460b0060489fd7a89830106611000096104005282807f296734b17119fc08cc91898ad0f9e679ee796e87d0e698e631e85fb233d1a6ef830106611000096104205282807f097d2d234ba4772c752f7262e71e05ad7bb6daa27f0222ee227a4f7c7f80532d830106611000096104405282807f12eead87ab9d649a8e7bb9350a23d769f52b66953f101a05e7b1a5611bb8c063830106611000096104605282807f2185c84d03f0ceb116d14b6007c4546cf900de4c0625bcd3b701598571513ade830106611000096104805282807f21466153ea4a70cdb89019a7a3e651e74003be067d41431bbaa775f2a8fea833830106611000096104a05282807f1d75bdd0718fb47a00397a029280a39afeb21a594f1a08b878ac9752fc6b53a5830106611000096104c05282807f070c5f05a668b3398867614e95fdbfbfdd1ba7d4876b4931262159382bd39dbc830106611000096104e05282807f0af4572d0afe5fe1412c7ca6b1b019aaec65d4b6f5fb65d9dd938309093bfac5830106611000096105005282807f0beb5e960ef05f7426f8e9a191f200d0289ec9bc830c975b39e020e39a1c39ad830106611000096105205282807efadda1bdb2b06caab63923f2e07b9174726aade727eaa517ebbad0260a818e830106611000096105405282807f06bcda193c5474ac5fe6b5f74524881525509376a7361c2d447d551eb317c82f830106611000096105605282807f0f40c30277d5052dea5d795749f1e7a1ee2b534339ac64067aa9ca7147f975e7830106611000096105805282807f28b389113b1d1c24c7ca256be24a58acc6baa5f412687e607b4e94027b5a858b830106611000096105a05282807f171f38e9be9d7c94c674ed1bc8e0b3e794481655a07a39f49b7d627962ad5cdf830106611000096105c05282807f19a751be229dd99d826d4959f55737f4d56458062852cd7339c933013ea9bab6830106611000096105e05282807e3c17f5e8907b841c1089a549c7a9d6e43e4b66c4cce12fa221e2df39cca15d830106611000096106005282807f272573c088d418d490fd0c627cd70f2bf77806766c726200edba92865506e6b7830106611000096106205282807f1222f380031a264f9c82dcab8f471ca673ca0bb0511ae6887386fcce73df5836830106611000096106405282807f13ddf80a011cab301dc85b3c5cd19b77c1356871de735cc36a7ff3f12d55b5ff830106611000096106605282807f20fba161f79db17d8cea550296a44ae718a45cebb5ea1ac2fb6859d924497174830106611000096106805282807f1e03a8e524e06bf8e83a3df1b756ed83939d3db6e60ff73ba633d4cb4b490592830106611000096106a05282807f291501f354de0fad242103650e09f95f3e1a9e0d04f70ef0edc00e96cad73a32830106611000096106c05282807f14ff1cbde7180444c6cf15a4f7090659bb50743ed0404cfa5d1db2ae3e57e9b1830106611000096106e05282807f2327845130cdbbd1a1d54f6f499a989a71116dd4e3eff9cf0646bb12f238b99c830106611000096107005282807f20dea1744e4ad8e9b328811ca5cd294a3f8ba4c9d71a249f06c5bd52890a8b6c830106611000096107205282807f1e2c9cfa2f4647152f97a69a014549fe406fcd76ba9f9b2d809fb7bdf9f9ea6a830106611000096107405282807f03415057c9f054d3c9360c4a764d39a1d9af37d42622a5e38dc45f29a45103a3830106611000096107605282807f04522e838edeaf76e13dea88a1de5225d4d21e24a8f31c217828cac4a2957a56830106611000096107805282807f197d107534009697d8f364199928147d0a6892e3c2c72417a6d3ae873562e7f0830106611000096107a05282807f190338a01581b460693a0c0e1c7a66b93d363659a2672c938bcad0b2e35e6dad830106611000096107c05282807f2f24b56eedd4fff326360a90472ad03468d0715b019cf44f410f5555093c2d65830106611000096107e05282807f1ab69c7e115cb4b5ddb8fe53580dba57478331f7276ba86cc3a48c1589d8bfcb830106611000096108005282807f1fbfe4a677f32a14423da30a25e83c868e0297c1b177103171641d57670afd30830106611000096108205282807f0eeb19098b3df11c1fbf20d34bd18356d9ff29fa1bef6479407bb7f094b07f2c830106611000096108405282807f18221fb3b961db5c3eca9ec6d7f4740d3ca7311f45becfe93690acc1370ffd06830106611000096108605282807f3029c14367abdf272c8711ff32b2534d933adf6f146f0cdaee146a4ecfd87aa7830106611000096108805282807f0558c1b32b0a3cb3b42684bc946257994b8708a9b61a3ed8edecae9bccffb440830106611000096108a05282807f12b904e5d7dc06b54af6e053f1387bd4ba831e35bd4e32ad0be25470c82aea4f830106611000096108c05282807f0fc0f26e7571b07d3e069c7b4279ce1400fadc221ab3a9afa3cd539e68b4a56e830106611000096108e05282807f1bb89cfca8a2552c9c299dd2beabc0a61e9a881d514684370e99db6fd420b365830106611000096109005282807f21212a9bd86d52758fe4d28a6f33d1e1594644fd3d6ffae4cfba93302b96472c830106611000096109205282807f09a350961498d17ffd9ce42c0defc9a84ae91f1048533f2f41e10176d02f07ad830106611000096109405282807f294e4dc5090561248a98d6416bc3a443b28badf308f3ce80a61fc378fb2829a1830106611000096109605282807f1076381b931341027112fdfa81ff24204203e09c56f34fdeb2a361d55f43cd61830106611000096109805282807f289781269ee85498875da00dbcbd84300cabf163be600727dd69a7d3762d574d830106611000096109a05282807f1838a5a6094cf464d97895c7dd7653a057322efdf1f3ed007c81ba2d72ceaea8830106611000096109c05282807f0348db597fe96c33eef2db5ddf0dd75fc7c8e15e47a003219ed7020280dc71be830106611000096109e05282807f1759226e9ccc2deae55a2ab93a5bf93d6ed533575b924a256666eda096d18b8a83010661100009610a005282807f0bcea208031fc00503f959c232271bede00c00c208c525608dbb770b283d18ad83010661100009610a205282807f2577483a072cb9ee56e70fe30f3972e1e6969a9c77a88b2557128b8097f6766183010661100009610a405282807f0eb88ee9c76f3c4757e51b3d1e2beaf8af14b3637d2331a5f9609b43959b3e6183010661100009610a605282807f2fad09d0cad58e91ad927744ccfeaddd3db816e25ba94a85c647a5cbeb8a032583010661100009610a805282807f301ecb6f813d5f31725c635bf897a9101aaab66fe034e201294a84802868b8bc83010661100009610aa05282807f16da9b1d020b6155e0b771c688208b6b0bd00a745cfa42940a7a87eee570264083010661100009610ac05282807e31b38f45d4dbdd1052e96525e820646dce03dc54fff9a1ed2138835cf021cd83010661100009610ae05282807f1918ff7ec17699f49d5d436f12d114a5c3012601f0af21f71d824a3fc432c49a83010661100009610b005282807f0d07dddb4de9fe554914398a44c143c4185090a525fd38fbef49c4688e049f3e83010661100009610b205282807f186db40c7de025a7e21a2299bba796aeb74adb265e07fdde0e8fa8d22bef498a83010661100009610b405282807f02806dd6a143b9eb7c7c9f0483d8db708e361d1ed6dc133acda9d6392413f8ca83010661100009610b605282807f2b90f142cfffd0bb89ec861da13ee8b351989ccb2f99733cf8287e00e7ddc4e283010661100009610b805282807f1c4c3a258629905ef6036a4037c3aa6ae18d1d2452d64bd2684cfa8ede70fdc783010661100009610ba05282807f07860ac423eb675b0f58b6a7bb29fcb5685c6e9a41787999198db2f9d055050083010661100009610bc05282807ef21103ef0266d640799f130cbe2e573a267e2ee8818f6cdbeddccbea14e85b83010661100009610be05282807f040f355b7ad8d1226e0e4ec2ef5685be07a702b62eaea51cbd2ded2663b8d9cc83010661100009610c005282807f020874c590d6ef16edd82bfb32a594615bb73f42f510afec6ddd7fd9bd280a3483010661100009610c2052010661100009610c40526116d7610987565b600080516020613379833981519152806103605181816103a051096103a0528180826103c051097f0931d596de2fd10f01ddd073fd5a90a976f169c76f039bb91c4775720042d43a096103c0528180826103e051097f027a358499c5042bb4027fd7a5355d71b8c12c177494f0cad00a58f9769a2ee2096103e05281808261040051097f0155db474b2e1a04485afe4b7197c9223cf4e6d55917283ce331ef8f66028578096104005281808261042051097f06fd19c17017a420ebbebc2bb08771e339ba79c0a8d2d7ab11f995e1bc2e5912096104205281808261044051097f26e7214f958d28fd4320d3539a6352afac7d0da5fab74da32167a617707facd4096104405281808261046051097f1d75a0eb35943b8f29d48c81775d80f3330881b33aa9568b5c305032d4473f9e096104605281808261048051097f0ede8625dd40d178a17efa5679bd03f02f3309fc7393b3bd8ce09c0e7eaec52309610480528180826104a051097f0f1ded1ef6e72f5bffc02c0edd9b0675e8302a41fc782d75893a7fa1470157ce096104a0528180826104c051097f12ee90a26fa1ebafb816cbb3ef00b4c22981cdef2a9f67d8cb355e40f394ac5c096104c0528180826104e051097f2957ef6d3ac8ecf02fe8e467eb83989d4b184073f24e27601dc09c5bc42c6245096104e05281808261050051097f256ff745d63340487723c90fcfd13eb23bce139183be0ab7664e728ae6c4053c096105005281808261052051097f2478efdcd24140b591575c14ef8f578cff951e8bf6acd9360a01d4b055e3c654096105205281808261054051097f2f6970d1237eefbd0d9a0c928ea0dccbb3c17d9a929185ec2bf63ac3c9f57e73096105405281808261056051097f29a77459a4dd2b7d58698fbf3c5cd04802e354d1d2835463ff64a0753ce837d2096105605281808261058051097f21238b70695c9afbcdf2cc5f378f70bb3a089505400d0c8ac9382b22a8068a1a09610580528180826105a051097f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76096105a0528180826105c051097f1945158922942394f1db589ab8a0a47593ebd1f2d93f369ca864931a8d52a322096105c0528180826105e051097f16bcfcb4be93c68c35e2fc5c8c2a206852cf90425166a31e0a18c292b156454b096105e05281808261060051097f3028367cf8a124a59c3fbc1137b9ae8643f59ce1b4ec8f61a1c012b4b6335ea4096106005281808261062051097f093edab2585d87552753395404aa493130bbe1d20d470e905627630d9af9194a096106205281808261064051097f1e415af2de1779da1bcd690af23a3bb6b469dc98289e8a08d05af8c57c20a7cb096106405281808261066051097f1c865668e014f4f99a87ea7a24afbce566fe7fd69b4613cdd96201a2c2aa4a02096106605281808261068051097f0f68ad10e993eeac2b65f0b3eadd0d760f8f8b5cc3cf55ce48799bbacbb68e8d09610680528180826106a051097f1260a58dbc513430d01607c4ca2a6ad99496aa9193a979559dae20c8a4b6fa6f096106a0528180826106c051097f074f4c7f8c53907c942f425173775efdea194a3b74c261a05621e6fd2528c5cf096106c0528180826106e051097f1b6531b4fa199be4f18130118a7852036ce37409a9792396e6c442e5b1a81650096106e05281808261070051097f0d3cca21b063e458167af64737e6bfc2b7227a7395c976c23d9b3a80fdc74665096107005281808261072051097f0f85acfe92e6c7400527c499dbb42f12e8a8437ea29f4bf23d1c384166f57495096107205281808261074051097f1237b178b1eb591488b89f1c803c0e5ee7c41ad1bf19d563c3423dd5f6061597096107405281808261076051097f2d22fe1b17414b55ef1a396c0b341ebb4e84b0745396caadb61d966a4baefc5e096107605281808261078051097f2c121fef5252f0b2d7125b2ddfa306375361ca23d0c6546fcbb92acf4d6a85ab09610780528180826107a051097f16e73dfdad310991df5ce19ce85943e01dcb5564b6f24c799d0e470cba9d1811096107a0528180826107c051097f176115d2cbafebc94f1639a86506f1a3eafdb1eed75243fdb81724e10ca19254096107c0528180826107e051097f013f9903f35ca036921a3b263a568828bf6376ed781c7c4202d2a03ee6c3d29c096107e05281808261080051097f15adb1f4cfd4eb73da97476329739e05e0b0b651524dc824803d697e66274036096108005281808261082051097f10a469cc693e76157612a2ac5b991bd69a315086c842605fd27dd83c88f502d1096108205281808261084051097f2179356955f3af0d989124e335afd5064e34be4e5dca0c1803663da35b4f80d5096108405281808261086051097f18422ebf27cfc4cd7985a6efa98ce44feb8cb72933faa0a80d5148d2b8f002fb096108605281808261088051097e3a8d2f7985c1028bc933b74ecf050f94f908d9654a63b655cd8b452027855a09610880528180826108a051097f2b0b8cbfb62763760429c0f9ed1f00c3dcacdf9ec39f31b855f546f823004bc1096108a0528180826108c051097f1dab498d095599746d5965629048dc886db0ca12bc6b3de437ffa12327d515b2096108c0528180826108e051097f20a35c046bbfefac7a49a93b3f078a4927390c265f05c6e1a014a1f5874b5a93096108e05281808261090051097f14abb176388f4afd1c26a7e3c2d597b70999602b2872ec5a35481a241bdf4c9c096109005281808261092051097f0f4323d708c44db4286b732c124d867bceeda34b3c4975ac74276263c469b8d5096109205281808261094051097f26c0fddccc98cea9bab3618a73918eb4dd4ac938316631620200f41d1fd0f854096109405281808261096051097f071600add82c3f052db76f7515bdb41975a83a5570c5a2109dc2321af4d7d660096109605281808261098051097f1fee16574e1e5f27473d47bbff82343ce63007ac22c620b2913e93be90bc32a009610980528180826109a051097f07cccd4c42494b9130f2a5a8c4c3d42d1b87f6e4bb59696966784dc079d2a8b4096109a0528180826109c051097f182ba8ccd7e4abc4ded7afeea40b04bcd101b94a87c58390c7603b667d315159096109c0528180826109e051097f2d1b7319614833f5c95d6a58a27380fd606b06ea32196d6fa50af3916f238e43096109e052818082610a0051097f190b2c044465723ed2f61afd47255f1fb95eb4f11e27266bdd7b07f3592e747709610a0052818082610a2051097f2495ac6ade11e024b456ebf44f5a3c6f4827e78670f44b30b6267e88c7c2e75409610a2052818082610a4051097f0aed0638da04e63b616935d37247e57b419d4dac0210e56beccf6a13580989a009610a4052818082610a6051097f21abbf8919c263e2606b2a7963556d64791f34e4fc963eeb4a815a505a64c1a009610a6052818082610a8051097eb744a2165c11980abdce71b482aa7fea7bd1661e10260b7d9a4fc80475fcdc09610a8052818082610aa051097e4583035ff440f845f3e25a88e9af4d0d8931d899848e901a977113c797474509610aa052818082610ac051097f1989b355df263ed3d798d3eff960ccf21c63ddd41cbf2dfd39676da50a8fd9c109610ac052818082610ae051097f30329ae39b5cc44ca7fd5c515b9937f8ba65e46c24b976ef56c0bd10930fde3409610ae052818082610b0051097f174b4ef41fbb06351af302476eb043b76532c246890a4e9a265fab542bcd3b6709610b0052818082610b2051097f235c70979347a1d46f3c0c2c3cc014990fe357a353bc37955498312b61fb60c309610b2052818082610b4051097f17f69a6663517a81d636231cc5d9c1ae70e90d221bb172b335524cc1c410b67709610b4052818082610b6051097f2de3e09c3fede63e3bd3a6b1fda87cec99fdcb29a2dd5d5676381f5acbec073709610b6052818082610b8051097f04d35d301131cf6e2e63bf98e0426fa9d69b4b7d4a1ffd544bb9779308223b1f09610b8052818082610ba051097f1418144d5b080fcac24cdb7649bdadf246a6cb2426e324bedb94fb05118f023a09610ba052818082610bc051097f28de43aebd4638cea8f78f0ec6575ba7bfd779ae3840f6f82a54429a1faafb0109610bc052818082610be051097f2f723d6ef22f395377d6a6a374c32a05ee0d6a199137e12467f418c805eb17a609610be052818082610c0051097f2c5519176658cf074a41f6f3922ad29f208ce5924b0acb7486b4086d8c47263509610c0052818082610c2051097f2e5bd9ad505ab112ca7819bb4edbc3fbcc7ca90584a8c0a4d60475ba32d7f5cd09610c2052610c4051097f110b3bef522ff64e61236f996184b2cfd2bc2c9a2839ff0387e135dc73b6f87d09610c4052565b6000805160206133798339815191528080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080610304356103a05109600003010681610324356103c051099003010681610344356103e051099003010681610364356104005109900301068161038435610420510990030106816103a435610440510990030106816103c435610460510990030106816103e43561048051099003010681610404356104a051099003010681610424356104c051099003010681610444356104e051099003010681610464356105005109900301068161048435610520510990030106816104a435610540510990030106816104c435610560510990030106816104e43561058051099003010681610504356105a051099003010681610524356105c051099003010681610544356105e051099003010681610564356106005109900301068161058435610620510990030106816105a435610640510990030106816105c435610660510990030106816105e43561068051099003010681610604356106a051099003010681610624356106c051099003010681610644356106e051099003010681610664356107005109900301068161068435610720510990030106816106a435610740510990030106816106c435610760510990030106816106e43561078051099003010681610704356107a051099003010681610724356107c051099003010681610744356107e051099003010681610764356108005109900301068161078435610820510990030106816107a435610840510990030106816107c435610860510990030106816107e43561088051099003010681610804356108a051099003010681610824356108c051099003010681610844356108e051099003010681610864356109005109900301068161088435610920510990030106816108a435610940510990030106816108c435610960510990030106816108e43561098051099003010681610904356109a051099003010681610924356109c051099003010681610944356109e05109900301068161096435610a005109900301068161098435610a20510990030106816109a435610a40510990030106816109c435610a60510990030106816109e435610a8051099003010681610a0435610aa051099003010681610a2435610ac051099003010681610a4435610ae051099003010681610a6435610b0051099003010681610a8435610b2051099003010681610aa435610b4051099003010681610ac435610b6051099003010681610ae435610b8051099003010681610b0435610ba051099003010681610b2435610bc051099003010681610b4435610be051099003010681610b6435610c0051099003010681610b8435610c2051099003010681610ba435610c4051099003010661020052565b61020051600080516020613379833981519152908180610340516103a051099181808060a0518160c051918160805193816102e435938180846102843508938180808381806102c4358909610264350808946102a4359009610244350808090909098103069381030690080861022052565b604090608082516020610240938451835261026051828401528051868401520151606082015260066107cf195a01fa15610a2557565b60409060808251825181526020830151602082015261028051848201526102a051606082015260066107cf195a01fa15610a2557565b6040906080825182518152602083015160208201526102c051848201526102e051606082015260066107cf195a01fa15610a2557565b608060409260208451918451835281850151828401528051868401520151606082015260066107cf195a01fa15610a2557565b604051907f0c739a90a4c08ede904b4005bb29727f6f47e86ffe9f4b0ad8d91b7293f6917782527f0a559483250bf77c5029a9be97616f1776b12b61d45fc30fe6577bd956cc9c576020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f26b6cd7727d0e2ea9b831a4df456879b7a4787927770625b91572f8456698cdd82527f0f2ae08938010a69fc2ff8fc3973ac0cddb80e838afed52de963d0098fd884d26020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f2a69a88c4b674e5d918b7d26d134ff6cffbb1723104891e5558a34d110703b2c82527f099cafb81bf75cb3b3b8043cc4a879a4395d7c21e68fe264a9a6fae0bb2e07316020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f155e43437cabe7380a36dad36e811d82db73c35427d3b31b2f66a9c08cb8fe8982527f2a4d0a2f38844c678569ebfa8f7efa6a35fb6bf6b462eb48360859efe64536c66020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f15b76fed0ac8f1d6e459da90be39d050e389c9945debfedf26a9af1ace4f51c282527f1061f6f6e767cb48b7f745a7be53721de0964d6a7c35559bb8abdcc155d82f6e6020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261028094855190526102a05160608401525a01fa15610a2557565b91906040519283526020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261028094855190526102a05160608401525a01fa15610a2557565b916040519182526020820152604081019283526107cf19906040816060816007865a01fa15610a2557600660809260409585519052602085015160608401525a01fa15610a2557565b60606040928351907f1c435f833d6b71739e0d200d27dca10160533269d4550a1042d02ac034b9a69082527f20393615f5c7e74249fb870fee140e74f3e47681d425cc2ef69416de40f2755860208301528482015260076107cf195a01fa15610a2557565b9190604093606092855192835260208301528482015260076107cf195a01fa15610a2557565b60208201519151612d02939291612cca565b565b612d0260c051612eef60405191612eef61010093848101604052612d6d7f2d6ae14ca6e1e55e808ad564dc250451c8f3bb839fb5b975d39496c9a91ec102610240527f076832dd56494dd4c64e39691e8822401679b6a91527bc8c85803a1dc86fdebb61026052565b612e9f600080516020613379833981519152612d9181610264356102443509612914565b612d9d610244356129a0565b612da961026435612a2c565b612db561028435612ab8565b612e1f6101205182608051918180610340516103a051098160c08a0195612de58760c4358152602060e435910152565b818d816101e05197818084818060038609610284350808938180828180600288096102643508089361024435080809090908089085612cf0565b612e618160a05181806102e435818460805109099181604089019a8180808381806102c4358909610264350808946102a4359009610244350808090986612c65565b6080830196612e7b88610104358152602061012435910152565b612e8e815161016435610144358b612c1c565b5180096101a4356101843588612c1c565b61036051612eb560a08301918251885189612cca565b606082017f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd479081815181030690528151810306905261283f565b61283f565b6102405161028090815261026051906102a0918252612f1b61014051602435600435612bd0565b612f2d61016051606435604435612bd0565b612f3f6101805160a435608435612bd0565b6101a051916040517f2e5ef81c197058f5dc62b9f3ead75813bd9db12098dea5b0c4d1d7aa091b4d3981527f13bdc30c7f44781fe99c2834cd947c0367f5b88a250d74c20428fcaed40bbac06020820152604081019384526107cf19936040826060816007895a01fa15610a2557604094608093600692865190525160608401525a01fa15610a2557612d026101c051612b44565b610220516000805160206133798339815191520360008051602061337983398151915290066101405161016051610180516101a051916101c051936101e05195604051966001885260208801600290526102e43590600080516020613379833981519152910995600080516020613379833981519152906102c4350994600080516020613379833981519152906102a43509936000805160206133798339815191529061028435099260008051602061337983398151915290610264350991600080516020613379833981519152906102443509600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910860408201526107cf195a01606060409260076102c093fa15610a2557565b60405161024081016040526020816101806132cc8183016101c084016132b3610200860161316a846101c435815260206101e435910152565b6102043583526102243560208401526132ad6101e09361318c8551828b612cf0565b613196868a6128e1565b898901947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd479586815181030690527f26186a2d65ee4d2f9c9a5b91f86597d35f192cd120caf7e935d8443d1938e23d60408b01527f30441fd1b5d3370482c42152a8899027716989a6996c2535bc9f7fee8aaef79e60608b01527f1970ea81dd6992adfbc571effb03503adbbb6a857f578403c6c40e22d65b3c0260808b01527f054793348f12c0cf5622c340573cb277586319de359ab9389778f689786b1e4860a08b015261326d60e05160c08c019889612cf0565b7f0931d596de2fd10f01ddd073fd5a90a976f169c76f039bb91c4775720042d43a600080516020613379833981519152809260e051905109099083612cf0565b836128e1565b6132bc82612875565b6102e090815181030690526128ab565b7f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101008301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101208301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6101408301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6101608301528160086107cf195a01fa9051169056fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212203e22c92ad59c0217aefeaf54dea9ffbd9cfc54f404d568b80fa78e29e031925f64736f6c63430008140033
Deployed Bytecode
0x600436101561000d57600080fd5b6000803560e01c63b36ccadc1461002357600080fd5b3461092357610bc03660031901126109235736610304116109235736610bc41161092357610c6060405261005961024435610a0e565b61006561026435610a0e565b61007161028435610a0e565b61007d6102a435610a0e565b6100896102c435610a0e565b6100956102e435610a0e565b6040517f0c739a90a4c08ede904b4005bb29727f6f47e86ffe9f4b0ad8d91b7293f691778152602081017f0a559483250bf77c5029a9be97616f1776b12b61d45fc30fe6577bd956cc9c579052604081017f26b6cd7727d0e2ea9b831a4df456879b7a4787927770625b91572f8456698cdd9052606081017f0f2ae08938010a69fc2ff8fc3973ac0cddb80e838afed52de963d0098fd884d29052608081017f2a69a88c4b674e5d918b7d26d134ff6cffbb1723104891e5558a34d110703b2c905260a081017f099cafb81bf75cb3b3b8043cc4a879a4395d7c21e68fe264a9a6fae0bb2e0731905260c081017f155e43437cabe7380a36dad36e811d82db73c35427d3b31b2f66a9c08cb8fe89905260e081017f2a4d0a2f38844c678569ebfa8f7efa6a35fb6bf6b462eb48360859efe64536c6905261010081017f2d6ae14ca6e1e55e808ad564dc250451c8f3bb839fb5b975d39496c9a91ec102905261012081017f076832dd56494dd4c64e39691e8822401679b6a91527bc8c85803a1dc86fdebb905261014081017f2e5ef81c197058f5dc62b9f3ead75813bd9db12098dea5b0c4d1d7aa091b4d39905261016081017f13bdc30c7f44781fe99c2834cd947c0367f5b88a250d74c20428fcaed40bbac0905261018081017f15b76fed0ac8f1d6e459da90be39d050e389c9945debfedf26a9af1ace4f51c290526101a081017f1061f6f6e767cb48b7f745a7be53721de0964d6a7c35559bb8abdcc155d82f6e90526101c081017f1c435f833d6b71739e0d200d27dca10160533269d4550a1042d02ac034b9a69090526101e081017f20393615f5c7e74249fb870fee140e74f3e47681d425cc2ef69416de40f27558905261030435610200820152610324356102208201526103443561024082015261036435610260820152610384356102808201526103a4356102a08201526103c4356102c08201526103e4356102e082015261040435610300820152610424356103208201526104443561034082015261046435610360820152610484356103808201526104a4356103a08201526104c4356103c08201526104e4356103e082015261050435610400820152610524356104208201526105443561044082015261056435610460820152610584356104808201526105a4356104a08201526105c4356104c08201526105e4356104e082015261060435610500820152610624356105208201526106443561054082015261066435610560820152610684356105808201526106a4356105a08201526106c4356105c08201526106e4356105e082015261070435610600820152610724356106208201526107443561064082015261076435610660820152610784356106808201526107a4356106a08201526107c4356106c08201526107e4356106e082015261080435610700820152610824356107208201526108443561074082015261086435610760820152610884356107808201526108a4356107a08201526108c4356107c08201526108e4356107e082015261090435610800820152610924356108208201526109443561084082015261096435610860820152610984356108808201526109a4356108a08201526109c4356108c08201526109e4356108e0820152610a0435610900820152610a2435610920820152610a4435610940820152610a6435610960820152610a8435610980820152610aa4356109a0820152610ac4356109c0820152610ae4356109e0820152610b0435610a00820152610b2435610a20820152610b4435610a40820152610b6435610a60820152610b8435610a80820152610ba435610aa0820152600435610ac0820152602435610ae0820152604435610b00820152606435610b20820152608435610b4082015260a435610b60820152610b80812060008051602061337983398151915290068060a052602060a020600080516020613379833981519152900660c05280825260c051602083015260c435604083015260e4356060830152608082206000805160206133798339815191529006806080526000805160206133798339815191528180096103405282526101043560208301526101243560408301526101443560608301526101643560808301526101843560a08301526101a43560c083015260e0822060008051602061337983398151915290068060e0528083526102443560208401526102643560408401526102843560608401526102a43560808401526102c43560a08401526102e43560c084015260e0832060008051602061337983398151915290069181836101405260008051602061337983398151915291096101205280600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980600080516020613379833981519152910980610100527f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000000160008051602061337983398151915290068061036052610380526000805160206133798339815191528180098181610160526000805160206133798339815191529109818161018052600080516020613379833981519152910990816101a05260008051602061337983398151915291096101c0526101c43581526101e43560208201526102043560408201526102243560608201526080902060008051602061337983398151915290066101e0526108ec610a2f565b6108f4612358565b6108fc6127cd565b610904612d04565b61090c612ef4565b610914612fd4565b61091c613131565b8152602090f35b80fd5b600060019160008051602061337983398151915290805b61096f575060019192501161096a57600081126109575790565b6000805160206133798339815191520190565b600080fd5b8082058481029093039392909190820290038061093d565b604051610380516103a0905b610c6082106109e7576109a590610926565b91601f19918201919081015b61038083116109bf57505052565b81809160008051602061337983398151915280825188099686519009958552019201916109b1565b80600080516020613379833981519152918493945283519009906020809101920190610993565b6000805160206133798339815191521115610a2557565b6000805260206000f35b600080516020613379833981519152807f1f5912838f01a9db572cd61d1ffca58d5577bbae517f718dbc00bfb77c49078460e05182807f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000830106611000096103a05282807f273278dc0301cf1ab67275428426c7b3b1427e810ab5d4d8279a8021efbd2bc7830106611000096103c05282807f2dea18ee476c9bfe044dc5dedc4bfaeb6f72bc3105247fc673d79c9a7965d11f830106611000096103e05282807f2f0e732b960386256ff5476b0fe98f3aeb3f017320a2485460b0060489fd7a89830106611000096104005282807f296734b17119fc08cc91898ad0f9e679ee796e87d0e698e631e85fb233d1a6ef830106611000096104205282807f097d2d234ba4772c752f7262e71e05ad7bb6daa27f0222ee227a4f7c7f80532d830106611000096104405282807f12eead87ab9d649a8e7bb9350a23d769f52b66953f101a05e7b1a5611bb8c063830106611000096104605282807f2185c84d03f0ceb116d14b6007c4546cf900de4c0625bcd3b701598571513ade830106611000096104805282807f21466153ea4a70cdb89019a7a3e651e74003be067d41431bbaa775f2a8fea833830106611000096104a05282807f1d75bdd0718fb47a00397a029280a39afeb21a594f1a08b878ac9752fc6b53a5830106611000096104c05282807f070c5f05a668b3398867614e95fdbfbfdd1ba7d4876b4931262159382bd39dbc830106611000096104e05282807f0af4572d0afe5fe1412c7ca6b1b019aaec65d4b6f5fb65d9dd938309093bfac5830106611000096105005282807f0beb5e960ef05f7426f8e9a191f200d0289ec9bc830c975b39e020e39a1c39ad830106611000096105205282807efadda1bdb2b06caab63923f2e07b9174726aade727eaa517ebbad0260a818e830106611000096105405282807f06bcda193c5474ac5fe6b5f74524881525509376a7361c2d447d551eb317c82f830106611000096105605282807f0f40c30277d5052dea5d795749f1e7a1ee2b534339ac64067aa9ca7147f975e7830106611000096105805282807f28b389113b1d1c24c7ca256be24a58acc6baa5f412687e607b4e94027b5a858b830106611000096105a05282807f171f38e9be9d7c94c674ed1bc8e0b3e794481655a07a39f49b7d627962ad5cdf830106611000096105c05282807f19a751be229dd99d826d4959f55737f4d56458062852cd7339c933013ea9bab6830106611000096105e05282807e3c17f5e8907b841c1089a549c7a9d6e43e4b66c4cce12fa221e2df39cca15d830106611000096106005282807f272573c088d418d490fd0c627cd70f2bf77806766c726200edba92865506e6b7830106611000096106205282807f1222f380031a264f9c82dcab8f471ca673ca0bb0511ae6887386fcce73df5836830106611000096106405282807f13ddf80a011cab301dc85b3c5cd19b77c1356871de735cc36a7ff3f12d55b5ff830106611000096106605282807f20fba161f79db17d8cea550296a44ae718a45cebb5ea1ac2fb6859d924497174830106611000096106805282807f1e03a8e524e06bf8e83a3df1b756ed83939d3db6e60ff73ba633d4cb4b490592830106611000096106a05282807f291501f354de0fad242103650e09f95f3e1a9e0d04f70ef0edc00e96cad73a32830106611000096106c05282807f14ff1cbde7180444c6cf15a4f7090659bb50743ed0404cfa5d1db2ae3e57e9b1830106611000096106e05282807f2327845130cdbbd1a1d54f6f499a989a71116dd4e3eff9cf0646bb12f238b99c830106611000096107005282807f20dea1744e4ad8e9b328811ca5cd294a3f8ba4c9d71a249f06c5bd52890a8b6c830106611000096107205282807f1e2c9cfa2f4647152f97a69a014549fe406fcd76ba9f9b2d809fb7bdf9f9ea6a830106611000096107405282807f03415057c9f054d3c9360c4a764d39a1d9af37d42622a5e38dc45f29a45103a3830106611000096107605282807f04522e838edeaf76e13dea88a1de5225d4d21e24a8f31c217828cac4a2957a56830106611000096107805282807f197d107534009697d8f364199928147d0a6892e3c2c72417a6d3ae873562e7f0830106611000096107a05282807f190338a01581b460693a0c0e1c7a66b93d363659a2672c938bcad0b2e35e6dad830106611000096107c05282807f2f24b56eedd4fff326360a90472ad03468d0715b019cf44f410f5555093c2d65830106611000096107e05282807f1ab69c7e115cb4b5ddb8fe53580dba57478331f7276ba86cc3a48c1589d8bfcb830106611000096108005282807f1fbfe4a677f32a14423da30a25e83c868e0297c1b177103171641d57670afd30830106611000096108205282807f0eeb19098b3df11c1fbf20d34bd18356d9ff29fa1bef6479407bb7f094b07f2c830106611000096108405282807f18221fb3b961db5c3eca9ec6d7f4740d3ca7311f45becfe93690acc1370ffd06830106611000096108605282807f3029c14367abdf272c8711ff32b2534d933adf6f146f0cdaee146a4ecfd87aa7830106611000096108805282807f0558c1b32b0a3cb3b42684bc946257994b8708a9b61a3ed8edecae9bccffb440830106611000096108a05282807f12b904e5d7dc06b54af6e053f1387bd4ba831e35bd4e32ad0be25470c82aea4f830106611000096108c05282807f0fc0f26e7571b07d3e069c7b4279ce1400fadc221ab3a9afa3cd539e68b4a56e830106611000096108e05282807f1bb89cfca8a2552c9c299dd2beabc0a61e9a881d514684370e99db6fd420b365830106611000096109005282807f21212a9bd86d52758fe4d28a6f33d1e1594644fd3d6ffae4cfba93302b96472c830106611000096109205282807f09a350961498d17ffd9ce42c0defc9a84ae91f1048533f2f41e10176d02f07ad830106611000096109405282807f294e4dc5090561248a98d6416bc3a443b28badf308f3ce80a61fc378fb2829a1830106611000096109605282807f1076381b931341027112fdfa81ff24204203e09c56f34fdeb2a361d55f43cd61830106611000096109805282807f289781269ee85498875da00dbcbd84300cabf163be600727dd69a7d3762d574d830106611000096109a05282807f1838a5a6094cf464d97895c7dd7653a057322efdf1f3ed007c81ba2d72ceaea8830106611000096109c05282807f0348db597fe96c33eef2db5ddf0dd75fc7c8e15e47a003219ed7020280dc71be830106611000096109e05282807f1759226e9ccc2deae55a2ab93a5bf93d6ed533575b924a256666eda096d18b8a83010661100009610a005282807f0bcea208031fc00503f959c232271bede00c00c208c525608dbb770b283d18ad83010661100009610a205282807f2577483a072cb9ee56e70fe30f3972e1e6969a9c77a88b2557128b8097f6766183010661100009610a405282807f0eb88ee9c76f3c4757e51b3d1e2beaf8af14b3637d2331a5f9609b43959b3e6183010661100009610a605282807f2fad09d0cad58e91ad927744ccfeaddd3db816e25ba94a85c647a5cbeb8a032583010661100009610a805282807f301ecb6f813d5f31725c635bf897a9101aaab66fe034e201294a84802868b8bc83010661100009610aa05282807f16da9b1d020b6155e0b771c688208b6b0bd00a745cfa42940a7a87eee570264083010661100009610ac05282807e31b38f45d4dbdd1052e96525e820646dce03dc54fff9a1ed2138835cf021cd83010661100009610ae05282807f1918ff7ec17699f49d5d436f12d114a5c3012601f0af21f71d824a3fc432c49a83010661100009610b005282807f0d07dddb4de9fe554914398a44c143c4185090a525fd38fbef49c4688e049f3e83010661100009610b205282807f186db40c7de025a7e21a2299bba796aeb74adb265e07fdde0e8fa8d22bef498a83010661100009610b405282807f02806dd6a143b9eb7c7c9f0483d8db708e361d1ed6dc133acda9d6392413f8ca83010661100009610b605282807f2b90f142cfffd0bb89ec861da13ee8b351989ccb2f99733cf8287e00e7ddc4e283010661100009610b805282807f1c4c3a258629905ef6036a4037c3aa6ae18d1d2452d64bd2684cfa8ede70fdc783010661100009610ba05282807f07860ac423eb675b0f58b6a7bb29fcb5685c6e9a41787999198db2f9d055050083010661100009610bc05282807ef21103ef0266d640799f130cbe2e573a267e2ee8818f6cdbeddccbea14e85b83010661100009610be05282807f040f355b7ad8d1226e0e4ec2ef5685be07a702b62eaea51cbd2ded2663b8d9cc83010661100009610c005282807f020874c590d6ef16edd82bfb32a594615bb73f42f510afec6ddd7fd9bd280a3483010661100009610c2052010661100009610c40526116d7610987565b600080516020613379833981519152806103605181816103a051096103a0528180826103c051097f0931d596de2fd10f01ddd073fd5a90a976f169c76f039bb91c4775720042d43a096103c0528180826103e051097f027a358499c5042bb4027fd7a5355d71b8c12c177494f0cad00a58f9769a2ee2096103e05281808261040051097f0155db474b2e1a04485afe4b7197c9223cf4e6d55917283ce331ef8f66028578096104005281808261042051097f06fd19c17017a420ebbebc2bb08771e339ba79c0a8d2d7ab11f995e1bc2e5912096104205281808261044051097f26e7214f958d28fd4320d3539a6352afac7d0da5fab74da32167a617707facd4096104405281808261046051097f1d75a0eb35943b8f29d48c81775d80f3330881b33aa9568b5c305032d4473f9e096104605281808261048051097f0ede8625dd40d178a17efa5679bd03f02f3309fc7393b3bd8ce09c0e7eaec52309610480528180826104a051097f0f1ded1ef6e72f5bffc02c0edd9b0675e8302a41fc782d75893a7fa1470157ce096104a0528180826104c051097f12ee90a26fa1ebafb816cbb3ef00b4c22981cdef2a9f67d8cb355e40f394ac5c096104c0528180826104e051097f2957ef6d3ac8ecf02fe8e467eb83989d4b184073f24e27601dc09c5bc42c6245096104e05281808261050051097f256ff745d63340487723c90fcfd13eb23bce139183be0ab7664e728ae6c4053c096105005281808261052051097f2478efdcd24140b591575c14ef8f578cff951e8bf6acd9360a01d4b055e3c654096105205281808261054051097f2f6970d1237eefbd0d9a0c928ea0dccbb3c17d9a929185ec2bf63ac3c9f57e73096105405281808261056051097f29a77459a4dd2b7d58698fbf3c5cd04802e354d1d2835463ff64a0753ce837d2096105605281808261058051097f21238b70695c9afbcdf2cc5f378f70bb3a089505400d0c8ac9382b22a8068a1a09610580528180826105a051097f07b0c561a6148404f086204a9f36ffb0617942546750f230c893619174a57a76096105a0528180826105c051097f1945158922942394f1db589ab8a0a47593ebd1f2d93f369ca864931a8d52a322096105c0528180826105e051097f16bcfcb4be93c68c35e2fc5c8c2a206852cf90425166a31e0a18c292b156454b096105e05281808261060051097f3028367cf8a124a59c3fbc1137b9ae8643f59ce1b4ec8f61a1c012b4b6335ea4096106005281808261062051097f093edab2585d87552753395404aa493130bbe1d20d470e905627630d9af9194a096106205281808261064051097f1e415af2de1779da1bcd690af23a3bb6b469dc98289e8a08d05af8c57c20a7cb096106405281808261066051097f1c865668e014f4f99a87ea7a24afbce566fe7fd69b4613cdd96201a2c2aa4a02096106605281808261068051097f0f68ad10e993eeac2b65f0b3eadd0d760f8f8b5cc3cf55ce48799bbacbb68e8d09610680528180826106a051097f1260a58dbc513430d01607c4ca2a6ad99496aa9193a979559dae20c8a4b6fa6f096106a0528180826106c051097f074f4c7f8c53907c942f425173775efdea194a3b74c261a05621e6fd2528c5cf096106c0528180826106e051097f1b6531b4fa199be4f18130118a7852036ce37409a9792396e6c442e5b1a81650096106e05281808261070051097f0d3cca21b063e458167af64737e6bfc2b7227a7395c976c23d9b3a80fdc74665096107005281808261072051097f0f85acfe92e6c7400527c499dbb42f12e8a8437ea29f4bf23d1c384166f57495096107205281808261074051097f1237b178b1eb591488b89f1c803c0e5ee7c41ad1bf19d563c3423dd5f6061597096107405281808261076051097f2d22fe1b17414b55ef1a396c0b341ebb4e84b0745396caadb61d966a4baefc5e096107605281808261078051097f2c121fef5252f0b2d7125b2ddfa306375361ca23d0c6546fcbb92acf4d6a85ab09610780528180826107a051097f16e73dfdad310991df5ce19ce85943e01dcb5564b6f24c799d0e470cba9d1811096107a0528180826107c051097f176115d2cbafebc94f1639a86506f1a3eafdb1eed75243fdb81724e10ca19254096107c0528180826107e051097f013f9903f35ca036921a3b263a568828bf6376ed781c7c4202d2a03ee6c3d29c096107e05281808261080051097f15adb1f4cfd4eb73da97476329739e05e0b0b651524dc824803d697e66274036096108005281808261082051097f10a469cc693e76157612a2ac5b991bd69a315086c842605fd27dd83c88f502d1096108205281808261084051097f2179356955f3af0d989124e335afd5064e34be4e5dca0c1803663da35b4f80d5096108405281808261086051097f18422ebf27cfc4cd7985a6efa98ce44feb8cb72933faa0a80d5148d2b8f002fb096108605281808261088051097e3a8d2f7985c1028bc933b74ecf050f94f908d9654a63b655cd8b452027855a09610880528180826108a051097f2b0b8cbfb62763760429c0f9ed1f00c3dcacdf9ec39f31b855f546f823004bc1096108a0528180826108c051097f1dab498d095599746d5965629048dc886db0ca12bc6b3de437ffa12327d515b2096108c0528180826108e051097f20a35c046bbfefac7a49a93b3f078a4927390c265f05c6e1a014a1f5874b5a93096108e05281808261090051097f14abb176388f4afd1c26a7e3c2d597b70999602b2872ec5a35481a241bdf4c9c096109005281808261092051097f0f4323d708c44db4286b732c124d867bceeda34b3c4975ac74276263c469b8d5096109205281808261094051097f26c0fddccc98cea9bab3618a73918eb4dd4ac938316631620200f41d1fd0f854096109405281808261096051097f071600add82c3f052db76f7515bdb41975a83a5570c5a2109dc2321af4d7d660096109605281808261098051097f1fee16574e1e5f27473d47bbff82343ce63007ac22c620b2913e93be90bc32a009610980528180826109a051097f07cccd4c42494b9130f2a5a8c4c3d42d1b87f6e4bb59696966784dc079d2a8b4096109a0528180826109c051097f182ba8ccd7e4abc4ded7afeea40b04bcd101b94a87c58390c7603b667d315159096109c0528180826109e051097f2d1b7319614833f5c95d6a58a27380fd606b06ea32196d6fa50af3916f238e43096109e052818082610a0051097f190b2c044465723ed2f61afd47255f1fb95eb4f11e27266bdd7b07f3592e747709610a0052818082610a2051097f2495ac6ade11e024b456ebf44f5a3c6f4827e78670f44b30b6267e88c7c2e75409610a2052818082610a4051097f0aed0638da04e63b616935d37247e57b419d4dac0210e56beccf6a13580989a009610a4052818082610a6051097f21abbf8919c263e2606b2a7963556d64791f34e4fc963eeb4a815a505a64c1a009610a6052818082610a8051097eb744a2165c11980abdce71b482aa7fea7bd1661e10260b7d9a4fc80475fcdc09610a8052818082610aa051097e4583035ff440f845f3e25a88e9af4d0d8931d899848e901a977113c797474509610aa052818082610ac051097f1989b355df263ed3d798d3eff960ccf21c63ddd41cbf2dfd39676da50a8fd9c109610ac052818082610ae051097f30329ae39b5cc44ca7fd5c515b9937f8ba65e46c24b976ef56c0bd10930fde3409610ae052818082610b0051097f174b4ef41fbb06351af302476eb043b76532c246890a4e9a265fab542bcd3b6709610b0052818082610b2051097f235c70979347a1d46f3c0c2c3cc014990fe357a353bc37955498312b61fb60c309610b2052818082610b4051097f17f69a6663517a81d636231cc5d9c1ae70e90d221bb172b335524cc1c410b67709610b4052818082610b6051097f2de3e09c3fede63e3bd3a6b1fda87cec99fdcb29a2dd5d5676381f5acbec073709610b6052818082610b8051097f04d35d301131cf6e2e63bf98e0426fa9d69b4b7d4a1ffd544bb9779308223b1f09610b8052818082610ba051097f1418144d5b080fcac24cdb7649bdadf246a6cb2426e324bedb94fb05118f023a09610ba052818082610bc051097f28de43aebd4638cea8f78f0ec6575ba7bfd779ae3840f6f82a54429a1faafb0109610bc052818082610be051097f2f723d6ef22f395377d6a6a374c32a05ee0d6a199137e12467f418c805eb17a609610be052818082610c0051097f2c5519176658cf074a41f6f3922ad29f208ce5924b0acb7486b4086d8c47263509610c0052818082610c2051097f2e5bd9ad505ab112ca7819bb4edbc3fbcc7ca90584a8c0a4d60475ba32d7f5cd09610c2052610c4051097f110b3bef522ff64e61236f996184b2cfd2bc2c9a2839ff0387e135dc73b6f87d09610c4052565b6000805160206133798339815191528080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080610304356103a05109600003010681610324356103c051099003010681610344356103e051099003010681610364356104005109900301068161038435610420510990030106816103a435610440510990030106816103c435610460510990030106816103e43561048051099003010681610404356104a051099003010681610424356104c051099003010681610444356104e051099003010681610464356105005109900301068161048435610520510990030106816104a435610540510990030106816104c435610560510990030106816104e43561058051099003010681610504356105a051099003010681610524356105c051099003010681610544356105e051099003010681610564356106005109900301068161058435610620510990030106816105a435610640510990030106816105c435610660510990030106816105e43561068051099003010681610604356106a051099003010681610624356106c051099003010681610644356106e051099003010681610664356107005109900301068161068435610720510990030106816106a435610740510990030106816106c435610760510990030106816106e43561078051099003010681610704356107a051099003010681610724356107c051099003010681610744356107e051099003010681610764356108005109900301068161078435610820510990030106816107a435610840510990030106816107c435610860510990030106816107e43561088051099003010681610804356108a051099003010681610824356108c051099003010681610844356108e051099003010681610864356109005109900301068161088435610920510990030106816108a435610940510990030106816108c435610960510990030106816108e43561098051099003010681610904356109a051099003010681610924356109c051099003010681610944356109e05109900301068161096435610a005109900301068161098435610a20510990030106816109a435610a40510990030106816109c435610a60510990030106816109e435610a8051099003010681610a0435610aa051099003010681610a2435610ac051099003010681610a4435610ae051099003010681610a6435610b0051099003010681610a8435610b2051099003010681610aa435610b4051099003010681610ac435610b6051099003010681610ae435610b8051099003010681610b0435610ba051099003010681610b2435610bc051099003010681610b4435610be051099003010681610b6435610c0051099003010681610b8435610c2051099003010681610ba435610c4051099003010661020052565b61020051600080516020613379833981519152908180610340516103a051099181808060a0518160c051918160805193816102e435938180846102843508938180808381806102c4358909610264350808946102a4359009610244350808090909098103069381030690080861022052565b604090608082516020610240938451835261026051828401528051868401520151606082015260066107cf195a01fa15610a2557565b60409060808251825181526020830151602082015261028051848201526102a051606082015260066107cf195a01fa15610a2557565b6040906080825182518152602083015160208201526102c051848201526102e051606082015260066107cf195a01fa15610a2557565b608060409260208451918451835281850151828401528051868401520151606082015260066107cf195a01fa15610a2557565b604051907f0c739a90a4c08ede904b4005bb29727f6f47e86ffe9f4b0ad8d91b7293f6917782527f0a559483250bf77c5029a9be97616f1776b12b61d45fc30fe6577bd956cc9c576020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f26b6cd7727d0e2ea9b831a4df456879b7a4787927770625b91572f8456698cdd82527f0f2ae08938010a69fc2ff8fc3973ac0cddb80e838afed52de963d0098fd884d26020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f2a69a88c4b674e5d918b7d26d134ff6cffbb1723104891e5558a34d110703b2c82527f099cafb81bf75cb3b3b8043cc4a879a4395d7c21e68fe264a9a6fae0bb2e07316020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f155e43437cabe7380a36dad36e811d82db73c35427d3b31b2f66a9c08cb8fe8982527f2a4d0a2f38844c678569ebfa8f7efa6a35fb6bf6b462eb48360859efe64536c66020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261024094855190526102605160608401525a01fa15610a2557565b604051907f15b76fed0ac8f1d6e459da90be39d050e389c9945debfedf26a9af1ace4f51c282527f1061f6f6e767cb48b7f745a7be53721de0964d6a7c35559bb8abdcc155d82f6e6020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261028094855190526102a05160608401525a01fa15610a2557565b91906040519283526020830152604082019081526107cf196040836060816007855a01fa15610a2557604092600660809261028094855190526102a05160608401525a01fa15610a2557565b916040519182526020820152604081019283526107cf19906040816060816007865a01fa15610a2557600660809260409585519052602085015160608401525a01fa15610a2557565b60606040928351907f1c435f833d6b71739e0d200d27dca10160533269d4550a1042d02ac034b9a69082527f20393615f5c7e74249fb870fee140e74f3e47681d425cc2ef69416de40f2755860208301528482015260076107cf195a01fa15610a2557565b9190604093606092855192835260208301528482015260076107cf195a01fa15610a2557565b60208201519151612d02939291612cca565b565b612d0260c051612eef60405191612eef61010093848101604052612d6d7f2d6ae14ca6e1e55e808ad564dc250451c8f3bb839fb5b975d39496c9a91ec102610240527f076832dd56494dd4c64e39691e8822401679b6a91527bc8c85803a1dc86fdebb61026052565b612e9f600080516020613379833981519152612d9181610264356102443509612914565b612d9d610244356129a0565b612da961026435612a2c565b612db561028435612ab8565b612e1f6101205182608051918180610340516103a051098160c08a0195612de58760c4358152602060e435910152565b818d816101e05197818084818060038609610284350808938180828180600288096102643508089361024435080809090908089085612cf0565b612e618160a05181806102e435818460805109099181604089019a8180808381806102c4358909610264350808946102a4359009610244350808090986612c65565b6080830196612e7b88610104358152602061012435910152565b612e8e815161016435610144358b612c1c565b5180096101a4356101843588612c1c565b61036051612eb560a08301918251885189612cca565b606082017f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd479081815181030690528151810306905261283f565b61283f565b6102405161028090815261026051906102a0918252612f1b61014051602435600435612bd0565b612f2d61016051606435604435612bd0565b612f3f6101805160a435608435612bd0565b6101a051916040517f2e5ef81c197058f5dc62b9f3ead75813bd9db12098dea5b0c4d1d7aa091b4d3981527f13bdc30c7f44781fe99c2834cd947c0367f5b88a250d74c20428fcaed40bbac06020820152604081019384526107cf19936040826060816007895a01fa15610a2557604094608093600692865190525160608401525a01fa15610a2557612d026101c051612b44565b610220516000805160206133798339815191520360008051602061337983398151915290066101405161016051610180516101a051916101c051936101e05195604051966001885260208801600290526102e43590600080516020613379833981519152910995600080516020613379833981519152906102c4350994600080516020613379833981519152906102a43509936000805160206133798339815191529061028435099260008051602061337983398151915290610264350991600080516020613379833981519152906102443509600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910890600080516020613379833981519152910860408201526107cf195a01606060409260076102c093fa15610a2557565b60405161024081016040526020816101806132cc8183016101c084016132b3610200860161316a846101c435815260206101e435910152565b6102043583526102243560208401526132ad6101e09361318c8551828b612cf0565b613196868a6128e1565b898901947f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd479586815181030690527f26186a2d65ee4d2f9c9a5b91f86597d35f192cd120caf7e935d8443d1938e23d60408b01527f30441fd1b5d3370482c42152a8899027716989a6996c2535bc9f7fee8aaef79e60608b01527f1970ea81dd6992adfbc571effb03503adbbb6a857f578403c6c40e22d65b3c0260808b01527f054793348f12c0cf5622c340573cb277586319de359ab9389778f689786b1e4860a08b015261326d60e05160c08c019889612cf0565b7f0931d596de2fd10f01ddd073fd5a90a976f169c76f039bb91c4775720042d43a600080516020613379833981519152809260e051905109099083612cf0565b836128e1565b6132bc82612875565b6102e090815181030690526128ab565b7f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101008301527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101208301527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6101408301527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6101608301528160086107cf195a01fa9051169056fe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a26469706673582212203e22c92ad59c0217aefeaf54dea9ffbd9cfc54f404d568b80fa78e29e031925f64736f6c63430008140033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.