Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 21 from a total of 21 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 15841589 | 769 days ago | IN | 0 ETH | 0.00184102 | ||||
Deposit | 15841431 | 769 days ago | IN | 0.8 ETH | 0.07390383 | ||||
Register | 15841421 | 769 days ago | IN | 0.01 ETH | 0.00635099 | ||||
Deposit | 15835776 | 770 days ago | IN | 0.1 ETH | 0.04311096 | ||||
Register | 15835537 | 770 days ago | IN | 0.01 ETH | 0.0024619 | ||||
Register | 15835536 | 770 days ago | IN | 0.01 ETH | 0.00364487 | ||||
Register | 15835389 | 770 days ago | IN | 0.01 ETH | 0.00200645 | ||||
Register | 15835385 | 770 days ago | IN | 0.01 ETH | 0.002763 | ||||
Register | 15835383 | 770 days ago | IN | 0.01 ETH | 0.00200659 | ||||
Register | 15835382 | 770 days ago | IN | 0.01 ETH | 0.00200645 | ||||
Register | 15835381 | 770 days ago | IN | 0.01 ETH | 0.00200659 | ||||
Register | 15835380 | 770 days ago | IN | 0.01 ETH | 0.00270848 | ||||
Register | 15835378 | 770 days ago | IN | 0.01 ETH | 0.00200659 | ||||
Register | 15835376 | 770 days ago | IN | 0.01 ETH | 0.0027333 | ||||
Register | 15835361 | 770 days ago | IN | 0.01 ETH | 0.00271865 | ||||
Register | 15835358 | 770 days ago | IN | 0.01 ETH | 0.00202691 | ||||
Register | 15835357 | 770 days ago | IN | 0.01 ETH | 0.00202705 | ||||
Register | 15835356 | 770 days ago | IN | 0.01 ETH | 0.00273023 | ||||
Register | 15835355 | 770 days ago | IN | 0.01 ETH | 0.00276481 | ||||
Register | 15834752 | 770 days ago | IN | 0.01 ETH | 0.00606033 | ||||
Administrate | 15828083 | 771 days ago | IN | 0 ETH | 0.00075509 |
Latest 19 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
15841431 | 769 days ago | 0.8 ETH | ||||
15841421 | 769 days ago | 0.01 ETH | ||||
15835776 | 770 days ago | 0.1 ETH | ||||
15835537 | 770 days ago | 0.01 ETH | ||||
15835536 | 770 days ago | 0.01 ETH | ||||
15835389 | 770 days ago | 0.01 ETH | ||||
15835385 | 770 days ago | 0.01 ETH | ||||
15835383 | 770 days ago | 0.01 ETH | ||||
15835382 | 770 days ago | 0.01 ETH | ||||
15835381 | 770 days ago | 0.01 ETH | ||||
15835380 | 770 days ago | 0.01 ETH | ||||
15835378 | 770 days ago | 0.01 ETH | ||||
15835376 | 770 days ago | 0.01 ETH | ||||
15835361 | 770 days ago | 0.01 ETH | ||||
15835358 | 770 days ago | 0.01 ETH | ||||
15835357 | 770 days ago | 0.01 ETH | ||||
15835356 | 770 days ago | 0.01 ETH | ||||
15835355 | 770 days ago | 0.01 ETH | ||||
15834752 | 770 days ago | 0.01 ETH |
Loading...
Loading
Contract Name:
FirnLogic
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./FirnBase.sol"; import "./DepositVerifier.sol"; import "./TransferVerifier.sol"; import "./WithdrawalVerifier.sol"; import "./Utils.sol"; contract FirnLogic { using Utils for uint256; using Utils for Utils.Point; mapping(bytes32 => uint64) _lastRollOver; bytes32[] _nonces; // would be more natural to use a mapping (really a set), but they can't be deleted / reset! uint64 _lastGlobalUpdate = 0; // will be also used as a proxy for "current epoch", seeing as rollovers will be anticipated uint256 constant EPOCH_LENGTH = 60; FirnBase immutable _base; DepositVerifier immutable _deposit; TransferVerifier immutable _transfer; WithdrawalVerifier immutable _withdrawal; event RegisterOccurred(address indexed sender, bytes32 indexed account); event DepositOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D, address indexed source, uint32 amount); // amount not indexed event TransferOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D); event WithdrawalOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D, uint32 amount, address indexed destination, bytes data); address _owner; address _treasury; uint32 _fee; // some duplication here, but this is less painful than trying to retrieve it from the IP verifier / elsewhere. bytes32 immutable _gX; bytes32 immutable _gY; modifier onlyOwner() { require(msg.sender == _owner, "Caller is not the owner."); _; } constructor(address payable base_, address deposit_, address transfer_, address withdrawal_) { _owner = msg.sender; _base = FirnBase(base_); _deposit = DepositVerifier(deposit_); _transfer = TransferVerifier(transfer_); _withdrawal = WithdrawalVerifier(withdrawal_); Utils.Point memory gTemp = Utils.mapInto("g"); _gX = gTemp.x; _gY = gTemp.y; } function administrate(address owner_, address treasury_, uint32 fee_) external onlyOwner { _owner = owner_; _treasury = treasury_; _fee = fee_; } function g() internal view returns (Utils.Point memory) { return Utils.Point(_gX, _gY); } function rollOver(bytes32 Y, uint64 epoch) internal { if (_lastRollOver[Y] < epoch) { Utils.Point[2] memory acc; (acc[0].x, acc[0].y) = _base.acc(Y, 0); (acc[1].x, acc[1].y) = _base.acc(Y, 1); Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y, 0); (pending[1].x, pending[1].y) = _base.pending(Y, 1); acc[0] = acc[0].add(pending[0]); acc[1] = acc[1].add(pending[1]); delete pending; _base.setAcc(Y, acc); _base.setPending(Y, pending); _lastRollOver[Y] = epoch; } } function touch(bytes32 Y, uint32 credit, uint64 epoch) internal { // could save a few operations if we check for the special case that current.epoch == epoch. FirnBase.Info memory current; (current.epoch, current.index, current.amount) = _base.info(Y); if (current.epoch > 0) { // will only be false for registration...? _base.setList(current.epoch, current.index, _base.lists(current.epoch, _base.lengths(current.epoch) - 1)); // list[current.index] = list[list.length - 1]; _base.popList(current.epoch); // lists[current.epoch].pop(); if (_base.lengths(current.epoch) == 0) _base.removeEpoch(current.epoch); // if (lists[current.epoch].length == 0) remove(current.epoch); else if (current.index < _base.lengths(current.epoch)) { // else if (current.index < lists[current.epoch].length) info[lists[current.epoch][current.index]].index = current.index; FirnBase.Info memory other; (other.epoch, other.index, other.amount) = _base.info(_base.lists(current.epoch, current.index)); other.index = current.index; _base.setInfo(_base.lists(current.epoch, current.index), other); } } current.epoch = epoch; current.amount += credit; // implicit conversion of RHS to uint64? if (!_base.exists(epoch)) { _base.insertEpoch(epoch); } current.index = uint64(_base.lengths(epoch)); // uint64(lists[epoch].length); _base.setInfo(Y, current); _base.pushList(epoch, Y); // lists[epoch].push(Y); } function simulateAccounts(bytes32[] calldata Y, uint32 epoch) external view returns (bytes32[2][] memory result) { // interestingly, we lose no efficiency by accepting compressed, because we never have to decompress. result = new bytes32[2][](Y.length); for (uint256 i = 0; i < Y.length; i++) { Utils.Point[2] memory acc; (acc[0].x, acc[0].y) = _base.acc(Y[i], 0); (acc[1].x, acc[1].y) = _base.acc(Y[i], 1); if (_lastRollOver[Y[i]] < epoch) { Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y[i], 0); (pending[1].x, pending[1].y) = _base.pending(Y[i], 1); acc[0] = acc[0].add(pending[0]); acc[1] = acc[1].add(pending[1]); } result[i][0] = Utils.compress(acc[0]); result[i][1] = Utils.compress(acc[1]); } } function register(bytes32 Y, bytes32[2] calldata signature) external payable { require(msg.value == 1e16, "Amount must be 0.010 ETH."); uint64 epoch = uint64(block.timestamp / EPOCH_LENGTH); uint32 credit = uint32(msg.value / 1e15); // == 10. (bool success,) = payable(_base).call{value: msg.value}(""); // forward $ to base require(success, "Forwarding funds to base failed."); require(address(_base).balance <= 1e15 * 0xFFFFFFFF, "Escrow pool now too large."); Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y, 0); (pending[1].x, pending[1].y) = _base.pending(Y, 1); pending[0] = pending[0].add(g().mul(credit)); // convert to uint256? _base.setPending(Y, pending); Utils.Point memory pub = Utils.decompress(Y); Utils.Point memory K = g().mul(uint256(signature[1])).add(pub.mul(uint256(signature[0]).neg())); uint256 c = uint256(keccak256(abi.encode("Welcome to Firn.", address(this), Y, K))).mod(); require(bytes32(c) == signature[0], "Signature failed to verify."); touch(Y, credit, epoch); emit RegisterOccurred(msg.sender, Y); } function deposit(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes calldata proof) external payable { // not doing a minimum amount here... the idea is that this function can't be used to force your way into the tree. require(msg.value % 1e15 == 0, "Must be a multiple of 0.001 ETH."); uint64 epoch = uint64(block.timestamp / EPOCH_LENGTH); uint32 credit = uint32(msg.value / 1e15); // can't overflow, by the above. (bool success,) = payable(_base).call{value: msg.value}(""); // forward $ to base require(success, "Forwarding funds to base failed."); require(address(_base).balance <= 1e15 * 0xFFFFFFFF, "Escrow pool now too large."); Utils.Statement memory statement; statement.D = Utils.decompress(D); for (uint256 i = 0; i < N; i++) { rollOver(Y[i], epoch); statement.Y[i] = Utils.decompress(Y[i]); statement.C[i] = Utils.decompress(C[i]); // mutate their pending, in advance of success. Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y[i], 0); (pending[1].x, pending[1].y) = _base.pending(Y[i], 1); pending[0] = pending[0].add(statement.C[i]); pending[1] = pending[1].add(statement.D); _base.setPending(Y[i], pending); FirnBase.Info memory info; (info.epoch,,) = _base.info(Y[i]); require(info.epoch > 0, "Only cached accounts allowed."); touch(Y[i], credit, epoch); // weird question whether this should be 0 or credit... revisit. } _deposit.verify(credit, statement, Utils.deserializeDeposit(proof)); emit DepositOccurred(Y, C, D, msg.sender, credit); } function transfer(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes32 u, uint64 epoch, uint32 tip, bytes calldata proof) external { require(epoch == block.timestamp / EPOCH_LENGTH, "Wrong epoch."); // conversion of RHS to uint64 is unnecessary / redundant if (_lastGlobalUpdate < epoch) { _lastGlobalUpdate = epoch; delete _nonces; } for (uint256 i = 0; i < _nonces.length; i++) { require(_nonces[i] != u, "Nonce already seen."); } _nonces.push(u); Utils.Statement memory statement; statement.D = Utils.decompress(D); for (uint256 i = 0; i < N; i++) { rollOver(Y[i], epoch); statement.Y[i] = Utils.decompress(Y[i]); statement.C[i] = Utils.decompress(C[i]); Utils.Point[2] memory acc; (acc[0].x, acc[0].y) = _base.acc(Y[i], 0); (acc[1].x, acc[1].y) = _base.acc(Y[i], 1); statement.CLn[i] = acc[0].add(statement.C[i]); statement.CRn[i] = acc[1].add(statement.D); // mutate their pending, in advance of success. Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y[i], 0); (pending[1].x, pending[1].y) = _base.pending(Y[i], 1); pending[0] = pending[0].add(statement.C[i]); pending[1] = pending[1].add(statement.D); _base.setPending(Y[i], pending); FirnBase.Info memory info; (info.epoch,,) = _base.info(Y[i]); require(info.epoch > 0, "Only cached accounts allowed."); touch(Y[i], 0, epoch); } statement.epoch = epoch; statement.u = Utils.decompress(u); statement.fee = tip; _transfer.verify(statement, Utils.deserializeTransfer(proof)); _base.pay(msg.sender, uint256(tip) * 1e15, ""); // use all gas here... no reason not to emit TransferOccurred(Y, C, D); } function withdraw(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes32 u, uint64 epoch, uint32 amount, uint32 tip, bytes calldata proof, address destination, bytes calldata data) external { require(epoch == block.timestamp / EPOCH_LENGTH, "Wrong epoch."); // conversion of RHS to uint64 is unnecessary. // could supply epoch ourselves; check early to save gas if (_lastGlobalUpdate < epoch) { _lastGlobalUpdate = epoch; delete _nonces; } for (uint256 i = 0; i < _nonces.length; i++) { require(_nonces[i] != u, "Nonce already seen."); } _nonces.push(u); emit WithdrawalOccurred(Y, C, D, amount, destination, data); // emit here, because of stacktoodeep. Utils.Statement memory statement; statement.D = Utils.decompress(D); for (uint256 i = 0; i < N; i++) { bytes32 Y_i = Y[i]; // necessary for stacktoodeep rollOver(Y_i, epoch); statement.Y[i] = Utils.decompress(Y_i); statement.C[i] = Utils.decompress(C[i]); Utils.Point[2] memory acc; (acc[0].x, acc[0].y) = _base.acc(Y_i, 0); (acc[1].x, acc[1].y) = _base.acc(Y_i, 1); statement.CLn[i] = acc[0].add(statement.C[i]); statement.CRn[i] = acc[1].add(statement.D); // mutate their pending, in advance of success. Utils.Point[2] memory pending; (pending[0].x, pending[0].y) = _base.pending(Y_i, 0); (pending[1].x, pending[1].y) = _base.pending(Y_i, 1); pending[0] = pending[0].add(statement.C[i]); pending[1] = pending[1].add(statement.D); _base.setPending(Y_i, pending); FirnBase.Info memory info; (info.epoch,,) = _base.info(Y_i); require(info.epoch > 0, "Only cached accounts allowed."); } uint32 burn = amount / _fee; statement.epoch = epoch; // implicit conversion to uint256 statement.u = Utils.decompress(u); statement.fee = tip + burn; // implicit conversion to uint256 uint256 salt = uint256(keccak256(abi.encode(destination, data))); // .mod(); _withdrawal.verify(amount, statement, Utils.deserializeWithdrawal(proof), salt); _base.pay{gas: 10000}(msg.sender, uint256(tip) * 1e15, ""); // payable(msg.sender).transfer(uint256(tip) * 1e15); _base.pay(_treasury, uint256(burn) * 1e15, ""); // (bool success,) = payable(_treasury).call{value: uint256(burn) * 1e15}(""); _base.pay(destination, uint256(amount) * 1e15, data); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./InnerProductVerifier.sol"; import "./Utils.sol"; contract DepositVerifier { using Utils for uint256; using Utils for Utils.Point; InnerProductVerifier immutable _ip; constructor(address ip_) { _ip = InnerProductVerifier(ip_); } function g() internal view returns (Utils.Point memory) { return Utils.Point(_ip.gX(), _ip.gY()); } function h() internal view returns (Utils.Point memory) { return Utils.Point(_ip.hX(), _ip.hY()); } function gs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.gs(i); return Utils.Point(x, y); } function hs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.hs(i); return Utils.Point(x, y); } struct Locals { uint256 v; uint256 w; uint256 vPow; uint256 wPow; uint256[n][2] f; // could just allocate extra space in the proof? uint256[N] r; // each poly is an array of length N. evaluations of prods Utils.Point temp; Utils.Point C_XR; Utils.Point y_XR; uint256 c; Utils.Point A_D; Utils.Point A_X; } function verify(uint256 amount, Utils.Statement calldata statement, Utils.DepositProof calldata proof) external view { Locals memory locals; locals.v = uint256(keccak256(abi.encode(amount, statement.Y, statement.C, statement.D, proof.A, proof.B))).mod(); locals.w = uint256(keccak256(abi.encode(locals.v, proof.C_XG, proof.y_XG))).mod(); for (uint256 k = 0; k < n; k++) { locals.f[1][k] = proof.f[k]; locals.f[0][k] = locals.w.sub(proof.f[k]); locals.temp = locals.temp.add(gs(k).mul(locals.f[1][k])); locals.temp = locals.temp.add(hs(k).mul(locals.f[1][k].mul(locals.f[0][k]))); } require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed."); locals.r = Utils.assemblePolynomials(locals.f); locals.wPow = 1; for (uint256 k = 0; k < n; k++) { locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(locals.wPow.neg())); locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(locals.wPow.neg())); locals.wPow = locals.wPow.mul(locals.w); } locals.vPow = locals.v; // used to be 1 for (uint256 i = 0; i < N; i++) { uint256 multiplier = locals.r[i].add(locals.vPow.mul(locals.wPow.sub(locals.r[i]))); // locals. ? locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier)); locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier)); locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0) } locals.C_XR = locals.C_XR.add(g().mul(amount.neg().mul(locals.wPow))); // this line is new locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg())); locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg())); locals.c = uint256(keccak256(abi.encode(locals.v, locals.A_D, locals.A_X))).mod(); require(locals.c == proof.c, "Sigma protocol failure."); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.17; // ---------------------------------------------------------------------------- // BokkyPooBah's Red-Black Tree Library v1.0-pre-release-a // // A Solidity Red-Black Tree binary search library to store and access a sorted // list of unsigned integer data. The Red-Black algorithm rebalances the binary // search tree, resulting in O(log n) insert, remove and search time (and ~gas) // // https://github.com/bokkypoobah/BokkyPooBahsRedBlackTreeLibrary // // // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2020. The MIT Licence. // ---------------------------------------------------------------------------- contract EpochTree { struct Node { uint64 parent; uint64 left; uint64 right; bool red; } uint64 public root; uint64 public blackHeight; uint64 constant EMPTY = 0; mapping(uint64 => Node) public nodes; function exists(uint64 key) public view returns (bool) { // need public for FirnLogic.sol return (key != EMPTY) && ((key == root) || (nodes[key].parent != EMPTY)); } function rotateLeft(uint64 key) internal { uint64 cursor = nodes[key].right; uint64 keyParent = nodes[key].parent; uint64 cursorLeft = nodes[cursor].left; nodes[key].right = cursorLeft; if (cursorLeft != EMPTY) { nodes[cursorLeft].parent = key; } nodes[cursor].parent = keyParent; if (keyParent == EMPTY) { root = cursor; } else if (key == nodes[keyParent].left) { nodes[keyParent].left = cursor; } else { nodes[keyParent].right = cursor; } nodes[cursor].left = key; nodes[key].parent = cursor; } function rotateRight(uint64 key) internal { uint64 cursor = nodes[key].left; uint64 keyParent = nodes[key].parent; uint64 cursorRight = nodes[cursor].right; nodes[key].left = cursorRight; if (cursorRight != EMPTY) { nodes[cursorRight].parent = key; } nodes[cursor].parent = keyParent; if (keyParent == EMPTY) { root = cursor; } else if (key == nodes[keyParent].right) { nodes[keyParent].right = cursor; } else { nodes[keyParent].left = cursor; } nodes[cursor].right = key; nodes[key].parent = cursor; } function insertFixup(uint64 key) internal { uint64 cursor; while (key != root && nodes[nodes[key].parent].red) { uint64 keyParent = nodes[key].parent; if (keyParent == nodes[nodes[keyParent].parent].left) { cursor = nodes[nodes[keyParent].parent].right; if (nodes[cursor].red) { nodes[keyParent].red = false; nodes[cursor].red = false; nodes[nodes[keyParent].parent].red = true; key = nodes[keyParent].parent; } else { if (key == nodes[keyParent].right) { key = keyParent; rotateLeft(key); } keyParent = nodes[key].parent; nodes[keyParent].red = false; nodes[nodes[keyParent].parent].red = true; rotateRight(nodes[keyParent].parent); } } else { cursor = nodes[nodes[keyParent].parent].left; if (nodes[cursor].red) { nodes[keyParent].red = false; nodes[cursor].red = false; nodes[nodes[keyParent].parent].red = true; key = nodes[keyParent].parent; } else { if (key == nodes[keyParent].left) { key = keyParent; rotateRight(key); } keyParent = nodes[key].parent; nodes[keyParent].red = false; nodes[nodes[keyParent].parent].red = true; rotateLeft(nodes[keyParent].parent); } } } if (nodes[root].red) { nodes[root].red = false; blackHeight++; } } function insert(uint64 key) internal { uint64 cursor = EMPTY; uint64 probe = root; while (probe != EMPTY) { cursor = probe; if (key < probe) { probe = nodes[probe].left; } else { probe = nodes[probe].right; } } nodes[key] = Node({parent : cursor, left : EMPTY, right : EMPTY, red : true}); if (cursor == EMPTY) { root = key; } else if (key < cursor) { nodes[cursor].left = key; } else { nodes[cursor].right = key; } insertFixup(key); } function replaceParent(uint64 a, uint64 b) internal { uint64 bParent = nodes[b].parent; nodes[a].parent = bParent; if (bParent == EMPTY) { root = a; } else { if (b == nodes[bParent].left) { nodes[bParent].left = a; } else { nodes[bParent].right = a; } } } function removeFixup(uint64 key) internal { uint64 cursor; while (key != root && !nodes[key].red) { uint64 keyParent = nodes[key].parent; if (key == nodes[keyParent].left) { cursor = nodes[keyParent].right; if (nodes[cursor].red) { nodes[cursor].red = false; nodes[keyParent].red = true; rotateLeft(keyParent); cursor = nodes[keyParent].right; } if (!nodes[nodes[cursor].left].red && !nodes[nodes[cursor].right].red) { nodes[cursor].red = true; key = keyParent; } else { if (!nodes[nodes[cursor].right].red) { nodes[nodes[cursor].left].red = false; nodes[cursor].red = true; rotateRight(cursor); cursor = nodes[keyParent].right; } nodes[cursor].red = nodes[keyParent].red; nodes[keyParent].red = false; nodes[nodes[cursor].right].red = false; rotateLeft(keyParent); return; // key = root; } } else { cursor = nodes[keyParent].left; if (nodes[cursor].red) { nodes[cursor].red = false; nodes[keyParent].red = true; rotateRight(keyParent); cursor = nodes[keyParent].left; } if (!nodes[nodes[cursor].right].red && !nodes[nodes[cursor].left].red) { nodes[cursor].red = true; key = keyParent; } else { if (!nodes[nodes[cursor].left].red) { nodes[nodes[cursor].right].red = false; nodes[cursor].red = true; rotateLeft(cursor); cursor = nodes[keyParent].left; } nodes[cursor].red = nodes[keyParent].red; nodes[keyParent].red = false; nodes[nodes[cursor].left].red = false; rotateRight(keyParent); return; // key = root; } } } if (nodes[key].red) nodes[key].red = false; else blackHeight--; } function remove(uint64 key) internal { uint64 probe; uint64 cursor; if (nodes[key].left == EMPTY || nodes[key].right == EMPTY) { cursor = key; } else { cursor = nodes[key].right; while (nodes[cursor].left != EMPTY) { cursor = nodes[cursor].left; } } if (nodes[cursor].left != EMPTY) { probe = nodes[cursor].left; } else { probe = nodes[cursor].right; } uint64 yParent = nodes[cursor].parent; nodes[probe].parent = yParent; if (yParent != EMPTY) { if (cursor == nodes[yParent].left) { nodes[yParent].left = probe; } else { nodes[yParent].right = probe; } } else { root = probe; } bool doFixup = !nodes[cursor].red; if (cursor != key) { replaceParent(cursor, key); nodes[cursor].left = nodes[key].left; nodes[nodes[cursor].left].parent = cursor; nodes[cursor].right = nodes[key].right; nodes[nodes[cursor].right].parent = cursor; nodes[cursor].red = nodes[key].red; (cursor, key) = (key, cursor); } if (doFixup) { removeFixup(probe); } delete nodes[cursor]; } } // ---------------------------------------------------------------------------- // End - BokkyPooBah's Red-Black Tree Library // ----------------------------------------------------------------------------
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./Utils.sol"; import "./EpochTree.sol"; contract FirnBase is EpochTree { address _owner; address _logic; mapping(bytes32 => Utils.Point[2]) public acc; // main account mapping mapping(bytes32 => Utils.Point[2]) public pending; // storage for pending transfers struct Info { // try to save storage space by using smaller int types here uint64 epoch; uint64 index; // index in the list uint64 amount; } mapping(bytes32 => Info) public info; // public key --> deposit info mapping(uint64 => bytes32[]) public lists; // epoch --> list of depositing accounts function lengths(uint64 epoch) external view returns (uint256) { // see https://ethereum.stackexchange.com/a/20838. return lists[epoch].length; } modifier onlyOwner() { require(msg.sender == _owner, "Caller is not the owner."); _; } modifier onlyLogic() { require(msg.sender == _logic, "Caller is not the logic contract."); _; } constructor() { _owner = msg.sender; } function administrate(address owner_, address logic_) external onlyOwner { _owner = owner_; _logic = logic_; } receive() external payable onlyLogic { // modifier isn't necessary for security, but will prevent people from wasting funds } function setAcc(bytes32 pub, Utils.Point[2] calldata value) external onlyLogic { // acc[pub] = value; // Copying of type struct Utils.Point calldata[2] calldata to storage not yet supported. acc[pub][0] = value[0]; acc[pub][1] = value[1]; } function setPending(bytes32 pub, Utils.Point[2] calldata value) external onlyLogic { // pending[pub] = value; // Copying of type struct Utils.Point calldata[2] calldata to storage not yet supported. pending[pub][0] = value[0]; pending[pub][1] = value[1]; } function setInfo(bytes32 pub, Info calldata value) external onlyLogic { info[pub] = value; } function setList(uint64 epoch, uint256 index, bytes32 value) external onlyLogic { lists[epoch][index] = value; } function popList(uint64 epoch) external onlyLogic { lists[epoch].pop(); } function pushList(uint64 epoch, bytes32 value) external onlyLogic { lists[epoch].push(value); } function insertEpoch(uint64 epoch) external onlyLogic { insert(epoch); } function removeEpoch(uint64 epoch) external onlyLogic { remove(epoch); } function pay(address destination, uint256 value, bytes calldata data) external payable onlyLogic { (bool success,) = payable(destination).call{value: value}(data); require(success, "External call failed."); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./Utils.sol"; contract InnerProductVerifier { using Utils for uint256; using Utils for Utils.Point; bytes32 public immutable gX; bytes32 public immutable gY; bytes32 public immutable hX; bytes32 public immutable hY; // above, emulating immutable `Utils.Point`s using raw `bytes32`s. save some sloads later. Utils.Point[M << 1] public gs; Utils.Point[M << 1] public hs; // have to use storage, not immutable, because solidity doesn't support non-primitive immutable types constructor() { Utils.Point memory gTemp = Utils.mapInto("g"); gX = gTemp.x; gY = gTemp.y; Utils.Point memory hTemp = Utils.mapInto("h"); hX = hTemp.x; hY = hTemp.y; for (uint256 i = 0; i < M << 1; i++) { gs[i] = Utils.mapInto("g", i); hs[i] = Utils.mapInto("h", i); } } struct Locals { uint256 o; Utils.Point P; uint256[m + 1] challenges; uint256[M << 1] s; } function verify(Utils.InnerProductStatement calldata statement, Utils.InnerProductProof calldata proof, bool transfer) external view { Locals memory locals; locals.o = statement.salt; locals.P = statement.P; uint256 M_ = M << (transfer ? 1 : 0); uint256 m_ = m + (transfer ? 1 : 0); for (uint256 i = 0; i < m_; i++) { locals.o = uint256(keccak256(abi.encode(locals.o, proof.L[i], proof.R[i]))).mod(); // overwrites locals.challenges[i] = locals.o; uint256 inverse = locals.o.inv(); locals.P = locals.P.add(proof.L[i].mul(locals.o.mul(locals.o))).add(proof.R[i].mul(inverse.mul(inverse))); } locals.s[0] = 1; for (uint256 i = 0; i < m_; i++) locals.s[0] = locals.s[0].mul(locals.challenges[i]); locals.s[0] = locals.s[0].inv(); for (uint256 i = 0; i < m_; i++) { for (uint256 j = 0; j < M_; j += 1 << m_ - i) { locals.s[j + (1 << m_ - i - 1)] = locals.s[j].mul(locals.challenges[i]).mul(locals.challenges[i]); } } Utils.Point memory temp = statement.u.mul(proof.a.mul(proof.b)); for (uint256 i = 0; i < M_; i++) { temp = temp.add(gs[i].mul(locals.s[i].mul(proof.a))); temp = temp.add(statement.hs[i].mul(locals.s[M_ - 1 - i].mul(proof.b))); } require(temp.eq(locals.P), "Inner product proof failed."); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./InnerProductVerifier.sol"; import "./Utils.sol"; contract TransferVerifier { using Utils for uint256; using Utils for Utils.Point; InnerProductVerifier immutable _ip; bytes32 immutable _gSumX; // 0x2fa4d012d8b2496ef27316c1447cd8958b034225a0fad7f9e9b944b7de8c5064 when Utils.m == 5 bytes32 immutable _gSumY; // 0x0c648fe5b6fbbda8eec3d8ce13a891b005f4228f90638e84041b46a17bff0aae constructor(address ip_) { _ip = InnerProductVerifier(ip_); Utils.Point memory gSumTemp; for (uint256 i = 0; i < M << 1; i++) { gSumTemp = gSumTemp.add(gs(i)); } _gSumX = gSumTemp.x; _gSumY = gSumTemp.y; } function g() internal view returns (Utils.Point memory) { return Utils.Point(_ip.gX(), _ip.gY()); } function h() internal view returns (Utils.Point memory) { return Utils.Point(_ip.hX(), _ip.hY()); } function gs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.gs(i); return Utils.Point(x, y); } function hs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.hs(i); return Utils.Point(x, y); } function gSum() private view returns (Utils.Point memory) { return Utils.Point(_gSumX, _gSumY); } struct Locals { uint256 v; uint256 w; uint256 vPow; uint256 wPow; uint256[n][2][2] f; uint256[N][2] r; // each poly is an array of length N. evaluations of prods Utils.Point temp; Utils.Point CLnR; Utils.Point CRnR; Utils.Point CR; Utils.Point DR; Utils.Point yR; Utils.Point gR; Utils.Point C_XR; Utils.Point y_XR; uint256 y; uint256[M << 1] ys; uint256 z; uint256[2] zs; // [z^2, z^3] uint256[M << 1] twoTimesZSquared; uint256 zSum; uint256 x; uint256 t; uint256 k; Utils.Point tEval; uint256 c; Utils.Point A_y; Utils.Point A_D; Utils.Point A_b; Utils.Point A_X; Utils.Point A_t; Utils.Point gEpoch; Utils.Point A_u; } function verify(Utils.Statement calldata statement, Utils.TransferProof calldata proof) external view { Locals memory locals; locals.v = uint256(keccak256(abi.encode(statement.Y, statement.CLn, statement.CRn, statement.C, statement.D, statement.epoch, statement.fee, proof.BA, proof.BS, proof.A, proof.B))).mod(); locals.w = uint256(keccak256(abi.encode(locals.v, proof.CLnG, proof.CRnG, proof.C_0G, proof.DG, proof.y_0G, proof.gG, proof.C_XG, proof.y_XG))).mod(); for (uint256 row = 0; row < 2; row++) { for (uint256 k = 0; k < n; k++) { locals.f[row][1][k] = proof.f[row][k]; locals.f[row][0][k] = locals.w.sub(proof.f[row][k]); locals.temp = locals.temp.add(gs(k + n * row).mul(locals.f[row][1][k])); locals.temp = locals.temp.add(hs(k + n * row).mul(locals.f[row][1][k].mul(locals.f[row][0][k]))); } } require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed."); locals.r[0] = Utils.assemblePolynomials(locals.f[0]); locals.r[1] = Utils.assemblePolynomials(locals.f[1]); locals.wPow = 1; for (uint256 k = 0; k < n; k++) { uint256 wNeg = locals.wPow.neg(); locals.CLnR = locals.CLnR.add(proof.CLnG[k].mul(wNeg)); locals.CRnR = locals.CRnR.add(proof.CRnG[k].mul(wNeg)); locals.CR = locals.CR.add(proof.C_0G[k].mul(wNeg)); locals.DR = locals.DR.add(proof.DG[k].mul(wNeg)); locals.yR = locals.yR.add(proof.y_0G[k].mul(wNeg)); locals.gR = locals.gR.add(proof.gG[k].mul(wNeg)); locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(wNeg)); locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(wNeg)); locals.wPow = locals.wPow.mul(locals.w); } locals.vPow = locals.v; for (uint256 i = 0; i < N; i++) { locals.CLnR = locals.CLnR.add(statement.CLn[i].mul(locals.r[0][i])); locals.CRnR = locals.CRnR.add(statement.CRn[i].mul(locals.r[0][i])); locals.CR = locals.CR.add(statement.C[i].mul(locals.r[0][i])); locals.yR = locals.yR.add(statement.Y[i].mul(locals.r[0][i])); uint256 multiplier = locals.r[0][i].add(locals.r[1][i]); multiplier = multiplier.add(locals.vPow.mul(locals.wPow.sub(multiplier))); locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier)); locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier)); locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0) } locals.DR = locals.DR.add(statement.D.mul(locals.wPow)); locals.gR = locals.gR.add(g().mul(locals.wPow)); locals.C_XR = locals.C_XR.add(g().mul(statement.fee.mul(locals.wPow))); // this line is new locals.y = uint256(keccak256(abi.encode(locals.w))).mod(); locals.ys[0] = 1; locals.k = 1; for (uint256 i = 1; i < M << 1; i++) { locals.ys[i] = locals.ys[i - 1].mul(locals.y); locals.k = locals.k.add(locals.ys[i]); } locals.z = uint256(keccak256(abi.encode(locals.y))).mod(); locals.zs[0] = locals.z.mul(locals.z); locals.zs[1] = locals.zs[0].mul(locals.z); locals.zSum = locals.zs[0].add(locals.zs[1]).mul(locals.z); locals.k = locals.k.mul(locals.z.sub(locals.zs[0])).sub(locals.zSum.mul(1 << M).sub(locals.zSum)); locals.t = proof.tHat.sub(locals.k); // t = tHat - delta(y, z) for (uint256 i = 0; i < M; i++) { locals.twoTimesZSquared[i] = locals.zs[0].mul(1 << i); locals.twoTimesZSquared[i + M] = locals.zs[1].mul(1 << i); } locals.x = uint256(keccak256(abi.encode(locals.z, proof.T_1, proof.T_2))).mod(); locals.tEval = proof.T_1.mul(locals.x).add(proof.T_2.mul(locals.x.mul(locals.x))); // replace with "commit"? locals.A_y = locals.gR.mul(proof.s_sk).add(locals.yR.mul(proof.c.neg())); locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg())); locals.A_b = g().mul(proof.s_b).add(locals.DR.mul(locals.zs[0].neg()).add(locals.CRnR.mul(locals.zs[1])).mul(proof.s_sk).add(locals.CR.add(g().mul(statement.fee.mul(locals.wPow))).mul(locals.zs[0].neg()).add(locals.CLnR.mul(locals.zs[1])).mul(proof.c.neg()))); locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg())); locals.A_t = g().mul(locals.t).add(locals.tEval.neg()).mul(proof.c.mul(locals.wPow)).add(h().mul(proof.s_tau)).add(g().mul(proof.s_b.neg())); locals.gEpoch = Utils.mapInto("Firn Epoch", statement.epoch); // TODO: cast my own address to string as well? locals.A_u = locals.gEpoch.mul(proof.s_sk).add(statement.u.mul(proof.c.neg())); locals.c = uint256(keccak256(abi.encode(locals.x, locals.A_y, locals.A_D, locals.A_b, locals.A_X, locals.A_t, locals.A_u))).mod(); require(locals.c == proof.c, "Sigma protocol failure."); Utils.InnerProductStatement memory ip; // statement ip.salt = uint256(keccak256(abi.encode(locals.c))).mod(); ip.u = h().mul(ip.salt); ip.P = proof.BA.add(proof.BS.mul(locals.x)).add(gSum().mul(locals.z.neg())).add(h().mul(proof.mu.neg())).add(ip.u.mul(proof.tHat)); for (uint256 i = 0; i < M << 1; i++) { ip.hs[i] = hs(i).mul(locals.ys[i].inv()); ip.P = ip.P.add(ip.hs[i].mul(locals.ys[i].mul(locals.z).add(locals.twoTimesZSquared[i]))); } _ip.verify(ip, proof.ip, true); } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; uint256 constant n = 4; uint256 constant N = 1 << n; uint256 constant m = 5; uint256 constant M = 1 << m; library Utils { uint256 constant GROUP_ORDER = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001; uint256 constant FIELD_ORDER = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47; uint256 constant PPLUS1DIV4 = 0x0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52; function add(uint256 x, uint256 y) internal pure returns (uint256) { return addmod(x, y, GROUP_ORDER); } function mul(uint256 x, uint256 y) internal pure returns (uint256) { return mulmod(x, y, GROUP_ORDER); } function inv(uint256 x) internal view returns (uint256) { return exp(x, GROUP_ORDER - 2); } function mod(uint256 x) internal pure returns (uint256) { return x % GROUP_ORDER; } function sub(uint256 x, uint256 y) internal pure returns (uint256) { return x >= y ? x - y : GROUP_ORDER - y + x; } function neg(uint256 x) internal pure returns (uint256) { return GROUP_ORDER - x; } function exp(uint256 base, uint256 exponent) internal view returns (uint256 output) { uint256 order = GROUP_ORDER; assembly { let location := mload(0x40) mstore(location, 0x20) mstore(add(location, 0x20), 0x20) mstore(add(location, 0x40), 0x20) mstore(add(location, 0x60), base) mstore(add(location, 0x80), exponent) mstore(add(location, 0xa0), order) if iszero(staticcall(gas(), 0x05, location, 0xc0, location, 0x20)) { revert(0, 0) } output := mload(location) } } function fieldExp(uint256 base, uint256 exponent) internal view returns (uint256 output) { // warning: mod p, not q uint256 order = FIELD_ORDER; assembly { let location := mload(0x40) mstore(location, 0x20) mstore(add(location, 0x20), 0x20) mstore(add(location, 0x40), 0x20) mstore(add(location, 0x60), base) mstore(add(location, 0x80), exponent) mstore(add(location, 0xa0), order) if iszero(staticcall(gas(), 0x05, location, 0xc0, location, 0x20)) { revert(0, 0) } output := mload(location) } } struct Point { bytes32 x; bytes32 y; } function add(Point memory p1, Point memory p2) internal view returns (Point memory r) { assembly { let location := mload(0x40) mstore(location, mload(p1)) mstore(add(location, 0x20), mload(add(p1, 0x20))) mstore(add(location, 0x40), mload(p2)) mstore(add(location, 0x60), mload(add(p2, 0x20))) if iszero(staticcall(gas(), 0x06, location, 0x80, r, 0x40)) { revert(0, 0) } } } function mul(Point memory p, uint256 s) internal view returns (Point memory r) { assembly { let location := mload(0x40) mstore(location, mload(p)) mstore(add(location, 0x20), mload(add(p, 0x20))) mstore(add(location, 0x40), s) if iszero(staticcall(gas(), 0x07, location, 0x60, r, 0x40)) { revert(0, 0) } } } function neg(Point memory p) internal pure returns (Point memory) { return Point(p.x, bytes32(FIELD_ORDER - uint256(p.y))); // p.y should already be reduced mod P? } function eq(Point memory p1, Point memory p2) internal pure returns (bool) { return p1.x == p2.x && p1.y == p2.y; } function decompress(bytes32 input) internal view returns (Point memory) { if (input == 0x00) return Point(0x00, 0x00); uint256 x = uint256(input); uint256 sign = (x & 0x8000000000000000000000000000000000000000000000000000000000000000) >> 255; x &= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; uint256 ySquared = fieldExp(x, 3) + 3; uint256 y = fieldExp(ySquared, PPLUS1DIV4); Point memory result = Point(bytes32(x), bytes32(y)); if (sign != y & 0x01) return neg(result); return result; } function compress(Point memory input) internal pure returns (bytes32) { uint256 result = uint256(input.x); if (uint256(input.y) & 0x01 == 0x01) result |= 0x8000000000000000000000000000000000000000000000000000000000000000; return bytes32(result); } function mapInto(uint256 seed) internal view returns (Point memory) { uint256 y; while (true) { uint256 ySquared = fieldExp(seed, 3) + 3; // addmod instead of add: waste of gas, plus function overhead cost y = fieldExp(ySquared, PPLUS1DIV4); if (fieldExp(y, 2) == ySquared) { break; } seed += 1; } return Point(bytes32(seed), bytes32(y)); } function mapInto(string memory input) internal view returns (Point memory) { return mapInto(uint256(keccak256(abi.encodePacked(input))) % FIELD_ORDER); } function mapInto(string memory input, uint256 i) internal view returns (Point memory) { return mapInto(uint256(keccak256(abi.encodePacked(input, i))) % FIELD_ORDER); } function slice(bytes memory input, uint256 start) internal pure returns (bytes32 result) { assembly { result := mload(add(add(input, 0x20), start)) } } struct Statement { Point[N] Y; Point[N] CLn; Point[N] CRn; Point[N] C; Point D; uint256 epoch; Point u; uint256 fee; } struct DepositProof { Point A; Point B; Point[n] C_XG; Point[n] y_XG; uint256[n] f; uint256 z_A; uint256 c; uint256 s_r; } function deserializeDeposit(bytes memory arr) internal view returns (DepositProof memory proof) { proof.A = decompress(slice(arr, 0)); proof.B = decompress(slice(arr, 32)); for (uint256 k = 0; k < n; k++) { proof.C_XG[k] = decompress(slice(arr, 64 + k * 32)); proof.y_XG[k] = decompress(slice(arr, 64 + (k + n) * 32)); proof.f[k] = uint256(slice(arr, 64 + n * 64 + k * 32)); } uint256 starting = n * 96; proof.z_A = uint256(slice(arr, 64 + starting)); proof.c = uint256(slice(arr, 96 + starting)); proof.s_r = uint256(slice(arr, 128 + starting)); return proof; } struct TransferProof { Point BA; Point BS; Point A; Point B; Point[n] CLnG; Point[n] CRnG; Point[n] C_0G; Point[n] DG; Point[n] y_0G; Point[n] gG; Point[n] C_XG; Point[n] y_XG; uint256[n][2] f; uint256 z_A; Point T_1; Point T_2; uint256 tHat; uint256 mu; uint256 c; uint256 s_sk; uint256 s_r; uint256 s_b; uint256 s_tau; InnerProductProof ip; } function deserializeTransfer(bytes memory arr) internal view returns (TransferProof memory proof) { proof.BA = decompress(slice(arr, 0)); proof.BS = decompress(slice(arr, 32)); proof.A = decompress(slice(arr, 64)); proof.B = decompress(slice(arr, 96)); for (uint256 k = 0; k < n; k++) { proof.CLnG[k] = decompress(slice(arr, 128 + k * 32)); proof.CRnG[k] = decompress(slice(arr, 128 + (k + n) * 32)); proof.C_0G[k] = decompress(slice(arr, 128 + n * 64 + k * 32)); proof.DG[k] = decompress(slice(arr, 128 + n * 96 + k * 32)); proof.y_0G[k] = decompress(slice(arr, 128 + n * 128 + k * 32)); proof.gG[k] = decompress(slice(arr, 128 + n * 160 + k * 32)); proof.C_XG[k] = decompress(slice(arr, 128 + n * 192 + k * 32)); proof.y_XG[k] = decompress(slice(arr, 128 + n * 224 + k * 32)); proof.f[0][k] = uint256(slice(arr, 128 + n * 256 + k * 32)); proof.f[1][k] = uint256(slice(arr, 128 + n * 288 + k * 32)); } uint256 starting = n * 320; proof.z_A = uint256(slice(arr, 128 + starting)); proof.T_1 = decompress(slice(arr, 160 + starting)); proof.T_2 = decompress(slice(arr, 192 + starting)); proof.tHat = uint256(slice(arr, 224 + starting)); proof.mu = uint256(slice(arr, 256 + starting)); proof.c = uint256(slice(arr, 288 + starting)); proof.s_sk = uint256(slice(arr, 320 + starting)); proof.s_r = uint256(slice(arr, 352 + starting)); proof.s_b = uint256(slice(arr, 384 + starting)); proof.s_tau = uint256(slice(arr, 416 + starting)); for (uint256 i = 0; i < m + 1; i++) { proof.ip.L[i] = decompress(slice(arr, 448 + starting + i * 32)); proof.ip.R[i] = decompress(slice(arr, 448 + starting + (i + m + 1) * 32)); } proof.ip.a = uint256(slice(arr, 448 + starting + (m + 1) * 64)); proof.ip.b = uint256(slice(arr, 480 + starting + (m + 1) * 64)); return proof; } struct WithdrawalProof { Point BA; Point BS; Point A; Point B; Point[n] CLnG; Point[n] CRnG; Point[n] y_0G; Point[n] gG; Point[n] C_XG; Point[n] y_XG; uint256[n] f; uint256 z_A; Point T_1; Point T_2; uint256 tHat; uint256 mu; uint256 c; uint256 s_sk; uint256 s_r; uint256 s_b; uint256 s_tau; InnerProductProof ip; } function deserializeWithdrawal(bytes memory arr) internal view returns (WithdrawalProof memory proof) { proof.BA = decompress(slice(arr, 0)); proof.BS = decompress(slice(arr, 32)); proof.A = decompress(slice(arr, 64)); proof.B = decompress(slice(arr, 96)); for (uint256 k = 0; k < n; k++) { proof.CLnG[k] = decompress(slice(arr, 128 + k * 32)); proof.CRnG[k] = decompress(slice(arr, 128 + (k + n) * 32)); proof.y_0G[k] = decompress(slice(arr, 128 + n * 64 + k * 32)); proof.gG[k] = decompress(slice(arr, 128 + n * 96 + k * 32)); proof.C_XG[k] = decompress(slice(arr, 128 + n * 128 + k * 32)); proof.y_XG[k] = decompress(slice(arr, 128 + n * 160 + k * 32)); proof.f[k] = uint256(slice(arr, 128 + n * 192 + k * 32)); } uint256 starting = n * 224; proof.z_A = uint256(slice(arr, 128 + starting)); proof.T_1 = decompress(slice(arr, 160 + starting)); proof.T_2 = decompress(slice(arr, 192 + starting)); proof.tHat = uint256(slice(arr, 224 + starting)); proof.mu = uint256(slice(arr, 256 + starting)); proof.c = uint256(slice(arr, 288 + starting)); proof.s_sk = uint256(slice(arr, 320 + starting)); proof.s_r = uint256(slice(arr, 352 + starting)); proof.s_b = uint256(slice(arr, 384 + starting)); proof.s_tau = uint256(slice(arr, 416 + starting)); for (uint256 i = 0; i < m; i++) { // will leave the `m`th element empty proof.ip.L[i] = decompress(slice(arr, 448 + starting + i * 32)); proof.ip.R[i] = decompress(slice(arr, 448 + starting + (i + m) * 32)); } proof.ip.a = uint256(slice(arr, 448 + starting + m * 64)); proof.ip.b = uint256(slice(arr, 480 + starting + m * 64)); return proof; } struct InnerProductStatement { uint256 salt; Point[M << 1] hs; // "overridden" parameters. Point u; Point P; } struct InnerProductProof { Point[m + 1] L; Point[m + 1] R; uint256 a; uint256 b; } function assemblePolynomials(uint256[n][2] memory f) internal pure returns (uint256[N] memory result) { // f is a 2m-by-2 array... containing the f's and x - f's, twice (i.e., concatenated). // output contains two "rows", each of length N. result[0] = 1; for (uint256 k = 0; k < n; k++) { for (uint256 i = 0; i < N; i += 1 << n - k) { result[i + (1 << n - 1 - k)] = mul(result[i], f[1][n - 1 - k]); result[i] = mul(result[i], f[0][n - 1 - k]); } } } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.17; import "./InnerProductVerifier.sol"; import "./Utils.sol"; contract WithdrawalVerifier { using Utils for uint256; using Utils for Utils.Point; InnerProductVerifier immutable _ip; bytes32 immutable _gSumX; // 0x1bcf9024624aef47656cdbd47d104a1b30efac20504e72d395e7e012727c73a3 when Utils.m == 5 bytes32 immutable _gSumY; // 0x052d5b8798a0be8c27d47246f021c2e9841837904a92a33dc4f6c755fda097bd constructor(address ip_) { _ip = InnerProductVerifier(ip_); Utils.Point memory gSumTemp; for (uint256 i = 0; i < M; i++) { gSumTemp = gSumTemp.add(gs(i)); } _gSumX = gSumTemp.x; _gSumY = gSumTemp.y; } function g() internal view returns (Utils.Point memory) { return Utils.Point(_ip.gX(), _ip.gY()); } function h() internal view returns (Utils.Point memory) { return Utils.Point(_ip.hX(), _ip.hY()); } function gs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.gs(i); return Utils.Point(x, y); } function hs(uint256 i) internal view returns (Utils.Point memory) { (bytes32 x, bytes32 y) = _ip.hs(i); return Utils.Point(x, y); } function gSum() private view returns (Utils.Point memory) { return Utils.Point(_gSumX, _gSumY); } struct Locals { uint256 v; uint256 w; uint256 vPow; uint256 wPow; uint256[n][2] f; // could just allocate extra space in the proof? uint256[N] r; // each poly is an array of length N. evaluations of prods Utils.Point temp; Utils.Point CLnR; Utils.Point CRnR; Utils.Point yR; Utils.Point gR; Utils.Point C_XR; Utils.Point y_XR; uint256 y; uint256[M] ys; uint256 z; uint256[1] zs; // silly. just to match zether. uint256[M] twoTimesZSquared; uint256 zSum; uint256 x; uint256 t; uint256 k; Utils.Point tEval; uint256 c; Utils.Point A_y; Utils.Point A_D; Utils.Point A_b; Utils.Point A_X; Utils.Point A_t; Utils.Point gEpoch; Utils.Point A_u; } function verify(uint256 amount, Utils.Statement calldata statement, Utils.WithdrawalProof calldata proof, uint256 salt) external view { Locals memory locals; locals.v = uint256(keccak256(abi.encode(salt, amount, statement.Y, statement.CLn, statement.CRn, statement.C, statement.D, statement.epoch, statement.fee, proof.BA, proof.BS, proof.A, proof.B))).mod(); locals.w = uint256(keccak256(abi.encode(locals.v, proof.CLnG, proof.CRnG, proof.y_0G, proof.gG, proof.C_XG, proof.y_XG))).mod(); for (uint256 k = 0; k < n; k++) { locals.f[1][k] = proof.f[k]; locals.f[0][k] = locals.w.sub(proof.f[k]); locals.temp = locals.temp.add(gs(k).mul(locals.f[1][k])); locals.temp = locals.temp.add(hs(k).mul(locals.f[1][k].mul(locals.f[0][k]))); } require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed."); locals.r = Utils.assemblePolynomials(locals.f); locals.wPow = 1; for (uint256 k = 0; k < n; k++) { locals.CLnR = locals.CLnR.add(proof.CLnG[k].mul(locals.wPow.neg())); locals.CRnR = locals.CRnR.add(proof.CRnG[k].mul(locals.wPow.neg())); locals.yR = locals.yR.add(proof.y_0G[k].mul(locals.wPow.neg())); locals.gR = locals.gR.add(proof.gG[k].mul(locals.wPow.neg())); locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(locals.wPow.neg())); locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(locals.wPow.neg())); locals.wPow = locals.wPow.mul(locals.w); } locals.vPow = locals.v; // used to be 1 for (uint256 i = 0; i < N; i++) { locals.CLnR = locals.CLnR.add(statement.CLn[i].mul(locals.r[i])); locals.CRnR = locals.CRnR.add(statement.CRn[i].mul(locals.r[i])); locals.yR = locals.yR.add(statement.Y[i].mul(locals.r[i])); uint256 multiplier = locals.r[i].add(locals.vPow.mul(locals.wPow.sub(locals.r[i]))); // locals. ? locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier)); locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier)); locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0) } locals.gR = locals.gR.add(g().mul(locals.wPow)); locals.C_XR = locals.C_XR.add(g().mul(statement.fee.add(amount).mul(locals.wPow))); // this line is new locals.y = uint256(keccak256(abi.encode(locals.w))).mod(); locals.ys[0] = 1; locals.k = 1; for (uint256 i = 1; i < M; i++) { locals.ys[i] = locals.ys[i - 1].mul(locals.y); locals.k = locals.k.add(locals.ys[i]); } locals.z = uint256(keccak256(abi.encode(locals.y))).mod(); locals.zs[0] = locals.z.mul(locals.z); locals.zSum = locals.zs[0].mul(locals.z); // trivial sum locals.k = locals.k.mul(locals.z.sub(locals.zs[0])).sub(locals.zSum.mul(1 << M).sub(locals.zSum)); locals.t = proof.tHat.sub(locals.k); for (uint256 i = 0; i < M; i++) { locals.twoTimesZSquared[i] = locals.zs[0].mul(1 << i); } locals.x = uint256(keccak256(abi.encode(locals.z, proof.T_1, proof.T_2))).mod(); locals.tEval = proof.T_1.mul(locals.x).add(proof.T_2.mul(locals.x.mul(locals.x))); // replace with "commit"? locals.A_y = locals.gR.mul(proof.s_sk).add(locals.yR.mul(proof.c.neg())); locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg())); locals.A_b = g().mul(proof.s_b).add(locals.CRnR.mul(locals.zs[0]).mul(proof.s_sk).add(locals.CLnR.mul(locals.zs[0]).mul(proof.c.neg()))); locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg())); locals.A_t = g().mul(locals.t).add(locals.tEval.neg()).mul(proof.c.mul(locals.wPow)).add(h().mul(proof.s_tau)).add(g().mul(proof.s_b.neg())); locals.gEpoch = Utils.mapInto("Firn Epoch", statement.epoch); // TODO: cast my own address to string as well? locals.A_u = locals.gEpoch.mul(proof.s_sk).add(statement.u.mul(proof.c.neg())); locals.c = uint256(keccak256(abi.encode(locals.x, locals.A_y, locals.A_D, locals.A_b, locals.A_X, locals.A_t, locals.A_u))).mod(); require(locals.c == proof.c, "Sigma protocol failure."); Utils.InnerProductStatement memory ip; // statement ip.salt = uint256(keccak256(abi.encode(locals.c))).mod(); ip.u = h().mul(ip.salt); ip.P = proof.BA.add(proof.BS.mul(locals.x)).add(gSum().mul(locals.z.neg())).add(h().mul(proof.mu.neg())).add(ip.u.mul(proof.tHat)); for (uint256 i = 0; i < M; i++) { ip.hs[i] = hs(i).mul(locals.ys[i].inv()); ip.P = ip.P.add(ip.hs[i].mul(locals.ys[i].mul(locals.z).add(locals.twoTimesZSquared[i]))); } _ip.verify(ip, proof.ip, false); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address payable","name":"base_","type":"address"},{"internalType":"address","name":"deposit_","type":"address"},{"internalType":"address","name":"transfer_","type":"address"},{"internalType":"address","name":"withdrawal_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"},{"indexed":true,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"DepositOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"account","type":"bytes32"}],"name":"RegisterOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"}],"name":"TransferOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"},{"indexed":true,"internalType":"address","name":"destination","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"WithdrawalOccurred","type":"event"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"uint32","name":"fee_","type":"uint32"}],"name":"administrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"Y","type":"bytes32"},{"internalType":"bytes32[2]","name":"signature","type":"bytes32[2]"}],"name":"register","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"Y","type":"bytes32[]"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"simulateAccounts","outputs":[{"internalType":"bytes32[2][]","name":"result","type":"bytes32[2][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes32","name":"u","type":"bytes32"},{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint32","name":"tip","type":"uint32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes32","name":"u","type":"bytes32"},{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"tip","type":"uint32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"address","name":"destination","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
610140604052600280546001600160401b03191690553480156200002257600080fd5b5060405162005ed838038062005ed8833981016040819052620000459162000258565b60028054600160401b600160e01b0319163368010000000000000000021790556001600160a01b0384811660805283811660a05282811660c052811660e0526040805180820190915260018152606760f81b602080830191909152600091620000b791620000d1811b6200287317901c565b805161010052602001516101205250620003369350505050565b60408051808201909152600080825260208201526200013760008051602062005eb8833981519152836040516020016200010c9190620002c0565b6040516020818303038152906040528051906020012060001c620001319190620002f1565b6200013d565b92915050565b604080518082019091526000808252602082015260005b600062000163846003620001e7565b6200017090600362000314565b90506200019e817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52620001e7565b915080620001ae836002620001e7565b03620001bb5750620001d1565b620001c860018562000314565b93505062000154565b6040805180820190915292835260208301525090565b60008060008051602062005eb8833981519152905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa6200023657600080fd5b51949350505050565b6001600160a01b03811681146200025557600080fd5b50565b600080600080608085870312156200026f57600080fd5b84516200027c816200023f565b60208601519094506200028f816200023f565b6040860151909350620002a2816200023f565b6060860151909250620002b5816200023f565b939692955090935050565b6000825160005b81811015620002e35760208186018101518583015201620002c7565b506000920191825250919050565b6000826200030f57634e487b7160e01b600052601260045260246000fd5b500690565b808201808211156200013757634e487b7160e01b600052601160045260246000fd5b60805160a05160c05160e05161010051610120516159cd620004eb60003960008181610e630152610fa4015260008181610e400152610f81015260006119d801526000610931015260006122f101526000818161035a015281816104130152818161054c01528181610605015281816106f3015281816107ad015281816109ce01528181610b5d01528181610c2a01528181610cdf01528181610d9a01528181610ec101528181611437015281816114f201528181611609015281816116c4015281816117960152818161185a01528181611a9801528181611b7101528181611c3b01528181611d6c01528181611e3901528181611f590152818161201201528181612100015281816121ba0152818161246b0152818161252601528181612632015281816126ed01528181612a2e01528181612ae901528181612b9f01528181612c5a01528181612d2a01528181612dc101528181612f1301528181612fdf015281816131b20152818161325101528181613308015281816133ac01528181613498015281816135da01528181613750015281816138000152818161389d015281816139700152613a1101526159cd6000f3fe6080604052600436106100655760003560e01c806362ab46821161004357806362ab4682146100bf57806379a80fdb146100df578063e220a18f146100f257600080fd5b80630e0404401461006a57806330d000121461008c5780635603c04e1461009f575b600080fd5b34801561007657600080fd5b5061008a610085366004614ba1565b610128565b005b61008a61009a366004614c45565b610adf565b3480156100ab57600080fd5b5061008a6100ba366004614c8f565b61109f565b3480156100cb57600080fd5b5061008a6100da366004614cd2565b61119a565b61008a6100ed366004614dd0565b611ce6565b3480156100fe57600080fd5b5061011261010d366004614e45565b6123ff565b60405161011f9190614ec0565b60405180910390f35b610133603c42614f87565b8467ffffffffffffffff16146101905760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60025467ffffffffffffffff808616911610156101e757600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff86161790556101e760016000614678565b60005b60015481101561027257856001828154811061020857610208614f9b565b9060005260206000200154036102605760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e000000000000000000000000006044820152606401610187565b8061026a81614fca565b9150506101ea565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018590556102af614699565b6102b8876128ea565b608082015260005b60108110156108e3576102e98a82601081106102de576102de614f9b565b6020020135876129cd565b6103088a82601081106102fe576102fe614f9b565b60200201356128ea565b8251826010811061031b5761031b614f9b565b60200201526103358982601081106102fe576102fe614f9b565b8260600151826010811061034b5761034b614f9b565b602002015261035861471b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663478373168c846010811061039957610399614f9b565b602002013560006040518363ffffffff1660e01b81526004016103c6929190918252602082015260400190565b6040805180830381865afa1580156103e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104069190615002565b82516020810191909152527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663478373168c846010811061045257610452614f9b565b602002013560016040518363ffffffff1660e01b815260040161047f929190918252602082015260400190565b6040805180830381865afa15801561049b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bf9190615002565b602080840151908101919091525260608301516104fb9083601081106104e7576104e7614f9b565b60200201518260005b602002015190612e73565b8360200151836010811061051157610511614f9b565b60200201526080830151610527908260016104f0565b8360400151836010811061053d5761053d614f9b565b602002015261054a61471b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc588d856010811061058b5761058b614f9b565b602002013560006040518363ffffffff1660e01b81526004016105b8929190918252602082015260400190565b6040805180830381865afa1580156105d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f89190615002565b82516020810191909152527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc588d856010811061064457610644614f9b565b602002013560016040518363ffffffff1660e01b8152600401610671929190918252602082015260400190565b6040805180830381865afa15801561068d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b19190615002565b602080840151908101919091525260608401516106d99084601081106104e7576104e7614f9b565b815260808401516106ec908260016104f0565b60208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633d02f9b18d856010811061073257610732614f9b565b6020020135836040518363ffffffff1660e01b8152600401610755929190615026565b600060405180830381600087803b15801561076f57600080fd5b505af1158015610783573d6000803e3d6000fd5b5050604080516060810182526000808252602082018190529181019190915291506107ab9050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b64a097e8e86601081106107ec576107ec614f9b565b60200201356040518263ffffffff1660e01b815260040161080f91815260200190565b606060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190615072565b505067ffffffffffffffff168082526108ab5760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b6108cd8d85601081106108c0576108c0614f9b565b602002013560008b612ec3565b50505080806108db90614fca565b9150506102c0565b5067ffffffffffffffff851660a08201526108fd866128ea565b60c082015263ffffffff841660e0820152604080516020601f85018190048102820181019092528381526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163a00ceb1291849161097f91908890889081908401838280828437600092019190915250613a7d92505050565b6040518363ffffffff1660e01b815260040161099c929190615282565b60006040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663911adc1a338663ffffffff1666038d7ea4c68000610a159190615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600087803b158015610a8157600080fd5b505af1158015610a95573d6000803e3d6000fd5b505050507ff6f8a48e4a3e66a7c69c76d4c466f5c8ecffc318c99005256a2630b44045c772898989604051610acc9392919061545b565b60405180910390a1505050505050505050565b34662386f26fc1000014610b355760405162461bcd60e51b815260206004820152601960248201527f416d6f756e74206d75737420626520302e303130204554482e000000000000006044820152606401610187565b6000610b42603c42614f87565b90506000610b5766038d7ea4c6800034614f87565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d8060008114610bc6576040519150601f19603f3d011682016040523d82523d6000602084013e610bcb565b606091505b5050905080610c1c5760405162461bcd60e51b815260206004820181905260248201527f466f7277617264696e672066756e647320746f2062617365206661696c65642e6044820152606401610187565b6a038d7ea4c2f2815b3980007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316311115610ca15760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e0000000000006044820152606401610187565b610ca961471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101879052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a4edfc58906044016040805180830381865afa158015610d2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d519190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101879052600160248201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a4edfc58906044016040805180830381865afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e049190615002565b6020808401519081019190915252610e97610e8f63ffffffff8516610e89604080518082018252600080825260209182015281518083019092527f000000000000000000000000000000000000000000000000000000000000000082527f00000000000000000000000000000000000000000000000000000000000000009082015290565b90613f7a565b8260006104f0565b81526040517f3d02f9b10000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633d02f9b190610f009089908590600401615026565b600060405180830381600087803b158015610f1a57600080fd5b505af1158015610f2e573d6000803e3d6000fd5b505050506000610f3d876128ea565b90506000610fd0610f58610f518935613fb8565b8490613f7a565b610fca60208a0135610e89604080518082018252600080825260209182015281518083019092527f000000000000000000000000000000000000000000000000000000000000000082527f00000000000000000000000000000000000000000000000000000000000000009082015290565b90612e73565b9050600061100a308a84604051602001610fec9392919061547d565b6040516020818303038152906040528051906020012060001c613fe4565b90508735811461105c5760405162461bcd60e51b815260206004820152601b60248201527f5369676e6174757265206661696c656420746f207665726966792e00000000006044820152606401610187565b611067898789612ec3565b604051899033907f05ec147cbb865958fbd62b0f318cd69d8f0e1b1f21531b8d008f9a39bce062f890600090a3505050505050505050565b6002546801000000000000000090046001600160a01b031633146111055760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420746865206f776e65722e00000000000000006044820152606401610187565b600280546001600160a01b0394851668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff9091161790556003805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009092169290931691909117179055565b6111a5603c42614f87565b8867ffffffffffffffff16146111fd5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e00000000000000000000000000000000000000006044820152606401610187565b60025467ffffffffffffffff808a169116101561125457600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff8a1617905561125460016000614678565b60005b6001548110156112df57896001828154811061127557611275614f9b565b9060005260206000200154036112cd5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e000000000000000000000000006044820152606401610187565b806112d781614fca565b915050611257565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018990556040516001600160a01b038416907f455f9623b71a09d41c2aab8b7edd236e2a1ab057ad848f6be4290c5079c5934790611359908f908f908f908d9089908990615530565b60405180910390a2611369614699565b6113728b6128ea565b608082015260005b601081101561193f5760008e826010811061139757611397614f9b565b602002013590506113a8818c6129cd565b6113b1816128ea565b835183601081106113c4576113c4614f9b565b60200201526113de8e83601081106102fe576102fe614f9b565b836060015183601081106113f4576113f4614f9b565b602002015261140161471b565b6040517f4783731600000000000000000000000000000000000000000000000000000000815260048101839052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906347837316906044016040805180830381865afa158015611485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a99190615002565b82516020810191909152526040517f4783731600000000000000000000000000000000000000000000000000000000815260048101839052600160248201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906347837316906044016040805180830381865afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190615002565b602080840151908101919091525260608401516115849084601081106104e7576104e7614f9b565b8460200151846010811061159a5761159a614f9b565b602002015260808401516115b0908260016104f0565b846040015184601081106115c6576115c6614f9b565b60200201526115d361471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101849052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a4edfc58906044016040805180830381865afa158015611657573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167b9190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101849052600160248201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a4edfc58906044016040805180830381865afa15801561170a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172e9190615002565b602080840151908101919091525260608501516117569085601081106104e7576104e7614f9b565b81526080850151611769908260016104f0565b60208201526040517f3d02f9b10000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633d02f9b1906117d59086908590600401615026565b600060405180830381600087803b1580156117ef57600080fd5b505af1158015611803573d6000803e3d6000fd5b50506040805160608101825260008082526020820181905291810191909152915061182b9050565b6040517fb64a097e000000000000000000000000000000000000000000000000000000008152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b64a097e90602401606060405180830381865afa1580156118a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118cd9190615072565b505067ffffffffffffffff168082526119285760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b50505050808061193790614fca565b91505061137a565b5060035460009061196e9074010000000000000000000000000000000000000000900463ffffffff168a615578565b67ffffffffffffffff8b1660a084015290506119898b6128ea565b60c0830152611998818961559b565b63ffffffff1660e08301526040516000906119bb908790879087906020016155b8565b6040516020818303038152906040528051906020012060001c90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663f11b521f8b85611a468c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061401092505050565b856040518563ffffffff1660e01b8152600401611a6694939291906155e4565b60006040518083038186803b158015611a7e57600080fd5b505afa158015611a92573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663911adc1a612710338c63ffffffff1666038d7ea4c68000611ae29190615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600088803b158015611b4e57600080fd5b5087f1158015611b62573d6000803e3d6000fd5b50506003546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116945063911adc1a9350169050611bb563ffffffff861666038d7ea4c68000615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600087803b158015611c2157600080fd5b505af1158015611c35573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663911adc1a878c63ffffffff1666038d7ea4c68000611c829190615444565b88886040518563ffffffff1660e01b8152600401611ca39493929190615799565b600060405180830381600087803b158015611cbd57600080fd5b505af1158015611cd1573d6000803e3d6000fd5b50505050505050505050505050505050505050565b611cf766038d7ea4c68000346157c2565b15611d445760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e6044820152606401610187565b6000611d51603c42614f87565b90506000611d6666038d7ea4c6800034614f87565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d8060008114611dd5576040519150601f19603f3d011682016040523d82523d6000602084013e611dda565b606091505b5050905080611e2b5760405162461bcd60e51b815260206004820181905260248201527f466f7277617264696e672066756e647320746f2062617365206661696c65642e6044820152606401610187565b6a038d7ea4c2f2815b3980007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316311115611eb05760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e0000000000006044820152606401610187565b611eb8614699565b611ec1876128ea565b608082015260005b60108110156122ee57611ef28a8260108110611ee757611ee7614f9b565b6020020135866129cd565b611f078a82601081106102fe576102fe614f9b565b82518260108110611f1a57611f1a614f9b565b6020020152611f348982601081106102fe576102fe614f9b565b82606001518260108110611f4a57611f4a614f9b565b6020020152611f5761471b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc588c8460108110611f9857611f98614f9b565b602002013560006040518363ffffffff1660e01b8152600401611fc5929190918252602082015260400190565b6040805180830381865afa158015611fe1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120059190615002565b82516020810191909152527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc588c846010811061205157612051614f9b565b602002013560016040518363ffffffff1660e01b815260040161207e929190918252602082015260400190565b6040805180830381865afa15801561209a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120be9190615002565b602080840151908101919091525260608301516120e69083601081106104e7576104e7614f9b565b815260808301516120f9908260016104f0565b60208201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633d02f9b18c846010811061213f5761213f614f9b565b6020020135836040518363ffffffff1660e01b8152600401612162929190615026565b600060405180830381600087803b15801561217c57600080fd5b505af1158015612190573d6000803e3d6000fd5b5050604080516060810182526000808252602082018190529181019190915291506121b89050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b64a097e8d85601081106121f9576121f9614f9b565b60200201356040518263ffffffff1660e01b815260040161221c91815260200190565b606060405180830381865afa158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190615072565b505067ffffffffffffffff168082526122b85760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b6122d98c84601081106122cd576122cd614f9b565b60200201358789612ec3565b505080806122e690614fca565b915050611ec9565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166377f73355848361235f8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061438592505050565b6040518463ffffffff1660e01b815260040161237d939291906157d6565b60006040518083038186803b15801561239557600080fd5b505afa1580156123a9573d6000803e3d6000fd5b50505050336001600160a01b03167fbdee54bab8aa68aecbb89de2313baaa387447195fe74aa236a4d9345799b33008a8a8a876040516123ec9493929190615880565b60405180910390a2505050505050505050565b60608267ffffffffffffffff81111561241a5761241a6158b0565b60405190808252806020026020018201604052801561245357816020015b612440614754565b8152602001906001900390816124385790505b50905060005b8381101561286b5761246961471b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663478373168787858181106124aa576124aa614f9b565b9050602002013560006040518363ffffffff1660e01b81526004016124d9929190918252602082015260400190565b6040805180830381865afa1580156124f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125199190615002565b82516020810191909152527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634783731687878581811061256557612565614f9b565b9050602002013560016040518363ffffffff1660e01b8152600401612594929190918252602082015260400190565b6040805180830381865afa1580156125b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d49190615002565b602080840151908101919091525263ffffffff84166000808888868181106125fe576125fe614f9b565b602090810292909201358352508101919091526040016000205467ffffffffffffffff1610156127da5761263061471b565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc5888888681811061267157612671614f9b565b9050602002013560006040518363ffffffff1660e01b81526004016126a0929190918252602082015260400190565b6040805180830381865afa1580156126bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e09190615002565b82516020810191909152527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a4edfc5888888681811061272c5761272c614f9b565b9050602002013560016040518363ffffffff1660e01b815260040161275b929190918252602082015260400190565b6040805180830381865afa158015612777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279b9190615002565b60208084015190810191909152526127bd8160005b60200201518360006104f0565b82526127d38160015b60200201518360016104f0565b6020830152505b6127eb8160005b60200201516144d7565b8383815181106127fd576127fd614f9b565b602002602001015160006002811061281757612817614f9b565b60200201526128278160016127e1565b83838151811061283957612839614f9b565b602002602001015160016002811061285357612853614f9b565b6020020152508061286381614fca565b915050612459565b509392505050565b60408051808201909152600080825260208201526128e47f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47836040516020016128bc91906158df565b6040516020818303038152906040528051906020012060001c6128df91906157c2565b614515565b92915050565b60408051808201909152600080825260208201526000829003612920575050604080518082019091526000808252602082015290565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c60006129558360036145b2565b61296090600361590e565b9050600061298e827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f526145b2565b60408051808201909152858152602081018290529091506001821684146129c3576129b88161461a565b979650505050505050565b9695505050505050565b60008281526020819052604090205467ffffffffffffffff80831691161015612e6f576129f861471b565b6040517f4783731600000000000000000000000000000000000000000000000000000000815260048101849052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906347837316906044016040805180830381865afa158015612a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa09190615002565b82516020810191909152526040517f4783731600000000000000000000000000000000000000000000000000000000815260048101849052600160248201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906347837316906044016040805180830381865afa158015612b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b539190615002565b6020808401519081019190915252612b6961471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101859052600060248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a4edfc58906044016040805180830381865afa158015612bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c119190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101859052600160248201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a4edfc58906044016040805180830381865afa158015612ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc49190615002565b6020808401519081019190915252612cdd8160006127b0565b8252612cea8160016127c6565b6020830152612cf761471b565b6040517f8eaad12e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690638eaad12e90612d619087908690600401615026565b600060405180830381600087803b158015612d7b57600080fd5b505af1158015612d8f573d6000803e3d6000fd5b50506040517f3d02f9b10000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250633d02f9b19150612dfa9087908590600401615026565b600060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050600085815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff86161790555050505b5050565b60408051808201909152600080825260208201526040518351815260208401516020820152825160408201526020830151606082015260408260808360065afa612ebc57600080fd5b5092915050565b604080516060810182526000808252602082018190528183015290517fb64a097e000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063b64a097e90602401606060405180830381865afa158015612f5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7e9190615072565b67ffffffffffffffff9081166040850152908116602084015216808252156136ea57805160208201516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169263f6c18c11929091849063e2226a7c9084906001908490632316aa6c90602401602060405180830381865afa158015613045573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130699190615921565b613073919061593a565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815267ffffffffffffffff90921660048301526024820152604401602060405180830381865afa1580156130d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f99190615921565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815267ffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b15801561316157600080fd5b505af1158015613175573d6000803e3d6000fd5b505082516040517f32de71bd00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506332de71bd9150602401600060405180830381600087803b15801561320057600080fd5b505af1158015613214573d6000803e3d6000fd5b505082516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250632316aa6c9150602401602060405180830381865afa1580156132a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c69190615921565b6000036133715780516040517f92752df500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906392752df590602401600060405180830381600087803b15801561335457600080fd5b505af1158015613368573d6000803e3d6000fd5b505050506136ea565b80516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632316aa6c90602401602060405180830381865afa1580156133fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061341f9190615921565b816020015167ffffffffffffffff1610156136ea576040805160608101825260008082526020820181905291810191909152815160208301516040517fe2226a7c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b64a097e90829063e2226a7c90604401602060405180830381865afa1580156134ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135139190615921565b6040518263ffffffff1660e01b815260040161353191815260200190565b606060405180830381865afa15801561354e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135729190615072565b67ffffffffffffffff90811660408581019190915291811660208086019182529382168552928501805182169093528451925191517fe2226a7c00000000000000000000000000000000000000000000000000000000815292811660048401521660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e29ec7790829063e2226a7c90604401602060405180830381865afa158015613631573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136559190615921565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252845167ffffffffffffffff908116602484015260208601518116604484015290850151166064820152608401600060405180830381600087803b1580156136d057600080fd5b505af11580156136e4573d6000803e3d6000fd5b50505050505b67ffffffffffffffff8216815260408101805163ffffffff8516919061371190839061594d565b67ffffffffffffffff9081169091526040517f4149629600000000000000000000000000000000000000000000000000000000815290841660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169150634149629690602401602060405180830381865afa1580156137a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137c4919061596e565b613865576040517ffea6c9de00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063fea6c9de90602401600060405180830381600087803b15801561384c57600080fd5b505af1158015613860573d6000803e3d6000fd5b505050505b6040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632316aa6c90602401602060405180830381865afa1580156138ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139109190615921565b67ffffffffffffffff90811660208301908152604080517f2e29ec770000000000000000000000000000000000000000000000000000000081526004810188905284518416602482015291518316604483015283015190911660648201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e29ec7790608401600060405180830381600087803b1580156139bc57600080fd5b505af11580156139d0573d6000803e3d6000fd5b50506040517ff0284e0e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602481018790527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063f0284e0e9150604401600060405180830381600087803b158015613a5f57600080fd5b505af1158015613a73573d6000803e3d6000fd5b5050505050505050565b613a85614772565b6020820151613a98906128ea565b6128ea565b81526040820151613aa8906128ea565b60208201526060820151613abb906128ea565b60408201526080820151613ace906128ea565b606082015260005b6004811015613d7657613b04613a9384613af1846020615444565b613afc90608061590e565b016020015190565b82608001518260048110613b1a57613b1a614f9b565b6020020152613b3c613a9384613b3160048561590e565b613af1906020615444565b8260a001518260048110613b5257613b52614f9b565b6020020181905250613b8f613a9384836020613b6e9190615444565b613b7a60046040615444565b613b8590608061590e565b613afc919061590e565b8260c001518260048110613ba557613ba5614f9b565b6020020181905250613bcd613a9384836020613bc19190615444565b613b7a60046060615444565b8260e001518260048110613be357613be3614f9b565b6020020181905250613c0b613a9384836020613bff9190615444565b613b7a60046080615444565b8261010001518260048110613c2257613c22614f9b565b6020020181905250613c4a613a9384836020613c3e9190615444565b613b7a600460a0615444565b8261012001518260048110613c6157613c61614f9b565b6020020181905250613c89613a9384836020613c7d9190615444565b613b7a600460c0615444565b8261014001518260048110613ca057613ca0614f9b565b6020020181905250613cc8613a9384836020613cbc9190615444565b613b7a600460e0615444565b8261016001518260048110613cdf57613cdf614f9b565b6020020181905250613d0583826020613cf89190615444565b613b7a6004610100615444565b610180830151518260048110613d1d57613d1d614f9b565b602002018181525050613d4483826020613d379190615444565b613b7a6004610120615444565b610180830151602001518260048110613d5f57613d5f614f9b565b602002015280613d6e81614fca565b915050613ad6565b506000613d866004610140615444565b9050613d9783613afc83608061590e565b6101a0830152613daf613a9384613afc8460a061590e565b6101c0830152613dc7613a9384613afc8460c061590e565b6101e0830152613ddc83613afc8360e061590e565b610200830152613df283613afc8361010061590e565b610220830152613e0883613afc8361012061590e565b610240830152613e1e83613afc8361014061590e565b610260830152613e3483613afc8361016061590e565b610280830152613e4a83613afc8361018061590e565b6102a0830152613e6083613afc836101a061590e565b6102c083015260005b613e756005600161590e565b811015613f1157613e9a613a9385613e8e846020615444565b613b85866101c061590e565b6102e0840151518260068110613eb257613eb2614f9b565b6020020152613edf613a9385613ec960058561590e565b613ed490600161590e565b613e8e906020615444565b836102e00151602001518260068110613efa57613efa614f9b565b602002015280613f0981614fca565b915050613e69565b50613f3983613f226005600161590e565b613f2d906040615444565b613b85846101c061590e565b6102e083015160400152613f6a83613f536005600161590e565b613f5e906040615444565b613b85846101e061590e565b6102e08301516060015250919050565b6040805180820190915260008082526020820152604051835181526020840151602082015282604082015260408260608360075afa612ebc57600080fd5b60006128e4827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161593a565b60006128e47f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001836157c2565b6140186148c3565b6020820151614026906128ea565b81526040820151614036906128ea565b60208201526060820151614049906128ea565b6040820152608082015161405c906128ea565b606082015260005b60048110156141d35761407f613a9384613af1846020615444565b8260800151826004811061409557614095614f9b565b60200201526140ac613a9384613b3160048561590e565b8260a0015182600481106140c2576140c2614f9b565b60200201819052506140de613a9384836020613b6e9190615444565b8260c0015182600481106140f4576140f4614f9b565b6020020181905250614110613a9384836020613bc19190615444565b8260e00151826004811061412657614126614f9b565b6020020181905250614142613a9384836020613bff9190615444565b826101000151826004811061415957614159614f9b565b6020020181905250614175613a9384836020613c3e9190615444565b826101200151826004811061418c5761418c614f9b565b60200201819052506141a583826020613c7d9190615444565b61014083015182600481106141bc576141bc614f9b565b6020020152806141cb81614fca565b915050614064565b5060006141e2600460e0615444565b90506141f383613afc83608061590e565b61016083015261420b613a9384613afc8460a061590e565b610180830152614223613a9384613afc8460c061590e565b6101a083015261423883613afc8360e061590e565b6101c083015261424e83613afc8361010061590e565b6101e083015261426483613afc8361012061590e565b61020083015261427a83613afc8361014061590e565b61022083015261429083613afc8361016061590e565b6102408301526142a683613afc8361018061590e565b6102608301526142bc83613afc836101a061590e565b61028083015260005b6005811015614341576142e0613a9385613e8e846020615444565b6102a08401515182600681106142f8576142f8614f9b565b602002015261430f613a9385613ed460058561590e565b836102a0015160200151826006811061432a5761432a614f9b565b60200201528061433981614fca565b9150506142c5565b5061435283613f2d60056040615444565b60001c826102a0015160400181815250506143758360056040613f5e9190615444565b6102a08301516060015250919050565b61438d61497f565b602082015161439b906128ea565b815260408201516143ab906128ea565b602082015260005b6004811015614484576143d9613a93846143ce846020615444565b613afc90604061590e565b826040015182600481106143ef576143ef614f9b565b6020020152614411613a938461440660048561590e565b6143ce906020615444565b8260600151826004811061442757614427614f9b565b6020020181905250614457838260206144409190615444565b61444c60046040615444565b613b8590604061590e565b6080830151826004811061446d5761446d614f9b565b60200201528061447c81614fca565b9150506143b3565b50600061449360046060615444565b90506144a483613afc83604061590e565b60a08301526144b883613afc83606061590e565b60c08301526144cc83613afc83608061590e565b60e083015250919050565b8051602082015160009190600190811690036128e4577f80000000000000000000000000000000000000000000000000000000000000001792915050565b604080518082019091526000808252602082015260005b60006145398460036145b2565b61454490600361590e565b9050614570817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f526145b2565b91508061457e8360026145b2565b03614589575061459c565b61459460018561590e565b93505061452c565b6040805180820190915292835260208301525090565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa61461157600080fd5b51949350505050565b6040805180820190915260008082526020820152604080518082019091528251815260208084015190820190614670907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4761593a565b905292915050565b508054600082559060005260206000209081019061469691906149f5565b50565b6040518061010001604052806146ad614a0e565b81526020016146ba614a0e565b81526020016146c7614a0e565b81526020016146d4614a0e565b815260408051808201825260008082526020808301829052808501929092528284018190528251808401909352808352908201819052606083019190915260809091015290565b60405180604001604052806002905b604080518082019091526000808252602082015281526020019060019003908161472a5790505090565b60405180604001604052806002906020820280368337509192915050565b6040805161034081018252600061030082018181526103208301829052825282518084018452818152602080820183905280840191909152835180850185528281528082018390528385015283518085019094528184528301526060810191909152608081016147e0614a3a565b81526020016147ed614a3a565b81526020016147fa614a3a565b8152602001614807614a3a565b8152602001614814614a3a565b8152602001614821614a3a565b815260200161482e614a3a565b815260200161483b614a3a565b8152602001614848614a63565b81526000602080830182905260408051808201825283815280830184905281850152805180820190915282815290810182905260608301526080820181905260a0820181905260c0820181905260e0820181905261010082018190526101208201819052610140820152610160016148be614a90565b905290565b604080516103008101825260006102c082018181526102e0830182905282528251808401845281815260208082018390528084019190915283518085018552828152808201839052838501528351808501909452818452830152606081019190915260808101614931614a3a565b815260200161493e614a3a565b815260200161494b614a3a565b8152602001614958614a3a565b8152602001614965614a3a565b8152602001614972614a3a565b8152602001614848614ac4565b6040805161014081018252600061010082018181526101208301829052825282518084018452818152602080820192909252908201529081016149c0614a3a565b81526020016149cd614a3a565b81526020016149da614ac4565b81526020016000815260200160008152602001600081525090565b5b80821115614a0a57600081556001016149f6565b5090565b604080516102408101909152600061020082018181526102208301919091528152600f6020820161472a565b6040805160c0810190915260006080820181815260a0830191909152815260036020820161472a565b60405180604001604052806002905b614a7a614ac4565b815260200190600190039081614a725790505090565b6040518060800160405280614aa3614ae2565b8152602001614ab0614ae2565b815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b604080516101008101909152600060c0820181815260e0830191909152815260056020820161472a565b8061020081018310156128e457600080fd5b67ffffffffffffffff8116811461469657600080fd5b8035614b3f81614b1e565b919050565b803563ffffffff81168114614b3f57600080fd5b60008083601f840112614b6a57600080fd5b50813567ffffffffffffffff811115614b8257600080fd5b602083019150836020828501011115614b9a57600080fd5b9250929050565b6000806000806000806000806104a0898b031215614bbe57600080fd5b614bc88a8a614b0c565b9750614bd88a6102008b01614b0c565b965061040089013595506104208901359450610440890135614bf981614b1e565b9350614c086104608a01614b44565b925061048089013567ffffffffffffffff811115614c2557600080fd5b614c318b828c01614b58565b999c989b5096995094979396929594505050565b60008060608385031215614c5857600080fd5b8235915083606084011115614c6c57600080fd5b50926020919091019150565b80356001600160a01b0381168114614b3f57600080fd5b600080600060608486031215614ca457600080fd5b614cad84614c78565b9250614cbb60208501614c78565b9150614cc960408501614b44565b90509250925092565b6000806000806000806000806000806000806105008d8f031215614cf557600080fd5b614cff8e8e614b0c565b9b50614d0f8e6102008f01614b0c565b9a506104008d013599506104208d01359850614d2e6104408e01614b34565b9750614d3d6104608e01614b44565b9650614d4c6104808e01614b44565b955067ffffffffffffffff6104a08e01351115614d6857600080fd5b614d798e6104a08f01358f01614b58565b9095509350614d8b6104c08e01614c78565b925067ffffffffffffffff6104e08e01351115614da757600080fd5b614db88e6104e08f01358f01614b58565b81935080925050509295989b509295989b509295989b565b60008060008060006104408688031215614de957600080fd5b614df38787614b0c565b9450614e03876102008801614b0c565b9350610400860135925061042086013567ffffffffffffffff811115614e2857600080fd5b614e3488828901614b58565b969995985093965092949392505050565b600080600060408486031215614e5a57600080fd5b833567ffffffffffffffff80821115614e7257600080fd5b818601915086601f830112614e8657600080fd5b813581811115614e9557600080fd5b8760208260051b8501011115614eaa57600080fd5b602092830195509350614cc99186019050614b44565b60208082528251828201819052600091906040908185019086840185805b83811015614f1b57825185835b6002811015614f0857825182529189019190890190600101614eeb565b5050509385019391860191600101614ede565b509298975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082614f9657614f96614f29565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614ffb57614ffb614f58565b5060010190565b6000806040838503121561501557600080fd5b505080516020909101519092909150565b82815260a0810160208083018460005b60028110156150675761505483835180518252602090810151910152565b6040929092019190830190600101615036565b505050509392505050565b60008060006060848603121561508757600080fd5b835161509281614b1e565b60208501519093506150a381614b1e565b60408501519092506150b481614b1e565b809150509250925092565b8060005b60108110156150f7576150e184835180518252602090810151910152565b60409390930192602091909101906001016150c3565b50505050565b6151088282516150bf565b602081015161511b6104008401826150bf565b50604081015161512f6108008401826150bf565b506060810151615143610c008401826150bf565b506080810151805161100084015260209081015161102084015260a082015161104084015260c08201518051611060850152015161108083015260e001516110a090910152565b8060005b60048110156150f7576151ac84835180518252602090810151910152565b604093909301926020919091019060010161518e565b8060005b60048110156150f75781518452602093840193909101906001016151c6565b8060005b60028110156150f7576151fd8483516151c2565b60809390930192602091909101906001016151e9565b8060005b60068110156150f75761523584835180518252602090810151910152565b6040939093019260209190910190600101615217565b615256828251615213565b6020810151615269610180840182615213565b5060408101516103008301526060015161032090910152565b611f80810161529182856150fd565b825180516110c08401526020908101516110e0840152808401518051611100850152810151611120840152604084015180516111408501528101516111608401526060840151805161118085015201516111a083015260808301516152fa6111c084018261518a565b5060a083015161530e6112c084018261518a565b5060c08301516153226113c084018261518a565b5060e08301516153366114c084018261518a565b5061010083015161534b6115c084018261518a565b506101208301516153606116c084018261518a565b506101408301516153756117c084018261518a565b5061016083015161538a6118c084018261518a565b5061018083015161539f6119c08401826151e5565b506101a0830151611ac08301526101c08301518051611ae0840152602090810151611b008401526101e08401518051611b208501520151611b40830152610200830151611b60830152610220830151611b80830152610240830151611ba0830152610260830151611bc0830152610280830151611be08301526102a0830151611c008301526102c0830151611c208301526102e083015161286b611c4084018261524b565b80820281158282048414176128e4576128e4614f58565b6104208101610200808684378085828501375082610400830152949350505050565b60a08082526010908201527f57656c636f6d6520746f204669726e2e0000000000000000000000000000000060c08201526001600160a01b03841660208201526040810183905260e081016154df606083018480518252602090810151910152565b949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6000610460610200808a8537808982860137508661040084015263ffffffff86166104208401528061044084015261556b81840185876154e7565b9998505050505050505050565b600063ffffffff8084168061558f5761558f614f29565b92169190910492915050565b63ffffffff818116838216019080821115612ebc57612ebc614f58565b6001600160a01b03841681526040602082015260006155db6040830184866154e7565b95945050505050565b63ffffffff85168152611d4081016155ff60208301866150fd565b835180516110e084015260209081015161110084015280850151805161112085015281015161114084015260408501518051611160850152810151611180840152606085015180516111a085015201516111c083015260808401516156686111e084018261518a565b5060a084015161567c6112e084018261518a565b5060c08401516156906113e084018261518a565b5060e08401516156a46114e084018261518a565b506101008401516156b96115e084018261518a565b506101208401516156ce6116e084018261518a565b506101408401516156e36117e08401826151c2565b5061016084015161186083015261018084015180516118808401526020908101516118a08401526101a085015180516118c085015201516118e08301526101c08401516119008301526101e08401516119208301526102008401516119408301526102208401516119608301526102408401516119808301526102608401516119a08301526102808401516119c08301526102a08401516157886119e084018261524b565b5082611d2083015295945050505050565b6001600160a01b03851681528360208201526060604082015260006129c36060830184866154e7565b6000826157d1576157d1614f29565b500690565b63ffffffff8416815261144081016157f160208301856150fd565b825180516110e08401526020908101516111008401528084015180516111208501520151611140830152604083015161582e61116084018261518a565b50606083015161584261126084018261518a565b5060808301516158566113608401826151c2565b5060a08301516113e083015260c083015161140083015260e0830151611420830152949350505050565b610440810161020080878437808682850137508361040083015263ffffffff831661042083015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000825160005b8181101561590057602081860181015185830152016158e6565b506000920191825250919050565b808201808211156128e4576128e4614f58565b60006020828403121561593357600080fd5b5051919050565b818103818111156128e4576128e4614f58565b67ffffffffffffffff818116838216019080821115612ebc57612ebc614f58565b60006020828403121561598057600080fd5b8151801515811461599057600080fd5b939250505056fea26469706673582212209bc53e924ec0ef938ad596785f1e0a1125402beadedac46bc5df89054ae3e3b664736f6c6343000811003330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83750000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680
Deployed Bytecode
0x6080604052600436106100655760003560e01c806362ab46821161004357806362ab4682146100bf57806379a80fdb146100df578063e220a18f146100f257600080fd5b80630e0404401461006a57806330d000121461008c5780635603c04e1461009f575b600080fd5b34801561007657600080fd5b5061008a610085366004614ba1565b610128565b005b61008a61009a366004614c45565b610adf565b3480156100ab57600080fd5b5061008a6100ba366004614c8f565b61109f565b3480156100cb57600080fd5b5061008a6100da366004614cd2565b61119a565b61008a6100ed366004614dd0565b611ce6565b3480156100fe57600080fd5b5061011261010d366004614e45565b6123ff565b60405161011f9190614ec0565b60405180910390f35b610133603c42614f87565b8467ffffffffffffffff16146101905760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60025467ffffffffffffffff808616911610156101e757600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff86161790556101e760016000614678565b60005b60015481101561027257856001828154811061020857610208614f9b565b9060005260206000200154036102605760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e000000000000000000000000006044820152606401610187565b8061026a81614fca565b9150506101ea565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018590556102af614699565b6102b8876128ea565b608082015260005b60108110156108e3576102e98a82601081106102de576102de614f9b565b6020020135876129cd565b6103088a82601081106102fe576102fe614f9b565b60200201356128ea565b8251826010811061031b5761031b614f9b565b60200201526103358982601081106102fe576102fe614f9b565b8260600151826010811061034b5761034b614f9b565b602002015261035861471b565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663478373168c846010811061039957610399614f9b565b602002013560006040518363ffffffff1660e01b81526004016103c6929190918252602082015260400190565b6040805180830381865afa1580156103e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104069190615002565b82516020810191909152527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663478373168c846010811061045257610452614f9b565b602002013560016040518363ffffffff1660e01b815260040161047f929190918252602082015260400190565b6040805180830381865afa15801561049b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104bf9190615002565b602080840151908101919091525260608301516104fb9083601081106104e7576104e7614f9b565b60200201518260005b602002015190612e73565b8360200151836010811061051157610511614f9b565b60200201526080830151610527908260016104f0565b8360400151836010811061053d5761053d614f9b565b602002015261054a61471b565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc588d856010811061058b5761058b614f9b565b602002013560006040518363ffffffff1660e01b81526004016105b8929190918252602082015260400190565b6040805180830381865afa1580156105d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f89190615002565b82516020810191909152527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc588d856010811061064457610644614f9b565b602002013560016040518363ffffffff1660e01b8152600401610671929190918252602082015260400190565b6040805180830381865afa15801561068d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106b19190615002565b602080840151908101919091525260608401516106d99084601081106104e7576104e7614f9b565b815260808401516106ec908260016104f0565b60208201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316633d02f9b18d856010811061073257610732614f9b565b6020020135836040518363ffffffff1660e01b8152600401610755929190615026565b600060405180830381600087803b15801561076f57600080fd5b505af1158015610783573d6000803e3d6000fd5b5050604080516060810182526000808252602082018190529181019190915291506107ab9050565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663b64a097e8e86601081106107ec576107ec614f9b565b60200201356040518263ffffffff1660e01b815260040161080f91815260200190565b606060405180830381865afa15801561082c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108509190615072565b505067ffffffffffffffff168082526108ab5760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b6108cd8d85601081106108c0576108c0614f9b565b602002013560008b612ec3565b50505080806108db90614fca565b9150506102c0565b5067ffffffffffffffff851660a08201526108fd866128ea565b60c082015263ffffffff841660e0820152604080516020601f85018190048102820181019092528381526001600160a01b037f000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c169163a00ceb1291849161097f91908890889081908401838280828437600092019190915250613a7d92505050565b6040518363ffffffff1660e01b815260040161099c929190615282565b60006040518083038186803b1580156109b457600080fd5b505afa1580156109c8573d6000803e3d6000fd5b505050507f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663911adc1a338663ffffffff1666038d7ea4c68000610a159190615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600087803b158015610a8157600080fd5b505af1158015610a95573d6000803e3d6000fd5b505050507ff6f8a48e4a3e66a7c69c76d4c466f5c8ecffc318c99005256a2630b44045c772898989604051610acc9392919061545b565b60405180910390a1505050505050505050565b34662386f26fc1000014610b355760405162461bcd60e51b815260206004820152601960248201527f416d6f756e74206d75737420626520302e303130204554482e000000000000006044820152606401610187565b6000610b42603c42614f87565b90506000610b5766038d7ea4c6800034614f87565b905060007f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03163460405160006040518083038185875af1925050503d8060008114610bc6576040519150601f19603f3d011682016040523d82523d6000602084013e610bcb565b606091505b5050905080610c1c5760405162461bcd60e51b815260206004820181905260248201527f466f7277617264696e672066756e647320746f2062617365206661696c65642e6044820152606401610187565b6a038d7ea4c2f2815b3980007f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316311115610ca15760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e0000000000006044820152606401610187565b610ca961471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101879052600060248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063a4edfc58906044016040805180830381865afa158015610d2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d519190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101879052600160248201526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375169063a4edfc58906044016040805180830381865afa158015610de0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e049190615002565b6020808401519081019190915252610e97610e8f63ffffffff8516610e89604080518082018252600080825260209182015281518083019092527f14bcc435f49d130d189737f9762feb25c44ef5b886bef833e31a702af6be474882527f10cd33954522ad058f00a2553fd4e10d859fe125997e98adba777910dddc53229082015290565b90613f7a565b8260006104f0565b81526040517f3d02f9b10000000000000000000000000000000000000000000000000000000081527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690633d02f9b190610f009089908590600401615026565b600060405180830381600087803b158015610f1a57600080fd5b505af1158015610f2e573d6000803e3d6000fd5b505050506000610f3d876128ea565b90506000610fd0610f58610f518935613fb8565b8490613f7a565b610fca60208a0135610e89604080518082018252600080825260209182015281518083019092527f14bcc435f49d130d189737f9762feb25c44ef5b886bef833e31a702af6be474882527f10cd33954522ad058f00a2553fd4e10d859fe125997e98adba777910dddc53229082015290565b90612e73565b9050600061100a308a84604051602001610fec9392919061547d565b6040516020818303038152906040528051906020012060001c613fe4565b90508735811461105c5760405162461bcd60e51b815260206004820152601b60248201527f5369676e6174757265206661696c656420746f207665726966792e00000000006044820152606401610187565b611067898789612ec3565b604051899033907f05ec147cbb865958fbd62b0f318cd69d8f0e1b1f21531b8d008f9a39bce062f890600090a3505050505050505050565b6002546801000000000000000090046001600160a01b031633146111055760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420746865206f776e65722e00000000000000006044820152606401610187565b600280546001600160a01b0394851668010000000000000000027fffffffff0000000000000000000000000000000000000000ffffffffffffffff9091161790556003805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009092169290931691909117179055565b6111a5603c42614f87565b8867ffffffffffffffff16146111fd5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e00000000000000000000000000000000000000006044820152606401610187565b60025467ffffffffffffffff808a169116101561125457600280547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff8a1617905561125460016000614678565b60005b6001548110156112df57896001828154811061127557611275614f9b565b9060005260206000200154036112cd5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e000000000000000000000000006044820152606401610187565b806112d781614fca565b915050611257565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018990556040516001600160a01b038416907f455f9623b71a09d41c2aab8b7edd236e2a1ab057ad848f6be4290c5079c5934790611359908f908f908f908d9089908990615530565b60405180910390a2611369614699565b6113728b6128ea565b608082015260005b601081101561193f5760008e826010811061139757611397614f9b565b602002013590506113a8818c6129cd565b6113b1816128ea565b835183601081106113c4576113c4614f9b565b60200201526113de8e83601081106102fe576102fe614f9b565b836060015183601081106113f4576113f4614f9b565b602002015261140161471b565b6040517f4783731600000000000000000000000000000000000000000000000000000000815260048101839052600060248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316906347837316906044016040805180830381865afa158015611485573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a99190615002565b82516020810191909152526040517f4783731600000000000000000000000000000000000000000000000000000000815260048101839052600160248201526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb837516906347837316906044016040805180830381865afa158015611538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155c9190615002565b602080840151908101919091525260608401516115849084601081106104e7576104e7614f9b565b8460200151846010811061159a5761159a614f9b565b602002015260808401516115b0908260016104f0565b846040015184601081106115c6576115c6614f9b565b60200201526115d361471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101849052600060248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063a4edfc58906044016040805180830381865afa158015611657573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167b9190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101849052600160248201526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375169063a4edfc58906044016040805180830381865afa15801561170a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172e9190615002565b602080840151908101919091525260608501516117569085601081106104e7576104e7614f9b565b81526080850151611769908260016104f0565b60208201526040517f3d02f9b10000000000000000000000000000000000000000000000000000000081527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690633d02f9b1906117d59086908590600401615026565b600060405180830381600087803b1580156117ef57600080fd5b505af1158015611803573d6000803e3d6000fd5b50506040805160608101825260008082526020820181905291810191909152915061182b9050565b6040517fb64a097e000000000000000000000000000000000000000000000000000000008152600481018590527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063b64a097e90602401606060405180830381865afa1580156118a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118cd9190615072565b505067ffffffffffffffff168082526119285760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b50505050808061193790614fca565b91505061137a565b5060035460009061196e9074010000000000000000000000000000000000000000900463ffffffff168a615578565b67ffffffffffffffff8b1660a084015290506119898b6128ea565b60c0830152611998818961559b565b63ffffffff1660e08301526040516000906119bb908790879087906020016155b8565b6040516020818303038152906040528051906020012060001c90507f0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b6806001600160a01b031663f11b521f8b85611a468c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061401092505050565b856040518563ffffffff1660e01b8152600401611a6694939291906155e4565b60006040518083038186803b158015611a7e57600080fd5b505afa158015611a92573d6000803e3d6000fd5b505050507f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663911adc1a612710338c63ffffffff1666038d7ea4c68000611ae29190615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600088803b158015611b4e57600080fd5b5087f1158015611b62573d6000803e3d6000fd5b50506003546001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83758116945063911adc1a9350169050611bb563ffffffff861666038d7ea4c68000615444565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526060604482015260006064820152608401600060405180830381600087803b158015611c2157600080fd5b505af1158015611c35573d6000803e3d6000fd5b505050507f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663911adc1a878c63ffffffff1666038d7ea4c68000611c829190615444565b88886040518563ffffffff1660e01b8152600401611ca39493929190615799565b600060405180830381600087803b158015611cbd57600080fd5b505af1158015611cd1573d6000803e3d6000fd5b50505050505050505050505050505050505050565b611cf766038d7ea4c68000346157c2565b15611d445760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e6044820152606401610187565b6000611d51603c42614f87565b90506000611d6666038d7ea4c6800034614f87565b905060007f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03163460405160006040518083038185875af1925050503d8060008114611dd5576040519150601f19603f3d011682016040523d82523d6000602084013e611dda565b606091505b5050905080611e2b5760405162461bcd60e51b815260206004820181905260248201527f466f7277617264696e672066756e647320746f2062617365206661696c65642e6044820152606401610187565b6a038d7ea4c2f2815b3980007f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316311115611eb05760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e0000000000006044820152606401610187565b611eb8614699565b611ec1876128ea565b608082015260005b60108110156122ee57611ef28a8260108110611ee757611ee7614f9b565b6020020135866129cd565b611f078a82601081106102fe576102fe614f9b565b82518260108110611f1a57611f1a614f9b565b6020020152611f348982601081106102fe576102fe614f9b565b82606001518260108110611f4a57611f4a614f9b565b6020020152611f5761471b565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc588c8460108110611f9857611f98614f9b565b602002013560006040518363ffffffff1660e01b8152600401611fc5929190918252602082015260400190565b6040805180830381865afa158015611fe1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120059190615002565b82516020810191909152527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc588c846010811061205157612051614f9b565b602002013560016040518363ffffffff1660e01b815260040161207e929190918252602082015260400190565b6040805180830381865afa15801561209a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120be9190615002565b602080840151908101919091525260608301516120e69083601081106104e7576104e7614f9b565b815260808301516120f9908260016104f0565b60208201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316633d02f9b18c846010811061213f5761213f614f9b565b6020020135836040518363ffffffff1660e01b8152600401612162929190615026565b600060405180830381600087803b15801561217c57600080fd5b505af1158015612190573d6000803e3d6000fd5b5050604080516060810182526000808252602082018190529181019190915291506121b89050565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663b64a097e8d85601081106121f9576121f9614f9b565b60200201356040518263ffffffff1660e01b815260040161221c91815260200190565b606060405180830381865afa158015612239573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225d9190615072565b505067ffffffffffffffff168082526122b85760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e0000006044820152606401610187565b6122d98c84601081106122cd576122cd614f9b565b60200201358789612ec3565b505080806122e690614fca565b915050611ec9565b507f0000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e636001600160a01b03166377f73355848361235f8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061438592505050565b6040518463ffffffff1660e01b815260040161237d939291906157d6565b60006040518083038186803b15801561239557600080fd5b505afa1580156123a9573d6000803e3d6000fd5b50505050336001600160a01b03167fbdee54bab8aa68aecbb89de2313baaa387447195fe74aa236a4d9345799b33008a8a8a876040516123ec9493929190615880565b60405180910390a2505050505050505050565b60608267ffffffffffffffff81111561241a5761241a6158b0565b60405190808252806020026020018201604052801561245357816020015b612440614754565b8152602001906001900390816124385790505b50905060005b8381101561286b5761246961471b565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663478373168787858181106124aa576124aa614f9b565b9050602002013560006040518363ffffffff1660e01b81526004016124d9929190918252602082015260400190565b6040805180830381865afa1580156124f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125199190615002565b82516020810191909152527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316634783731687878581811061256557612565614f9b565b9050602002013560016040518363ffffffff1660e01b8152600401612594929190918252602082015260400190565b6040805180830381865afa1580156125b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d49190615002565b602080840151908101919091525263ffffffff84166000808888868181106125fe576125fe614f9b565b602090810292909201358352508101919091526040016000205467ffffffffffffffff1610156127da5761263061471b565b7f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc5888888681811061267157612671614f9b565b9050602002013560006040518363ffffffff1660e01b81526004016126a0929190918252602082015260400190565b6040805180830381865afa1580156126bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e09190615002565b82516020810191909152527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031663a4edfc5888888681811061272c5761272c614f9b565b9050602002013560016040518363ffffffff1660e01b815260040161275b929190918252602082015260400190565b6040805180830381865afa158015612777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061279b9190615002565b60208084015190810191909152526127bd8160005b60200201518360006104f0565b82526127d38160015b60200201518360016104f0565b6020830152505b6127eb8160005b60200201516144d7565b8383815181106127fd576127fd614f9b565b602002602001015160006002811061281757612817614f9b565b60200201526128278160016127e1565b83838151811061283957612839614f9b565b602002602001015160016002811061285357612853614f9b565b6020020152508061286381614fca565b915050612459565b509392505050565b60408051808201909152600080825260208201526128e47f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47836040516020016128bc91906158df565b6040516020818303038152906040528051906020012060001c6128df91906157c2565b614515565b92915050565b60408051808201909152600080825260208201526000829003612920575050604080518082019091526000808252602082015290565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c60006129558360036145b2565b61296090600361590e565b9050600061298e827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f526145b2565b60408051808201909152858152602081018290529091506001821684146129c3576129b88161461a565b979650505050505050565b9695505050505050565b60008281526020819052604090205467ffffffffffffffff80831691161015612e6f576129f861471b565b6040517f4783731600000000000000000000000000000000000000000000000000000000815260048101849052600060248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316906347837316906044016040805180830381865afa158015612a7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa09190615002565b82516020810191909152526040517f4783731600000000000000000000000000000000000000000000000000000000815260048101849052600160248201526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb837516906347837316906044016040805180830381865afa158015612b2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b539190615002565b6020808401519081019190915252612b6961471b565b6040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101859052600060248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063a4edfc58906044016040805180830381865afa158015612bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c119190615002565b82516020810191909152526040517fa4edfc5800000000000000000000000000000000000000000000000000000000815260048101859052600160248201526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375169063a4edfc58906044016040805180830381865afa158015612ca0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc49190615002565b6020808401519081019190915252612cdd8160006127b0565b8252612cea8160016127c6565b6020830152612cf761471b565b6040517f8eaad12e0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83751690638eaad12e90612d619087908690600401615026565b600060405180830381600087803b158015612d7b57600080fd5b505af1158015612d8f573d6000803e3d6000fd5b50506040517f3d02f9b10000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375169250633d02f9b19150612dfa9087908590600401615026565b600060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050600085815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff86161790555050505b5050565b60408051808201909152600080825260208201526040518351815260208401516020820152825160408201526020830151606082015260408260808360065afa612ebc57600080fd5b5092915050565b604080516060810182526000808252602082018190528183015290517fb64a097e000000000000000000000000000000000000000000000000000000008152600481018590526001600160a01b037f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375169063b64a097e90602401606060405180830381865afa158015612f5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7e9190615072565b67ffffffffffffffff9081166040850152908116602084015216808252156136ea57805160208201516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169263f6c18c11929091849063e2226a7c9084906001908490632316aa6c90602401602060405180830381865afa158015613045573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130699190615921565b613073919061593a565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815267ffffffffffffffff90921660048301526024820152604401602060405180830381865afa1580156130d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130f99190615921565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815267ffffffffffffffff93841660048201529290911660248301526044820152606401600060405180830381600087803b15801561316157600080fd5b505af1158015613175573d6000803e3d6000fd5b505082516040517f32de71bd00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031692506332de71bd9150602401600060405180830381600087803b15801561320057600080fd5b505af1158015613214573d6000803e3d6000fd5b505082516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169250632316aa6c9150602401602060405180830381865afa1580156132a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c69190615921565b6000036133715780516040517f92752df500000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316906392752df590602401600060405180830381600087803b15801561335457600080fd5b505af1158015613368573d6000803e3d6000fd5b505050506136ea565b80516040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690632316aa6c90602401602060405180830381865afa1580156133fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061341f9190615921565b816020015167ffffffffffffffff1610156136ea576040805160608101825260008082526020820181905291810191909152815160208301516040517fe2226a7c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9283166004820152911660248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063b64a097e90829063e2226a7c90604401602060405180830381865afa1580156134ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135139190615921565b6040518263ffffffff1660e01b815260040161353191815260200190565b606060405180830381865afa15801561354e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135729190615072565b67ffffffffffffffff90811660408581019190915291811660208086019182529382168552928501805182169093528451925191517fe2226a7c00000000000000000000000000000000000000000000000000000000815292811660048401521660248201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690632e29ec7790829063e2226a7c90604401602060405180830381865afa158015613631573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136559190615921565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526004810192909252845167ffffffffffffffff908116602484015260208601518116604484015290850151166064820152608401600060405180830381600087803b1580156136d057600080fd5b505af11580156136e4573d6000803e3d6000fd5b50505050505b67ffffffffffffffff8216815260408101805163ffffffff8516919061371190839061594d565b67ffffffffffffffff9081169091526040517f4149629600000000000000000000000000000000000000000000000000000000815290841660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169150634149629690602401602060405180830381865afa1580156137a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137c4919061596e565b613865576040517ffea6c9de00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b03169063fea6c9de90602401600060405180830381600087803b15801561384c57600080fd5b505af1158015613860573d6000803e3d6000fd5b505050505b6040517f2316aa6c00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff831660048201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690632316aa6c90602401602060405180830381865afa1580156138ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139109190615921565b67ffffffffffffffff90811660208301908152604080517f2e29ec770000000000000000000000000000000000000000000000000000000081526004810188905284518416602482015291518316604483015283015190911660648201527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b031690632e29ec7790608401600060405180830381600087803b1580156139bc57600080fd5b505af11580156139d0573d6000803e3d6000fd5b50506040517ff0284e0e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602481018790527f000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83756001600160a01b0316925063f0284e0e9150604401600060405180830381600087803b158015613a5f57600080fd5b505af1158015613a73573d6000803e3d6000fd5b5050505050505050565b613a85614772565b6020820151613a98906128ea565b6128ea565b81526040820151613aa8906128ea565b60208201526060820151613abb906128ea565b60408201526080820151613ace906128ea565b606082015260005b6004811015613d7657613b04613a9384613af1846020615444565b613afc90608061590e565b016020015190565b82608001518260048110613b1a57613b1a614f9b565b6020020152613b3c613a9384613b3160048561590e565b613af1906020615444565b8260a001518260048110613b5257613b52614f9b565b6020020181905250613b8f613a9384836020613b6e9190615444565b613b7a60046040615444565b613b8590608061590e565b613afc919061590e565b8260c001518260048110613ba557613ba5614f9b565b6020020181905250613bcd613a9384836020613bc19190615444565b613b7a60046060615444565b8260e001518260048110613be357613be3614f9b565b6020020181905250613c0b613a9384836020613bff9190615444565b613b7a60046080615444565b8261010001518260048110613c2257613c22614f9b565b6020020181905250613c4a613a9384836020613c3e9190615444565b613b7a600460a0615444565b8261012001518260048110613c6157613c61614f9b565b6020020181905250613c89613a9384836020613c7d9190615444565b613b7a600460c0615444565b8261014001518260048110613ca057613ca0614f9b565b6020020181905250613cc8613a9384836020613cbc9190615444565b613b7a600460e0615444565b8261016001518260048110613cdf57613cdf614f9b565b6020020181905250613d0583826020613cf89190615444565b613b7a6004610100615444565b610180830151518260048110613d1d57613d1d614f9b565b602002018181525050613d4483826020613d379190615444565b613b7a6004610120615444565b610180830151602001518260048110613d5f57613d5f614f9b565b602002015280613d6e81614fca565b915050613ad6565b506000613d866004610140615444565b9050613d9783613afc83608061590e565b6101a0830152613daf613a9384613afc8460a061590e565b6101c0830152613dc7613a9384613afc8460c061590e565b6101e0830152613ddc83613afc8360e061590e565b610200830152613df283613afc8361010061590e565b610220830152613e0883613afc8361012061590e565b610240830152613e1e83613afc8361014061590e565b610260830152613e3483613afc8361016061590e565b610280830152613e4a83613afc8361018061590e565b6102a0830152613e6083613afc836101a061590e565b6102c083015260005b613e756005600161590e565b811015613f1157613e9a613a9385613e8e846020615444565b613b85866101c061590e565b6102e0840151518260068110613eb257613eb2614f9b565b6020020152613edf613a9385613ec960058561590e565b613ed490600161590e565b613e8e906020615444565b836102e00151602001518260068110613efa57613efa614f9b565b602002015280613f0981614fca565b915050613e69565b50613f3983613f226005600161590e565b613f2d906040615444565b613b85846101c061590e565b6102e083015160400152613f6a83613f536005600161590e565b613f5e906040615444565b613b85846101e061590e565b6102e08301516060015250919050565b6040805180820190915260008082526020820152604051835181526020840151602082015282604082015260408260608360075afa612ebc57600080fd5b60006128e4827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000161593a565b60006128e47f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001836157c2565b6140186148c3565b6020820151614026906128ea565b81526040820151614036906128ea565b60208201526060820151614049906128ea565b6040820152608082015161405c906128ea565b606082015260005b60048110156141d35761407f613a9384613af1846020615444565b8260800151826004811061409557614095614f9b565b60200201526140ac613a9384613b3160048561590e565b8260a0015182600481106140c2576140c2614f9b565b60200201819052506140de613a9384836020613b6e9190615444565b8260c0015182600481106140f4576140f4614f9b565b6020020181905250614110613a9384836020613bc19190615444565b8260e00151826004811061412657614126614f9b565b6020020181905250614142613a9384836020613bff9190615444565b826101000151826004811061415957614159614f9b565b6020020181905250614175613a9384836020613c3e9190615444565b826101200151826004811061418c5761418c614f9b565b60200201819052506141a583826020613c7d9190615444565b61014083015182600481106141bc576141bc614f9b565b6020020152806141cb81614fca565b915050614064565b5060006141e2600460e0615444565b90506141f383613afc83608061590e565b61016083015261420b613a9384613afc8460a061590e565b610180830152614223613a9384613afc8460c061590e565b6101a083015261423883613afc8360e061590e565b6101c083015261424e83613afc8361010061590e565b6101e083015261426483613afc8361012061590e565b61020083015261427a83613afc8361014061590e565b61022083015261429083613afc8361016061590e565b6102408301526142a683613afc8361018061590e565b6102608301526142bc83613afc836101a061590e565b61028083015260005b6005811015614341576142e0613a9385613e8e846020615444565b6102a08401515182600681106142f8576142f8614f9b565b602002015261430f613a9385613ed460058561590e565b836102a0015160200151826006811061432a5761432a614f9b565b60200201528061433981614fca565b9150506142c5565b5061435283613f2d60056040615444565b60001c826102a0015160400181815250506143758360056040613f5e9190615444565b6102a08301516060015250919050565b61438d61497f565b602082015161439b906128ea565b815260408201516143ab906128ea565b602082015260005b6004811015614484576143d9613a93846143ce846020615444565b613afc90604061590e565b826040015182600481106143ef576143ef614f9b565b6020020152614411613a938461440660048561590e565b6143ce906020615444565b8260600151826004811061442757614427614f9b565b6020020181905250614457838260206144409190615444565b61444c60046040615444565b613b8590604061590e565b6080830151826004811061446d5761446d614f9b565b60200201528061447c81614fca565b9150506143b3565b50600061449360046060615444565b90506144a483613afc83604061590e565b60a08301526144b883613afc83606061590e565b60c08301526144cc83613afc83608061590e565b60e083015250919050565b8051602082015160009190600190811690036128e4577f80000000000000000000000000000000000000000000000000000000000000001792915050565b604080518082019091526000808252602082015260005b60006145398460036145b2565b61454490600361590e565b9050614570817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f526145b2565b91508061457e8360026145b2565b03614589575061459c565b61459460018561590e565b93505061452c565b6040805180820190915292835260208301525090565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa61461157600080fd5b51949350505050565b6040805180820190915260008082526020820152604080518082019091528251815260208084015190820190614670907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4761593a565b905292915050565b508054600082559060005260206000209081019061469691906149f5565b50565b6040518061010001604052806146ad614a0e565b81526020016146ba614a0e565b81526020016146c7614a0e565b81526020016146d4614a0e565b815260408051808201825260008082526020808301829052808501929092528284018190528251808401909352808352908201819052606083019190915260809091015290565b60405180604001604052806002905b604080518082019091526000808252602082015281526020019060019003908161472a5790505090565b60405180604001604052806002906020820280368337509192915050565b6040805161034081018252600061030082018181526103208301829052825282518084018452818152602080820183905280840191909152835180850185528281528082018390528385015283518085019094528184528301526060810191909152608081016147e0614a3a565b81526020016147ed614a3a565b81526020016147fa614a3a565b8152602001614807614a3a565b8152602001614814614a3a565b8152602001614821614a3a565b815260200161482e614a3a565b815260200161483b614a3a565b8152602001614848614a63565b81526000602080830182905260408051808201825283815280830184905281850152805180820190915282815290810182905260608301526080820181905260a0820181905260c0820181905260e0820181905261010082018190526101208201819052610140820152610160016148be614a90565b905290565b604080516103008101825260006102c082018181526102e0830182905282528251808401845281815260208082018390528084019190915283518085018552828152808201839052838501528351808501909452818452830152606081019190915260808101614931614a3a565b815260200161493e614a3a565b815260200161494b614a3a565b8152602001614958614a3a565b8152602001614965614a3a565b8152602001614972614a3a565b8152602001614848614ac4565b6040805161014081018252600061010082018181526101208301829052825282518084018452818152602080820192909252908201529081016149c0614a3a565b81526020016149cd614a3a565b81526020016149da614ac4565b81526020016000815260200160008152602001600081525090565b5b80821115614a0a57600081556001016149f6565b5090565b604080516102408101909152600061020082018181526102208301919091528152600f6020820161472a565b6040805160c0810190915260006080820181815260a0830191909152815260036020820161472a565b60405180604001604052806002905b614a7a614ac4565b815260200190600190039081614a725790505090565b6040518060800160405280614aa3614ae2565b8152602001614ab0614ae2565b815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b604080516101008101909152600060c0820181815260e0830191909152815260056020820161472a565b8061020081018310156128e457600080fd5b67ffffffffffffffff8116811461469657600080fd5b8035614b3f81614b1e565b919050565b803563ffffffff81168114614b3f57600080fd5b60008083601f840112614b6a57600080fd5b50813567ffffffffffffffff811115614b8257600080fd5b602083019150836020828501011115614b9a57600080fd5b9250929050565b6000806000806000806000806104a0898b031215614bbe57600080fd5b614bc88a8a614b0c565b9750614bd88a6102008b01614b0c565b965061040089013595506104208901359450610440890135614bf981614b1e565b9350614c086104608a01614b44565b925061048089013567ffffffffffffffff811115614c2557600080fd5b614c318b828c01614b58565b999c989b5096995094979396929594505050565b60008060608385031215614c5857600080fd5b8235915083606084011115614c6c57600080fd5b50926020919091019150565b80356001600160a01b0381168114614b3f57600080fd5b600080600060608486031215614ca457600080fd5b614cad84614c78565b9250614cbb60208501614c78565b9150614cc960408501614b44565b90509250925092565b6000806000806000806000806000806000806105008d8f031215614cf557600080fd5b614cff8e8e614b0c565b9b50614d0f8e6102008f01614b0c565b9a506104008d013599506104208d01359850614d2e6104408e01614b34565b9750614d3d6104608e01614b44565b9650614d4c6104808e01614b44565b955067ffffffffffffffff6104a08e01351115614d6857600080fd5b614d798e6104a08f01358f01614b58565b9095509350614d8b6104c08e01614c78565b925067ffffffffffffffff6104e08e01351115614da757600080fd5b614db88e6104e08f01358f01614b58565b81935080925050509295989b509295989b509295989b565b60008060008060006104408688031215614de957600080fd5b614df38787614b0c565b9450614e03876102008801614b0c565b9350610400860135925061042086013567ffffffffffffffff811115614e2857600080fd5b614e3488828901614b58565b969995985093965092949392505050565b600080600060408486031215614e5a57600080fd5b833567ffffffffffffffff80821115614e7257600080fd5b818601915086601f830112614e8657600080fd5b813581811115614e9557600080fd5b8760208260051b8501011115614eaa57600080fd5b602092830195509350614cc99186019050614b44565b60208082528251828201819052600091906040908185019086840185805b83811015614f1b57825185835b6002811015614f0857825182529189019190890190600101614eeb565b5050509385019391860191600101614ede565b509298975050505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082614f9657614f96614f29565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614ffb57614ffb614f58565b5060010190565b6000806040838503121561501557600080fd5b505080516020909101519092909150565b82815260a0810160208083018460005b60028110156150675761505483835180518252602090810151910152565b6040929092019190830190600101615036565b505050509392505050565b60008060006060848603121561508757600080fd5b835161509281614b1e565b60208501519093506150a381614b1e565b60408501519092506150b481614b1e565b809150509250925092565b8060005b60108110156150f7576150e184835180518252602090810151910152565b60409390930192602091909101906001016150c3565b50505050565b6151088282516150bf565b602081015161511b6104008401826150bf565b50604081015161512f6108008401826150bf565b506060810151615143610c008401826150bf565b506080810151805161100084015260209081015161102084015260a082015161104084015260c08201518051611060850152015161108083015260e001516110a090910152565b8060005b60048110156150f7576151ac84835180518252602090810151910152565b604093909301926020919091019060010161518e565b8060005b60048110156150f75781518452602093840193909101906001016151c6565b8060005b60028110156150f7576151fd8483516151c2565b60809390930192602091909101906001016151e9565b8060005b60068110156150f75761523584835180518252602090810151910152565b6040939093019260209190910190600101615217565b615256828251615213565b6020810151615269610180840182615213565b5060408101516103008301526060015161032090910152565b611f80810161529182856150fd565b825180516110c08401526020908101516110e0840152808401518051611100850152810151611120840152604084015180516111408501528101516111608401526060840151805161118085015201516111a083015260808301516152fa6111c084018261518a565b5060a083015161530e6112c084018261518a565b5060c08301516153226113c084018261518a565b5060e08301516153366114c084018261518a565b5061010083015161534b6115c084018261518a565b506101208301516153606116c084018261518a565b506101408301516153756117c084018261518a565b5061016083015161538a6118c084018261518a565b5061018083015161539f6119c08401826151e5565b506101a0830151611ac08301526101c08301518051611ae0840152602090810151611b008401526101e08401518051611b208501520151611b40830152610200830151611b60830152610220830151611b80830152610240830151611ba0830152610260830151611bc0830152610280830151611be08301526102a0830151611c008301526102c0830151611c208301526102e083015161286b611c4084018261524b565b80820281158282048414176128e4576128e4614f58565b6104208101610200808684378085828501375082610400830152949350505050565b60a08082526010908201527f57656c636f6d6520746f204669726e2e0000000000000000000000000000000060c08201526001600160a01b03841660208201526040810183905260e081016154df606083018480518252602090810151910152565b949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6000610460610200808a8537808982860137508661040084015263ffffffff86166104208401528061044084015261556b81840185876154e7565b9998505050505050505050565b600063ffffffff8084168061558f5761558f614f29565b92169190910492915050565b63ffffffff818116838216019080821115612ebc57612ebc614f58565b6001600160a01b03841681526040602082015260006155db6040830184866154e7565b95945050505050565b63ffffffff85168152611d4081016155ff60208301866150fd565b835180516110e084015260209081015161110084015280850151805161112085015281015161114084015260408501518051611160850152810151611180840152606085015180516111a085015201516111c083015260808401516156686111e084018261518a565b5060a084015161567c6112e084018261518a565b5060c08401516156906113e084018261518a565b5060e08401516156a46114e084018261518a565b506101008401516156b96115e084018261518a565b506101208401516156ce6116e084018261518a565b506101408401516156e36117e08401826151c2565b5061016084015161186083015261018084015180516118808401526020908101516118a08401526101a085015180516118c085015201516118e08301526101c08401516119008301526101e08401516119208301526102008401516119408301526102208401516119608301526102408401516119808301526102608401516119a08301526102808401516119c08301526102a08401516157886119e084018261524b565b5082611d2083015295945050505050565b6001600160a01b03851681528360208201526060604082015260006129c36060830184866154e7565b6000826157d1576157d1614f29565b500690565b63ffffffff8416815261144081016157f160208301856150fd565b825180516110e08401526020908101516111008401528084015180516111208501520151611140830152604083015161582e61116084018261518a565b50606083015161584261126084018261518a565b5060808301516158566113608401826151c2565b5060a08301516113e083015260c083015161140083015260e0830151611420830152949350505050565b610440810161020080878437808682850137508361040083015263ffffffff831661042083015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000825160005b8181101561590057602081860181015185830152016158e6565b506000920191825250919050565b808201808211156128e4576128e4614f58565b60006020828403121561593357600080fd5b5051919050565b818103818111156128e4576128e4614f58565b67ffffffffffffffff818116838216019080821115612ebc57612ebc614f58565b60006020828403121561598057600080fd5b8151801515811461599057600080fd5b939250505056fea26469706673582212209bc53e924ec0ef938ad596785f1e0a1125402beadedac46bc5df89054ae3e3b664736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb83750000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680
-----Decoded View---------------
Arg [0] : base_ (address): 0x047AD931277c2Cac84B3204Dfa94c3bdF5fb8375
Arg [1] : deposit_ (address): 0x7940467Dde784c9836F95b264003a0ceB6e91e63
Arg [2] : transfer_ (address): 0xEd4f30624bFbe3B5F6660313B4a50bBf04Ef391C
Arg [3] : withdrawal_ (address): 0x7F72b657905f748D55Dd4dDC17e893C62499b680
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000047ad931277c2cac84b3204dfa94c3bdf5fb8375
Arg [1] : 0000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63
Arg [2] : 000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c
Arg [3] : 0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680
Deployed Bytecode Sourcemap
213:12890:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8477:1995;;;;;;;;;;-1:-1:-1;8477:1995:3;;;;;:::i;:::-;;:::i;:::-;;5476:1207;;;;;;:::i;:::-;;:::i;1952:173::-;;;;;;;;;;-1:-1:-1;1952:173:3;;;;;:::i;:::-;;:::i;10478:2623::-;;;;;;;;;;-1:-1:-1;10478:2623:3;;;;;:::i;:::-;;:::i;6689:1782::-;;;;;;:::i;:::-;;:::i;4537:933::-;;;;;;;;;;-1:-1:-1;4537:933:3;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8477:1995;8647:30;623:2;8647:15;:30;:::i;:::-;8638:5;:39;;;8630:64;;;;-1:-1:-1;;;8630:64:3;;7454:2:8;8630:64:3;;;7436:21:8;7493:2;7473:18;;;7466:30;7532:14;7512:18;;;7505:42;7564:18;;8630:64:3;;;;;;;;;8767:17;;:25;;;;:17;;:25;8763:109;;;8808:17;:25;;;;;;;;;;8847:14;-1:-1:-1;;8847:14:3;:::i;:::-;8886:9;8881:117;8905:7;:14;8901:18;;8881:117;;;8962:1;8948:7;8956:1;8948:10;;;;;;;;:::i;:::-;;;;;;;;;:15;8940:47;;;;-1:-1:-1;;;8940:47:3;;7984:2:8;8940:47:3;;;7966:21:8;8023:2;8003:18;;;7996:30;8062:21;8042:18;;;8035:49;8101:18;;8940:47:3;7782:343:8;8940:47:3;8921:3;;;;:::i;:::-;;;;8881:117;;;-1:-1:-1;9007:7:3;:15;;;;;;;-1:-1:-1;9007:15:3;;;;;;;;;9033:32;;:::i;:::-;9089:19;9106:1;9089:16;:19::i;:::-;9075:11;;;:33;9123:9;9118:1033;110:6:6;9138:5:3;;9118:1033;;;9164:21;9173:1;9175;9173:4;;;;;;;:::i;:::-;;;;;9179:5;9164:8;:21::i;:::-;9217:22;9234:1;9236;9234:4;;;;;;;:::i;:::-;;;;;9217:16;:22::i;:::-;9200:11;;9212:1;9200:14;;;;;;;:::i;:::-;;;;:39;9270:22;9287:1;9289;9287:4;;;;;;;:::i;9270:22::-;9253:9;:11;;;9265:1;9253:14;;;;;;;:::i;:::-;;;;:39;9306:25;;:::i;:::-;9368:5;-1:-1:-1;;;;;9368:9:3;;9378:1;9380;9378:4;;;;;;;:::i;:::-;;;;;9384:1;9368:18;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;9368:18:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9346:6;;;9356:8;;9345:41;;;;;9423:5;-1:-1:-1;;;;;9423:9:3;;9433:1;9435;9433:4;;;;;;;:::i;:::-;;;;;9439:1;9423:18;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;9423:18:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9401:6;;;;;9411:8;;;9400:41;;;;;9485:11;;;;9474:26;;9497:1;9485:14;;;;;;;:::i;:::-;;;;;9474:3;9478:1;9474:6;;;;;;:10;:26::i;:::-;9455:9;:13;;;9469:1;9455:16;;;;;;;:::i;:::-;;;;:45;9544:11;;;;9533:23;;:3;9537:1;9533:6;;:23;9514:9;:13;;;9528:1;9514:16;;;;;;;:::i;:::-;;;;:42;9630:29;;:::i;:::-;9704:5;-1:-1:-1;;;;;9704:13:3;;9718:1;9720;9718:4;;;;;;;:::i;:::-;;;;;9724:1;9704:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;9704:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9674:10;;;9688:12;;9673:53;;;;;9771:5;-1:-1:-1;;;;;9771:13:3;;9785:1;9787;9785:4;;;;;;;:::i;:::-;;;;;9791:1;9771:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;9771:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9741:10;;;;;9755:12;;;9740:53;;;;;9835:11;;;;9820:30;;9847:1;9835:14;;;;;;;:::i;9820:30::-;9807:43;;9892:11;;;;9877:27;;9807:7;9885:1;9877:10;;:27;9864:10;;;:40;9918:5;-1:-1:-1;;;;;9918:16:3;;9935:1;9937;9935:4;;;;;;;:::i;:::-;;;;;9941:7;9918:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9963:25:3;;-1:-1:-1;;9963:25:3;10019:5;-1:-1:-1;;;;;10019:10:3;;10030:1;10032;10030:4;;;;;;;:::i;:::-;;;;;10019:16;;;;;;;;;;;;;10023:25:8;;10011:2;9996:18;;9877:177;10019:16:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;10002:33:3;;;;;10049:56;;;;-1:-1:-1;;;10049:56:3;;10779:2:8;10049:56:3;;;10761:21:8;10818:2;10798:18;;;10791:30;10857:31;10837:18;;;10830:59;10906:18;;10049:56:3;10577:353:8;10049:56:3;10119:21;10125:1;10127;10125:4;;;;;;;:::i;:::-;;;;;10131:1;10134:5;10119;:21::i;:::-;9150:1001;;;9145:3;;;;;:::i;:::-;;;;9118:1033;;;-1:-1:-1;10160:23:3;;;:15;;;:23;10207:19;10224:1;10207:16;:19::i;:::-;10193:11;;;:33;10236:19;;;:13;;;:19;10294:32;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10266:9:3;:16;;;;10193:9;;10294:32;;;10320:5;;;;;;10294:32;;10320:5;;;;10294:32;;;;;;;;;-1:-1:-1;10294:25:3;;-1:-1:-1;;;10294:32:3:i;:::-;10266:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10338:5;-1:-1:-1;;;;;10338:9:3;;10348:10;10368:3;10360:12;;10375:4;10360:19;;;;:::i;:::-;10338:46;;;;;;;;;;-1:-1:-1;;;;;17448:55:8;;;10338:46:3;;;17430:74:8;17520:18;;;17513:34;17583:2;17563:18;;;17556:30;-1:-1:-1;17602:18:8;;;17595:29;17641:19;;10338:46:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10440:25;10457:1;10460;10463;10440:25;;;;;;;;:::i;:::-;;;;;;;;8620:1852;8477:1995;;;;;;;;:::o;5476:1207::-;5571:9;5584:4;5571:17;5563:55;;;;-1:-1:-1;;;5563:55:3;;18346:2:8;5563:55:3;;;18328:21:8;18385:2;18365:18;;;18358:30;18424:27;18404:18;;;18397:55;18469:18;;5563:55:3;18144:349:8;5563:55:3;5629:12;5651:30;623:2;5651:15;:30;:::i;:::-;5629:53;-1:-1:-1;5693:13:3;5716:16;5728:4;5716:9;:16;:::i;:::-;5693:40;;5754:12;5779:5;-1:-1:-1;;;;;5771:19:3;5798:9;5771:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5753:59;;;5851:7;5843:52;;;;-1:-1:-1;;;5843:52:3;;18910:2:8;5843:52:3;;;18892:21:8;;;18929:18;;;18922:30;18988:34;18968:18;;;18961:62;19040:18;;5843:52:3;18708:356:8;5843:52:3;5939:17;5921:5;-1:-1:-1;;;;;5913:22:3;;:43;;5905:82;;;;-1:-1:-1;;;5905:82:3;;19271:2:8;5905:82:3;;;19253:21:8;19310:2;19290:18;;;19283:30;19349:28;19329:18;;;19322:56;19395:18;;5905:82:3;19069:350:8;5905:82:3;5997:29;;:::i;:::-;6067:19;;;;;;;;8512:25:8;;;6084:1:3;8553:18:8;;;8546:34;6067:5:3;-1:-1:-1;;;;;6067:13:3;;;;8485:18:8;;6067:19:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6037:10;;;6051:12;;6036:50;;;;;6127:19;;;;;;;;8512:25:8;;;6144:1:3;8553:18:8;;;8546:34;-1:-1:-1;;;;;6127:5:3;:13;;;;8485:18:8;;6127:19:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6097:10;;;;;6111:12;;;6096:50;;;;;6169:31;6184:15;;;;:3;-1:-1:-1;;;;;;;;;;;;;;;;;2204:21:3;;;;;;;;2216:3;2204:21;;2221:3;2204:21;;;;;2131:101;6184:3;:7;;:15::i;:::-;6169:7;6177:1;6169:10;;:31;6156:44;;6233:28;;;;;:5;-1:-1:-1;;;;;6233:16:3;;;;:28;;6250:1;;6156:7;;6233:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6272:22;6297:19;6314:1;6297:16;:19::i;:::-;6272:44;-1:-1:-1;6326:20:3;6349:72;6384:36;6392:27;6400:12;;6392:25;:27::i;:::-;6384:3;;:7;:36::i;:::-;6349:30;6365:12;;;;6349:3;-1:-1:-1;;;;;;;;;;;;;;;;;2204:21:3;;;;;;;;2216:3;2204:21;;2221:3;2204:21;;;;;2131:101;6349:30;:34;;:72::i;:::-;6326:95;;6431:9;6443:77;6500:4;6507:1;6510;6461:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;6451:62;;;;;;6443:71;;:75;:77::i;:::-;6431:89;-1:-1:-1;6552:12:3;;6538:26;;6530:66;;;;-1:-1:-1;;;6530:66:3;;20302:2:8;6530:66:3;;;20284:21:8;20341:2;20321:18;;;20314:30;20380:29;20360:18;;;20353:57;20427:18;;6530:66:3;20100:351:8;6530:66:3;6606:23;6612:1;6615:6;6623:5;6606;:23::i;:::-;6645:31;;6674:1;;6662:10;;6645:31;;;;;5553:1130;;;;;;;5476:1207;;:::o;1952:173::-;1473:6;;;;;-1:-1:-1;;;;;1473:6:3;1459:10;:20;1451:57;;;;-1:-1:-1;;;1451:57:3;;20658:2:8;1451:57:3;;;20640:21:8;20697:2;20677:18;;;20670:30;20736:26;20716:18;;;20709:54;20780:18;;1451:57:3;20456:348:8;1451:57:3;2051:6:::1;:15:::0;;-1:-1:-1;;;;;2051:15:3;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;2076:9:::1;:21:::0;;2107:11:::1;::::0;;::::1;::::0;::::1;::::0;;;;2076:21;;;::::1;2107:11:::0;;;;::::1;::::0;;1952:173::o;10478:2623::-;10705:30;623:2;10705:15;:30;:::i;:::-;10696:5;:39;;;10688:64;;;;-1:-1:-1;;;10688:64:3;;7454:2:8;10688:64:3;;;7436:21:8;7493:2;7473:18;;;7466:30;7532:14;7512:18;;;7505:42;7564:18;;10688:64:3;7252:336:8;10688:64:3;10871:17;;:25;;;;:17;;:25;10867:109;;;10912:17;:25;;;;;;;;;;10951:14;-1:-1:-1;;10951:14:3;:::i;:::-;10990:9;10985:117;11009:7;:14;11005:18;;10985:117;;;11066:1;11052:7;11060:1;11052:10;;;;;;;;:::i;:::-;;;;;;;;;:15;11044:47;;;;-1:-1:-1;;;11044:47:3;;7984:2:8;11044:47:3;;;7966:21:8;8023:2;8003:18;;;7996:30;8062:21;8042:18;;;8035:49;8101:18;;11044:47:3;7782:343:8;11044:47:3;11025:3;;;;:::i;:::-;;;;10985:117;;;-1:-1:-1;11111:7:3;:15;;;;;;;-1:-1:-1;11111:15:3;;;;;;;;;11142:54;;-1:-1:-1;;;;;11142:54:3;;;;;;;11161:1;;11164;;11167;;11170:6;;11191:4;;;;11142:54;:::i;:::-;;;;;;;;11246:32;;:::i;:::-;11302:19;11319:1;11302:16;:19::i;:::-;11288:11;;;:33;11336:9;11331:1052;110:6:6;11351:5:3;;11331:1052;;;11377:11;11391:1;11393;11391:4;;;;;;;:::i;:::-;;;;;11377:18;;11439:20;11448:3;11453:5;11439:8;:20::i;:::-;11491:21;11508:3;11491:16;:21::i;:::-;11474:11;;11486:1;11474:14;;;;;;;:::i;:::-;;;;:38;11543:22;11560:1;11562;11560:4;;;;;;;:::i;11543:22::-;11526:9;:11;;;11538:1;11526:14;;;;;;;:::i;:::-;;;;:39;11579:25;;:::i;:::-;11641:17;;;;;;;;8512:25:8;;;11656:1:3;8553:18:8;;;8546:34;11641:5:3;-1:-1:-1;;;;;11641:9:3;;;;8485:18:8;;11641:17:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11619:6;;;11629:8;;11618:40;;;;;11695:17;;;;;;;;8512:25:8;;;11710:1:3;8553:18:8;;;8546:34;-1:-1:-1;;;;;11695:5:3;:9;;;;8485:18:8;;11695:17:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11673:6;;;;;11683:8;;;11672:40;;;;;11756:11;;;;11745:26;;11768:1;11756:14;;;;;;;:::i;11745:26::-;11726:9;:13;;;11740:1;11726:16;;;;;;;:::i;:::-;;;;:45;11815:11;;;;11804:23;;:3;11808:1;11804:6;;:23;11785:9;:13;;;11799:1;11785:16;;;;;;;:::i;:::-;;;;:42;11901:29;;:::i;:::-;11975:21;;;;;;;;8512:25:8;;;11994:1:3;8553:18:8;;;8546:34;11975:5:3;-1:-1:-1;;;;;11975:13:3;;;;8485:18:8;;11975:21:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11945:10;;;11959:12;;11944:52;;;;;12041:21;;;;;;;;8512:25:8;;;12060:1:3;8553:18:8;;;8546:34;-1:-1:-1;;;;;12041:5:3;:13;;;;8485:18:8;;12041:21:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12011:10;;;;;12025:12;;;12010:52;;;;;12104:11;;;;12089:30;;12116:1;12104:14;;;;;;;:::i;12089:30::-;12076:43;;12161:11;;;;12146:27;;12076:7;12154:1;12146:10;;:27;12133:10;;;:40;12187:30;;;;;:5;-1:-1:-1;;;;;12187:16:3;;;;:30;;12204:3;;12133:7;;12187:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12231:25:3;;-1:-1:-1;;12231:25:3;12287:15;;;;;;;;10023:25:8;;;12287:5:3;-1:-1:-1;;;;;12287:10:3;;;;9996:18:8;;12287:15:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;12270:32:3;;;;;12316:56;;;;-1:-1:-1;;;12316:56:3;;10779:2:8;12316:56:3;;;10761:21:8;10818:2;10798:18;;;10791:30;10857:31;10837:18;;;10830:59;10906:18;;12316:56:3;10577:353:8;12316:56:3;11363:1020;;;;11358:3;;;;;:::i;:::-;;;;11331:1052;;;-1:-1:-1;12415:4:3;;12392:11;;12406:13;;12415:4;;;;;12406:6;:13;:::i;:::-;12429:23;;;:15;;;:23;12392:27;-1:-1:-1;12510:19:3;12527:1;12510:16;:19::i;:::-;12496:11;;;:33;12555:10;12561:4;12555:3;:10;:::i;:::-;12539:26;;:13;;;:26;12643:29;;12610:12;;12643:29;;12654:11;;12667:4;;;;12643:29;;;:::i;:::-;;;;;;;;;;;;;12633:40;;;;;;12625:49;;12610:64;;12695:11;-1:-1:-1;;;;;12695:18:3;;12714:6;12722:9;12733:34;12761:5;;12733:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12733:27:3;;-1:-1:-1;;;12733:34:3:i;:::-;12769:4;12695:79;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12785:5;-1:-1:-1;;;;;12785:9:3;;12800:5;12807:10;12827:3;12819:12;;12834:4;12819:19;;;;:::i;:::-;12785:58;;;;;;;;;;-1:-1:-1;;;;;17448:55:8;;;12785:58:3;;;17430:74:8;17520:18;;;17513:34;17583:2;17563:18;;;17556:30;-1:-1:-1;17602:18:8;;;17595:29;17641:19;;12785:58:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12917:9:3;;-1:-1:-1;;;;;12907:5:3;:9;;;-1:-1:-1;12907:9:3;;-1:-1:-1;12917:9:3;;-1:-1:-1;12928:20:3;:13;;;12944:4;12928:20;:::i;:::-;12907:46;;;;;;;;;;-1:-1:-1;;;;;17448:55:8;;;12907:46:3;;;17430:74:8;17520:18;;;17513:34;17583:2;17563:18;;;17556:30;-1:-1:-1;17602:18:8;;;17595:29;17641:19;;12907:46:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13042:5;-1:-1:-1;;;;;13042:9:3;;13052:11;13073:6;13065:15;;13083:4;13065:22;;;;:::i;:::-;13089:4;;13042:52;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10678:2423;;;10478:2623;;;;;;;;;;;;:::o;6689:1782::-;6944:16;6956:4;6944:9;:16;:::i;:::-;:21;6936:66;;;;-1:-1:-1;;;6936:66:3;;26282:2:8;6936:66:3;;;26264:21:8;;;26301:18;;;26294:30;26360:34;26340:18;;;26333:62;26412:18;;6936:66:3;26080:356:8;6936:66:3;7012:12;7034:30;623:2;7034:15;:30;:::i;:::-;7012:53;-1:-1:-1;7075:13:3;7098:16;7110:4;7098:9;:16;:::i;:::-;7075:40;;7159:12;7184:5;-1:-1:-1;;;;;7176:19:3;7203:9;7176:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7158:59;;;7256:7;7248:52;;;;-1:-1:-1;;;7248:52:3;;18910:2:8;7248:52:3;;;18892:21:8;;;18929:18;;;18922:30;18988:34;18968:18;;;18961:62;19040:18;;7248:52:3;18708:356:8;7248:52:3;7344:17;7326:5;-1:-1:-1;;;;;7318:22:3;;:43;;7310:82;;;;-1:-1:-1;;;7310:82:3;;19271:2:8;7310:82:3;;;19253:21:8;19310:2;19290:18;;;19283:30;19349:28;19329:18;;;19322:56;19395:18;;7310:82:3;19069:350:8;7310:82:3;7403:32;;:::i;:::-;7459:19;7476:1;7459:16;:19::i;:::-;7445:11;;;:33;7493:9;7488:839;110:6:6;7508:5:3;;7488:839;;;7534:21;7543:1;7545;7543:4;;;;;;;:::i;:::-;;;;;7549:5;7534:8;:21::i;:::-;7587:22;7604:1;7606;7604:4;;;;;;;:::i;7587:22::-;7570:11;;7582:1;7570:14;;;;;;;:::i;:::-;;;;:39;7640:22;7657:1;7659;7657:4;;;;;;;:::i;7640:22::-;7623:9;:11;;;7635:1;7623:14;;;;;;;:::i;:::-;;;;:39;7736:29;;:::i;:::-;7810:5;-1:-1:-1;;;;;7810:13:3;;7824:1;7826;7824:4;;;;;;;:::i;:::-;;;;;7830:1;7810:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;7810:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7780:10;;;7794:12;;7779:53;;;;;7877:5;-1:-1:-1;;;;;7877:13:3;;7891:1;7893;7891:4;;;;;;;:::i;:::-;;;;;7897:1;7877:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;7877:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7847:10;;;;;7861:12;;;7846:53;;;;;7941:11;;;;7926:30;;7953:1;7941:14;;;;;;;:::i;7926:30::-;7913:43;;7998:11;;;;7983:27;;7913:7;7991:1;7983:10;;:27;7970:10;;;:40;8024:5;-1:-1:-1;;;;;8024:16:3;;8041:1;8043;8041:4;;;;;;;:::i;:::-;;;;;8047:7;8024:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8069:25:3;;-1:-1:-1;;8069:25:3;8125:5;-1:-1:-1;;;;;8125:10:3;;8136:1;8138;8136:4;;;;;;;:::i;:::-;;;;;8125:16;;;;;;;;;;;;;10023:25:8;;10011:2;9996:18;;9877:177;8125:16:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;8108:33:3;;;;;8155:56;;;;-1:-1:-1;;;8155:56:3;;10779:2:8;8155:56:3;;;10761:21:8;10818:2;10798:18;;;10791:30;10857:31;10837:18;;;10830:59;10906:18;;8155:56:3;10577:353:8;8155:56:3;8225:26;8231:1;8233;8231:4;;;;;;;:::i;:::-;;;;;8237:6;8245:5;8225;:26::i;:::-;7520:807;;7515:3;;;;;:::i;:::-;;;;7488:839;;;;8337:8;-1:-1:-1;;;;;8337:15:3;;8353:6;8361:9;8372:31;8397:5;;8372:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8372:24:3;;-1:-1:-1;;;8372:31:3:i;:::-;8337:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8445:10;-1:-1:-1;;;;;8420:44:3;;8436:1;8439;8442;8457:6;8420:44;;;;;;;;;:::i;:::-;;;;;;;;6802:1669;;;;6689:1782;;;;;:::o;4537:933::-;4622:26;4796:1;4779:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4770:35;;4820:9;4815:649;4835:12;;;4815:649;;;4868:25;;:::i;:::-;4930:5;-1:-1:-1;;;;;4930:9:3;;4940:1;;4942;4940:4;;;;;;;:::i;:::-;;;;;;;4946:1;4930:18;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;4930:18:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4908:6;;;4918:8;;4907:41;;;;;4985:5;-1:-1:-1;;;;;4985:9:3;;4995:1;;4997;4995:4;;;;;;;:::i;:::-;;;;;;;5001:1;4985:18;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;4985:18:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4963:6;;;;;4973:8;;;4962:41;;;;;5021:27;;;-1:-1:-1;;5035:1:3;;5037;5035:4;;;;;;;:::i;:::-;;;;;;;;;;5021:19;;-1:-1:-1;5021:19:3;;;;;;;;-1:-1:-1;5021:19:3;;;;:27;5017:335;;;5068:29;;:::i;:::-;5146:5;-1:-1:-1;;;;;5146:13:3;;5160:1;;5162;5160:4;;;;;;;:::i;:::-;;;;;;;5166:1;5146:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;5146:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5116:10;;;5130:12;;5115:53;;;;;5217:5;-1:-1:-1;;;;;5217:13:3;;5231:1;;5233;5231:4;;;;;;;:::i;:::-;;;;;;;5237:1;5217:22;;;;;;;;;;;;;;;8512:25:8;;;8568:2;8553:18;;8546:34;8500:2;8485:18;;8330:256;5217:22:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5187:10;;;;;5201:12;;;5186:53;;;;;5266:22;5187:7;-1:-1:-1;5277:10:3;;;;;5266:3;5270:1;5266:6;;:22;5257:31;;5315:22;5326:7;5334:1;5326:10;;;;;5315:3;5319:1;5315:6;;:22;5306:6;;;:31;-1:-1:-1;5017:335:3;5380:22;5395:3;5399:1;5395:6;;;;;5380:14;:22::i;:::-;5365:6;5372:1;5365:9;;;;;;;;:::i;:::-;;;;;;;5375:1;5365:12;;;;;;;:::i;:::-;;;;:37;5431:22;5446:3;5450:1;5446:6;;5431:22;5416:6;5423:1;5416:9;;;;;;;;:::i;:::-;;;;;;;5426:1;5416:12;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;4849:3:3;;;;:::i;:::-;;;;4815:649;;;;4537:933;;;;;:::o;5121:165:6:-;-1:-1:-1;;;;;;;;;;;;;;;;;5213:66:6;326;5256:5;5239:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;5229:34;;;;;;5221:43;;:57;;;;:::i;:::-;5213:7;:66::i;:::-;5206:73;5121:165;-1:-1:-1;;5121:165:6:o;3790:586::-;-1:-1:-1;;;;;;;;;;;;;;;;;3885:4:6;3876:13;;;3872:43;;-1:-1:-1;;3898:17:6;;;;;;;;;-1:-1:-1;3898:17:6;;;;;;;;3790:586::o;3872:43::-;4070:66;4065:71;;4052:3;3976:79;;;3925:9;4165:14;4065:71;4177:1;4165:8;:14::i;:::-;:18;;4182:1;4165:18;:::i;:::-;4146:37;;4193:9;4205:30;4214:8;428:66;4205:8;:30::i;:::-;4267:29;;;;;;;;;;;;;;;;;;4193:42;;-1:-1:-1;4322:4:6;4318:8;;4310:16;;4306:40;;4335:11;4339:6;4335:3;:11::i;:::-;4328:18;3790:586;-1:-1:-1;;;;;;;3790:586:6:o;4306:40::-;4363:6;3790:586;-1:-1:-1;;;;;;3790:586:6:o;2238:655:3:-;2304:13;:16;;;;;;;;;;;:24;;;;:16;;:24;2300:587;;;2344:25;;:::i;:::-;2406:15;;;;;;;;8512:25:8;;;2419:1:3;8553:18:8;;;8546:34;2406:5:3;-1:-1:-1;;;;;2406:9:3;;;;8485:18:8;;2406:15:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2384:6;;;2394:8;;2383:38;;;;;2458:15;;;;;;;;8512:25:8;;;2471:1:3;8553:18:8;;;8546:34;-1:-1:-1;;;;;2458:5:3;:9;;;;8485:18:8;;2458:15:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2436:6;;;;;2446:8;;;2435:38;;;;;2487:29;;:::i;:::-;2561:19;;;;;;;;8512:25:8;;;2578:1:3;8553:18:8;;;8546:34;2561:5:3;-1:-1:-1;;;;;2561:13:3;;;;8485:18:8;;2561:19:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2531:10;;;2545:12;;2530:50;;;;;2625:19;;;;;;;;8512:25:8;;;2642:1:3;8553:18:8;;;8546:34;-1:-1:-1;;;;;2625:5:3;:13;;;;8485:18:8;;2625:19:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2595:10;;;;;2609:12;;;2594:50;;;;;2667:22;2595:7;-1:-1:-1;2678:10:3;;2667:22;2658:31;;2712:22;2723:7;2731:1;2723:10;;2712:22;2703:6;;;:31;2748:14;;:::i;:::-;2776:20;;;;;2748:14;;-1:-1:-1;;;;;;2776:5:3;:12;;;;:20;;2789:1;;2792:3;;2776:20;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;2810:28:3;;;;;-1:-1:-1;;;;;2810:5:3;:16;;-1:-1:-1;2810:16:3;;-1:-1:-1;2810:28:3;;2827:1;;2830:7;;2810:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2852:13:3;:16;;;;;;;;;;:24;;;;;;;;;;-1:-1:-1;;;2300:587:3;2238:655;;:::o;2553:494:6:-;-1:-1:-1;;;;;;;;;;;;;;;;;2694:4:6;2688:11;2735:2;2729:9;2719:8;2712:27;2794:4;2790:2;2786:13;2780:20;2773:4;2763:8;2759:19;2752:49;2848:2;2842:9;2835:4;2825:8;2821:19;2814:38;2907:4;2903:2;2899:13;2893:20;2886:4;2876:8;2872:19;2865:49;2980:4;2977:1;2971:4;2961:8;2955:4;2948:5;2937:48;2927:104;;3015:1;3012;3005:12;2927:104;;2553:494;;;;:::o;2899:1632:3:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;3161:13:3;;;;;;;;10023:25:8;;;-1:-1:-1;;;;;3161:5:3;:10;;;;9996:18:8;;3161:13:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3112:62;;;;3143:14;;;3112:62;;;;3128:13;;;3112:62;;;;;3188:17;3184:971;;3278:13;;3293;;;;3335:28;;;;;29157:18:8;29145:31;;3335:28:3;;;29127:50:8;3264:5:3;-1:-1:-1;;;;;3264:13:3;;;;3278;;3264;;3308:11;;3278:13;;3366:1;;3264:13;;3335;;29100:18:8;;3335:28:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:32;;;;:::i;:::-;3308:60;;;;;;;;;;29712:18:8;29700:31;;;3308:60:3;;;29682:50:8;29748:18;;;29741:34;29655:18;;3308:60:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3264:105;;;;;;;;;;30184:18:8;30229:15;;;3264:105:3;;;30211:34:8;30281:15;;;;30261:18;;;30254:43;30313:18;;;30306:34;30147:18;;3264:105:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3445:13:3;;3431:28;;;;;29157:18:8;29145:31;;;3431:28:3;;;29127:50:8;3431:5:3;-1:-1:-1;;;;;3431:13:3;;-1:-1:-1;3431:13:3;;-1:-1:-1;29100:18:8;;3431:28:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3522:13:3;;3508:28;;;;;29157:18:8;29145:31;;;3508:28:3;;;29127:50:8;3508:5:3;-1:-1:-1;;;;;3508:13:3;;-1:-1:-1;3508:13:3;;-1:-1:-1;29100:18:8;;3508:28:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3540:1;3508:33;3504:641;;3561:13;;3543:32;;;;;29157:18:8;29145:31;;;3543:32:3;;;29127:50:8;3543:5:3;-1:-1:-1;;;;;3543:17:3;;;;29100:18:8;;3543:32:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3504:641;;;3692:13;;3678:28;;;;;29157:18:8;29145:31;;;3678:28:3;;;29127:50:8;3678:5:3;-1:-1:-1;;;;;3678:13:3;;;;29100:18:8;;3678:28:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3662:7;:13;;;:44;;;3658:487;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;3974:13:3;;3989;;;;3962:41;;;;;30532:18:8;30577:15;;;3962:41:3;;;30559:34:8;30629:15;;30609:18;;;30602:43;3951:5:3;-1:-1:-1;;;;;3951:10:3;;;;;;3962:11;;30495:18:8;;3962:41:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3951:53;;;;;;;;;;;;;10023:25:8;;10011:2;9996:18;;9877:177;3951:53:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3908:96;;;;3935:12;;;;3908:96;;;;;;;3922:11;;;;3908:96;;;;;;;;4036:13;;;;;4022:27;;;;;4093:13;;4108;;4081:41;;;;;30577:15:8;;;4081:41:3;;;30559:34:8;30629:15;30609:18;;;30602:43;4067:5:3;-1:-1:-1;;;;;4067:13:3;;;;;;4081:11;;30495:18:8;;4081:41:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4067:63;;;;;;;;;;;;;;30875:25:8;;;;30977:13;;30919:18;30973:22;;;30953:18;;;30946:50;30968:2;31042:15;;31036:22;31032:31;;31012:18;;;31005:59;31110:15;;;31104:22;31100:31;31080:18;;;31073:59;30847:19;;4067:63:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3708:437;3658:487;4164:21;;;;;4195:14;;;:24;;;;;;:14;:24;;;;;:::i;:::-;;;;;;;;4275:19;;;;;29145:31:8;;;4275:19:3;;;29127:50:8;4275:5:3;-1:-1:-1;;;;;4275:12:3;;-1:-1:-1;4275:12:3;;29100:18:8;;4275:19:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4270:75;;4310:24;;;;;29157:18:8;29145:31;;4310:24:3;;;29127:50:8;4310:5:3;-1:-1:-1;;;;;4310:17:3;;;;29100:18:8;;4310:24:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4270:75;4377:20;;;;;29157:18:8;29145:31;;4377:20:3;;;29127:50:8;4377:5:3;-1:-1:-1;;;;;4377:13:3;;;;29100:18:8;;4377:20:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4354:44;;;;:13;;;:44;;;4440:25;;;;;;;;;30875::8;;;30977:13;;30973:22;;30953:18;;;30946:50;31036:22;;31032:31;;31012:18;;;31005:59;31110:15;;31104:22;31100:31;;;31080:18;;;31073:59;4440:5:3;-1:-1:-1;;;;;4440:13:3;;;;30847:19:8;;4440:25:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4475:24:3;;;;;29712:18:8;29700:31;;4475:24:3;;;29682:50:8;29748:18;;;29741:34;;;4475:5:3;-1:-1:-1;;;;;4475:14:3;;-1:-1:-1;4475:14:3;;-1:-1:-1;29655:18:8;;4475:24:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2963:1568;2899:1632;;;:::o;7291:2083:6:-;7361:26;;:::i;:::-;5630:4;5615:28;;5609:35;7410:25;;:10;:25::i;7421:13::-;7410:10;:25::i;:::-;7399:36;;5615:28;;;5609:35;7456:26;;7410:10;:25::i;7456:26::-;7445:8;;;:37;5615:28;;;5609:35;7502:26;;7410:10;:25::i;7502:26::-;7492:7;;;:36;5615:28;;;5609:35;7548:26;;7410:10;:25::i;7548:26::-;7538:7;;;:36;7590:9;7585:777;86:1;7605;:5;7585:777;;;7647:36;7658:24;7664:3;7675:6;:1;7679:2;7675:6;:::i;:::-;7669:12;;:3;:12;:::i;:::-;5615:28;5630:4;5615:28;5609:35;;5477:183;7647:36;7631:5;:10;;;7642:1;7631:13;;;;;;;:::i;:::-;;;;:52;7713:42;7724:30;7730:3;7742:5;86:1;7742;:5;:::i;:::-;7741:12;;7751:2;7741:12;:::i;7713:42::-;7697:5;:10;;;7708:1;7697:13;;;;;;;:::i;:::-;;;;:58;;;;7785:45;7796:33;7802:3;7822:1;7826:2;7822:6;;;;:::i;:::-;7813;86:1;7817:2;7813:6;:::i;:::-;7807:12;;:3;:12;:::i;:::-;:21;;;;:::i;7785:45::-;7769:5;:10;;;7780:1;7769:13;;;;;;;:::i;:::-;;;;:61;;;;7858:45;7869:33;7875:3;7895:1;7899:2;7895:6;;;;:::i;:::-;7886;86:1;7890:2;7886:6;:::i;7858:45::-;7844:5;:8;;;7853:1;7844:11;;;;;;;:::i;:::-;;;;:59;;;;7933:46;7944:34;7950:3;7971:1;7975:2;7971:6;;;;:::i;:::-;7961:7;86:1;7965:3;7961:7;:::i;7933:46::-;7917:5;:10;;;7928:1;7917:13;;;;;;;:::i;:::-;;;;:62;;;;8007:46;8018:34;8024:3;8045:1;8049:2;8045:6;;;;:::i;:::-;8035:7;86:1;8039:3;8035:7;:::i;8007:46::-;7993:5;:8;;;8002:1;7993:11;;;;;;;:::i;:::-;;;;:60;;;;8083:46;8094:34;8100:3;8121:1;8125:2;8121:6;;;;:::i;:::-;8111:7;86:1;8115:3;8111:7;:::i;8083:46::-;8067:5;:10;;;8078:1;8067:13;;;;;;;:::i;:::-;;;;:62;;;;8159:46;8170:34;8176:3;8197:1;8201:2;8197:6;;;;:::i;:::-;8187:7;86:1;8191:3;8187:7;:::i;8159:46::-;8143:5;:10;;;8154:1;8143:13;;;;;;;:::i;:::-;;;;:62;;;;8243:34;8249:3;8270:1;8274:2;8270:6;;;;:::i;:::-;8260:7;86:1;8264:3;8260:7;:::i;8243:34::-;8219:7;;;;:10;8230:1;8219:13;;;;;;;:::i;:::-;;;;:59;;;;;8316:34;8322:3;8343:1;8347:2;8343:6;;;;:::i;:::-;8333:7;86:1;8337:3;8333:7;:::i;8316:34::-;8292:7;;;;:10;;;8303:1;8292:13;;;;;;;:::i;:::-;;;;:59;7612:3;;;;:::i;:::-;;;;7585:777;;;-1:-1:-1;8372:16:6;8391:7;86:1;8395:3;8391:7;:::i;:::-;8372:26;-1:-1:-1;8428:26:6;8434:3;8439:14;8372:26;8439:3;:14;:::i;8428:26::-;8408:9;;;:47;8478:38;8489:26;8495:3;8500:14;8506:8;8500:3;:14;:::i;8478:38::-;8466:9;;;:50;8538:38;8549:26;8555:3;8560:14;8566:8;8560:3;:14;:::i;8538:38::-;8526:9;;;:50;8607:26;8613:3;8618:14;8624:8;8618:3;:14;:::i;8607:26::-;8586:10;;;:48;8663:26;8669:3;8674:14;8680:8;8674:3;:14;:::i;8663:26::-;8644:8;;;:46;8719:26;8725:3;8730:14;8736:8;8730:3;:14;:::i;8719:26::-;8701:7;;;:45;8777:26;8783:3;8788:14;8794:8;8788:3;:14;:::i;8777:26::-;8756:10;;;:48;8834:26;8840:3;8845:14;8851:8;8845:3;:14;:::i;8834:26::-;8814:9;;;:47;8891:26;8897:3;8902:14;8908:8;8902:3;:14;:::i;8891:26::-;8871:9;;;:47;8950:26;8956:3;8961:14;8967:8;8961:3;:14;:::i;8950:26::-;8928:11;;;:49;8942:35;8988:211;9012:5;139:1;9016;9012:5;:::i;:::-;9008:1;:9;8988:211;;;9054:47;9065:35;9071:3;9093:6;:1;9097:2;9093:6;:::i;:::-;9076:14;9082:8;9076:3;:14;:::i;9054:47::-;9038:8;;;;:10;9049:1;9038:13;;;;;;;:::i;:::-;;;;:63;9131:57;9142:45;9148:3;9171:5;139:1;9171;:5;:::i;:::-;:9;;9179:1;9171:9;:::i;:::-;9170:16;;9184:2;9170:16;:::i;9131:57::-;9115:5;:8;;;:10;;;9126:1;9115:13;;;;;;;:::i;:::-;;;;:73;9019:3;;;;:::i;:::-;;;;8988:211;;;-1:-1:-1;9229:41:6;9235:3;9258:5;139:1;9262;9258:5;:::i;:::-;9257:12;;9267:2;9257:12;:::i;:::-;9240:14;9246:8;9240:3;:14;:::i;9229:41::-;9208:8;;;;:10;;:63;9302:41;9308:3;9331:5;139:1;9335;9331:5;:::i;:::-;9330:12;;9340:2;9330:12;:::i;:::-;9313:14;9319:8;9313:3;:14;:::i;9302:41::-;9281:8;;;;:10;;:63;-1:-1:-1;9281:5:6;7291:2083;-1:-1:-1;7291:2083:6:o;3053:415::-;-1:-1:-1;;;;;;;;;;;;;;;;;3187:4:6;3181:11;3228:1;3222:8;3212;3205:26;3285:4;3282:1;3278:12;3272:19;3265:4;3255:8;3251:19;3244:48;3333:1;3326:4;3316:8;3312:19;3305:30;3401:4;3398:1;3392:4;3382:8;3376:4;3369:5;3358:48;3348:104;;3436:1;3433;3426:12;1088:95;1135:7;1161:15;1175:1;223:66;1161:15;:::i;854:95::-;901:7;927:15;223:66;927:1;:15;:::i;9886:1878::-;9958:28;;:::i;:::-;5630:4;5615:28;;5609:35;10009:25;;7410:10;:25::i;10009:::-;9998:36;;5615:28;;;5609:35;10055:26;;7410:10;:25::i;10055:26::-;10044:8;;;:37;5615:28;;;5609:35;10101:26;;7410:10;:25::i;10101:26::-;10091:7;;;:36;5615:28;;;5609:35;10147:26;;7410:10;:25::i;10147:26::-;10137:7;;;:36;10189:9;10184:551;86:1;10204;:5;10184:551;;;10246:36;10257:24;10263:3;10274:6;:1;10278:2;10274:6;:::i;10246:36::-;10230:5;:10;;;10241:1;10230:13;;;;;;;:::i;:::-;;;;:52;10312:42;10323:30;10329:3;10341:5;86:1;10341;:5;:::i;10312:42::-;10296:5;:10;;;10307:1;10296:13;;;;;;;:::i;:::-;;;;:58;;;;10384:45;10395:33;10401:3;10421:1;10425:2;10421:6;;;;:::i;10384:45::-;10368:5;:10;;;10379:1;10368:13;;;;;;;:::i;:::-;;;;:61;;;;10457:45;10468:33;10474:3;10494:1;10498:2;10494:6;;;;:::i;10457:45::-;10443:5;:8;;;10452:1;10443:11;;;;;;;:::i;:::-;;;;:59;;;;10532:46;10543:34;10549:3;10570:1;10574:2;10570:6;;;;:::i;10532:46::-;10516:5;:10;;;10527:1;10516:13;;;;;;;:::i;:::-;;;;:62;;;;10608:46;10619:34;10625:3;10646:1;10650:2;10646:6;;;;:::i;10608:46::-;10592:5;:10;;;10603:1;10592:13;;;;;;;:::i;:::-;;;;:62;;;;10689:34;10695:3;10716:1;10720:2;10716:6;;;;:::i;10689:34::-;10668:7;;;;10676:1;10668:10;;;;;;;:::i;:::-;;;;:56;10211:3;;;;:::i;:::-;;;;10184:551;;;-1:-1:-1;10744:16:6;10763:7;86:1;10767:3;10763:7;:::i;:::-;10744:26;-1:-1:-1;10800:26:6;10806:3;10811:14;10744:26;10811:3;:14;:::i;10800:26::-;10780:9;;;:47;10850:38;10861:26;10867:3;10872:14;10878:8;10872:3;:14;:::i;10850:38::-;10838:9;;;:50;10910:38;10921:26;10927:3;10932:14;10938:8;10932:3;:14;:::i;10910:38::-;10898:9;;;:50;10979:26;10985:3;10990:14;10996:8;10990:3;:14;:::i;10979:26::-;10958:10;;;:48;11035:26;11041:3;11046:14;11052:8;11046:3;:14;:::i;11035:26::-;11016:8;;;:46;11091:26;11097:3;11102:14;11108:8;11102:3;:14;:::i;11091:26::-;11073:7;;;:45;11149:26;11155:3;11160:14;11166:8;11160:3;:14;:::i;11149:26::-;11128:10;;;:48;11206:26;11212:3;11217:14;11223:8;11217:3;:14;:::i;11206:26::-;11186:9;;;:47;11263:26;11269:3;11274:14;11280:8;11274:3;:14;:::i;11263:26::-;11243:9;;;:47;11322:26;11328:3;11333:14;11339:8;11333:3;:14;:::i;11322:26::-;11300:11;;;:49;11314:35;11360:241;139:1;11380;:5;11360:241;;;11460:47;11471:35;11477:3;11499:6;:1;11503:2;11499:6;:::i;11460:47::-;11444:8;;;;:10;11455:1;11444:13;;;;;;;:::i;:::-;;;;:63;11537:53;11548:41;11554:3;11577:5;139:1;11577;:5;:::i;11537:53::-;11521:5;:8;;;:10;;;11532:1;11521:13;;;;;;;:::i;:::-;;;;:69;11387:3;;;;:::i;:::-;;;;11360:241;;;-1:-1:-1;11631:35:6;11637:3;11659:6;139:1;11663:2;11659:6;:::i;11631:35::-;11623:44;;11610:5;:8;;;:10;;:57;;;;;11698:35;11704:3;139:1;11730:2;11726:6;;;;:::i;11698:35::-;11677:8;;;;:10;;:57;-1:-1:-1;11677:5:6;9886:1878;-1:-1:-1;9886:1878:6:o;6057:677::-;6126:25;;:::i;:::-;5630:4;5615:28;;5609:35;6173:25;;7410:10;:25::i;6173:::-;6163:35;;5615:28;;;5609:35;6218:26;;7410:10;:25::i;6218:26::-;6208:7;;;:36;6260:9;6255:247;86:1;6275;:5;6255:247;;;6317:35;6328:23;6334:3;6344:6;:1;6348:2;6344:6;:::i;:::-;6339:11;;:2;:11;:::i;6317:35::-;6301:5;:10;;;6312:1;6301:13;;;;;;;:::i;:::-;;;;:51;6382:41;6393:29;6399:3;6410:5;86:1;6410;:5;:::i;:::-;6409:12;;6419:2;6409:12;:::i;6382:41::-;6366:5;:10;;;6377:1;6366:13;;;;;;;:::i;:::-;;;;:57;;;;6458:32;6464:3;6483:1;6487:2;6483:6;;;;:::i;:::-;6474;86:1;6478:2;6474:6;:::i;:::-;6469:11;;:2;:11;:::i;6458:32::-;6437:7;;;;6445:1;6437:10;;;;;;;:::i;:::-;;;;:54;6282:3;;;;:::i;:::-;;;;6255:247;;;-1:-1:-1;6511:16:6;6530:6;86:1;6534:2;6530:6;:::i;:::-;6511:25;-1:-1:-1;6566:25:6;6572:3;6577:13;6511:25;6577:2;:13;:::i;6566:25::-;6546:9;;;:46;6621:25;6627:3;6632:13;6637:8;6632:2;:13;:::i;6621:25::-;6603:7;;;:44;6677:26;6683:3;6688:14;6694:8;6688:3;:14;:::i;6677:26::-;6657:9;;;:47;-1:-1:-1;6657:5:6;6057:677;-1:-1:-1;6057:677:6:o;4382:275::-;4487:7;;4517;;;;4443;;4487;4528:4;4509:23;;;:31;;4505:113;;4552:66;4542:76;4643:6;4382:275;-1:-1:-1;;4382:275:6:o;4663:452::-;-1:-1:-1;;;;;;;;;;;;;;;;;4741:9:6;4760:300;4787:16;4806:17;4815:4;4821:1;4806:8;:17::i;:::-;:21;;4826:1;4806:21;:::i;:::-;4787:40;;4913:30;4922:8;428:66;4913:8;:30::i;:::-;4909:34;;4979:8;4961:14;4970:1;4973;4961:8;:14::i;:::-;:26;4957:70;;5007:5;;;4957:70;5040:9;5048:1;5040:9;;:::i;:::-;;;4773:287;4760:300;;;5076:32;;;;;;;;;;;;;;;;-1:-1:-1;5076:32:6;4663:452::o;1824:659::-;1897:14;1948:13;326:66;1948:27;;2030:4;2024:11;2065:4;2055:8;2048:22;2111:4;2104;2094:8;2090:19;2083:33;2157:4;2150;2140:8;2136:19;2129:33;2203:4;2196;2186:8;2182:19;2175:33;2249:8;2242:4;2232:8;2228:19;2221:37;2299:5;2292:4;2282:8;2278:19;2271:34;2378:4;2368:8;2362:4;2352:8;2346:4;2339:5;2328:55;2318:111;;2413:1;2410;2403:12;2318:111;2452:15;;1824:659;-1:-1:-1;;;;1824:659:6:o;3474:177::-;-1:-1:-1;;;;;;;;;;;;;;;;;3557:47:6;;;;;;;;;3563:3;;3557:47;;;3598:3;;;;3557:47;;;;3576:26;;326:66;3576:26;:::i;:::-;3557:47;;3550:54;3474:177;-1:-1:-1;;3474:177:6:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:160:8;108:6;141:3;129:16;;126:25;-1:-1:-1;123:45:8;;;164:1;161;154:12;179:129;264:18;257:5;253:30;246:5;243:41;233:69;;298:1;295;288:12;313:132;380:20;;409:30;380:20;409:30;:::i;:::-;313:132;;;:::o;450:163::-;517:20;;577:10;566:22;;556:33;;546:61;;603:1;600;593:12;618:347;669:8;679:6;733:3;726:4;718:6;714:17;710:27;700:55;;751:1;748;741:12;700:55;-1:-1:-1;774:20:8;;817:18;806:30;;803:50;;;849:1;846;839:12;803:50;886:4;878:6;874:17;862:29;;938:3;931:4;922:6;914;910:19;906:30;903:39;900:59;;;955:1;952;945:12;900:59;618:347;;;;;:::o;970:1011::-;1144:6;1152;1160;1168;1176;1184;1192;1200;1253:4;1241:9;1232:7;1228:23;1224:34;1221:54;;;1271:1;1268;1261:12;1221:54;1294:53;1339:7;1328:9;1294:53;:::i;:::-;1284:63;;1366;1421:7;1415:3;1404:9;1400:19;1366:63;:::i;:::-;1356:73;;1476:4;1465:9;1461:20;1448:34;1438:44;;1529:4;1518:9;1514:20;1501:34;1491:44;;1585:4;1574:9;1570:20;1557:34;1600:30;1624:5;1600:30;:::i;:::-;1649:5;-1:-1:-1;1673:39:8;1706:4;1691:20;;1673:39;:::i;:::-;1663:49;;1763:4;1752:9;1748:20;1735:34;1792:18;1784:6;1781:30;1778:50;;;1824:1;1821;1814:12;1778:50;1863:58;1913:7;1904:6;1893:9;1889:22;1863:58;:::i;:::-;970:1011;;;;-1:-1:-1;970:1011:8;;-1:-1:-1;970:1011:8;;;;;;1940:8;-1:-1:-1;;;970:1011:8:o;1986:319::-;2079:6;2087;2140:2;2128:9;2119:7;2115:23;2111:32;2108:52;;;2156:1;2153;2146:12;2108:52;2192:9;2179:23;2169:33;;2237:7;2232:2;2221:9;2217:18;2214:31;2211:51;;;2258:1;2255;2248:12;2211:51;-1:-1:-1;1986:319:8;2296:2;2281:18;;;;;-1:-1:-1;1986:319:8:o;2310:196::-;2378:20;;-1:-1:-1;;;;;2427:54:8;;2417:65;;2407:93;;2496:1;2493;2486:12;2511:332;2587:6;2595;2603;2656:2;2644:9;2635:7;2631:23;2627:32;2624:52;;;2672:1;2669;2662:12;2624:52;2695:29;2714:9;2695:29;:::i;:::-;2685:39;;2743:38;2777:2;2766:9;2762:18;2743:38;:::i;:::-;2733:48;;2800:37;2833:2;2822:9;2818:18;2800:37;:::i;:::-;2790:47;;2511:332;;;;;:::o;2848:1405::-;3059:6;3067;3075;3083;3091;3099;3107;3115;3123;3131;3139:7;3148;3202:4;3190:9;3181:7;3177:23;3173:34;3170:54;;;3220:1;3217;3210:12;3170:54;3243:53;3288:7;3277:9;3243:53;:::i;:::-;3233:63;;3315;3370:7;3364:3;3353:9;3349:19;3315:63;:::i;:::-;3305:73;;3425:4;3414:9;3410:20;3397:34;3387:44;;3478:4;3467:9;3463:20;3450:34;3440:44;;3503:39;3536:4;3525:9;3521:20;3503:39;:::i;:::-;3493:49;;3561:39;3594:4;3583:9;3579:20;3561:39;:::i;:::-;3551:49;;3619:39;3652:4;3641:9;3637:20;3619:39;:::i;:::-;3609:49;;3709:18;3701:4;3690:9;3686:20;3673:34;3670:58;3667:78;;;3741:1;3738;3731:12;3667:78;3780:86;3858:7;3849:4;3838:9;3834:20;3821:34;3810:9;3806:50;3780:86;:::i;:::-;3885:8;;-1:-1:-1;3912:8:8;-1:-1:-1;3939:40:8;3973:4;3958:20;;3939:40;:::i;:::-;3929:50;;4030:18;4022:4;4011:9;4007:20;3994:34;3991:58;3988:78;;;4062:1;4059;4052:12;3988:78;4103:86;4181:7;4172:4;4161:9;4157:20;4144:34;4133:9;4129:50;4103:86;:::i;:::-;4209:9;4198:20;;4238:9;4227:20;;;;2848:1405;;;;;;;;;;;;;;:::o;4258:732::-;4407:6;4415;4423;4431;4439;4492:4;4480:9;4471:7;4467:23;4463:34;4460:54;;;4510:1;4507;4500:12;4460:54;4533:53;4578:7;4567:9;4533:53;:::i;:::-;4523:63;;4605;4660:7;4654:3;4643:9;4639:19;4605:63;:::i;:::-;4595:73;;4715:4;4704:9;4700:20;4687:34;4677:44;;4772:4;4761:9;4757:20;4744:34;4801:18;4793:6;4790:30;4787:50;;;4833:1;4830;4823:12;4787:50;4872:58;4922:7;4913:6;4902:9;4898:22;4872:58;:::i;:::-;4258:732;;;;-1:-1:-1;4258:732:8;;-1:-1:-1;4949:8:8;;4846:84;4258:732;-1:-1:-1;;;4258:732:8:o;4995:693::-;5089:6;5097;5105;5158:2;5146:9;5137:7;5133:23;5129:32;5126:52;;;5174:1;5171;5164:12;5126:52;5214:9;5201:23;5243:18;5284:2;5276:6;5273:14;5270:34;;;5300:1;5297;5290:12;5270:34;5338:6;5327:9;5323:22;5313:32;;5383:7;5376:4;5372:2;5368:13;5364:27;5354:55;;5405:1;5402;5395:12;5354:55;5445:2;5432:16;5471:2;5463:6;5460:14;5457:34;;;5487:1;5484;5477:12;5457:34;5542:7;5535:4;5525:6;5522:1;5518:14;5514:2;5510:23;5506:34;5503:47;5500:67;;;5563:1;5560;5553:12;5500:67;5594:4;5586:13;;;;-1:-1:-1;5618:6:8;-1:-1:-1;5643:39:8;;5661:20;;;-1:-1:-1;5643:39:8;:::i;5693:1051::-;5910:2;5962:21;;;6032:13;;5935:18;;;6054:22;;;5881:4;;5910:2;6095;;6113:18;;;;6154:15;;;5881:4;;6218:500;6234:6;6229:3;6226:15;6218:500;;;6297:13;;6336:3;6419:1;6433:205;6449:4;6444:3;6441:13;6433:205;;;6522:15;;6508:30;;6607:17;;;;6564:14;;;;6473:1;6464:11;6433:205;;;-1:-1:-1;;;6658:12:8;;;;6693:15;;;;6260:1;6251:11;6218:500;;;-1:-1:-1;6735:3:8;;5693:1051;-1:-1:-1;;;;;;;;5693:1051:8:o;6749:184::-;6801:77;6798:1;6791:88;6898:4;6895:1;6888:15;6922:4;6919:1;6912:15;6938:184;6990:77;6987:1;6980:88;7087:4;7084:1;7077:15;7111:4;7108:1;7101:15;7127:120;7167:1;7193;7183:35;;7198:18;;:::i;:::-;-1:-1:-1;7232:9:8;;7127:120::o;7593:184::-;7645:77;7642:1;7635:88;7742:4;7739:1;7732:15;7766:4;7763:1;7756:15;8130:195;8169:3;8200:66;8193:5;8190:77;8187:103;;8270:18;;:::i;:::-;-1:-1:-1;8317:1:8;8306:13;;8130:195::o;8591:245::-;8670:6;8678;8731:2;8719:9;8710:7;8706:23;8702:32;8699:52;;;8747:1;8744;8737:12;8699:52;-1:-1:-1;;8770:16:8;;8826:2;8811:18;;;8805:25;8770:16;;8805:25;;-1:-1:-1;8591:245:8:o;9253:619::-;9520:25;;;9507:3;9492:19;;9564:2;9586:18;;;9646:6;9465:4;9680:186;9694:4;9691:1;9688:11;9680:186;;;9741:43;9780:3;9771:6;9765:13;9173:12;;9161:25;;9235:4;9224:16;;;9218:23;9202:14;;9195:47;9102:146;9741:43;9813:4;9804:14;;;;;9841:15;;;;9714:1;9707:9;9680:186;;;9684:3;;;;9253:619;;;;;:::o;10059:513::-;10144:6;10152;10160;10213:2;10201:9;10192:7;10188:23;10184:32;10181:52;;;10229:1;10226;10219:12;10181:52;10261:9;10255:16;10280:30;10304:5;10280:30;:::i;:::-;10379:2;10364:18;;10358:25;10329:5;;-1:-1:-1;10392:32:8;10358:25;10392:32;:::i;:::-;10495:2;10480:18;;10474:25;10443:7;;-1:-1:-1;10508:32:8;10474:25;10508:32;:::i;:::-;10559:7;10549:17;;;10059:513;;;;;:::o;10935:347::-;11055:5;11078:1;11088:188;11102:4;11099:1;11096:11;11088:188;;;11149:43;11188:3;11179:6;11173:13;9173:12;;9161:25;;9235:4;9224:16;;;9218:23;9202:14;;9195:47;9102:146;11149:43;11221:4;11212:14;;;;;11261:4;11249:17;;;;;11122:1;11115:9;11088:188;;;11092:3;;10935:347;;:::o;11287:935::-;11350:70;11416:3;11408:5;11402:12;11350:70;:::i;:::-;11466:4;11459:5;11455:16;11449:23;11481:83;11556:6;11551:3;11547:16;11533:12;11481:83;:::i;:::-;;11612:4;11605:5;11601:16;11595:23;11627:85;11704:6;11699:3;11695:16;11679:14;11627:85;:::i;:::-;;11760:4;11753:5;11749:16;11743:23;11775:85;11852:6;11847:3;11843:16;11827:14;11775:85;:::i;:::-;-1:-1:-1;11908:4:8;11897:16;;11891:23;9173:12;;11972:6;11963:16;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;12031:4;12020:16;;12014:23;12005:6;11996:16;;11989:49;12086:4;12075:16;;12069:23;9173:12;;12150:6;12141:16;;9161:25;9224:16;9218:23;9202:14;;;9195:47;12209:4;12198:16;12192:23;12183:6;12174:16;;;12167:49;11287:935::o;12227:347::-;12347:5;12370:1;12380:188;12394:4;12391:1;12388:11;12380:188;;;12441:43;12480:3;12471:6;12465:13;9173:12;;9161:25;;9235:4;9224:16;;;9218:23;9202:14;;9195:47;9102:146;12441:43;12513:4;12504:14;;;;;12553:4;12541:17;;;;;12414:1;12407:9;12380:188;;12579:326;12672:5;12695:1;12705:194;12719:4;12716:1;12713:11;12705:194;;;12778:13;;12766:26;;12815:4;12839:12;;;;12874:15;;;;12739:1;12732:9;12705:194;;12910:327;13009:5;13032:1;13042:189;13056:4;13053:1;13050:11;13042:189;;;13103:44;13143:3;13134:6;13128:13;13103:44;:::i;:::-;13176:4;13167:14;;;;;13216:4;13204:17;;;;;13076:1;13069:9;13042:189;;13242:325;13340:5;13363:1;13373:188;13387:4;13384:1;13381:11;13373:188;;;13434:43;13473:3;13464:6;13458:13;9173:12;;9161:25;;9235:4;9224:16;;;9218:23;9202:14;;9195:47;9102:146;13434:43;13506:4;13497:14;;;;;13546:4;13534:17;;;;;13407:1;13400:9;13373:188;;13572:363;13643:48;13687:3;13679:5;13673:12;13643:48;:::i;:::-;13737:4;13730:5;13726:16;13720:23;13752:61;13805:6;13800:3;13796:16;13782:12;13752:61;:::i;:::-;-1:-1:-1;13864:4:8;13853:16;;13847:23;13838:6;13829:16;;13822:49;13922:4;13911:16;13905:23;13896:6;13887:16;;;13880:49;13572:363::o;13940:3073::-;14218:4;14203:20;;14232:46;14207:9;14260:6;14232:46;:::i;:::-;14311:13;;9173:12;;14341:4;14326:20;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;14382:17;;;14376:24;9173:12;;14462:4;14447:20;;9161:25;9224:16;;9218:23;9202:14;;;9195:47;14517:4;14505:17;;14499:24;9173:12;;14587:4;14572:20;;9161:25;9224:16;;9218:23;9202:14;;;9195:47;14642:4;14630:17;;14624:24;9173:12;;14712:4;14697:20;;9161:25;9224:16;9218:23;9202:14;;;9195:47;14767:4;14755:17;;14749:24;14782:89;14865:4;14850:20;;14749:24;14782:89;:::i;:::-;;14920:4;14912:6;14908:17;14902:24;14935:89;15018:4;15007:9;15003:20;14987:14;14935:89;:::i;:::-;;15073:4;15065:6;15061:17;15055:24;15088:89;15171:4;15160:9;15156:20;15140:14;15088:89;:::i;:::-;;15226:4;15218:6;15214:17;15208:24;15241:89;15324:4;15313:9;15309:20;15293:14;15241:89;:::i;:::-;;15379:6;15371;15367:19;15361:26;15396:89;15479:4;15468:9;15464:20;15448:14;15396:89;:::i;:::-;;15534:6;15526;15522:19;15516:26;15551:89;15634:4;15623:9;15619:20;15603:14;15551:89;:::i;:::-;;15689:6;15681;15677:19;15671:26;15706:89;15789:4;15778:9;15774:20;15758:14;15706:89;:::i;:::-;;15845:6;15837;15833:19;15827:26;15862:90;15946:4;15935:9;15931:20;15914:15;15862:90;:::i;:::-;;16002:6;15994;15990:19;15984:26;16019:69;16082:4;16071:9;16067:20;16050:15;16019:69;:::i;:::-;-1:-1:-1;16144:6:8;16132:19;;16126:26;16119:4;16104:20;;16097:56;16203:6;16191:19;;16185:26;9173:12;;16276:4;16261:20;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;16332:6;16320:19;;16314:26;9173:12;;16405:4;16390:20;;9161:25;9224:16;9218:23;9202:14;;;9195:47;16467:6;16455:19;;16449:26;16442:4;16427:20;;16420:56;16532:6;16520:19;;16514:26;16507:4;16492:20;;16485:56;16597:6;16585:19;;16579:26;16572:4;16557:20;;16550:56;16662:6;16650:19;;16644:26;16637:4;16622:20;;16615:56;16727:6;16715:19;;16709:26;16702:4;16687:20;;16680:56;16792:6;16780:19;;16774:26;16767:4;16752:20;;16745:56;16857:6;16845:19;;16839:26;16832:4;16817:20;;16810:56;16916:6;16904:19;;16898:26;16933:74;17001:4;16986:20;;16898:26;16933:74;:::i;17018:168::-;17091:9;;;17122;;17139:15;;;17133:22;;17119:37;17109:71;;17160:18;;:::i;17671:468::-;17961:4;17946:20;;17985:6;;18024;17950:9;18000:35;18085:2;18077:6;18072:2;18061:9;18057:18;18044:44;;18126:6;18119:4;18108:9;18104:20;18097:36;17671:468;;;;;;:::o;19424:671::-;19756:3;19738:22;;;19797:2;19776:19;;;19769:31;19837:18;19831:3;19816:19;;19809:47;-1:-1:-1;;;;;19930:55:8;;19923:4;19908:20;;19901:85;20017:2;20002:18;;19995:34;;;19888:3;19873:19;;20038:51;-1:-1:-1;20070:18:8;;20062:6;9173:12;;9161:25;;9235:4;9224:16;;;9218:23;9202:14;;9195:47;9102:146;20038:51;19424:671;;;;;;:::o;20809:325::-;20897:6;20892:3;20885:19;20949:6;20942:5;20935:4;20930:3;20926:14;20913:43;;21001:1;20994:4;20985:6;20980:3;20976:16;20972:27;20965:38;20867:3;21123:4;21053:66;21048:2;21040:6;21036:15;21032:88;21027:3;21023:98;21019:109;21012:116;;20809:325;;;;:::o;21139:717::-;21469:4;21498;21521:6;21568:2;21560:6;21549:9;21536:35;21621:2;21613:6;21608:2;21597:9;21593:18;21580:44;;21662:6;21655:4;21644:9;21640:20;21633:36;21719:10;21711:6;21707:23;21700:4;21689:9;21685:20;21678:53;21769:2;21762:4;21751:9;21747:20;21740:32;21789:61;21846:2;21835:9;21831:18;21823:6;21815;21789:61;:::i;:::-;21781:69;21139:717;-1:-1:-1;;;;;;;;;21139:717:8:o;21861:191::-;21900:1;21926:10;21963:2;21960:1;21956:10;21985:3;21975:37;;21992:18;;:::i;:::-;22030:10;;22026:20;;;;;21861:191;-1:-1:-1;;21861:191:8:o;22057:172::-;22124:10;22154;;;22166;;;22150:27;;22189:11;;;22186:37;;;22203:18;;:::i;22234:364::-;-1:-1:-1;;;;;22423:6:8;22419:55;22408:9;22401:74;22511:2;22506;22495:9;22491:18;22484:30;22382:4;22531:61;22588:2;22577:9;22573:18;22565:6;22557;22531:61;:::i;:::-;22523:69;22234:364;-1:-1:-1;;;;;22234:364:8:o;22603:2915::-;22984:10;22972:23;;22954:42;;22940:4;22925:20;;23005:55;23056:2;23041:18;;23033:6;23005:55;:::i;:::-;23093:13;;9173:12;;23123:4;23108:20;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;23164:15;;;23158:22;9173:12;;23242:4;23227:20;;9161:25;9224:16;;9218:23;9202:14;;;9195:47;23297:4;23285:17;;23279:24;9173:12;;23367:4;23352:20;;9161:25;9224:16;;9218:23;9202:14;;;9195:47;23422:4;23410:17;;23404:24;9173:12;;23492:4;23477:20;;9161:25;9224:16;9218:23;9202:14;;;9195:47;23547:4;23535:17;;23529:24;23562:89;23645:4;23630:20;;23529:24;23562:89;:::i;:::-;;23700:4;23692:6;23688:17;23682:24;23715:89;23798:4;23787:9;23783:20;23767:14;23715:89;:::i;:::-;;23853:4;23845:6;23841:17;23835:24;23868:89;23951:4;23940:9;23936:20;23920:14;23868:89;:::i;:::-;;24006:4;23998:6;23994:17;23988:24;24021:89;24104:4;24093:9;24089:20;24073:14;24021:89;:::i;:::-;;24159:6;24151;24147:19;24141:26;24176:89;24259:4;24248:9;24244:20;24228:14;24176:89;:::i;:::-;;24314:6;24306;24302:19;24296:26;24331:89;24414:4;24403:9;24399:20;24383:14;24331:89;:::i;:::-;;24469:6;24461;24457:19;24451:26;24486:62;24542:4;24531:9;24527:20;24511:14;24486:62;:::i;:::-;-1:-1:-1;24604:6:8;24592:19;;24586:26;24579:4;24564:20;;24557:56;24663:6;24651:19;;24645:26;9173:12;;24736:4;24721:20;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;24792:6;24780:19;;24774:26;9173:12;;24865:4;24850:20;;9161:25;9224:16;9218:23;9202:14;;;9195:47;24927:6;24915:19;;24909:26;24902:4;24887:20;;24880:56;24992:6;24980:19;;24974:26;24967:4;24952:20;;24945:56;25057:6;25045:19;;25039:26;25032:4;25017:20;;25010:56;25122:6;25110:19;;25104:26;25097:4;25082:20;;25075:56;25187:6;25175:19;;25169:26;25162:4;25147:20;;25140:56;25252:6;25240:19;;25234:26;25227:4;25212:20;;25205:56;25317:6;25305:19;;25299:26;25292:4;25277:20;;25270:56;25376:6;25364:19;;25358:26;25393:74;25461:4;25446:20;;25358:26;25393:74;:::i;:::-;;25505:6;25498:4;25487:9;25483:20;25476:36;22603:2915;;;;;;;:::o;25523:435::-;-1:-1:-1;;;;;25740:6:8;25736:55;25725:9;25718:74;25828:6;25823:2;25812:9;25808:18;25801:34;25871:2;25866;25855:9;25851:18;25844:30;25699:4;25891:61;25948:2;25937:9;25933:18;25925:6;25917;25891:61;:::i;25963:112::-;25995:1;26021;26011:35;;26026:18;;:::i;:::-;-1:-1:-1;26060:9:8;;25963:112::o;26441:1238::-;26788:10;26776:23;;26758:42;;26744:4;26729:20;;26809:55;26860:2;26845:18;;26837:6;26809:55;:::i;:::-;26897:13;;9173:12;;26927:4;26912:20;;9161:25;9235:4;9224:16;;;9218:23;9202:14;;;9195:47;26968:15;;;26962:22;9173:12;;27046:4;27031:20;;9161:25;9224:16;9218:23;9202:14;;;9195:47;27101:4;27089:17;;27083:24;27116:89;27199:4;27184:20;;27083:24;27116:89;:::i;:::-;;27254:4;27246:6;27242:17;27236:24;27269:89;27352:4;27341:9;27337:20;27321:14;27269:89;:::i;:::-;;27407:4;27399:6;27395:17;27389:24;27422:62;27478:4;27467:9;27463:20;27447:14;27422:62;:::i;:::-;;27540:4;27532:6;27528:17;27522:24;27515:4;27504:9;27500:20;27493:54;27603:4;27595:6;27591:17;27585:24;27578:4;27567:9;27563:20;27556:54;27666:4;27658:6;27654:17;27648:24;27641:4;27630:9;27626:20;27619:54;26441:1238;;;;;;:::o;27684:556::-;28000:4;27985:20;;28024:6;;28063;27989:9;28039:35;28124:2;28116:6;28111:2;28100:9;28096:18;28083:44;;28165:6;28158:4;28147:9;28143:20;28136:36;28222:10;28214:6;28210:23;28203:4;28192:9;28188:20;28181:53;27684:556;;;;;;;:::o;28245:184::-;28297:77;28294:1;28287:88;28394:4;28391:1;28384:15;28418:4;28415:1;28408:15;28434:414;28565:3;28603:6;28597:13;28628:1;28638:129;28652:6;28649:1;28646:13;28638:129;;;28750:4;28734:14;;;28730:25;;28724:32;28711:11;;;28704:53;28667:12;28638:129;;;-1:-1:-1;28822:1:8;28786:16;;28811:13;;;-1:-1:-1;28786:16:8;28434:414;-1:-1:-1;28434:414:8:o;28853:125::-;28918:9;;;28939:10;;;28936:36;;;28952:18;;:::i;29188:184::-;29258:6;29311:2;29299:9;29290:7;29286:23;29282:32;29279:52;;;29327:1;29324;29317:12;29279:52;-1:-1:-1;29350:16:8;;29188:184;-1:-1:-1;29188:184:8:o;29377:128::-;29444:9;;;29465:11;;;29462:37;;;29479:18;;:::i;31143:180::-;31210:18;31248:10;;;31260;;;31244:27;;31283:11;;;31280:37;;;31297:18;;:::i;31328:277::-;31395:6;31448:2;31436:9;31427:7;31423:23;31419:32;31416:52;;;31464:1;31461;31454:12;31416:52;31496:9;31490:16;31549:5;31542:13;31535:21;31528:5;31525:32;31515:60;;31571:1;31568;31561:12;31515:60;31594:5;31328:277;-1:-1:-1;;;31328:277:8:o
Swarm Source
ipfs://9bc53e924ec0ef938ad596785f1e0a1125402beadedac46bc5df89054ae3e3b6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.