diff --git a/contracts/abi/L2MessageServiceV1.0.abi b/contracts/abi/L2MessageServiceV1.0.abi index 6323bcfe..5673358b 100644 --- a/contracts/abi/L2MessageServiceV1.0.abi +++ b/contracts/abi/L2MessageServiceV1.0.abi @@ -313,13 +313,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "pauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -483,13 +483,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "unPauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" diff --git a/contracts/abi/LineaRollupV6.0.abi b/contracts/abi/LineaRollupV6.0.abi index ad566584..481271af 100644 --- a/contracts/abi/LineaRollupV6.0.abi +++ b/contracts/abi/LineaRollupV6.0.abi @@ -330,6 +330,11 @@ "name": "MissingRollingHashForMessageNumber", "type": "error" }, + { + "inputs": [], + "name": "OnlyNonFallbackOperator", + "type": "error" + }, { "inputs": [ { @@ -724,13 +729,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "pauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -887,13 +892,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "unPauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -2103,12 +2108,12 @@ "inputs": [ { "internalType": "bytes32", - "name": "role", + "name": "_role", "type": "bytes32" }, { "internalType": "address", - "name": "account", + "name": "_account", "type": "address" } ], diff --git a/contracts/docs/api/LineaRollup.md b/contracts/docs/api/LineaRollup.md new file mode 100644 index 00000000..d0802195 --- /dev/null +++ b/contracts/docs/api/LineaRollup.md @@ -0,0 +1,468 @@ +# Solidity API + +## LineaRollup + +### CONTRACT_VERSION + +```solidity +string CONTRACT_VERSION +``` + +This is the ABI version and not the reinitialize version. + +### VERIFIER_SETTER_ROLE + +```solidity +bytes32 VERIFIER_SETTER_ROLE +``` + +The role required to set/add proof verifiers by type. + +### VERIFIER_UNSETTER_ROLE + +```solidity +bytes32 VERIFIER_UNSETTER_ROLE +``` + +The role required to set/remove proof verifiers by type. + +### GENESIS_SHNARF + +```solidity +bytes32 GENESIS_SHNARF +``` + +The default genesis shnarf using empty/default hashes and a default state. + +### SHNARF_EXISTS_DEFAULT_VALUE + +```solidity +uint256 SHNARF_EXISTS_DEFAULT_VALUE +``` + +_Value indicating a shnarf exists._ + +### EMPTY_HASH + +```solidity +bytes32 EMPTY_HASH +``` + +_The default hash value._ + +### BLS_CURVE_MODULUS + +```solidity +uint256 BLS_CURVE_MODULUS +``` + +_The BLS Curve modulus value used._ + +### POINT_EVALUATION_PRECOMPILE_ADDRESS + +```solidity +address POINT_EVALUATION_PRECOMPILE_ADDRESS +``` + +_The well-known precompile address for point evaluation._ + +### POINT_EVALUATION_RETURN_DATA_LENGTH + +```solidity +uint256 POINT_EVALUATION_RETURN_DATA_LENGTH +``` + +_The expected point evaluation return data length._ + +### POINT_EVALUATION_FIELD_ELEMENTS_LENGTH + +```solidity +uint256 POINT_EVALUATION_FIELD_ELEMENTS_LENGTH +``` + +_The expected point evaluation field element length returned._ + +### SIX_MONTHS_IN_SECONDS + +```solidity +uint256 SIX_MONTHS_IN_SECONDS +``` + +_In practice, when used, this is expected to be a close approximation to 6 months, and is intentional._ + +### dataFinalStateRootHashes + +```solidity +mapping(bytes32 => bytes32) dataFinalStateRootHashes +``` + +_DEPRECATED in favor of the single blobShnarfExists mapping._ + +### dataParents + +```solidity +mapping(bytes32 => bytes32) dataParents +``` + +_DEPRECATED in favor of the single blobShnarfExists mapping._ + +### dataShnarfHashes + +```solidity +mapping(bytes32 => bytes32) dataShnarfHashes +``` + +_DEPRECATED in favor of the single blobShnarfExists mapping._ + +### dataStartingBlock + +```solidity +mapping(bytes32 => uint256) dataStartingBlock +``` + +_DEPRECATED in favor of the single blobShnarfExists mapping._ + +### dataEndingBlock + +```solidity +mapping(bytes32 => uint256) dataEndingBlock +``` + +_DEPRECATED in favor of the single blobShnarfExists mapping._ + +### currentL2StoredL1MessageNumber + +```solidity +uint256 currentL2StoredL1MessageNumber +``` + +_DEPRECATED in favor of currentFinalizedState hash._ + +### currentL2StoredL1RollingHash + +```solidity +bytes32 currentL2StoredL1RollingHash +``` + +_DEPRECATED in favor of currentFinalizedState hash._ + +### currentFinalizedShnarf + +```solidity +bytes32 currentFinalizedShnarf +``` + +Contains the most recent finalized shnarf. + +### blobShnarfExists + +```solidity +mapping(bytes32 => uint256) blobShnarfExists +``` + +_NB: THIS IS THE ONLY MAPPING BEING USED FOR DATA SUBMISSION TRACKING. +NB: This was shnarfFinalBlockNumbers and is replaced to indicate only that a shnarf exists with a value of 1._ + +### currentFinalizedState + +```solidity +bytes32 currentFinalizedState +``` + +Hash of the L2 computed L1 message number, rolling hash and finalized timestamp. + +### fallbackOperator + +```solidity +address fallbackOperator +``` + +The address of the fallback operator. + +_This address is granted the OPERATOR_ROLE after six months of finalization inactivity by the current operators._ + +### constructor + +```solidity +constructor() public +``` + +### initialize + +```solidity +function initialize(struct ILineaRollup.InitializationData _initializationData) external +``` + +Initializes LineaRollup and underlying service dependencies - used for new networks only. + +_DEFAULT_ADMIN_ROLE is set for the security council. +OPERATOR_ROLE is set for operators. +Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _initializationData | struct ILineaRollup.InitializationData | The initial data used for proof verification. | + +### reinitializeLineaRollupV6 + +```solidity +function reinitializeLineaRollupV6(struct IPermissionsManager.RoleAddress[] _roleAddresses, struct IPauseManager.PauseTypeRole[] _pauseTypeRoles, struct IPauseManager.PauseTypeRole[] _unpauseTypeRoles, address _fallbackOperator) external +``` + +Sets permissions for a list of addresses and their roles as well as initialises the PauseManager pauseType:role mappings and fallback operator. + +_This function is a reinitializer and can only be called once per version. Should be called using an upgradeAndCall transaction to the ProxyAdmin._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roleAddresses | struct IPermissionsManager.RoleAddress[] | The list of addresses and roles to assign permissions to. | +| _pauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of pause types to associate with roles. | +| _unpauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of unpause types to associate with roles. | +| _fallbackOperator | address | The address of the fallback operator. | + +### renounceRole + +```solidity +function renounceRole(bytes32 _role, address _account) public +``` + +Revokes `role` from the calling account. + +_Fallback operator cannot renounce role. Reverts with OnlyNonFallbackOperator._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _role | bytes32 | The role to renounce. | +| _account | address | The account to renounce - can only be the _msgSender(). | + +### setVerifierAddress + +```solidity +function setVerifierAddress(address _newVerifierAddress, uint256 _proofType) external +``` + +Adds or updates the verifier contract address for a proof type. + +_VERIFIER_SETTER_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _newVerifierAddress | address | The address for the verifier contract. | +| _proofType | uint256 | The proof type being set/updated. | + +### setFallbackOperator + +```solidity +function setFallbackOperator(uint256 _messageNumber, bytes32 _rollingHash, uint256 _lastFinalizedTimestamp) external +``` + +Sets the fallback operator role to the specified address if six months have passed since the last finalization. + +_Reverts if six months have not passed since the last finalization._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | Last finalized L1 message number as part of the feedback loop. | +| _rollingHash | bytes32 | Last finalized L1 rolling hash as part of the feedback loop. | +| _lastFinalizedTimestamp | uint256 | Last finalized L2 block timestamp. | + +### unsetVerifierAddress + +```solidity +function unsetVerifierAddress(uint256 _proofType) external +``` + +Unset the verifier contract address for a proof type. + +_VERIFIER_UNSETTER_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _proofType | uint256 | The proof type being set/updated. | + +### submitBlobs + +```solidity +function submitBlobs(struct ILineaRollup.BlobSubmission[] _blobSubmissions, bytes32 _parentShnarf, bytes32 _finalBlobShnarf) external +``` + +Submit one or more EIP-4844 blobs. + +_OPERATOR_ROLE is required to execute. +This should be a blob carrying transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _blobSubmissions | struct ILineaRollup.BlobSubmission[] | The data for blob submission including proofs and required polynomials. | +| _parentShnarf | bytes32 | The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. | +| _finalBlobShnarf | bytes32 | The expected final shnarf post computation of all the blob shnarfs. | + +### submitDataAsCalldata + +```solidity +function submitDataAsCalldata(struct ILineaRollup.CompressedCalldataSubmission _submission, bytes32 _parentShnarf, bytes32 _expectedShnarf) external +``` + +Submit blobs using compressed data via calldata. + +_OPERATOR_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _submission | struct ILineaRollup.CompressedCalldataSubmission | The supporting data for compressed data submission including compressed data. | +| _parentShnarf | bytes32 | The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. | +| _expectedShnarf | bytes32 | The expected shnarf post computation of all the submission. | + +### _computeLastFinalizedState + +```solidity +function _computeLastFinalizedState(uint256 _messageNumber, bytes32 _rollingHash, uint256 _timestamp) internal pure returns (bytes32 hashedFinalizationState) +``` + +Internal function to compute and save the finalization state. + +_Using assembly this way is cheaper gas wise._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | Is the last L2 computed L1 message number in the finalization. | +| _rollingHash | bytes32 | Is the last L2 computed L1 rolling hash in the finalization. | +| _timestamp | uint256 | The final timestamp in the finalization. | + +### _computeShnarf + +```solidity +function _computeShnarf(bytes32 _parentShnarf, bytes32 _snarkHash, bytes32 _finalStateRootHash, bytes32 _dataEvaluationPoint, bytes32 _dataEvaluationClaim) internal pure returns (bytes32 shnarf) +``` + +Internal function to compute the shnarf more efficiently. + +_Using assembly this way is cheaper gas wise._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _parentShnarf | bytes32 | The shnarf of the parent data item. | +| _snarkHash | bytes32 | Is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. | +| _finalStateRootHash | bytes32 | The final state root hash of the data being submitted. | +| _dataEvaluationPoint | bytes32 | The data evaluation point. | +| _dataEvaluationClaim | bytes32 | The data evaluation claim. | + +### _verifyPointEvaluation + +```solidity +function _verifyPointEvaluation(bytes32 _currentDataHash, uint256 _dataEvaluationPoint, uint256 _dataEvaluationClaim, bytes _kzgCommitment, bytes _kzgProof) internal view +``` + +Performs point evaluation for the compressed blob. + +__dataEvaluationPoint is modular reduced to be lower than the BLS_CURVE_MODULUS for precompile checks._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _currentDataHash | bytes32 | The current blob versioned hash. | +| _dataEvaluationPoint | uint256 | The data evaluation point. | +| _dataEvaluationClaim | uint256 | The data evaluation claim. | +| _kzgCommitment | bytes | The blob KZG commitment. | +| _kzgProof | bytes | The blob KZG point proof. | + +### finalizeBlocks + +```solidity +function finalizeBlocks(bytes _aggregatedProof, uint256 _proofType, struct ILineaRollup.FinalizationDataV3 _finalizationData) external +``` + +Finalize compressed blocks with proof. + +_OPERATOR_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _aggregatedProof | bytes | The aggregated proof. | +| _proofType | uint256 | The proof type. | +| _finalizationData | struct ILineaRollup.FinalizationDataV3 | The full finalization data. | + +### _finalizeBlocks + +```solidity +function _finalizeBlocks(struct ILineaRollup.FinalizationDataV3 _finalizationData, uint256 _lastFinalizedBlock) internal returns (bytes32 finalShnarf) +``` + +Internal function to finalize compressed blocks. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _finalizationData | struct ILineaRollup.FinalizationDataV3 | The full finalization data. | +| _lastFinalizedBlock | uint256 | The last finalized block. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| finalShnarf | bytes32 | The final computed shnarf in finalizing. | + +### _validateL2ComputedRollingHash + +```solidity +function _validateL2ComputedRollingHash(uint256 _rollingHashMessageNumber, bytes32 _rollingHash) internal view +``` + +Internal function to validate l1 rolling hash. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _rollingHashMessageNumber | uint256 | Message number associated with the rolling hash as computed on L2. | +| _rollingHash | bytes32 | L1 rolling hash as computed on L2. | + +### _calculateY + +```solidity +function _calculateY(bytes _data, bytes32 _dataEvaluationPoint) internal pure returns (bytes32 compressedDataComputedY) +``` + +Internal function to calculate Y for public input generation. + +_Each chunk of 32 bytes must start with a 0 byte. +The dataEvaluationPoint value is modulo-ed down during the computation and scalar field checking is not needed. +There is a hard constraint in the circuit to enforce the polynomial degree limit (4096), which will also be enforced with EIP-4844._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _data | bytes | Compressed data from submission data. | +| _dataEvaluationPoint | bytes32 | The data evaluation point. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| compressedDataComputedY | bytes32 | The Y calculated value using the Horner method. | + diff --git a/contracts/docs/api/ZkEvmV2.md b/contracts/docs/api/ZkEvmV2.md new file mode 100644 index 00000000..a9c80d96 --- /dev/null +++ b/contracts/docs/api/ZkEvmV2.md @@ -0,0 +1,66 @@ +# Solidity API + +## ZkEvmV2 + +### MODULO_R + +```solidity +uint256 MODULO_R +``` + +### OPERATOR_ROLE + +```solidity +bytes32 OPERATOR_ROLE +``` + +### currentTimestamp + +```solidity +uint256 currentTimestamp +``` + +_DEPRECATED in favor of currentFinalizedState hash._ + +### currentL2BlockNumber + +```solidity +uint256 currentL2BlockNumber +``` + +The most recent finalized L2 block number. + +### stateRootHashes + +```solidity +mapping(uint256 => bytes32) stateRootHashes +``` + +The most recent L2 state root hash mapped by block number. + +### verifiers + +```solidity +mapping(uint256 => address) verifiers +``` + +The verifier address to use for a proof type when proving. + +### _verifyProof + +```solidity +function _verifyProof(uint256 _publicInput, uint256 _proofType, bytes _proof) internal +``` + +Verifies the proof with locally computed public inputs. + +_If the verifier based on proof type is not found, it reverts with InvalidProofType._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _publicInput | uint256 | The computed public input hash cast as uint256. | +| _proofType | uint256 | The proof type to determine which verifier contract to use. | +| _proof | bytes | The proof to be verified with the proof type verifier contract. | + diff --git a/contracts/docs/api/interfaces/IGenericErrors.md b/contracts/docs/api/interfaces/IGenericErrors.md new file mode 100644 index 00000000..e49b7900 --- /dev/null +++ b/contracts/docs/api/interfaces/IGenericErrors.md @@ -0,0 +1,28 @@ +# Solidity API + +## IGenericErrors + +### ZeroAddressNotAllowed + +```solidity +error ZeroAddressNotAllowed() +``` + +_Thrown when a parameter is the zero address._ + +### ZeroHashNotAllowed + +```solidity +error ZeroHashNotAllowed() +``` + +_Thrown when a parameter is the zero hash._ + +### ArrayLengthsDoNotMatch + +```solidity +error ArrayLengthsDoNotMatch() +``` + +_Thrown when array lengths are mismatched._ + diff --git a/contracts/docs/api/interfaces/IMessageService.md b/contracts/docs/api/interfaces/IMessageService.md new file mode 100644 index 00000000..87f84923 --- /dev/null +++ b/contracts/docs/api/interfaces/IMessageService.md @@ -0,0 +1,128 @@ +# Solidity API + +## IMessageService + +### MessageSent + +```solidity +event MessageSent(address _from, address _to, uint256 _fee, uint256 _value, uint256 _nonce, bytes _calldata, bytes32 _messageHash) +``` + +Emitted when a message is sent. + +__calldata has the _ because calldata is a reserved word. +We include the message hash to save hashing costs on the rollup. +This event is used on both L1 and L2._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _from | address | The indexed sender address of the message (msg.sender). | +| _to | address | The indexed intended recipient address of the message on the other layer. | +| _fee | uint256 | The fee being being paid to deliver the message to the recipient in Wei. | +| _value | uint256 | The value being sent to the recipient in Wei. | +| _nonce | uint256 | The unique message number. | +| _calldata | bytes | The calldata being passed to the intended recipient when being called on claiming. | +| _messageHash | bytes32 | The indexed hash of the message parameters. | + +### MessageClaimed + +```solidity +event MessageClaimed(bytes32 _messageHash) +``` + +Emitted when a message is claimed. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageHash | bytes32 | The indexed hash of the message that was claimed. | + +### FeeTooLow + +```solidity +error FeeTooLow() +``` + +_Thrown when fees are lower than the minimum fee._ + +### ValueSentTooLow + +```solidity +error ValueSentTooLow() +``` + +_Thrown when the value sent is less than the fee. +Value to forward on is msg.value - _fee._ + +### MessageSendingFailed + +```solidity +error MessageSendingFailed(address destination) +``` + +_Thrown when the destination address reverts._ + +### FeePaymentFailed + +```solidity +error FeePaymentFailed(address recipient) +``` + +_Thrown when the recipient address reverts._ + +### sendMessage + +```solidity +function sendMessage(address _to, uint256 _fee, bytes _calldata) external payable +``` + +Sends a message for transporting from the given chain. + +_This function should be called with a msg.value = _value + _fee. The fee will be paid on the destination chain._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _to | address | The destination address on the destination chain. | +| _fee | uint256 | The message service fee on the origin chain. | +| _calldata | bytes | The calldata used by the destination message service to call the destination contract. | + +### claimMessage + +```solidity +function claimMessage(address _from, address _to, uint256 _fee, uint256 _value, address payable _feeRecipient, bytes _calldata, uint256 _nonce) external +``` + +Deliver a message to the destination chain. +Is called by the Postman, dApp or end user. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _from | address | The msg.sender calling the origin message service. | +| _to | address | The destination address on the destination chain. | +| _fee | uint256 | The message service fee on the origin chain. | +| _value | uint256 | The value to be transferred to the destination address. | +| _feeRecipient | address payable | Address that will receive the fees. | +| _calldata | bytes | The calldata used by the destination message service to call/forward to the destination contract. | +| _nonce | uint256 | Unique message number. | + +### sender + +```solidity +function sender() external view returns (address originalSender) +``` + +Returns the original sender of the message on the origin layer. + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| originalSender | address | The original sender of the message on the origin layer. | + diff --git a/contracts/docs/api/interfaces/IPauseManager.md b/contracts/docs/api/interfaces/IPauseManager.md new file mode 100644 index 00000000..462732ae --- /dev/null +++ b/contracts/docs/api/interfaces/IPauseManager.md @@ -0,0 +1,157 @@ +# Solidity API + +## IPauseManager + +### PauseTypeRole + +```solidity +struct PauseTypeRole { + enum IPauseManager.PauseType pauseType; + bytes32 role; +} +``` + +### PauseType + +```solidity +enum PauseType { + UNUSED, + GENERAL, + L1_L2, + L2_L1, + BLOB_SUBMISSION, + CALLDATA_SUBMISSION, + FINALIZATION, + INITIATE_TOKEN_BRIDGING, + COMPLETE_TOKEN_BRIDGING +} +``` + +### Paused + +```solidity +event Paused(address messageSender, enum IPauseManager.PauseType pauseType) +``` + +Emitted when a pause type is paused. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| messageSender | address | The address performing the pause. | +| pauseType | enum IPauseManager.PauseType | The indexed pause type that was paused. | + +### UnPaused + +```solidity +event UnPaused(address messageSender, enum IPauseManager.PauseType pauseType) +``` + +Emitted when a pause type is unpaused. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| messageSender | address | The address performing the unpause. | +| pauseType | enum IPauseManager.PauseType | The indexed pause type that was unpaused. | + +### PauseTypeRoleSet + +```solidity +event PauseTypeRoleSet(enum IPauseManager.PauseType pauseType, bytes32 role) +``` + +Emitted when a pause type and its associated role are set in the `_pauseTypeRoles` mapping. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| pauseType | enum IPauseManager.PauseType | The indexed type of pause. | +| role | bytes32 | The indexed role associated with the pause type. | + +### UnPauseTypeRoleSet + +```solidity +event UnPauseTypeRoleSet(enum IPauseManager.PauseType unPauseType, bytes32 role) +``` + +Emitted when an unpause type and its associated role are set in the `_unPauseTypeRoles` mapping. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| unPauseType | enum IPauseManager.PauseType | The indexed type of unpause. | +| role | bytes32 | The indexed role associated with the unpause type. | + +### IsPaused + +```solidity +error IsPaused(enum IPauseManager.PauseType pauseType) +``` + +_Thrown when a specific pause type is paused._ + +### IsNotPaused + +```solidity +error IsNotPaused(enum IPauseManager.PauseType pauseType) +``` + +_Thrown when a specific pause type is not paused and expected to be._ + +### pauseByType + +```solidity +function pauseByType(enum IPauseManager.PauseType _pauseType) external +``` + +Pauses functionality by specific type. + +_Requires the role mapped in pauseTypeRoles for the pauseType._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +### unPauseByType + +```solidity +function unPauseByType(enum IPauseManager.PauseType _pauseType) external +``` + +Unpauses functionality by specific type. + +_Requires the role mapped in unPauseTypeRoles for the pauseType._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +### isPaused + +```solidity +function isPaused(enum IPauseManager.PauseType _pauseType) external view returns (bool pauseTypeIsPaused) +``` + +Check if a pause type is enabled. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| pauseTypeIsPaused | bool | Returns true if the pause type if paused, false otherwise. | + diff --git a/contracts/docs/api/interfaces/IPermissionsManager.md b/contracts/docs/api/interfaces/IPermissionsManager.md new file mode 100644 index 00000000..a280d918 --- /dev/null +++ b/contracts/docs/api/interfaces/IPermissionsManager.md @@ -0,0 +1,13 @@ +# Solidity API + +## IPermissionsManager + +### RoleAddress + +```solidity +struct RoleAddress { + address addressWithRole; + bytes32 role; +} +``` + diff --git a/contracts/docs/api/interfaces/IRateLimiter.md b/contracts/docs/api/interfaces/IRateLimiter.md new file mode 100644 index 00000000..f5683068 --- /dev/null +++ b/contracts/docs/api/interfaces/IRateLimiter.md @@ -0,0 +1,108 @@ +# Solidity API + +## IRateLimiter + +### RateLimitInitialized + +```solidity +event RateLimitInitialized(uint256 periodInSeconds, uint256 limitInWei, uint256 currentPeriodEnd) +``` + +Emitted when the Rate Limit is initialized. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| periodInSeconds | uint256 | The time period in seconds the rate limiter has been initialized to. | +| limitInWei | uint256 | The limit in Wei the rate limiter has been initialized to. | +| currentPeriodEnd | uint256 | The time the current rate limit period will end. | + +### AmountUsedInPeriodReset + +```solidity +event AmountUsedInPeriodReset(address resettingAddress) +``` + +Emitted when the amount in the period is reset to zero. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| resettingAddress | address | The indexed address of who reset the used amount back to zero. | + +### LimitAmountChanged + +```solidity +event LimitAmountChanged(address amountChangeBy, uint256 amount, bool amountUsedLoweredToLimit, bool usedAmountResetToZero) +``` + +Emitted when the limit is changed. + +_If the current used amount is higher than the new limit, the used amount is lowered to the limit. +amountUsedLoweredToLimit and usedAmountResetToZero cannot be true at the same time._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| amountChangeBy | address | The indexed address of who changed the rate limit. | +| amount | uint256 | The rate limited amount in Wei that was set. | +| amountUsedLoweredToLimit | bool | Indicates if the amount used was lowered to the limit to avoid confusion. | +| usedAmountResetToZero | bool | Indicates if the amount used was set to zero because of the current period expiring. | + +### RateLimitExceeded + +```solidity +error RateLimitExceeded() +``` + +_Thrown when an amount breaches the limit in the period._ + +### PeriodIsZero + +```solidity +error PeriodIsZero() +``` + +_Thrown when the period is initialised to zero._ + +### LimitIsZero + +```solidity +error LimitIsZero() +``` + +_Thrown when the limit is initialised to zero._ + +### resetRateLimitAmount + +```solidity +function resetRateLimitAmount(uint256 _amount) external +``` + +Resets the rate limit amount. + +_If the used amount is higher, it is set to the limit to avoid confusion/issues. +Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. +Emits the LimitAmountChanged event. +usedLimitAmountToSet will use the default value of zero if period has expired._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _amount | uint256 | The amount to reset the limit to. | + +### resetAmountUsedInPeriod + +```solidity +function resetAmountUsedInPeriod() external +``` + +Resets the amount used to zero. + +_Only the USED_RATE_LIMIT_RESETTER_ROLE is allowed to execute this function. +Emits the AmountUsedInPeriodReset event._ + diff --git a/contracts/docs/api/interfaces/l1/IL1MessageManager.md b/contracts/docs/api/interfaces/l1/IL1MessageManager.md new file mode 100644 index 00000000..cf90c2a8 --- /dev/null +++ b/contracts/docs/api/interfaces/l1/IL1MessageManager.md @@ -0,0 +1,97 @@ +# Solidity API + +## IL1MessageManager + +### RollingHashUpdated + +```solidity +event RollingHashUpdated(uint256 messageNumber, bytes32 rollingHash, bytes32 messageHash) +``` + +Emitted when a new message is sent and the rolling hash updated. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| messageNumber | uint256 | The unique indexed message number for the message. | +| rollingHash | bytes32 | The indexed rolling hash computed for the current message number. | +| messageHash | bytes32 | The indexed hash of the message parameters. | + +### L2MerkleRootAdded + +```solidity +event L2MerkleRootAdded(bytes32 l2MerkleRoot, uint256 treeDepth) +``` + +Emitted when the L2 Merkle root has been anchored on L1. + +_There may be more than one of these in a finalization depending on the amount of L2->L1 messages in the finalization._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| l2MerkleRoot | bytes32 | The indexed L2 Merkle root that has been anchored on L1 Ethereum. | +| treeDepth | uint256 | The indexed tree depth of the Merkle root. | + +### L2MessagingBlockAnchored + +```solidity +event L2MessagingBlockAnchored(uint256 l2Block) +``` + +Emitted when the L2 block contains L2 messages during finalization. + +_This is used externally in the logic for determining which messages belong to which Merkle root when claiming._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| l2Block | uint256 | The indexed L2 block containing L2 to L1 messages. | + +### MessageAlreadyClaimed + +```solidity +error MessageAlreadyClaimed(uint256 messageIndex) +``` + +_Thrown when the message has already been claimed._ + +### L2MerkleRootAlreadyAnchored + +```solidity +error L2MerkleRootAlreadyAnchored(bytes32 merkleRoot) +``` + +_Thrown when the L2 Merkle root has already been anchored on L1._ + +### BytesLengthNotMultipleOfTwo + +```solidity +error BytesLengthNotMultipleOfTwo(uint256 bytesLength) +``` + +_Thrown when the L2 messaging blocks offsets bytes length is not a multiple of 2._ + +### isMessageClaimed + +```solidity +function isMessageClaimed(uint256 _messageNumber) external view returns (bool isClaimed) +``` + +Checks if the L2->L1 message is claimed or not. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | The message number on L2. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| isClaimed | bool | Returns whether or not the message with _messageNumber has been claimed. | + diff --git a/contracts/docs/api/interfaces/l1/IL1MessageManagerV1.md b/contracts/docs/api/interfaces/l1/IL1MessageManagerV1.md new file mode 100644 index 00000000..f4283b8f --- /dev/null +++ b/contracts/docs/api/interfaces/l1/IL1MessageManagerV1.md @@ -0,0 +1,12 @@ +# Solidity API + +## IL1MessageManagerV1 + +### MessageDoesNotExistOrHasAlreadyBeenClaimed + +```solidity +error MessageDoesNotExistOrHasAlreadyBeenClaimed(bytes32 messageHash) +``` + +_Thrown when the message has already been claimed._ + diff --git a/contracts/docs/api/interfaces/l1/IL1MessageService.md b/contracts/docs/api/interfaces/l1/IL1MessageService.md new file mode 100644 index 00000000..6b70ac41 --- /dev/null +++ b/contracts/docs/api/interfaces/l1/IL1MessageService.md @@ -0,0 +1,67 @@ +# Solidity API + +## IL1MessageService + +### ClaimMessageWithProofParams + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | + +```solidity +struct ClaimMessageWithProofParams { + bytes32[] proof; + uint256 messageNumber; + uint32 leafIndex; + address from; + address to; + uint256 fee; + uint256 value; + address payable feeRecipient; + bytes32 merkleRoot; + bytes data; +} +``` + +### L2MerkleRootDoesNotExist + +```solidity +error L2MerkleRootDoesNotExist() +``` + +_Thrown when L2 Merkle root does not exist._ + +### InvalidMerkleProof + +```solidity +error InvalidMerkleProof() +``` + +_Thrown when the Merkle proof is invalid._ + +### ProofLengthDifferentThanMerkleDepth + +```solidity +error ProofLengthDifferentThanMerkleDepth(uint256 actual, uint256 expected) +``` + +_Thrown when Merkle depth doesn't match proof length._ + +### claimMessageWithProof + +```solidity +function claimMessageWithProof(struct IL1MessageService.ClaimMessageWithProofParams _params) external +``` + +Claims and delivers a cross-chain message using a Merkle proof. + +_if tree depth is empty, it will revert with L2MerkleRootDoesNotExist. +if tree depth is different than proof size, it will revert with ProofLengthDifferentThanMerkleDepth._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _params | struct IL1MessageService.ClaimMessageWithProofParams | Collection of claim data with proof and supporting data. | + diff --git a/contracts/docs/api/interfaces/l1/ILineaRollup.md b/contracts/docs/api/interfaces/l1/ILineaRollup.md new file mode 100644 index 00000000..747ccc2b --- /dev/null +++ b/contracts/docs/api/interfaces/l1/ILineaRollup.md @@ -0,0 +1,507 @@ +# Solidity API + +## ILineaRollup + +### InitializationData + +Initialization data structure for the LineaRollup contract. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | + +```solidity +struct InitializationData { + bytes32 initialStateRootHash; + uint256 initialL2BlockNumber; + uint256 genesisTimestamp; + address defaultVerifier; + uint256 rateLimitPeriodInSeconds; + uint256 rateLimitAmountInWei; + struct IPermissionsManager.RoleAddress[] roleAddresses; + struct IPauseManager.PauseTypeRole[] pauseTypeRoles; + struct IPauseManager.PauseTypeRole[] unpauseTypeRoles; + address fallbackOperator; + address defaultAdmin; +} +``` + +### CompressedCalldataSubmission + +Supporting data for compressed calldata submission including compressed data. + +_finalStateRootHash is used to set state root at the end of the data. +snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. +compressedData is the compressed transaction data. It contains ordered data for each L2 block - l2Timestamps, the encoded transaction data._ + +```solidity +struct CompressedCalldataSubmission { + bytes32 finalStateRootHash; + bytes32 snarkHash; + bytes compressedData; +} +``` + +### ShnarfData + +Shnarf data for validating a shnarf. + +_parentShnarf is the parent computed shnarf. +snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. +finalStateRootHash is the final state root hash. +dataEvaluationPoint is the data evaluation point. +dataEvaluationClaim is the data evaluation claim._ + +```solidity +struct ShnarfData { + bytes32 parentShnarf; + bytes32 snarkHash; + bytes32 finalStateRootHash; + bytes32 dataEvaluationPoint; + bytes32 dataEvaluationClaim; +} +``` + +### BlobSubmission + +Data stucture for compressed blob data submission. + +_submissionData The supporting data for blob data submission excluding the compressed data. +dataEvaluationClaim The data evaluation claim. +kzgCommitment The blob KZG commitment. +kzgProof The blob KZG point proof._ + +```solidity +struct BlobSubmission { + uint256 dataEvaluationClaim; + bytes kzgCommitment; + bytes kzgProof; + bytes32 finalStateRootHash; + bytes32 snarkHash; +} +``` + +### FinalizationDataV3 + +Supporting data for finalization with proof. + +_NB: the dynamic sized fields are placed last on purpose for efficient keccaking on public input. +parentStateRootHash is the expected last state root hash finalized. +endBlockNumber is the end block finalizing until. +shnarfData contains data about the last data submission's shnarf used in finalization. +lastFinalizedTimestamp is the expected last finalized block's timestamp. +finalTimestamp is the timestamp of the last block being finalized. +lastFinalizedL1RollingHash is the last stored L2 computed rolling hash used in finalization. +l1RollingHash is the calculated rolling hash on L2 that is expected to match L1 at l1RollingHashMessageNumber. +This value will be used along with the stored last finalized L2 calculated rolling hash in the public input. +lastFinalizedL1RollingHashMessageNumber is the last stored L2 computed message number used in finalization. +l1RollingHashMessageNumber is the calculated message number on L2 that is expected to match the existing L1 rolling hash. +This value will be used along with the stored last finalized L2 calculated message number in the public input. +l2MerkleTreesDepth is the depth of all l2MerkleRoots. +l2MerkleRoots is an array of L2 message Merkle roots of depth l2MerkleTreesDepth between last finalized block and finalSubmissionData.finalBlockNumber. +l2MessagingBlocksOffsets indicates by offset from currentL2BlockNumber which L2 blocks contain MessageSent events._ + +```solidity +struct FinalizationDataV3 { + bytes32 parentStateRootHash; + uint256 endBlockNumber; + struct ILineaRollup.ShnarfData shnarfData; + uint256 lastFinalizedTimestamp; + uint256 finalTimestamp; + bytes32 lastFinalizedL1RollingHash; + bytes32 l1RollingHash; + uint256 lastFinalizedL1RollingHashMessageNumber; + uint256 l1RollingHashMessageNumber; + uint256 l2MerkleTreesDepth; + bytes32[] l2MerkleRoots; + bytes l2MessagingBlocksOffsets; +} +``` + +### LineaRollupVersionChanged + +```solidity +event LineaRollupVersionChanged(bytes8 previousVersion, bytes8 newVersion) +``` + +Emitted when the LineaRollup contract version has changed. + +_All bytes8 values are string based SemVer in the format M.m - e.g. "6.0"._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| previousVersion | bytes8 | The previous version. | +| newVersion | bytes8 | The new version. | + +### FallbackOperatorRoleGranted + +```solidity +event FallbackOperatorRoleGranted(address caller, address fallbackOperator) +``` + +Emitted when the fallback operator role is granted. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| caller | address | The address that called the function granting the role. | +| fallbackOperator | address | The fallback operator address that received the operator role. | + +### FallbackOperatorAddressSet + +```solidity +event FallbackOperatorAddressSet(address caller, address fallbackOperator) +``` + +Emitted when the fallback operator role is set on the contract. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| caller | address | The address that set the fallback operator address. | +| fallbackOperator | address | The fallback operator address. | + +### VerifierAddressChanged + +```solidity +event VerifierAddressChanged(address verifierAddress, uint256 proofType, address verifierSetBy, address oldVerifierAddress) +``` + +Emitted when a verifier is set for a particular proof type. + +_The verifier will be set by an account with the VERIFIER_SETTER_ROLE. Typically the Safe. +The oldVerifierAddress can be the zero address._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| verifierAddress | address | The indexed new verifier address being set. | +| proofType | uint256 | The indexed proof type/index that the verifier is mapped to. | +| verifierSetBy | address | The index address who set the verifier at the mapping. | +| oldVerifierAddress | address | Indicates the previous address mapped to the proof type. | + +### DataSubmittedV3 + +```solidity +event DataSubmittedV3(bytes32 parentShnarf, bytes32 shnarf, bytes32 finalStateRootHash) +``` + +Emitted when compressed data is being submitted and verified succesfully on L1. + +_The block range is indexed and parent shnarf included for state reconstruction simplicity._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| parentShnarf | bytes32 | The parent shnarf for the data being submitted. | +| shnarf | bytes32 | The indexed shnarf for the data being submitted. | +| finalStateRootHash | bytes32 | The L2 state root hash that the current blob submission ends on. NB: The last blob in the collection. | + +### DataFinalizedV3 + +```solidity +event DataFinalizedV3(uint256 startBlockNumber, uint256 endBlockNumber, bytes32 shnarf, bytes32 parentStateRootHash, bytes32 finalStateRootHash) +``` + +Emitted when L2 blocks have been finalized on L1. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| startBlockNumber | uint256 | The indexed L2 block number indicating which block the finalization the data starts from. | +| endBlockNumber | uint256 | The indexed L2 block number indicating which block the finalization the data ends on. | +| shnarf | bytes32 | The indexed shnarf being set as currentFinalizedShnarf in the current finalization. | +| parentStateRootHash | bytes32 | The parent L2 state root hash that the current finalization starts from. | +| finalStateRootHash | bytes32 | The L2 state root hash that the current finalization ends on. | + +### LastFinalizationTimeNotLapsed + +```solidity +error LastFinalizationTimeNotLapsed() +``` + +_Thrown when the last finalization time has not lapsed when trying to grant the OPERATOR_ROLE to the fallback operator address._ + +### PointEvaluationResponseInvalid + +```solidity +error PointEvaluationResponseInvalid(uint256 fieldElements, uint256 blsCurveModulus) +``` + +_Thrown when the point evaluation precompile's call return data field(s) are wrong._ + +### PrecompileReturnDataLengthWrong + +```solidity +error PrecompileReturnDataLengthWrong(uint256 expected, uint256 actual) +``` + +_Thrown when the point evaluation precompile's call return data length is wrong._ + +### PointEvaluationFailed + +```solidity +error PointEvaluationFailed() +``` + +_Thrown when the point evaluation precompile call returns false._ + +### EmptyBlobDataAtIndex + +```solidity +error EmptyBlobDataAtIndex(uint256 index) +``` + +_Thrown when the blobhash at an index equals to the zero hash._ + +### BlobSubmissionDataIsMissing + +```solidity +error BlobSubmissionDataIsMissing() +``` + +_Thrown when the data for multiple blobs submission has length zero._ + +### BlobSubmissionDataEmpty + +```solidity +error BlobSubmissionDataEmpty(uint256 emptyBlobIndex) +``` + +_Thrown when a blob has been submitted but there is no data for it._ + +### DataAlreadySubmitted + +```solidity +error DataAlreadySubmitted(bytes32 currentDataHash) +``` + +_Thrown when the current data was already submitted._ + +### EmptySubmissionData + +```solidity +error EmptySubmissionData() +``` + +_Thrown when submissionData is empty._ + +### L1RollingHashDoesNotExistOnL1 + +```solidity +error L1RollingHashDoesNotExistOnL1(uint256 messageNumber, bytes32 rollingHash) +``` + +_Thrown when finalizationData.l1RollingHash does not exist on L1 (Feedback loop)._ + +### FinalizationStateIncorrect + +```solidity +error FinalizationStateIncorrect(bytes32 expected, bytes32 value) +``` + +_Thrown when finalization state does not match._ + +### FinalBlockNumberLessThanOrEqualToLastFinalizedBlock + +```solidity +error FinalBlockNumberLessThanOrEqualToLastFinalizedBlock(uint256 finalBlockNumber, uint256 lastFinalizedBlock) +``` + +_Thrown when the final block number in finalization data is less than or equal to the last finalized block during finalization._ + +### FinalBlockStateEqualsZeroHash + +```solidity +error FinalBlockStateEqualsZeroHash() +``` + +_Thrown when the final block state equals the zero hash during finalization._ + +### FinalizationInTheFuture + +```solidity +error FinalizationInTheFuture(uint256 l2BlockTimestamp, uint256 currentBlockTimestamp) +``` + +_Thrown when final l2 block timestamp higher than current block.timestamp during finalization._ + +### MissingMessageNumberForRollingHash + +```solidity +error MissingMessageNumberForRollingHash(bytes32 rollingHash) +``` + +_Thrown when a rolling hash is provided without a corresponding message number._ + +### MissingRollingHashForMessageNumber + +```solidity +error MissingRollingHashForMessageNumber(uint256 messageNumber) +``` + +_Thrown when a message number is provided without a corresponding rolling hash._ + +### FirstByteIsNotZero + +```solidity +error FirstByteIsNotZero() +``` + +_Thrown when the first byte is not zero. +This is used explicitly with the four bytes in assembly 0x729eebce._ + +### BytesLengthNotMultipleOf32 + +```solidity +error BytesLengthNotMultipleOf32() +``` + +_Thrown when bytes length is not a multiple of 32._ + +### FinalShnarfWrong + +```solidity +error FinalShnarfWrong(bytes32 expected, bytes32 value) +``` + +_Thrown when the computed shnarf does not match what is expected._ + +### ParentBlobNotSubmitted + +```solidity +error ParentBlobNotSubmitted(bytes32 shnarf) +``` + +_Thrown when a shnarf does not exist for a parent blob._ + +### FinalBlobNotSubmitted + +```solidity +error FinalBlobNotSubmitted(bytes32 shnarf) +``` + +_Thrown when a shnarf does not exist for the final blob being finalized._ + +### OnlyNonFallbackOperator + +```solidity +error OnlyNonFallbackOperator() +``` + +_Thrown when the fallback operator tries to renounce their operator role._ + +### setVerifierAddress + +```solidity +function setVerifierAddress(address _newVerifierAddress, uint256 _proofType) external +``` + +Adds or updates the verifier contract address for a proof type. + +_VERIFIER_SETTER_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _newVerifierAddress | address | The address for the verifier contract. | +| _proofType | uint256 | The proof type being set/updated. | + +### setFallbackOperator + +```solidity +function setFallbackOperator(uint256 _messageNumber, bytes32 _rollingHash, uint256 _lastFinalizedTimestamp) external +``` + +Sets the fallback operator role to the specified address if six months have passed since the last finalization. + +_Reverts if six months have not passed since the last finalization._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | Last finalized L1 message number as part of the feedback loop. | +| _rollingHash | bytes32 | Last finalized L1 rolling hash as part of the feedback loop. | +| _lastFinalizedTimestamp | uint256 | Last finalized L2 block timestamp. | + +### unsetVerifierAddress + +```solidity +function unsetVerifierAddress(uint256 _proofType) external +``` + +Unsets the verifier contract address for a proof type. + +_VERIFIER_UNSETTER_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _proofType | uint256 | The proof type being set/updated. | + +### submitBlobs + +```solidity +function submitBlobs(struct ILineaRollup.BlobSubmission[] _blobSubmissions, bytes32 _parentShnarf, bytes32 _finalBlobShnarf) external +``` + +Submit one or more EIP-4844 blobs. + +_OPERATOR_ROLE is required to execute. +This should be a blob carrying transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _blobSubmissions | struct ILineaRollup.BlobSubmission[] | The data for blob submission including proofs and required polynomials. | +| _parentShnarf | bytes32 | The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. | +| _finalBlobShnarf | bytes32 | The expected final shnarf post computation of all the blob shnarfs. | + +### submitDataAsCalldata + +```solidity +function submitDataAsCalldata(struct ILineaRollup.CompressedCalldataSubmission _submission, bytes32 _parentShnarf, bytes32 _expectedShnarf) external +``` + +Submit blobs using compressed data via calldata. + +_OPERATOR_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _submission | struct ILineaRollup.CompressedCalldataSubmission | The supporting data for compressed data submission including compressed data. | +| _parentShnarf | bytes32 | The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. | +| _expectedShnarf | bytes32 | The expected shnarf post computation of all the submission. | + +### finalizeBlocks + +```solidity +function finalizeBlocks(bytes _aggregatedProof, uint256 _proofType, struct ILineaRollup.FinalizationDataV3 _finalizationData) external +``` + +Finalize compressed blocks with proof. + +_OPERATOR_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _aggregatedProof | bytes | The aggregated proof. | +| _proofType | uint256 | The proof type. | +| _finalizationData | struct ILineaRollup.FinalizationDataV3 | The full finalization data. | + diff --git a/contracts/docs/api/interfaces/l1/IPlonkVerifier.md b/contracts/docs/api/interfaces/l1/IPlonkVerifier.md new file mode 100644 index 00000000..72ed2cd7 --- /dev/null +++ b/contracts/docs/api/interfaces/l1/IPlonkVerifier.md @@ -0,0 +1,25 @@ +# Solidity API + +## IPlonkVerifier + +### Verify + +```solidity +function Verify(bytes _proof, uint256[] _public_inputs) external returns (bool success) +``` + +Interface for verifier contracts. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _proof | bytes | The proof used to verify. | +| _public_inputs | uint256[] | The computed public inputs for the proof verification. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| success | bool | Returns true if successfully verified. | + diff --git a/contracts/docs/api/interfaces/l1/IZkEvmV2.md b/contracts/docs/api/interfaces/l1/IZkEvmV2.md new file mode 100644 index 00000000..9d2f757a --- /dev/null +++ b/contracts/docs/api/interfaces/l1/IZkEvmV2.md @@ -0,0 +1,44 @@ +# Solidity API + +## IZkEvmV2 + +### StartingRootHashDoesNotMatch + +```solidity +error StartingRootHashDoesNotMatch() +``` + +_Thrown when the starting rootHash does not match the existing state._ + +### ProofIsEmpty + +```solidity +error ProofIsEmpty() +``` + +_Thrown when zk proof is empty bytes._ + +### InvalidProofType + +```solidity +error InvalidProofType() +``` + +_Thrown when zk proof type is invalid._ + +### InvalidProof + +```solidity +error InvalidProof() +``` + +_Thrown when zk proof is invalid._ + +### InvalidProofOrProofVerificationRanOutOfGas + +```solidity +error InvalidProofOrProofVerificationRanOutOfGas(string errorReason) +``` + +_Thrown when the call to the verifier runs out of gas or reverts internally._ + diff --git a/contracts/docs/api/interfaces/l2/IL2MessageManager.md b/contracts/docs/api/interfaces/l2/IL2MessageManager.md new file mode 100644 index 00000000..9ae18047 --- /dev/null +++ b/contracts/docs/api/interfaces/l2/IL2MessageManager.md @@ -0,0 +1,91 @@ +# Solidity API + +## IL2MessageManager + +### RollingHashUpdated + +```solidity +event RollingHashUpdated(uint256 messageNumber, bytes32 rollingHash) +``` + +Emitted after all messages are anchored on L2 and the latest message index and rolling hash stored. + +_NB: This event is used to provide data to the rollup. The last messageNumber and rollingHash, +emitted in a rollup will be used in the public input for validating the L1->L2 messaging state transition._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| messageNumber | uint256 | The indexed unique L1 computed indexed message number for the message. | +| rollingHash | bytes32 | The indexed L1 rolling hash computed for the current message number. | + +### ServiceVersionMigrated + +```solidity +event ServiceVersionMigrated(uint256 version) +``` + +_Emitted when the service switches over to a new version. +This is currently not in use, but left for existing consumers._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| version | uint256 | The indexed version. | + +### MessageHashesListLengthIsZero + +```solidity +error MessageHashesListLengthIsZero() +``` + +_Reverts when the message hashes array length is zero._ + +### L1MessageNumberSynchronizationWrong + +```solidity +error L1MessageNumberSynchronizationWrong(uint256 expected, uint256 found) +``` + +_Reverts when message number synchronization is mismatched._ + +### L1RollingHashSynchronizationWrong + +```solidity +error L1RollingHashSynchronizationWrong(bytes32 expected, bytes32 found) +``` + +_Reverts when rolling hash synchronization is mismatched._ + +### FinalRollingHashIsZero + +```solidity +error FinalRollingHashIsZero() +``` + +_Reverts when final rolling hash is zero hash._ + +### anchorL1L2MessageHashes + +```solidity +function anchorL1L2MessageHashes(bytes32[] _messageHashes, uint256 _startingMessageNumber, uint256 _finalMessageNumber, bytes32 _finalRollingHash) external +``` + +Add cross-chain L1->L2 message hashes in storage. + +_Only address that has the role 'L1_L2_MESSAGE_SETTER_ROLE' are allowed to call this function. +NB: In the unlikely event of a duplicate anchoring, the lastAnchoredL1MessageNumber MUST NOT be incremented. +and the rolling hash not calculated, else synchronisation will break. +If starting number is zero, an underflow error is expected._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageHashes | bytes32[] | New message hashes to anchor on L2. | +| _startingMessageNumber | uint256 | The expected L1 message number to start when anchoring. | +| _finalMessageNumber | uint256 | The expected L1 message number to end on when anchoring. | +| _finalRollingHash | bytes32 | The expected L1 rolling hash to end on when anchoring. | + diff --git a/contracts/docs/api/interfaces/l2/IL2MessageManagerV1.md b/contracts/docs/api/interfaces/l2/IL2MessageManagerV1.md new file mode 100644 index 00000000..765f3693 --- /dev/null +++ b/contracts/docs/api/interfaces/l2/IL2MessageManagerV1.md @@ -0,0 +1,50 @@ +# Solidity API + +## IL2MessageManagerV1 + +### MinimumFeeChanged + +```solidity +event MinimumFeeChanged(uint256 previousMinimumFee, uint256 newMinimumFee, address calledBy) +``` + +Emitted when L2 minimum fee is changed. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| previousMinimumFee | uint256 | The previous minimum fee in Wei. | +| newMinimumFee | uint256 | The new minimum fee in Wei. | +| calledBy | address | The indexed address who changed the minimum fee. | + +### L1L2MessageHashesAddedToInbox + +```solidity +event L1L2MessageHashesAddedToInbox(bytes32[] messageHashes) +``` + +Emitted when L1->L2 message hashes have been added to L2 storage. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| messageHashes | bytes32[] | The message hashes that were added to L2 for claiming. | + +### MessageHashesListLengthHigherThanOneHundred + +```solidity +error MessageHashesListLengthHigherThanOneHundred(uint256 length) +``` + +_Thrown when the message hashes list length is higher than one hundred._ + +### MessageDoesNotExistOrHasAlreadyBeenClaimed + +```solidity +error MessageDoesNotExistOrHasAlreadyBeenClaimed(bytes32 messageHash) +``` + +_Thrown when the message does not exist or has already been claimed._ + diff --git a/contracts/docs/api/interfaces/l2/IL2MessageServiceV1.md b/contracts/docs/api/interfaces/l2/IL2MessageServiceV1.md new file mode 100644 index 00000000..22f7388b --- /dev/null +++ b/contracts/docs/api/interfaces/l2/IL2MessageServiceV1.md @@ -0,0 +1,20 @@ +# Solidity API + +## IL2MessageServiceV1 + +### setMinimumFee + +```solidity +function setMinimumFee(uint256 _feeInWei) external +``` + +The Fee Manager sets a minimum fee to address DOS protection. + +_MINIMUM_FEE_SETTER_ROLE is required to set the minimum fee._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _feeInWei | uint256 | New minimum fee in Wei. | + diff --git a/contracts/docs/api/lib/L2MessageServicePauseManager.md b/contracts/docs/api/lib/L2MessageServicePauseManager.md new file mode 100644 index 00000000..dfaa3cc1 --- /dev/null +++ b/contracts/docs/api/lib/L2MessageServicePauseManager.md @@ -0,0 +1,36 @@ +# Solidity API + +## L2MessageServicePauseManager + +### PAUSE_L1_L2_ROLE + +```solidity +bytes32 PAUSE_L1_L2_ROLE +``` + +This is used to pause L1 to L2 communication. + +### UNPAUSE_L1_L2_ROLE + +```solidity +bytes32 UNPAUSE_L1_L2_ROLE +``` + +This is used to unpause L1 to L2 communication. + +### PAUSE_L2_L1_ROLE + +```solidity +bytes32 PAUSE_L2_L1_ROLE +``` + +This is used to pause L2 to L1 communication. + +### UNPAUSE_L2_L1_ROLE + +```solidity +bytes32 UNPAUSE_L2_L1_ROLE +``` + +This is used to unpause L2 to L1 communication. + diff --git a/contracts/docs/api/lib/LineaRollupPauseManager.md b/contracts/docs/api/lib/LineaRollupPauseManager.md new file mode 100644 index 00000000..bfb0b025 --- /dev/null +++ b/contracts/docs/api/lib/LineaRollupPauseManager.md @@ -0,0 +1,68 @@ +# Solidity API + +## LineaRollupPauseManager + +### PAUSE_L1_L2_ROLE + +```solidity +bytes32 PAUSE_L1_L2_ROLE +``` + +This is used to pause L1 to L2 communication. + +### UNPAUSE_L1_L2_ROLE + +```solidity +bytes32 UNPAUSE_L1_L2_ROLE +``` + +This is used to unpause L1 to L2 communication. + +### PAUSE_L2_L1_ROLE + +```solidity +bytes32 PAUSE_L2_L1_ROLE +``` + +This is used to pause L2 to L1 communication. + +### UNPAUSE_L2_L1_ROLE + +```solidity +bytes32 UNPAUSE_L2_L1_ROLE +``` + +This is used to unpause L2 to L1 communication. + +### PAUSE_BLOB_SUBMISSION_ROLE + +```solidity +bytes32 PAUSE_BLOB_SUBMISSION_ROLE +``` + +This is used to pause blob submission. + +### UNPAUSE_BLOB_SUBMISSION_ROLE + +```solidity +bytes32 UNPAUSE_BLOB_SUBMISSION_ROLE +``` + +This is used to unpause blob submission. + +### PAUSE_FINALIZATION_ROLE + +```solidity +bytes32 PAUSE_FINALIZATION_ROLE +``` + +This is used to pause finalization submission. + +### UNPAUSE_FINALIZATION_ROLE + +```solidity +bytes32 UNPAUSE_FINALIZATION_ROLE +``` + +This is used to unpause finalization submission. + diff --git a/contracts/docs/api/lib/Mimc.md b/contracts/docs/api/lib/Mimc.md new file mode 100644 index 00000000..1fa9a993 --- /dev/null +++ b/contracts/docs/api/lib/Mimc.md @@ -0,0 +1,48 @@ +# Solidity API + +## Mimc + +### DataMissing + +```solidity +error DataMissing() +``` + +Thrown when the data is not provided + +### DataIsNotMod32 + +```solidity +error DataIsNotMod32() +``` + +Thrown when the data is not purely in 32 byte chunks + +### FR_FIELD + +```solidity +uint256 FR_FIELD +``` + +### hash + +```solidity +function hash(bytes _msg) external pure returns (bytes32 mimcHash) +``` + +Performs a MiMC hash on the data provided + +_Only data that has length modulus 32 is hashed, reverts otherwise_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _msg | bytes | The data to be hashed | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| mimcHash | bytes32 | The computed MiMC hash | + diff --git a/contracts/docs/api/lib/PauseManager.md b/contracts/docs/api/lib/PauseManager.md new file mode 100644 index 00000000..f0ac6064 --- /dev/null +++ b/contracts/docs/api/lib/PauseManager.md @@ -0,0 +1,153 @@ +# Solidity API + +## PauseManager + +### PAUSE_ALL_ROLE + +```solidity +bytes32 PAUSE_ALL_ROLE +``` + +This is used to pause all pausable functions. + +### UNPAUSE_ALL_ROLE + +```solidity +bytes32 UNPAUSE_ALL_ROLE +``` + +This is used to unpause all unpausable functions. + +### pauseTypeStatuses + +```solidity +mapping(bytes32 => bool) pauseTypeStatuses +``` + +### whenTypeAndGeneralNotPaused + +```solidity +modifier whenTypeAndGeneralNotPaused(enum IPauseManager.PauseType _pauseType) +``` + +_Modifier to make a function callable only when the specific and general types are not paused._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value being checked. Requirements: - The type must not be paused. | + +### whenTypeNotPaused + +```solidity +modifier whenTypeNotPaused(enum IPauseManager.PauseType _pauseType) +``` + +_Modifier to make a function callable only when the type is not paused._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value being checked. Requirements: - The type must not be paused. | + +### __PauseManager_init + +```solidity +function __PauseManager_init(struct IPauseManager.PauseTypeRole[] _pauseTypeRoleAssignments, struct IPauseManager.PauseTypeRole[] _unpauseTypeRoleAssignments) internal +``` + +Initializes the pause manager with the given pause and unpause roles. + +_This function is called during contract initialization to set up the pause and unpause roles._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseTypeRoleAssignments | struct IPauseManager.PauseTypeRole[] | An array of PauseTypeRole structs defining the pause types and their associated roles. | +| _unpauseTypeRoleAssignments | struct IPauseManager.PauseTypeRole[] | An array of PauseTypeRole structs defining the unpause types and their associated roles. | + +### _requireTypeAndGeneralNotPaused + +```solidity +function _requireTypeAndGeneralNotPaused(enum IPauseManager.PauseType _pauseType) internal view virtual +``` + +_Throws if the specific or general types are paused. +Checks the specific and general pause types._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value being checked. | + +### _requireTypeNotPaused + +```solidity +function _requireTypeNotPaused(enum IPauseManager.PauseType _pauseType) internal view virtual +``` + +_Throws if the type is paused. +Checks the specific pause type._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value being checked. | + +### pauseByType + +```solidity +function pauseByType(enum IPauseManager.PauseType _pauseType) external +``` + +Pauses functionality by specific type. + +_Requires the role mapped in `_pauseTypeRoles` for the pauseType._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +### unPauseByType + +```solidity +function unPauseByType(enum IPauseManager.PauseType _pauseType) external +``` + +Unpauses functionality by specific type. + +_Requires the role mapped in `_unPauseTypeRoles` for the pauseType._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +### isPaused + +```solidity +function isPaused(enum IPauseManager.PauseType _pauseType) public view returns (bool pauseTypeIsPaused) +``` + +Check if a pause type is enabled. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _pauseType | enum IPauseManager.PauseType | The pause type value. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| pauseTypeIsPaused | bool | Returns true if the pause type if paused, false otherwise. | + diff --git a/contracts/docs/api/lib/PermissionsManager.md b/contracts/docs/api/lib/PermissionsManager.md new file mode 100644 index 00000000..8af4ba67 --- /dev/null +++ b/contracts/docs/api/lib/PermissionsManager.md @@ -0,0 +1,18 @@ +# Solidity API + +## PermissionsManager + +### __Permissions_init + +```solidity +function __Permissions_init(struct IPermissionsManager.RoleAddress[] _roleAddresses) internal +``` + +Sets permissions for a list of addresses and their roles. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roleAddresses | struct IPermissionsManager.RoleAddress[] | The list of addresses and roles to assign permissions to. | + diff --git a/contracts/docs/api/lib/SparseMerkleProof.md b/contracts/docs/api/lib/SparseMerkleProof.md new file mode 100644 index 00000000..65d07974 --- /dev/null +++ b/contracts/docs/api/lib/SparseMerkleProof.md @@ -0,0 +1,214 @@ +# Solidity API + +## SparseMerkleProof + +### Account + +The Account struct represents the state of the account including the storage root, nonce, balance and codesize + +_This is mapped directly to the output of the storage proof_ + +```solidity +struct Account { + uint64 nonce; + uint256 balance; + bytes32 storageRoot; + bytes32 mimcCodeHash; + bytes32 keccakCodeHash; + uint64 codeSize; +} +``` + +### Leaf + +Represents the leaf structure in both account and storage tries + +_This is mapped directly to the output of the storage proof_ + +```solidity +struct Leaf { + uint256 prev; + uint256 next; + bytes32 hKey; + bytes32 hValue; +} +``` + +### WrongBytesLength + +```solidity +error WrongBytesLength(uint256 expectedLength, uint256 bytesLength) +``` + +Thrown when expected bytes length is incorrect + +### LengthNotMod32 + +```solidity +error LengthNotMod32() +``` + +Thrown when the length of bytes is not in exactly 32 byte chunks + +### MaxTreeLeafIndexExceed + +```solidity +error MaxTreeLeafIndexExceed() +``` + +Thrown when the leaf index is higher than the tree depth + +### WrongProofLength + +```solidity +error WrongProofLength(uint256 expectedLength, uint256 actualLength) +``` + +Thrown when the length of the unformatted proof is not provided exactly as expected (UNFORMATTED_PROOF_LENGTH) + +### TREE_DEPTH + +```solidity +uint256 TREE_DEPTH +``` + +### UNFORMATTED_PROOF_LENGTH + +```solidity +uint256 UNFORMATTED_PROOF_LENGTH +``` + +### ZERO_HASH + +```solidity +bytes32 ZERO_HASH +``` + +### MAX_TREE_LEAF_INDEX + +```solidity +uint256 MAX_TREE_LEAF_INDEX +``` + +### verifyProof + +```solidity +function verifyProof(bytes[] _rawProof, uint256 _leafIndex, bytes32 _root) external pure returns (bool) +``` + +Formats input, computes root and returns true if it matches the provided merkle root + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _rawProof | bytes[] | Raw sparse merkle tree proof | +| _leafIndex | uint256 | Index of the leaf | +| _root | bytes32 | Sparse merkle root | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | bool | If the computed merkle root matches the provided one | + +### mimcHash + +```solidity +function mimcHash(bytes _input) external pure returns (bytes32) +``` + +Hash a value using MIMC hash + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _input | bytes | Value to hash | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | bytes32 | {bytes32} Mimc hash | + +### getLeaf + +```solidity +function getLeaf(bytes _encodedLeaf) external pure returns (struct SparseMerkleProof.Leaf) +``` + +Get leaf + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _encodedLeaf | bytes | Encoded leaf bytes (prev, next, hKey, hValue) | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | struct SparseMerkleProof.Leaf | Leaf Formatted leaf struct | + +### getAccount + +```solidity +function getAccount(bytes _encodedAccountValue) external pure returns (struct SparseMerkleProof.Account) +``` + +Get account + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _encodedAccountValue | bytes | Encoded account value bytes (nonce, balance, storageRoot, mimcCodeHash, keccakCodeHash, codeSize) | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | struct SparseMerkleProof.Account | Account Formatted account struct | + +### hashAccountValue + +```solidity +function hashAccountValue(bytes _value) external pure returns (bytes32) +``` + +Hash account value + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _value | bytes | Encoded account value bytes (nonce, balance, storageRoot, mimcCodeHash, keccakCodeHash, codeSize) | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | bytes32 | {bytes32} Account value hash | + +### hashStorageValue + +```solidity +function hashStorageValue(bytes32 _value) external pure returns (bytes32) +``` + +Hash storage value + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _value | bytes32 | Encoded storage value bytes | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | bytes32 | {bytes32} Storage value hash | + diff --git a/contracts/docs/api/lib/TokenBridgePauseManager.md b/contracts/docs/api/lib/TokenBridgePauseManager.md new file mode 100644 index 00000000..0061c3d6 --- /dev/null +++ b/contracts/docs/api/lib/TokenBridgePauseManager.md @@ -0,0 +1,28 @@ +# Solidity API + +## TokenBridgePauseManager + +### PAUSE_INITIATE_TOKEN_BRIDGING_ROLE + +```solidity +bytes32 PAUSE_INITIATE_TOKEN_BRIDGING_ROLE +``` + +### UNPAUSE_INITIATE_TOKEN_BRIDGING_ROLE + +```solidity +bytes32 UNPAUSE_INITIATE_TOKEN_BRIDGING_ROLE +``` + +### PAUSE_COMPLETE_TOKEN_BRIDGING_ROLE + +```solidity +bytes32 PAUSE_COMPLETE_TOKEN_BRIDGING_ROLE +``` + +### UNPAUSE_COMPLETE_TOKEN_BRIDGING_ROLE + +```solidity +bytes32 UNPAUSE_COMPLETE_TOKEN_BRIDGING_ROLE +``` + diff --git a/contracts/docs/api/lib/Utils.md b/contracts/docs/api/lib/Utils.md new file mode 100644 index 00000000..37204966 --- /dev/null +++ b/contracts/docs/api/lib/Utils.md @@ -0,0 +1,34 @@ +# Solidity API + +## Utils + +### _efficientKeccak + +```solidity +function _efficientKeccak(bytes32 _left, bytes32 _right) internal pure returns (bytes32 value) +``` + +Performs a gas optimized keccak hash for two bytes32 values. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _left | bytes32 | Left value. | +| _right | bytes32 | Right value. | + +### _efficientKeccak + +```solidity +function _efficientKeccak(uint256 _left, address _right) internal pure returns (bytes32 value) +``` + +Performs a gas optimized keccak hash for uint256 and address. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _left | uint256 | Left value. | +| _right | address | Right value. | + diff --git a/contracts/docs/api/messageService/MessageServiceBase.md b/contracts/docs/api/messageService/MessageServiceBase.md new file mode 100644 index 00000000..3df994ae --- /dev/null +++ b/contracts/docs/api/messageService/MessageServiceBase.md @@ -0,0 +1,107 @@ +# Solidity API + +## MessageServiceBase + +### messageService + +```solidity +contract IMessageService messageService +``` + +The message service address on the current chain. + +### remoteSender + +```solidity +address remoteSender +``` + +The token bridge on the alternate/remote chain. + +### RemoteSenderSet + +```solidity +event RemoteSenderSet(address remoteSender, address setter) +``` + +_Event emitted when the remote sender is set._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| remoteSender | address | The address of the new remote sender. | +| setter | address | The address of the account that set the remote sender. | + +### CallerIsNotMessageService + +```solidity +error CallerIsNotMessageService() +``` + +_Thrown when the caller address is not the message service address_ + +### SenderNotAuthorized + +```solidity +error SenderNotAuthorized() +``` + +_Thrown when remote sender address is not authorized._ + +### onlyMessagingService + +```solidity +modifier onlyMessagingService() +``` + +_Modifier to make sure the caller is the known message service. + +Requirements: + +- The msg.sender must be the message service._ + +### onlyAuthorizedRemoteSender + +```solidity +modifier onlyAuthorizedRemoteSender() +``` + +_Modifier to make sure the original sender is allowed. + +Requirements: + +- The original message sender via the message service must be a known sender._ + +### __MessageServiceBase_init + +```solidity +function __MessageServiceBase_init(address _messageService) internal +``` + +Initializes the message service + +_Must be initialized in the initialize function of the main contract or constructor._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageService | address | The message service address, cannot be empty. | + +### _setRemoteSender + +```solidity +function _setRemoteSender(address _remoteSender) internal +``` + +Sets the remote sender + +_This function sets the remote sender address and emits the RemoteSenderSet event._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _remoteSender | address | The authorized remote sender address, cannot be empty. | + diff --git a/contracts/docs/api/messageService/l1/L1MessageManager.md b/contracts/docs/api/messageService/l1/L1MessageManager.md new file mode 100644 index 00000000..40a14fbc --- /dev/null +++ b/contracts/docs/api/messageService/l1/L1MessageManager.md @@ -0,0 +1,113 @@ +# Solidity API + +## L1MessageManager + +### rollingHashes + +```solidity +mapping(uint256 => bytes32) rollingHashes +``` + +Contains the L1 to L2 messaging rolling hashes mapped to message number computed on L1. + +### _messageClaimedBitMap + +```solidity +struct BitMaps.BitMap _messageClaimedBitMap +``` + +This maps which message numbers have been claimed to prevent duplicate claiming. + +### l2MerkleRootsDepths + +```solidity +mapping(bytes32 => uint256) l2MerkleRootsDepths +``` + +Contains the L2 messages Merkle roots mapped to their tree depth. + +### _addRollingHash + +```solidity +function _addRollingHash(uint256 _messageNumber, bytes32 _messageHash) internal +``` + +Take an existing message hash, calculates the rolling hash and stores at the message number. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | The current message number being sent. | +| _messageHash | bytes32 | The hash of the message being sent. | + +### _setL2L1MessageToClaimed + +```solidity +function _setL2L1MessageToClaimed(uint256 _messageNumber) internal +``` + +Set the L2->L1 message as claimed when a user claims a message on L1. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | The message number on L2. | + +### _addL2MerkleRoots + +```solidity +function _addL2MerkleRoots(bytes32[] _newRoots, uint256 _treeDepth) internal +``` + +Add the L2 Merkle roots to the storage. + +_This function is called during block finalization. +The _treeDepth does not need to be checked to be non-zero as it is, +already enforced to be non-zero in the circuit, and used in the proof's public input._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _newRoots | bytes32[] | New L2 Merkle roots. | +| _treeDepth | uint256 | | + +### _anchorL2MessagingBlocks + +```solidity +function _anchorL2MessagingBlocks(bytes _l2MessagingBlocksOffsets, uint256 _currentL2BlockNumber) internal +``` + +Emit an event for each L2 block containing L2->L1 messages. + +_This function is called during block finalization._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _l2MessagingBlocksOffsets | bytes | Is a sequence of uint16 values, where each value plus the last finalized L2 block number. indicates which L2 blocks have L2->L1 messages. | +| _currentL2BlockNumber | uint256 | Last L2 block number finalized on L1. | + +### isMessageClaimed + +```solidity +function isMessageClaimed(uint256 _messageNumber) external view returns (bool isClaimed) +``` + +Checks if the L2->L1 message is claimed or not. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageNumber | uint256 | The message number on L2. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| isClaimed | bool | Returns whether or not the message with _messageNumber has been claimed. | + diff --git a/contracts/docs/api/messageService/l1/L1MessageService.md b/contracts/docs/api/messageService/l1/L1MessageService.md new file mode 100644 index 00000000..5892e5c9 --- /dev/null +++ b/contracts/docs/api/messageService/l1/L1MessageService.md @@ -0,0 +1,79 @@ +# Solidity API + +## L1MessageService + +### systemMigrationBlock + +```solidity +uint256 systemMigrationBlock +``` + +_This is currently not in use, but is reserved for future upgrades._ + +### __MessageService_init + +```solidity +function __MessageService_init(uint256 _rateLimitPeriod, uint256 _rateLimitAmount) internal +``` + +Initialises underlying message service dependencies. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _rateLimitPeriod | uint256 | The period to rate limit against. | +| _rateLimitAmount | uint256 | The limit allowed for withdrawing the period. | + +### sendMessage + +```solidity +function sendMessage(address _to, uint256 _fee, bytes _calldata) external payable +``` + +Adds a message for sending cross-chain and emits MessageSent. + +_The message number is preset (nextMessageNumber) and only incremented at the end if successful for the next caller. +This function should be called with a msg.value = _value + _fee. The fee will be paid on the destination chain._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _to | address | The address the message is intended for. | +| _fee | uint256 | The fee being paid for the message delivery. | +| _calldata | bytes | The calldata to pass to the recipient. | + +### claimMessageWithProof + +```solidity +function claimMessageWithProof(struct IL1MessageService.ClaimMessageWithProofParams _params) external +``` + +Claims and delivers a cross-chain message using a Merkle proof. + +_if tree depth is empty, it will revert with L2MerkleRootDoesNotExist. +if tree depth is different than proof size, it will revert with ProofLengthDifferentThanMerkleDepth._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _params | struct IL1MessageService.ClaimMessageWithProofParams | Collection of claim data with proof and supporting data. | + +### sender + +```solidity +function sender() external view returns (address originalSender) +``` + +Claims and delivers a cross-chain message. + +_The message sender address is set temporarily in the transient storage when claiming._ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| originalSender | address | The message sender address that is stored temporarily in the transient storage when claiming. | + diff --git a/contracts/docs/api/messageService/l1/TransientStorageReentrancyGuardUpgradeable.md b/contracts/docs/api/messageService/l1/TransientStorageReentrancyGuardUpgradeable.md new file mode 100644 index 00000000..261ace02 --- /dev/null +++ b/contracts/docs/api/messageService/l1/TransientStorageReentrancyGuardUpgradeable.md @@ -0,0 +1,16 @@ +# Solidity API + +## TransientStorageReentrancyGuardUpgradeable + +### ReentrantCall + +```solidity +error ReentrantCall() +``` + +### nonReentrant + +```solidity +modifier nonReentrant() +``` + diff --git a/contracts/docs/api/messageService/l1/v1/L1MessageManagerV1.md b/contracts/docs/api/messageService/l1/v1/L1MessageManagerV1.md new file mode 100644 index 00000000..ecee43cb --- /dev/null +++ b/contracts/docs/api/messageService/l1/v1/L1MessageManagerV1.md @@ -0,0 +1,73 @@ +# Solidity API + +## L1MessageManagerV1 + +### INBOX_STATUS_UNKNOWN + +```solidity +uint8 INBOX_STATUS_UNKNOWN +``` + +The 2 legacy status constants for message statuses. + +### INBOX_STATUS_RECEIVED + +```solidity +uint8 INBOX_STATUS_RECEIVED +``` + +### OUTBOX_STATUS_UNKNOWN + +```solidity +uint8 OUTBOX_STATUS_UNKNOWN +``` + +The 3 legacy status constants for message statuses. + +### OUTBOX_STATUS_SENT + +```solidity +uint8 OUTBOX_STATUS_SENT +``` + +### OUTBOX_STATUS_RECEIVED + +```solidity +uint8 OUTBOX_STATUS_RECEIVED +``` + +### outboxL1L2MessageStatus + +```solidity +mapping(bytes32 => uint256) outboxL1L2MessageStatus +``` + +_DEPRECATED in favor of the rollingHashes mapping on the L1MessageManager for L1 to L2 messaging._ + +### inboxL2L1MessageStatus + +```solidity +mapping(bytes32 => uint256) inboxL2L1MessageStatus +``` + +_Mapping to store L2->L1 message hashes status. +messageHash => messageStatus (0: unknown, 1: received). +For the most part this has been deprecated. This is only used for messages received pre-AlphaV2._ + +### _updateL2L1MessageStatusToClaimed + +```solidity +function _updateL2L1MessageStatusToClaimed(bytes32 _messageHash) internal +``` + +Update the status of L2->L1 message when a user claims a message on L1. + +_The L2->L1 message is removed from storage. +Due to the nature of the rollup, we should not get a second entry of this._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageHash | bytes32 | Hash of the message. | + diff --git a/contracts/docs/api/messageService/l1/v1/L1MessageServiceV1.md b/contracts/docs/api/messageService/l1/v1/L1MessageServiceV1.md new file mode 100644 index 00000000..ff270a80 --- /dev/null +++ b/contracts/docs/api/messageService/l1/v1/L1MessageServiceV1.md @@ -0,0 +1,83 @@ +# Solidity API + +## L1MessageServiceV1 + +### nextMessageNumber + +```solidity +uint256 nextMessageNumber +``` + +### _messageSender + +```solidity +address _messageSender +``` + +_DEPRECATED in favor of new transient storage with `MESSAGE_SENDER_TRANSIENT_KEY` key._ + +### REFUND_OVERHEAD_IN_GAS + +```solidity +uint256 REFUND_OVERHEAD_IN_GAS +``` + +_adding these should not affect storage as they are constants and are stored in bytecode._ + +### MESSAGE_SENDER_TRANSIENT_KEY + +```solidity +bytes32 MESSAGE_SENDER_TRANSIENT_KEY +``` + +_The transient storage key to set the message sender against while claiming._ + +### DEFAULT_MESSAGE_SENDER_TRANSIENT_VALUE + +```solidity +address DEFAULT_MESSAGE_SENDER_TRANSIENT_VALUE +``` + +The default value for the message sender reset to post claiming using the MESSAGE_SENDER_TRANSIENT_KEY. + +### distributeFees + +```solidity +modifier distributeFees(uint256 _feeInWei, address _to, bytes _calldata, address _feeRecipient) +``` + +The unspent fee is refunded if applicable. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _feeInWei | uint256 | The fee paid for delivery in Wei. | +| _to | address | The recipient of the message and gas refund. | +| _calldata | bytes | The calldata of the message. | +| _feeRecipient | address | | + +### claimMessage + +```solidity +function claimMessage(address _from, address _to, uint256 _fee, uint256 _value, address payable _feeRecipient, bytes _calldata, uint256 _nonce) external +``` + +Claims and delivers a cross-chain message. + +__feeRecipient can be set to address(0) to receive as msg.sender. +The original message sender address is temporarily set in transient storage, +while claiming. This address is used in sender()._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _from | address | The address of the original sender. | +| _to | address | The address the message is intended for. | +| _fee | uint256 | The fee being paid for the message delivery. | +| _value | uint256 | The value to be transferred to the destination address. | +| _feeRecipient | address payable | The recipient for the fee. | +| _calldata | bytes | The calldata to pass to the recipient. | +| _nonce | uint256 | The unique auto generated nonce used when sending the message. | + diff --git a/contracts/docs/api/messageService/l2/L2MessageManager.md b/contracts/docs/api/messageService/l2/L2MessageManager.md new file mode 100644 index 00000000..003833b1 --- /dev/null +++ b/contracts/docs/api/messageService/l2/L2MessageManager.md @@ -0,0 +1,50 @@ +# Solidity API + +## L2MessageManager + +### L1_L2_MESSAGE_SETTER_ROLE + +```solidity +bytes32 L1_L2_MESSAGE_SETTER_ROLE +``` + +The role required to anchor L1 to L2 message hashes. + +### lastAnchoredL1MessageNumber + +```solidity +uint256 lastAnchoredL1MessageNumber +``` + +Contains the last L1 message number anchored on L2. + +### l1RollingHashes + +```solidity +mapping(uint256 => bytes32) l1RollingHashes +``` + +Contains the L1 to L2 messaging rolling hashes mapped to message number computed on L2. + +### anchorL1L2MessageHashes + +```solidity +function anchorL1L2MessageHashes(bytes32[] _messageHashes, uint256 _startingMessageNumber, uint256 _finalMessageNumber, bytes32 _finalRollingHash) external +``` + +Add cross-chain L1->L2 message hashes in storage. + +_Only address that has the role 'L1_L2_MESSAGE_SETTER_ROLE' are allowed to call this function. +NB: In the unlikely event of a duplicate anchoring, the lastAnchoredL1MessageNumber MUST NOT be incremented. +and the rolling hash not calculated, else synchronisation will break. +If starting number is zero, an underflow error is expected._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageHashes | bytes32[] | New message hashes to anchor on L2. | +| _startingMessageNumber | uint256 | The expected L1 message number to start when anchoring. | +| _finalMessageNumber | uint256 | The expected L1 message number to end on when anchoring. | +| _finalRollingHash | bytes32 | The expected L1 rolling hash to end on when anchoring. | + diff --git a/contracts/docs/api/messageService/l2/L2MessageService.md b/contracts/docs/api/messageService/l2/L2MessageService.md new file mode 100644 index 00000000..6ce7b23c --- /dev/null +++ b/contracts/docs/api/messageService/l2/L2MessageService.md @@ -0,0 +1,55 @@ +# Solidity API + +## L2MessageService + +### CONTRACT_VERSION + +```solidity +string CONTRACT_VERSION +``` + +_This is the ABI version and not the reinitialize version._ + +### constructor + +```solidity +constructor() public +``` + +### initialize + +```solidity +function initialize(uint256 _rateLimitPeriod, uint256 _rateLimitAmount, address _defaultAdmin, struct IPermissionsManager.RoleAddress[] _roleAddresses, struct IPauseManager.PauseTypeRole[] _pauseTypeRoles, struct IPauseManager.PauseTypeRole[] _unpauseTypeRoles) external +``` + +Initializes underlying message service dependencies. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _rateLimitPeriod | uint256 | The period to rate limit against. | +| _rateLimitAmount | uint256 | The limit allowed for withdrawing the period. | +| _defaultAdmin | address | The account to be given DEFAULT_ADMIN_ROLE on initialization. | +| _roleAddresses | struct IPermissionsManager.RoleAddress[] | The list of addresses to grant roles to. | +| _pauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of pause type roles. | +| _unpauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of unpause type roles. | + +### reinitializePauseTypesAndPermissions + +```solidity +function reinitializePauseTypesAndPermissions(struct IPermissionsManager.RoleAddress[] _roleAddresses, struct IPauseManager.PauseTypeRole[] _pauseTypeRoles, struct IPauseManager.PauseTypeRole[] _unpauseTypeRoles) external +``` + +Sets permissions for a list of addresses and their roles as well as initialises the PauseManager pauseType:role mappings. + +_This function is a reinitializer and can only be called once per version. Should be called using an upgradeAndCall transaction to the ProxyAdmin._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _roleAddresses | struct IPermissionsManager.RoleAddress[] | The list of addresses and roles to assign permissions to. | +| _pauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of pause types to associate with roles. | +| _unpauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of unpause types to associate with roles. | + diff --git a/contracts/docs/api/messageService/l2/v1/L2MessageManagerV1.md b/contracts/docs/api/messageService/l2/v1/L2MessageManagerV1.md new file mode 100644 index 00000000..85c73664 --- /dev/null +++ b/contracts/docs/api/messageService/l2/v1/L2MessageManagerV1.md @@ -0,0 +1,47 @@ +# Solidity API + +## L2MessageManagerV1 + +### INBOX_STATUS_UNKNOWN + +```solidity +uint8 INBOX_STATUS_UNKNOWN +``` + +The 3 status constants for L1 to L2 message statuses. + +### INBOX_STATUS_RECEIVED + +```solidity +uint8 INBOX_STATUS_RECEIVED +``` + +### INBOX_STATUS_CLAIMED + +```solidity +uint8 INBOX_STATUS_CLAIMED +``` + +### inboxL1L2MessageStatus + +```solidity +mapping(bytes32 => uint256) inboxL1L2MessageStatus +``` + +_Mapping to store L1->L2 message hashes status. +messageHash => messageStatus (0: unknown, 1: received, 2: claimed)._ + +### _updateL1L2MessageStatusToClaimed + +```solidity +function _updateL1L2MessageStatusToClaimed(bytes32 _messageHash) internal +``` + +Update the status of L1->L2 message when a user claims a message on L2. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageHash | bytes32 | Hash of the message. | + diff --git a/contracts/docs/api/messageService/l2/v1/L2MessageServiceV1.md b/contracts/docs/api/messageService/l2/v1/L2MessageServiceV1.md new file mode 100644 index 00000000..1dd41fe4 --- /dev/null +++ b/contracts/docs/api/messageService/l2/v1/L2MessageServiceV1.md @@ -0,0 +1,140 @@ +# Solidity API + +## L2MessageServiceV1 + +### MINIMUM_FEE_SETTER_ROLE + +```solidity +bytes32 MINIMUM_FEE_SETTER_ROLE +``` + +The role required to set the minimum DDOS fee. + +### _messageSender + +```solidity +address _messageSender +``` + +_The temporary message sender set when claiming a message._ + +### nextMessageNumber + +```solidity +uint256 nextMessageNumber +``` + +### minimumFeeInWei + +```solidity +uint256 minimumFeeInWei +``` + +### REFUND_OVERHEAD_IN_GAS + +```solidity +uint256 REFUND_OVERHEAD_IN_GAS +``` + +### DEFAULT_SENDER_ADDRESS + +```solidity +address DEFAULT_SENDER_ADDRESS +``` + +_The default message sender address reset after claiming a message._ + +### constructor + +```solidity +constructor() internal +``` + +### sendMessage + +```solidity +function sendMessage(address _to, uint256 _fee, bytes _calldata) external payable +``` + +Adds a message for sending cross-chain and emits a relevant event. + +_The message number is preset and only incremented at the end if successful for the next caller._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _to | address | The address the message is intended for. | +| _fee | uint256 | The fee being paid for the message delivery. | +| _calldata | bytes | The calldata to pass to the recipient. | + +### claimMessage + +```solidity +function claimMessage(address _from, address _to, uint256 _fee, uint256 _value, address payable _feeRecipient, bytes _calldata, uint256 _nonce) external +``` + +Claims and delivers a cross-chain message. + +__feeRecipient Can be set to address(0) to receive as msg.sender. +messageSender Is set temporarily when claiming and reset post._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _from | address | The address of the original sender. | +| _to | address | The address the message is intended for. | +| _fee | uint256 | The fee being paid for the message delivery. | +| _value | uint256 | The value to be transferred to the destination address. | +| _feeRecipient | address payable | The recipient for the fee. | +| _calldata | bytes | The calldata to pass to the recipient. | +| _nonce | uint256 | The unique auto generated message number used when sending the message. | + +### setMinimumFee + +```solidity +function setMinimumFee(uint256 _feeInWei) external +``` + +The Fee Manager sets a minimum fee to address DOS protection. + +_MINIMUM_FEE_SETTER_ROLE is required to set the minimum fee._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _feeInWei | uint256 | New minimum fee in Wei. | + +### sender + +```solidity +function sender() external view returns (address originalSender) +``` + +_The _messageSender address is set temporarily when claiming._ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| originalSender | address | The original sender stored temporarily at the _messageSender address in storage. | + +### distributeFees + +```solidity +modifier distributeFees(uint256 _feeInWei, address _to, bytes _calldata, address _feeRecipient) +``` + +The unspent fee is refunded if applicable. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _feeInWei | uint256 | The fee paid for delivery in Wei. | +| _to | address | The recipient of the message and gas refund. | +| _calldata | bytes | The calldata of the message. | +| _feeRecipient | address | | + diff --git a/contracts/docs/api/messageService/lib/MessageHashing.md b/contracts/docs/api/messageService/lib/MessageHashing.md new file mode 100644 index 00000000..dd8fe1b2 --- /dev/null +++ b/contracts/docs/api/messageService/lib/MessageHashing.md @@ -0,0 +1,26 @@ +# Solidity API + +## MessageHashing + +### _hashMessage + +```solidity +function _hashMessage(address _from, address _to, uint256 _fee, uint256 _valueSent, uint256 _messageNumber, bytes _calldata) internal pure returns (bytes32 messageHash) +``` + +Hashes messages using assembly for efficiency. + +_Adding 0xc0 is to indicate the calldata offset relative to the memory being added to. +If the calldata is not modulus 32, the extra bit needs to be added on at the end else the hash is wrong._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _from | address | The from address. | +| _to | address | The to address. | +| _fee | uint256 | The fee paid for delivery. | +| _valueSent | uint256 | The value to be sent when delivering. | +| _messageNumber | uint256 | The unique message number. | +| _calldata | bytes | The calldata to be passed to the destination address. | + diff --git a/contracts/docs/api/messageService/lib/RateLimiter.md b/contracts/docs/api/messageService/lib/RateLimiter.md new file mode 100644 index 00000000..4e191ea0 --- /dev/null +++ b/contracts/docs/api/messageService/lib/RateLimiter.md @@ -0,0 +1,113 @@ +# Solidity API + +## RateLimiter + +You can use this control numeric limits over a period using timestamp. + +### RATE_LIMIT_SETTER_ROLE + +```solidity +bytes32 RATE_LIMIT_SETTER_ROLE +``` + +### USED_RATE_LIMIT_RESETTER_ROLE + +```solidity +bytes32 USED_RATE_LIMIT_RESETTER_ROLE +``` + +### periodInSeconds + +```solidity +uint256 periodInSeconds +``` + +### limitInWei + +```solidity +uint256 limitInWei +``` + +### currentPeriodEnd + +```solidity +uint256 currentPeriodEnd +``` + +The time at which the current period ends at. + +_Public for ease of consumption._ + +### currentPeriodAmountInWei + +```solidity +uint256 currentPeriodAmountInWei +``` + +Amounts already withdrawn this period. + +_Public for ease of consumption._ + +### __RateLimiter_init + +```solidity +function __RateLimiter_init(uint256 _periodInSeconds, uint256 _limitInWei) internal +``` + +Initialises the limits and period for the rate limiter. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _periodInSeconds | uint256 | The length of the period in seconds. | +| _limitInWei | uint256 | The limit allowed in the period in Wei. | + +### _addUsedAmount + +```solidity +function _addUsedAmount(uint256 _usedAmount) internal +``` + +Increments the amount used in the period. + +_The amount determining logic is external to this (e.g. fees are included when calling here). +Ignores the calculation if _usedAmount is zero. +Reverts if the limit is breached._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _usedAmount | uint256 | The amount used to be added. | + +### resetRateLimitAmount + +```solidity +function resetRateLimitAmount(uint256 _amount) external +``` + +Resets the rate limit amount. + +_If the used amount is higher, it is set to the limit to avoid confusion/issues. +Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. +Emits the LimitAmountChanged event. +usedLimitAmountToSet will use the default value of zero if period has expired._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _amount | uint256 | The amount to reset the limit to. | + +### resetAmountUsedInPeriod + +```solidity +function resetAmountUsedInPeriod() external +``` + +Resets the amount used to zero. + +_Only the USED_RATE_LIMIT_RESETTER_ROLE is allowed to execute this function. +Emits the AmountUsedInPeriodReset event._ + diff --git a/contracts/docs/api/messageService/lib/SparseMerkleTreeVerifier.md b/contracts/docs/api/messageService/lib/SparseMerkleTreeVerifier.md new file mode 100644 index 00000000..6432d446 --- /dev/null +++ b/contracts/docs/api/messageService/lib/SparseMerkleTreeVerifier.md @@ -0,0 +1,68 @@ +# Solidity API + +## SparseMerkleTreeVerifier + +### SafeCastOverflowedUintDowncast + +```solidity +error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value) +``` + +_Value doesn't fit in a uint of `bits` size. +This is based on OpenZeppelin's SafeCast library._ + +### LeafIndexOutOfBounds + +```solidity +error LeafIndexOutOfBounds(uint32 leafIndex, uint32 maxAllowedIndex) +``` + +_Custom error for when the leaf index is out of bounds._ + +### _verifyMerkleProof + +```solidity +function _verifyMerkleProof(bytes32 _leafHash, bytes32[] _proof, uint32 _leafIndex, bytes32 _root) internal pure returns (bool proofIsValid) +``` + +Verify merkle proof + +_The depth of the tree is expected to be validated elsewhere beforehand._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _leafHash | bytes32 | Leaf hash. | +| _proof | bytes32[] | Sparse merkle tree proof. | +| _leafIndex | uint32 | Index of the leaf. | +| _root | bytes32 | Merkle root. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| proofIsValid | bool | Returns if the proof is valid or not. | + +### safeCastToUint32 + +```solidity +function safeCastToUint32(uint256 _value) internal pure returns (uint32 castUint32) +``` + +Tries to safely cast to uint32. + +_This is based on OpenZeppelin's SafeCast library._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _value | uint256 | The value being cast to uint32. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| castUint32 | uint32 | Returns a uint32 safely cast. | + diff --git a/contracts/docs/api/messageService/lib/TimeLock.md b/contracts/docs/api/messageService/lib/TimeLock.md new file mode 100644 index 00000000..9ffa653c --- /dev/null +++ b/contracts/docs/api/messageService/lib/TimeLock.md @@ -0,0 +1,12 @@ +# Solidity API + +## TimeLock + +This timelock contract will be the owner of all upgrades that gives users confidence and an ability to exit should they want to before an upgrade takes place + +### constructor + +```solidity +constructor(uint256 minDelay, address[] proposers, address[] executors, address admin) public +``` + diff --git a/contracts/docs/api/messageService/lib/TransientStorageHelpers.md b/contracts/docs/api/messageService/lib/TransientStorageHelpers.md new file mode 100644 index 00000000..889b9203 --- /dev/null +++ b/contracts/docs/api/messageService/lib/TransientStorageHelpers.md @@ -0,0 +1,74 @@ +# Solidity API + +## TransientStorageHelpers + +### tstoreUint256 + +```solidity +function tstoreUint256(bytes32 _key, uint256 _value) internal +``` + +Internal function that stores a uint256 value at a given key in the EVM's transient storage using the `tstore` opcode. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _key | bytes32 | The key in the EVM transient storage where the value should be stored. | +| _value | uint256 | The uint256 value to be stored at the specified key in the EVM transient storage. | + +### tloadUint256 + +```solidity +function tloadUint256(bytes32 _key) internal view returns (uint256 value) +``` + +Internal function that retrieves a uint256 value from the EVM's transient storage using the `tload` opcode. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _key | bytes32 | The key in the EVM transient storage from which the value should be retrieved. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| value | uint256 | The uint256 value retrieved from the specified key in the EVM transient storage. | + +### tstoreAddress + +```solidity +function tstoreAddress(bytes32 _key, address _addr) internal +``` + +Internal function that stores an address at a given key in the EVM's transient storage using the `tstore` opcode. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _key | bytes32 | The key in the EVM transient storage where the value should be stored. | +| _addr | address | The address to be stored at the specified key in the EVM transient storage. | + +### tloadAddress + +```solidity +function tloadAddress(bytes32 _key) internal view returns (address addr) +``` + +Internal function that retrieves an address from the EVM's transient storage using the `tload` opcode. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _key | bytes32 | The key in the EVM transient storage from which the value should be retrieved. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| addr | address | The address retrieved from the specified key in the EVM transient storage. | + diff --git a/contracts/docs/api/tokenBridge/BridgedToken.md b/contracts/docs/api/tokenBridge/BridgedToken.md new file mode 100644 index 00000000..44c01bc6 --- /dev/null +++ b/contracts/docs/api/tokenBridge/BridgedToken.md @@ -0,0 +1,91 @@ +# Solidity API + +## BridgedToken + +ERC20 token created when a native token is bridged to a target chain. + +### bridge + +```solidity +address bridge +``` + +### _decimals + +```solidity +uint8 _decimals +``` + +### OnlyBridge + +```solidity +error OnlyBridge(address bridgeAddress) +``` + +### constructor + +```solidity +constructor() public +``` + +_Disable constructor for safety_ + +### initialize + +```solidity +function initialize(string _tokenName, string _tokenSymbol, uint8 _tokenDecimals) external +``` + +### onlyBridge + +```solidity +modifier onlyBridge() +``` + +_Ensures call come from the bridge._ + +### mint + +```solidity +function mint(address _recipient, uint256 _amount) external +``` + +_Called by the bridge to mint tokens during a bridge transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _recipient | address | The address to receive the minted tokens. | +| _amount | uint256 | The amount of tokens to mint. | + +### burn + +```solidity +function burn(address _account, uint256 _amount) external +``` + +_Called by the bridge to burn tokens during a bridge transaction. +User should first have allowed the bridge to spend tokens on their behalf._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _account | address | The account from which tokens will be burned. | +| _amount | uint256 | The amount of tokens to burn. | + +### decimals + +```solidity +function decimals() public view returns (uint8) +``` + +_Overrides ERC20 default function to support tokens with different decimals._ + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint8 | The number of decimal. | + diff --git a/contracts/docs/api/tokenBridge/CustomBridgedToken.md b/contracts/docs/api/tokenBridge/CustomBridgedToken.md new file mode 100644 index 00000000..eeee0896 --- /dev/null +++ b/contracts/docs/api/tokenBridge/CustomBridgedToken.md @@ -0,0 +1,12 @@ +# Solidity API + +## CustomBridgedToken + +Custom ERC20 token manually deployed for the Linea TokenBridge. + +### initializeV2 + +```solidity +function initializeV2(string _tokenName, string _tokenSymbol, uint8 _tokenDecimals, address _bridge) public +``` + diff --git a/contracts/docs/api/tokenBridge/TokenBridge.md b/contracts/docs/api/tokenBridge/TokenBridge.md new file mode 100644 index 00000000..f4baeb46 --- /dev/null +++ b/contracts/docs/api/tokenBridge/TokenBridge.md @@ -0,0 +1,525 @@ +# Solidity API + +## TokenBridge + +Contract to manage cross-chain ERC20 bridging. + +### CONTRACT_VERSION + +```solidity +string CONTRACT_VERSION +``` + +_This is the ABI version and not the reinitialize version._ + +### SET_MESSAGE_SERVICE_ROLE + +```solidity +bytes32 SET_MESSAGE_SERVICE_ROLE +``` + +Role used for setting the message service address. + +### SET_REMOTE_TOKENBRIDGE_ROLE + +```solidity +bytes32 SET_REMOTE_TOKENBRIDGE_ROLE +``` + +Role used for setting the remote token bridge address. + +### SET_RESERVED_TOKEN_ROLE + +```solidity +bytes32 SET_RESERVED_TOKEN_ROLE +``` + +Role used for setting a reserved token address. + +### REMOVE_RESERVED_TOKEN_ROLE + +```solidity +bytes32 REMOVE_RESERVED_TOKEN_ROLE +``` + +Role used for removing a reserved token address. + +### SET_CUSTOM_CONTRACT_ROLE + +```solidity +bytes32 SET_CUSTOM_CONTRACT_ROLE +``` + +Role used for setting a custom token contract address. + +### EMPTY + +```solidity +address EMPTY +``` + +EMPTY means a token is not present in the mapping. + +### RESERVED_STATUS + +```solidity +address RESERVED_STATUS +``` + +RESERVED means a token is reserved and cannot be bridged. + +### NATIVE_STATUS + +```solidity +address NATIVE_STATUS +``` + +NATIVE means a token is native to the current local chain. + +### DEPLOYED_STATUS + +```solidity +address DEPLOYED_STATUS +``` + +DEPLOYED means the bridged token contract has been deployed on the remote chain. + +### _PERMIT_SELECTOR + +```solidity +bytes4 _PERMIT_SELECTOR +``` + +_The permit selector to be used when decoding the permit._ + +### tokenBeacon + +```solidity +address tokenBeacon +``` + +The token beacon for deployed tokens. + +### nativeToBridgedToken + +```solidity +mapping(uint256 => mapping(address => address)) nativeToBridgedToken +``` + +The chainId mapped to a native token address which is then mapped to the bridged token address. + +### bridgedToNativeToken + +```solidity +mapping(address => address) bridgedToNativeToken +``` + +The bridged token address mapped to the native token address. + +### sourceChainId + +```solidity +uint256 sourceChainId +``` + +The current layer's chainId from where the bridging is triggered. + +### targetChainId + +```solidity +uint256 targetChainId +``` + +The targeted layer's chainId where the bridging is received. + +### isNewToken + +```solidity +modifier isNewToken(address _token) +``` + +_Ensures the token has not been bridged before._ + +### nonZeroAddress + +```solidity +modifier nonZeroAddress(address _addr) +``` + +_Ensures the address is not address(0)._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _addr | address | Address to check. | + +### nonZeroAmount + +```solidity +modifier nonZeroAmount(uint256 _amount) +``` + +_Ensures the amount is not 0._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _amount | uint256 | amount to check. | + +### constructor + +```solidity +constructor() public +``` + +_Disable constructor for safety_ + +### initialize + +```solidity +function initialize(struct ITokenBridge.InitializationData _initializationData) external +``` + +Initializes TokenBridge and underlying service dependencies - used for new networks only. + +_Contract will be used as proxy implementation._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _initializationData | struct ITokenBridge.InitializationData | The initial data used for initializing the TokenBridge contract. | + +### reinitializePauseTypesAndPermissions + +```solidity +function reinitializePauseTypesAndPermissions(address _defaultAdmin, struct IPermissionsManager.RoleAddress[] _roleAddresses, struct IPauseManager.PauseTypeRole[] _pauseTypeRoles, struct IPauseManager.PauseTypeRole[] _unpauseTypeRoles) external +``` + +Sets permissions for a list of addresses and their roles as well as initialises the PauseManager pauseType:role mappings. + +_This function is a reinitializer and can only be called once per version. Should be called using an upgradeAndCall transaction to the ProxyAdmin._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _defaultAdmin | address | The default admin account's address. | +| _roleAddresses | struct IPermissionsManager.RoleAddress[] | The list of addresses and roles to assign permissions to. | +| _pauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of pause types to associate with roles. | +| _unpauseTypeRoles | struct IPauseManager.PauseTypeRole[] | The list of unpause types to associate with roles. | + +### bridgeToken + +```solidity +function bridgeToken(address _token, uint256 _amount, address _recipient) public payable +``` + +This function is the single entry point to bridge tokens to the + other chain, both for native and already bridged tokens. You can use it + to bridge any ERC20. If the token is bridged for the first time an ERC20 + (BridgedToken.sol) will be automatically deployed on the target chain. + +_User should first allow the bridge to transfer tokens on his behalf. + Alternatively, you can use BridgeTokenWithPermit to do so in a single + transaction. If you want the transfer to be automatically executed on the + destination chain. You should send enough ETH to pay the postman fees. + Note that Linea can reserve some tokens (which use a dedicated bridge). + In this case, the token cannot be bridged. Linea can only reserve tokens + that have not been bridged yet. + Linea can pause the bridge for security reason. In this case new bridge + transaction would revert. +Note: If, when bridging an unbridged token and decimals are unknown, +the call will revert to prevent mismatched decimals. Only those ERC20s, +with a decimals function are supported._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be bridged. | +| _amount | uint256 | The amount of the token to be bridged. | +| _recipient | address | The address that will receive the tokens on the other chain. | + +### bridgeTokenWithPermit + +```solidity +function bridgeTokenWithPermit(address _token, uint256 _amount, address _recipient, bytes _permitData) external payable +``` + +Similar to `bridgeToken` function but allows to pass additional + permit data to do the ERC20 approval in a single transaction. +_permit can fail silently, don't rely on this function passing as a form + of authentication + +_There is no need for validation at this level as the validation on pausing, +and empty values exists on the "bridgeToken" call._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be bridged. | +| _amount | uint256 | The amount of the token to be bridged. | +| _recipient | address | The address that will receive the tokens on the other chain. | +| _permitData | bytes | The permit data for the token, if applicable. | + +### completeBridging + +```solidity +function completeBridging(address _nativeToken, uint256 _amount, address _recipient, uint256 _chainId, bytes _tokenMetadata) external +``` + +_It can only be called from the Message Service. To finalize the bridging + process, a user or postman needs to use the `claimMessage` function of the + Message Service to trigger the transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeToken | address | The address of the token on its native chain. | +| _amount | uint256 | The amount of the token to be received. | +| _recipient | address | The address that will receive the tokens. | +| _chainId | uint256 | The token's origin layer chaindId | +| _tokenMetadata | bytes | Additional data used to deploy the bridged token if it doesn't exist already. | + +### setMessageService + +```solidity +function setMessageService(address _messageService) external +``` + +_Change the address of the Message Service. +SET_MESSAGE_SERVICE_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageService | address | The address of the new Message Service. | + +### confirmDeployment + +```solidity +function confirmDeployment(address[] _tokens) external payable +``` + +_Change the status to DEPLOYED to the tokens passed in parameter + Will call the method setDeployed on the other chain using the message Service_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _tokens | address[] | Array of bridged tokens that have been deployed. | + +### setDeployed + +```solidity +function setDeployed(address[] _nativeTokens) external +``` + +_Change the status of tokens to DEPLOYED. New bridge transaction will not + contain token metadata, which save gas. + Can only be called from the Message Service. A user or postman needs to use + the `claimMessage` function of the Message Service to trigger the transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeTokens | address[] | Array of native tokens for which the DEPLOYED status must be set. | + +### setRemoteTokenBridge + +```solidity +function setRemoteTokenBridge(address _remoteTokenBridge) external +``` + +_Sets the address of the remote token bridge. Can only be called once. +SET_REMOTE_TOKENBRIDGE_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _remoteTokenBridge | address | The address of the remote token bridge to be set. | + +### deployBridgedToken + +```solidity +function deployBridgedToken(address _nativeToken, bytes _tokenMetadata, uint256 _chainId) internal returns (address bridgedTokenAddress) +``` + +_Deploy a new EC20 contract for bridged token using a beacon proxy pattern. + To adapt to future requirements, Linea can update the implementation of + all (existing and future) contracts by updating the beacon. This update is + subject to a delay by a time lock. + Contracts are deployed using CREATE2 so deployment address is deterministic._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeToken | address | The address of the native token on the source chain. | +| _tokenMetadata | bytes | The encoded metadata for the token. | +| _chainId | uint256 | The chain id on which the token will be deployed, used to calculate the salt | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| bridgedTokenAddress | address | The address of the newly deployed BridgedToken contract. | + +### setReserved + +```solidity +function setReserved(address _token) external +``` + +Make sure that _token is native to the current chain + where you are calling this function from + +_Linea can reserve tokens. In this case, the token cannot be bridged. + Linea can only reserve tokens that have not been bridged before. +SET_RESERVED_TOKEN_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be set as reserved. | + +### removeReserved + +```solidity +function removeReserved(address _token) external +``` + +_Removes a token from the reserved list. +REMOVE_RESERVED_TOKEN_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be removed from the reserved list. | + +### setCustomContract + +```solidity +function setCustomContract(address _nativeToken, address _targetContract) external +``` + +_Linea can set a custom ERC20 contract for specific ERC20. + For security purpose, Linea can only call this function if the token has + not been bridged yet. +SET_CUSTOM_CONTRACT_ROLE is required to execute._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeToken | address | The address of the token on the source chain. | +| _targetContract | address | The address of the custom contract. | + +### _safeName + +```solidity +function _safeName(address _token) internal view returns (string tokenName) +``` + +_Provides a safe ERC20.name version which returns 'NO_NAME' as fallback string._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the ERC-20 token contract | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokenName | string | Returns the string of the token name. | + +### _safeSymbol + +```solidity +function _safeSymbol(address _token) internal view returns (string symbol) +``` + +_Provides a safe ERC20.symbol version which returns 'NO_SYMBOL' as fallback string_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the ERC-20 token contract | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| symbol | string | Returns the string of the symbol. | + +### _safeDecimals + +```solidity +function _safeDecimals(address _token) internal view returns (uint8) +``` + +Provides a safe ERC20.decimals version which reverts when decimals are unknown + Note Tokens with (decimals > 255) are not supported + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the ERC-20 token contract | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| [0] | uint8 | Returns the token's decimals value. | + +### _returnDataToString + +```solidity +function _returnDataToString(bytes _data) internal pure returns (string decodedString) +``` + +_Converts returned data to string. Returns 'NOT_VALID_ENCODING' as fallback value._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _data | bytes | returned data. | + +#### Return Values + +| Name | Type | Description | +| ---- | ---- | ----------- | +| decodedString | string | The decoded string data. | + +### _permit + +```solidity +function _permit(address _token, bytes _permitData) internal +``` + +Call the token permit method of extended ERC20 +Only support tokens implementing ERC-2612 + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | ERC20 token address | +| _permitData | bytes | Raw data of the call `permit` of the token | + diff --git a/contracts/docs/api/tokenBridge/interfaces/ITokenBridge.md b/contracts/docs/api/tokenBridge/interfaces/ITokenBridge.md new file mode 100644 index 00000000..2817d38f --- /dev/null +++ b/contracts/docs/api/tokenBridge/interfaces/ITokenBridge.md @@ -0,0 +1,488 @@ +# Solidity API + +## ITokenBridge + +### InitializationData + +```solidity +struct InitializationData { + address defaultAdmin; + address messageService; + address tokenBeacon; + uint256 sourceChainId; + uint256 targetChainId; + address[] reservedTokens; + struct IPermissionsManager.RoleAddress[] roleAddresses; + struct IPauseManager.PauseTypeRole[] pauseTypeRoles; + struct IPauseManager.PauseTypeRole[] unpauseTypeRoles; +} +``` + +### TokenReserved + +```solidity +event TokenReserved(address token) +``` + +Emitted when the token address is reserved. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| token | address | The indexed token address. | + +### ReservationRemoved + +```solidity +event ReservationRemoved(address token) +``` + +Emitted when the token address reservation is removed. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| token | address | The indexed token address. | + +### CustomContractSet + +```solidity +event CustomContractSet(address nativeToken, address customContract, address setBy) +``` + +Emitted when the custom token address is set. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| nativeToken | address | The indexed nativeToken token address. | +| customContract | address | The indexed custom contract address. | +| setBy | address | The indexed address of who set the custom contract. | + +### BridgingInitiated + +```solidity +event BridgingInitiated(address sender, address recipient, address token, uint256 amount) +``` + +Emitted when token bridging is initiated. + +_DEPRECATED in favor of BridgingInitiatedV2._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| sender | address | The indexed sender address. | +| recipient | address | The recipient address. | +| token | address | The indexed token address. | +| amount | uint256 | The indexed token amount. | + +### BridgingInitiatedV2 + +```solidity +event BridgingInitiatedV2(address sender, address recipient, address token, uint256 amount) +``` + +Emitted when token bridging is initiated. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| sender | address | The indexed sender address. | +| recipient | address | The indexed recipient address. | +| token | address | The indexed token address. | +| amount | uint256 | The token amount. | + +### BridgingFinalized + +```solidity +event BridgingFinalized(address nativeToken, address bridgedToken, uint256 amount, address recipient) +``` + +Emitted when token bridging is finalized. + +_DEPRECATED in favor of BridgingFinalizedV2._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| nativeToken | address | The indexed native token address. | +| bridgedToken | address | The indexed bridged token address. | +| amount | uint256 | The indexed token amount. | +| recipient | address | The recipient address. | + +### BridgingFinalizedV2 + +```solidity +event BridgingFinalizedV2(address nativeToken, address bridgedToken, uint256 amount, address recipient) +``` + +Emitted when token bridging is finalized. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| nativeToken | address | The indexed native token address. | +| bridgedToken | address | The indexed bridged token address. | +| amount | uint256 | The token amount. | +| recipient | address | The indexed recipient address. | + +### NewToken + +```solidity +event NewToken(address token) +``` + +Emitted when a new token is seen being bridged on the origin chain for the first time. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| token | address | The indexed token address. | + +### NewTokenDeployed + +```solidity +event NewTokenDeployed(address bridgedToken, address nativeToken) +``` + +Emitted when a new token is deployed. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| bridgedToken | address | The indexed bridged token address. | +| nativeToken | address | The indexed native token address. | + +### RemoteTokenBridgeSet + +```solidity +event RemoteTokenBridgeSet(address remoteTokenBridge, address setBy) +``` + +Emitted when the remote token bridge is set. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| remoteTokenBridge | address | The indexed remote token bridge address. | +| setBy | address | The indexed address that set the remote token bridge. | + +### TokenDeployed + +```solidity +event TokenDeployed(address token) +``` + +Emitted when the token is set as deployed. + +_This can be triggered by anyone calling confirmDeployment on the alternate chain._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| token | address | The indexed token address. | + +### DeploymentConfirmed + +```solidity +event DeploymentConfirmed(address[] tokens, address confirmedBy) +``` + +Emitted when the token deployment is confirmed. + +_This can be triggered by anyone provided there is correctly mapped token data._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| tokens | address[] | The token address list. | +| confirmedBy | address | The indexed address confirming deployment. | + +### MessageServiceUpdated + +```solidity +event MessageServiceUpdated(address newMessageService, address oldMessageService, address setBy) +``` + +Emitted when the message service address is set. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| newMessageService | address | The indexed new message service address. | +| oldMessageService | address | The indexed old message service address. | +| setBy | address | The indexed address setting the new message service address. | + +### ReservedToken + +```solidity +error ReservedToken(address token) +``` + +_Thrown when attempting to bridge a reserved token._ + +### RemoteTokenBridgeAlreadySet + +```solidity +error RemoteTokenBridgeAlreadySet(address remoteTokenBridge) +``` + +_Thrown when the remote token bridge is already set._ + +### AlreadyBridgedToken + +```solidity +error AlreadyBridgedToken(address token) +``` + +_Thrown when attempting to reserve an already bridged token._ + +### InvalidPermitData + +```solidity +error InvalidPermitData(bytes4 permitData, bytes4 permitSelector) +``` + +_Thrown when the permit data is invalid._ + +### PermitNotFromSender + +```solidity +error PermitNotFromSender(address owner) +``` + +_Thrown when the permit is not from the sender._ + +### PermitNotAllowingBridge + +```solidity +error PermitNotAllowingBridge(address spender) +``` + +_Thrown when the permit does not grant spending to the bridge._ + +### ZeroAmountNotAllowed + +```solidity +error ZeroAmountNotAllowed(uint256 amount) +``` + +_Thrown when the amount being bridged is zero._ + +### NotReserved + +```solidity +error NotReserved(address token) +``` + +_Thrown when trying to unreserve a non-reserved token._ + +### TokenNotDeployed + +```solidity +error TokenNotDeployed(address token) +``` + +_Thrown when trying to confirm deployment of a non-deployed token._ + +### AlreadyBrigedToNativeTokenSet + +```solidity +error AlreadyBrigedToNativeTokenSet(address token) +``` + +_Thrown when trying to set a custom contract on a bridged token._ + +### NativeToBridgedTokenAlreadySet + +```solidity +error NativeToBridgedTokenAlreadySet(address token) +``` + +_Thrown when trying to set a custom contract on an already set token._ + +### StatusAddressNotAllowed + +```solidity +error StatusAddressNotAllowed(address token) +``` + +_Thrown when trying to set a token that is already either native, deployed or reserved._ + +### DecimalsAreUnknown + +```solidity +error DecimalsAreUnknown(address token) +``` + +_Thrown when the decimals for a token cannot be determined._ + +### TokenListEmpty + +```solidity +error TokenListEmpty() +``` + +_Thrown when the token list is empty._ + +### bridgeTokenWithPermit + +```solidity +function bridgeTokenWithPermit(address _token, uint256 _amount, address _recipient, bytes _permitData) external payable +``` + +Similar to `bridgeToken` function but allows to pass additional + permit data to do the ERC20 approval in a single transaction. + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be bridged. | +| _amount | uint256 | The amount of the token to be bridged. | +| _recipient | address | The address that will receive the tokens on the other chain. | +| _permitData | bytes | The permit data for the token, if applicable. | + +### completeBridging + +```solidity +function completeBridging(address _nativeToken, uint256 _amount, address _recipient, uint256 _chainId, bytes _tokenMetadata) external +``` + +_It can only be called from the Message Service. To finalize the bridging + process, a user or postmen needs to use the `claimMessage` function of the + Message Service to trigger the transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeToken | address | The address of the token on its native chain. | +| _amount | uint256 | The amount of the token to be received. | +| _recipient | address | The address that will receive the tokens. | +| _chainId | uint256 | The source chainId or target chaindId for this token | +| _tokenMetadata | bytes | Additional data used to deploy the bridged token if it doesn't exist already. | + +### confirmDeployment + +```solidity +function confirmDeployment(address[] _tokens) external payable +``` + +_Change the status to DEPLOYED to the tokens passed in parameter + Will call the method setDeployed on the other chain using the message Service_ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _tokens | address[] | Array of bridged tokens that have been deployed. | + +### setMessageService + +```solidity +function setMessageService(address _messageService) external +``` + +_Change the address of the Message Service._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _messageService | address | The address of the new Message Service. | + +### setDeployed + +```solidity +function setDeployed(address[] _nativeTokens) external +``` + +_It can only be called from the Message Service. To change the status of + the native tokens to DEPLOYED meaning they have been deployed on the other chain + a user or postman needs to use the `claimMessage` function of the + Message Service to trigger the transaction._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeTokens | address[] | The addresses of the native tokens. | + +### setReserved + +```solidity +function setReserved(address _token) external +``` + +Make sure that _token is native to the current chain + where you are calling this function from + +_Linea can reserve tokens. In this case, the token cannot be bridged. + Linea can only reserve tokens that have not been bridged before._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be set as reserved. | + +### setRemoteTokenBridge + +```solidity +function setRemoteTokenBridge(address _remoteTokenBridge) external +``` + +_Sets the address of the remote token bridge. Can only be called once._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _remoteTokenBridge | address | The address of the remote token bridge to be set. | + +### removeReserved + +```solidity +function removeReserved(address _token) external +``` + +_Removes a token from the reserved list._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _token | address | The address of the token to be removed from the reserved list. | + +### setCustomContract + +```solidity +function setCustomContract(address _nativeToken, address _targetContract) external +``` + +_Linea can set a custom ERC20 contract for specific ERC20. + For security purpose, Linea can only call this function if the token has + not been bridged yet._ + +#### Parameters + +| Name | Type | Description | +| ---- | ---- | ----------- | +| _nativeToken | address | address of the token on the source chain. | +| _targetContract | address | address of the custom contract. | + diff --git a/contracts/docs/api/tokenBridge/lib/StorageFiller39.md b/contracts/docs/api/tokenBridge/lib/StorageFiller39.md new file mode 100644 index 00000000..ccee22b8 --- /dev/null +++ b/contracts/docs/api/tokenBridge/lib/StorageFiller39.md @@ -0,0 +1,4 @@ +# Solidity API + +## StorageFiller39 + diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 524e03a3..ed4aa4c9 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -12,6 +12,7 @@ import "./scripts/operational/renounceContractRolesTask"; import "./scripts/operational/setRateLimitTask"; import "./scripts/operational/setVerifierAddressTask"; import "./scripts/operational/transferOwnershipAndSetRemoteTokenBridgeTask"; +import "solidity-docgen"; dotenv.config(); @@ -149,6 +150,11 @@ const config: HardhatUserConfig = { }, ], }, + docgen: { + exclude: ["token", "test-contracts", "proxies", "tools", "interfaces/tools", "tokenBridge/mocks", "verifiers"], + pages: "files", + outputDir: "docs/api/", + }, }; export default config; diff --git a/contracts/local-deployments-artifacts/dynamic-artifacts/L2MessageService.json b/contracts/local-deployments-artifacts/dynamic-artifacts/L2MessageService.json index 5df84c51..ab2a2605 100644 --- a/contracts/local-deployments-artifacts/dynamic-artifacts/L2MessageService.json +++ b/contracts/local-deployments-artifacts/dynamic-artifacts/L2MessageService.json @@ -317,13 +317,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "pauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -487,13 +487,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "unPauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -979,7 +979,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "pauseTypeIsPaused", "type": "bool" } ], @@ -1246,7 +1246,7 @@ "outputs": [ { "internalType": "address", - "name": "", + "name": "originalSender", "type": "address" } ], @@ -1299,8 +1299,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b506200001c6200002c565b620000266200002c565b620000ed565b600054610100900460ff1615620000995760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000eb576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61319180620000fd6000396000f3fe6080604052600436106102dc5760003560e01c80638994588311610184578063b9174ba3116100d6578063c1dc0f071161008a578063d547741f11610064578063d547741f14610913578063e196fb5d14610933578063f866aa131461095357600080fd5b8063c1dc0f0714610899578063cc5782f6146108af578063cc6f7251146108df57600080fd5b8063bcbd6fcd116100bb578063bcbd6fcd1461081b578063bf3e75051461084f578063c0729ab11461088357600080fd5b8063b9174ba3146107c7578063bc61e733146107fb57600080fd5b80639ac25d0811610138578063ad422ff011610112578063ad422ff014610785578063aea4f7451461079b578063b837dbe9146107b057600080fd5b80639ac25d08146107295780639f3ce55a1461075d578063a217fddf1461077057600080fd5b806391d148541161016957806391d14854146106aa57806391f7b901146106fd5780639340a1d11461071257600080fd5b8063899458831461065f5780638de494871461067657600080fd5b806348922ab71161023d57806367e404ce116101f157806374377a34116101cb57806374377a34146105e85780637d1e8c551461061c5780637fe335d31461063157600080fd5b806367e404ce1461055e578063687a6fe0146105945780636a906b80146105b457600080fd5b80635230eef2116102225780635230eef2146104f4578063557eac7314610528578063587944561461054857600080fd5b806348922ab7146104ad578063491e0936146104d457600080fd5b80632f2ff15d1161029457806338b903331161027957806338b90333146104035780633b12eccb146104595780633c3621461461048d57600080fd5b80632f2ff15d146103c357806336568abe146103e357600080fd5b80631065a399116102c55780631065a39914610351578063182a750614610373578063248a9ca31461039357600080fd5b806301ffc9a7146102e15780630f6893ca14610316575b600080fd5b3480156102ed57600080fd5b506103016102fc366004612985565b610973565b60405190151581526020015b60405180910390f35b34801561032257600080fd5b506103436103313660046129c7565b60b06020526000908152604090205481565b60405190815260200161030d565b34801561035d57600080fd5b5061037161036c3660046129e0565b610a0c565b005b34801561037f57600080fd5b5061037161038e3660046129c7565b610b17565b34801561039f57600080fd5b506103436103ae3660046129c7565b60009081526065602052604090206001015490565b3480156103cf57600080fd5b506103716103de366004612a23565b610b8a565b3480156103ef57600080fd5b506103716103fe366004612a23565b610bb4565b34801561040f57600080fd5b5061044c6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405161030d9190612a77565b34801561046557600080fd5b506103437fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b34801561049957600080fd5b506103716104a8366004612ac8565b610c67565b3480156104b957600080fd5b506104c2600181565b60405160ff909116815260200161030d565b3480156104e057600080fd5b506103716104ef366004612b9c565b610f64565b34801561050057600080fd5b506103437f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b34801561053457600080fd5b506103716105433660046129c7565b61126d565b34801561055457600080fd5b5061034360995481565b34801561056a57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b3480156105a057600080fd5b506103716105af366004612c77565b611335565b3480156105c057600080fd5b506103437fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b3480156105f457600080fd5b506103437f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b34801561062857600080fd5b506104c2600081565b34801561063d57600080fd5b5061034361064c3660046129c7565b6101196020526000908152604090205481565b34801561066b57600080fd5b506103436101175481565b34801561068257600080fd5b506103437fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b3480156106b657600080fd5b506103016106c5366004612a23565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561070957600080fd5b506104c2600281565b34801561071e57600080fd5b506103436101185481565b34801561073557600080fd5b506103437f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b61037161076b366004612d39565b611553565b34801561077c57600080fd5b50610343600081565b34801561079157600080fd5b5061034360985481565b3480156107a757600080fd5b5061037161176e565b3480156107bc57600080fd5b506103436101165481565b3480156107d357600080fd5b506103437f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b34801561080757600080fd5b506103016108163660046129e0565b6117ca565b34801561082757600080fd5b506103437fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561085b57600080fd5b506103437f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b34801561088f57600080fd5b50610343609a5481565b3480156108a557600080fd5b5061034360975481565b3480156108bb57600080fd5b506103016108ca3660046129c7565b60a56020526000908152604090205460ff1681565b3480156108eb57600080fd5b506103437fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b34801561091f57600080fd5b5061037161092e366004612a23565b6117ef565b34801561093f57600080fd5b5061037161094e3660046129e0565b611814565b34801561095f57600080fd5b5061037161096e366004612d95565b6118ee565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a0657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60a86000826008811115610a2257610a22612e2f565b6008811115610a3357610a33612e2f565b815260200190815260200160002054610a4b81611a4a565b610a54826117ca565b610a9557816040517f18659654000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b60405180910390fd5b816008811115610aa757610aa7612e2f565b60a68054600190921b199091169055816008811115610ac857610ac8612e2f565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba2610b4181611a4a565b610117805490839055604080518281526020810185905233917f6d8040017e56a6d91bb242def14af5d7eae1eaff7475e45c678dac5d49d35498910160405180910390a2505050565b600082815260656020526040902060010154610ba581611a4a565b610baf8383611a57565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a8c565b610c638282611b4b565b5050565b6001610c7281611c06565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd67415610c9c81611a4a565b856000819003610cd8576040517f6446cc9c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6064811115610d16576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b6000849003610d51576040517f36a4bb9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101185480610d61600189612ed6565b14610dae57610d71600188612ed6565b6040517fd39e75f9000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610a8c565b6000818152610119602052604081205490805b84811015610e46578b8b82818110610ddb57610ddb612ee9565b905060200201359150600060ff1660b060008481526020019081526020016000205403610e3657600082815260b06020526040902060019055610e28838360009182526020526040902090565b9250610e3384612f18565b93505b610e3f81612f18565b9050610dc1565b50878314610e8a576040517fd39e75f90000000000000000000000000000000000000000000000000000000081526004810189905260248101849052604401610a8c565b818714610ecd576040517f7557a60a0000000000000000000000000000000000000000000000000000000081526004810188905260248101839052604401610a8c565b610118548314610f57576101188390556000838152610119602052604090819020839055517f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb90610f21908d908d90612f50565b60405180910390a1604051829084907f99b65a4301b38c09fb6a5f27052d73e8372bbe8f6779d678bfe8a41b66cce7ac90600090a35b5050505050505050505050565b610f6c611c48565b858784848760005a9050610f806002611cbb565b6000610f918f8f8f8f8c8f8f611d4d565b9050610f9c81611da8565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051611009929190612fa2565b60006040518083038185875af1925050503d8060008114611046576040519150601f19603f3d011682016040523d82523d6000602084013e61104b565b606091505b5091509150816110b5578051156110655780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610a8c919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a25050861590506112535785600084900361119f57853b15801561119d573a5a61113a61ae3486612fb2565b6111449190612ed6565b61114e9190612fc5565b9150818811156111995773ffffffffffffffffffffffffffffffffffffffff87166108fc61117c848b612ed6565b6040518115909202916000818181858888f193505050505061119d565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff8416156111c357836111c5565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505090508061124f576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610a8c565b5050505b505050505050611263600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261129781611a4a565b60008060004260995410156112be576097546112b39042612fb2565b6099555060016112d0565b609a548510156112d057849250600191505b609885905580806112de5750815b156112e957609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b600054610100900460ff16158080156113555750600054600160ff909116105b8061136f5750303b15801561136f575060005460ff166001145b6113fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561145957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b611461611e0e565b611469611e0e565b611471611e0e565b61147b8a8a611ea7565b611483612017565b61148f858585856120b6565b61149a600089611a57565b6114a48787612380565b60016101165561011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055655af3107a400061011755801561154757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61155d6003611cbb565b73ffffffffffffffffffffffffffffffffffffffff84166115aa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348311156115e4576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015611622576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061162f8387612ed6565b915061163b8634612ed6565b6101168054919250600091908261165183612f18565b9091555090506116696116648484612fb2565b612555565b600061167a338a8686868c8c611d4d565b9050808973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8787878d8d6040516116e2959493929190612fdc565b60405180910390a4604051600090419087908381818185875af1925050503d806000811461172c576040519150601f19603f3d011682016040523d82523d6000602084013e611731565b606091505b5050905080611547576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610a8c565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf961179881611a4a565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b60008160088111156117de576117de612e2f565b60a654600190911b16151592915050565b60008281526065602052604090206001015461180a81611a4a565b610baf8383611b4b565b60a7600082600881111561182a5761182a612e2f565b600881111561183b5761183b612e2f565b81526020019081526020016000205461185381611a4a565b61185c826117ca565b1561189557816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b8160088111156118a7576118a7612e2f565b60a68054600190921b90911790558160088111156118c7576118c7612e2f565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933610aeb565b600054600690610100900460ff16158015611910575060005460ff8083169116105b61199c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556119d78787612380565b6119e3858585856120b6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b611a5481336125cb565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c6357600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611aed3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c6357600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b611c0f816117ca565b15611a5457806040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b600260b15403611cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a8c565b600260b155565b60a654816008811115611cd057611cd0612e2f565b6001901b811615611d0f57816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b6002811615610c635760016040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b600060405188815287602082015286604082015285606082015284608082015260c060a08201528260c08201526020830660008115611d8d578160200390505b848660e085013790930160e001902098975050505050505050565b600081815260b06020526040902054600114611df3576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b600090815260b06020526040902060029055565b600160b155565b600054610100900460ff16611ea5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b565b600054610100900460ff16611f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b81600003611f78576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611fb2576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611fc68242612fb2565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b600054610100900460ff166120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b611ea5612685565b600054610100900460ff1661214d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b8260005b818110156122615785858281811061216b5761216b612ee9565b9050604002016020013560a7600088888581811061218b5761218b612ee9565b6121a192602060409092020190810191506129e0565b60088111156121b2576121b2612e2f565b60088111156121c3576121c3612e2f565b81526020810191909152604001600020557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609186868381811061220757612207612ee9565b61221d92602060409092020190810191506129e0565b87878481811061222f5761222f612ee9565b9050604002016020013560405161224792919061303e565b60405180910390a18061225981612f18565b915050612151565b5081905060005b818110156123785783838281811061228257612282612ee9565b9050604002016020013560a860008686858181106122a2576122a2612ee9565b6122b892602060409092020190810191506129e0565b60088111156122c9576122c9612e2f565b60088111156122da576122da612e2f565b81526020810191909152604001600020557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c284848381811061231e5761231e612ee9565b61233492602060409092020190810191506129e0565b85858481811061234657612346612ee9565b9050604002016020013560405161235e92919061303e565b60405180910390a18061237081612f18565b915050612268565b505050505050565b600054610100900460ff16612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b8060005b8181101561254f57600084848381811061243757612437612ee9565b61244d9260206040909202019081019150613059565b73ffffffffffffffffffffffffffffffffffffffff160361249a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383828181106124ac576124ac612ee9565b905060400201602001356000801b036124f1576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61253d84848381811061250657612506612ee9565b9050604002016020013585858481811061252257612522612ee9565b6125389260206040909202019081019150613059565b611a57565b8061254781612f18565b91505061241b565b50505050565b8015611a545742609954101561257a576097546125729042612fb2565b60995561258a565b609a546125879082612fb2565b90505b6098548111156125c6576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c635761260b8161271c565b61261683602061273b565b604051602001612627929190613076565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610a8c91600401612a77565b600054610100900460ff16611e07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b6060610a0673ffffffffffffffffffffffffffffffffffffffff831660145b6060600061274a836002612fc5565b612755906002612fb2565b67ffffffffffffffff81111561276d5761276d6130f7565b6040519080825280601f01601f191660200182016040528015612797576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106127ce576127ce612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061283157612831612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061286d846002612fc5565b612878906001612fb2565b90505b6001811115612915577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106128b9576128b9612ee9565b1a60f81b8282815181106128cf576128cf612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361290e81613126565b905061287b565b50831561297e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a8c565b9392505050565b60006020828403121561299757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461297e57600080fd5b6000602082840312156129d957600080fd5b5035919050565b6000602082840312156129f257600080fd5b81356009811061297e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611a5457600080fd5b60008060408385031215612a3657600080fd5b823591506020830135612a4881612a01565b809150509250929050565b60005b83811015612a6e578181015183820152602001612a56565b50506000910152565b6020815260008251806020840152612a96816040850160208701612a53565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600080600060808688031215612ae057600080fd5b853567ffffffffffffffff80821115612af857600080fd5b818801915088601f830112612b0c57600080fd5b813581811115612b1b57600080fd5b8960208260051b8501011115612b3057600080fd5b60209283019a909950918801359760408101359750606001359550909350505050565b60008083601f840112612b6557600080fd5b50813567ffffffffffffffff811115612b7d57600080fd5b602083019150836020828501011115612b9557600080fd5b9250929050565b60008060008060008060008060e0898b031215612bb857600080fd5b8835612bc381612a01565b97506020890135612bd381612a01565b965060408901359550606089013594506080890135612bf181612a01565b935060a089013567ffffffffffffffff811115612c0d57600080fd5b612c198b828c01612b53565b999c989b50969995989497949560c00135949350505050565b60008083601f840112612c4457600080fd5b50813567ffffffffffffffff811115612c5c57600080fd5b6020830191508360208260061b8501011115612b9557600080fd5b600080600080600080600080600060c08a8c031215612c9557600080fd5b8935985060208a0135975060408a0135612cae81612a01565b965060608a013567ffffffffffffffff80821115612ccb57600080fd5b612cd78d838e01612c32565b909850965060808c0135915080821115612cf057600080fd5b612cfc8d838e01612c32565b909650945060a08c0135915080821115612d1557600080fd5b50612d228c828d01612c32565b915080935050809150509295985092959850929598565b60008060008060608587031215612d4f57600080fd5b8435612d5a81612a01565b935060208501359250604085013567ffffffffffffffff811115612d7d57600080fd5b612d8987828801612b53565b95989497509550505050565b60008060008060008060608789031215612dae57600080fd5b863567ffffffffffffffff80821115612dc657600080fd5b612dd28a838b01612c32565b90985096506020890135915080821115612deb57600080fd5b612df78a838b01612c32565b90965094506040890135915080821115612e1057600080fd5b50612e1d89828a01612c32565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60098110612e95577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60208101610a068284612e5e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a0657610a06612ea7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612f4957612f49612ea7565b5060010190565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612f8957600080fd5b8260051b80856040850137919091016040019392505050565b8183823760009101908152919050565b80820180821115610a0657610a06612ea7565b8082028115828204841417610a0657610a06612ea7565b85815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101949350505050565b6040810161304c8285612e5e565b8260208301529392505050565b60006020828403121561306b57600080fd5b813561297e81612a01565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516130ae816017850160208801612a53565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516130eb816028840160208801612a53565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008161313557613135612ea7565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220470c39572685968d6ec85d8e7d7ed38ca849845528f9e12455980a8581d1854164736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106102dc5760003560e01c80638994588311610184578063b9174ba3116100d6578063c1dc0f071161008a578063d547741f11610064578063d547741f14610913578063e196fb5d14610933578063f866aa131461095357600080fd5b8063c1dc0f0714610899578063cc5782f6146108af578063cc6f7251146108df57600080fd5b8063bcbd6fcd116100bb578063bcbd6fcd1461081b578063bf3e75051461084f578063c0729ab11461088357600080fd5b8063b9174ba3146107c7578063bc61e733146107fb57600080fd5b80639ac25d0811610138578063ad422ff011610112578063ad422ff014610785578063aea4f7451461079b578063b837dbe9146107b057600080fd5b80639ac25d08146107295780639f3ce55a1461075d578063a217fddf1461077057600080fd5b806391d148541161016957806391d14854146106aa57806391f7b901146106fd5780639340a1d11461071257600080fd5b8063899458831461065f5780638de494871461067657600080fd5b806348922ab71161023d57806367e404ce116101f157806374377a34116101cb57806374377a34146105e85780637d1e8c551461061c5780637fe335d31461063157600080fd5b806367e404ce1461055e578063687a6fe0146105945780636a906b80146105b457600080fd5b80635230eef2116102225780635230eef2146104f4578063557eac7314610528578063587944561461054857600080fd5b806348922ab7146104ad578063491e0936146104d457600080fd5b80632f2ff15d1161029457806338b903331161027957806338b90333146104035780633b12eccb146104595780633c3621461461048d57600080fd5b80632f2ff15d146103c357806336568abe146103e357600080fd5b80631065a399116102c55780631065a39914610351578063182a750614610373578063248a9ca31461039357600080fd5b806301ffc9a7146102e15780630f6893ca14610316575b600080fd5b3480156102ed57600080fd5b506103016102fc366004612985565b610973565b60405190151581526020015b60405180910390f35b34801561032257600080fd5b506103436103313660046129c7565b60b06020526000908152604090205481565b60405190815260200161030d565b34801561035d57600080fd5b5061037161036c3660046129e0565b610a0c565b005b34801561037f57600080fd5b5061037161038e3660046129c7565b610b17565b34801561039f57600080fd5b506103436103ae3660046129c7565b60009081526065602052604090206001015490565b3480156103cf57600080fd5b506103716103de366004612a23565b610b8a565b3480156103ef57600080fd5b506103716103fe366004612a23565b610bb4565b34801561040f57600080fd5b5061044c6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405161030d9190612a77565b34801561046557600080fd5b506103437fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b34801561049957600080fd5b506103716104a8366004612ac8565b610c67565b3480156104b957600080fd5b506104c2600181565b60405160ff909116815260200161030d565b3480156104e057600080fd5b506103716104ef366004612b9c565b610f64565b34801561050057600080fd5b506103437f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b34801561053457600080fd5b506103716105433660046129c7565b61126d565b34801561055457600080fd5b5061034360995481565b34801561056a57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b3480156105a057600080fd5b506103716105af366004612c77565b611335565b3480156105c057600080fd5b506103437fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b3480156105f457600080fd5b506103437f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b34801561062857600080fd5b506104c2600081565b34801561063d57600080fd5b5061034361064c3660046129c7565b6101196020526000908152604090205481565b34801561066b57600080fd5b506103436101175481565b34801561068257600080fd5b506103437fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b3480156106b657600080fd5b506103016106c5366004612a23565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561070957600080fd5b506104c2600281565b34801561071e57600080fd5b506103436101185481565b34801561073557600080fd5b506103437f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b61037161076b366004612d39565b611553565b34801561077c57600080fd5b50610343600081565b34801561079157600080fd5b5061034360985481565b3480156107a757600080fd5b5061037161176e565b3480156107bc57600080fd5b506103436101165481565b3480156107d357600080fd5b506103437f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b34801561080757600080fd5b506103016108163660046129e0565b6117ca565b34801561082757600080fd5b506103437fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561085b57600080fd5b506103437f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b34801561088f57600080fd5b50610343609a5481565b3480156108a557600080fd5b5061034360975481565b3480156108bb57600080fd5b506103016108ca3660046129c7565b60a56020526000908152604090205460ff1681565b3480156108eb57600080fd5b506103437fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b34801561091f57600080fd5b5061037161092e366004612a23565b6117ef565b34801561093f57600080fd5b5061037161094e3660046129e0565b611814565b34801561095f57600080fd5b5061037161096e366004612d95565b6118ee565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a0657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60a86000826008811115610a2257610a22612e2f565b6008811115610a3357610a33612e2f565b815260200190815260200160002054610a4b81611a4a565b610a54826117ca565b610a9557816040517f18659654000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b60405180910390fd5b816008811115610aa757610aa7612e2f565b60a68054600190921b199091169055816008811115610ac857610ac8612e2f565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba2610b4181611a4a565b610117805490839055604080518281526020810185905233917f6d8040017e56a6d91bb242def14af5d7eae1eaff7475e45c678dac5d49d35498910160405180910390a2505050565b600082815260656020526040902060010154610ba581611a4a565b610baf8383611a57565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a8c565b610c638282611b4b565b5050565b6001610c7281611c06565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd67415610c9c81611a4a565b856000819003610cd8576040517f6446cc9c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6064811115610d16576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b6000849003610d51576040517f36a4bb9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101185480610d61600189612ed6565b14610dae57610d71600188612ed6565b6040517fd39e75f9000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610a8c565b6000818152610119602052604081205490805b84811015610e46578b8b82818110610ddb57610ddb612ee9565b905060200201359150600060ff1660b060008481526020019081526020016000205403610e3657600082815260b06020526040902060019055610e28838360009182526020526040902090565b9250610e3384612f18565b93505b610e3f81612f18565b9050610dc1565b50878314610e8a576040517fd39e75f90000000000000000000000000000000000000000000000000000000081526004810189905260248101849052604401610a8c565b818714610ecd576040517f7557a60a0000000000000000000000000000000000000000000000000000000081526004810188905260248101839052604401610a8c565b610118548314610f57576101188390556000838152610119602052604090819020839055517f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb90610f21908d908d90612f50565b60405180910390a1604051829084907f99b65a4301b38c09fb6a5f27052d73e8372bbe8f6779d678bfe8a41b66cce7ac90600090a35b5050505050505050505050565b610f6c611c48565b858784848760005a9050610f806002611cbb565b6000610f918f8f8f8f8c8f8f611d4d565b9050610f9c81611da8565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051611009929190612fa2565b60006040518083038185875af1925050503d8060008114611046576040519150601f19603f3d011682016040523d82523d6000602084013e61104b565b606091505b5091509150816110b5578051156110655780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610a8c919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a25050861590506112535785600084900361119f57853b15801561119d573a5a61113a61ae3486612fb2565b6111449190612ed6565b61114e9190612fc5565b9150818811156111995773ffffffffffffffffffffffffffffffffffffffff87166108fc61117c848b612ed6565b6040518115909202916000818181858888f193505050505061119d565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff8416156111c357836111c5565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505090508061124f576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610a8c565b5050505b505050505050611263600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261129781611a4a565b60008060004260995410156112be576097546112b39042612fb2565b6099555060016112d0565b609a548510156112d057849250600191505b609885905580806112de5750815b156112e957609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b600054610100900460ff16158080156113555750600054600160ff909116105b8061136f5750303b15801561136f575060005460ff166001145b6113fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561145957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b611461611e0e565b611469611e0e565b611471611e0e565b61147b8a8a611ea7565b611483612017565b61148f858585856120b6565b61149a600089611a57565b6114a48787612380565b60016101165561011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055655af3107a400061011755801561154757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b61155d6003611cbb565b73ffffffffffffffffffffffffffffffffffffffff84166115aa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348311156115e4576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015611622576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061162f8387612ed6565b915061163b8634612ed6565b6101168054919250600091908261165183612f18565b9091555090506116696116648484612fb2565b612555565b600061167a338a8686868c8c611d4d565b9050808973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8787878d8d6040516116e2959493929190612fdc565b60405180910390a4604051600090419087908381818185875af1925050503d806000811461172c576040519150601f19603f3d011682016040523d82523d6000602084013e611731565b606091505b5050905080611547576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610a8c565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf961179881611a4a565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b60008160088111156117de576117de612e2f565b60a654600190911b16151592915050565b60008281526065602052604090206001015461180a81611a4a565b610baf8383611b4b565b60a7600082600881111561182a5761182a612e2f565b600881111561183b5761183b612e2f565b81526020019081526020016000205461185381611a4a565b61185c826117ca565b1561189557816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b8160088111156118a7576118a7612e2f565b60a68054600190921b90911790558160088111156118c7576118c7612e2f565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933610aeb565b600054600690610100900460ff16158015611910575060005460ff8083169116105b61199c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556119d78787612380565b6119e3858585856120b6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b611a5481336125cb565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c6357600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611aed3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c6357600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b611c0f816117ca565b15611a5457806040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b600260b15403611cb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a8c565b600260b155565b60a654816008811115611cd057611cd0612e2f565b6001901b811615611d0f57816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b6002811615610c635760016040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612e99565b600060405188815287602082015286604082015285606082015284608082015260c060a08201528260c08201526020830660008115611d8d578160200390505b848660e085013790930160e001902098975050505050505050565b600081815260b06020526040902054600114611df3576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b600090815260b06020526040902060029055565b600160b155565b600054610100900460ff16611ea5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b565b600054610100900460ff16611f3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b81600003611f78576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611fb2576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611fc68242612fb2565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b600054610100900460ff166120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b611ea5612685565b600054610100900460ff1661214d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b8260005b818110156122615785858281811061216b5761216b612ee9565b9050604002016020013560a7600088888581811061218b5761218b612ee9565b6121a192602060409092020190810191506129e0565b60088111156121b2576121b2612e2f565b60088111156121c3576121c3612e2f565b81526020810191909152604001600020557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609186868381811061220757612207612ee9565b61221d92602060409092020190810191506129e0565b87878481811061222f5761222f612ee9565b9050604002016020013560405161224792919061303e565b60405180910390a18061225981612f18565b915050612151565b5081905060005b818110156123785783838281811061228257612282612ee9565b9050604002016020013560a860008686858181106122a2576122a2612ee9565b6122b892602060409092020190810191506129e0565b60088111156122c9576122c9612e2f565b60088111156122da576122da612e2f565b81526020810191909152604001600020557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c284848381811061231e5761231e612ee9565b61233492602060409092020190810191506129e0565b85858481811061234657612346612ee9565b9050604002016020013560405161235e92919061303e565b60405180910390a18061237081612f18565b915050612268565b505050505050565b600054610100900460ff16612417576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b8060005b8181101561254f57600084848381811061243757612437612ee9565b61244d9260206040909202019081019150613059565b73ffffffffffffffffffffffffffffffffffffffff160361249a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383828181106124ac576124ac612ee9565b905060400201602001356000801b036124f1576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61253d84848381811061250657612506612ee9565b9050604002016020013585858481811061252257612522612ee9565b6125389260206040909202019081019150613059565b611a57565b8061254781612f18565b91505061241b565b50505050565b8015611a545742609954101561257a576097546125729042612fb2565b60995561258a565b609a546125879082612fb2565b90505b6098548111156125c6576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c635761260b8161271c565b61261683602061273b565b604051602001612627929190613076565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610a8c91600401612a77565b600054610100900460ff16611e07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b6060610a0673ffffffffffffffffffffffffffffffffffffffff831660145b6060600061274a836002612fc5565b612755906002612fb2565b67ffffffffffffffff81111561276d5761276d6130f7565b6040519080825280601f01601f191660200182016040528015612797576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106127ce576127ce612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061283157612831612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061286d846002612fc5565b612878906001612fb2565b90505b6001811115612915577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106128b9576128b9612ee9565b1a60f81b8282815181106128cf576128cf612ee9565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361290e81613126565b905061287b565b50831561297e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a8c565b9392505050565b60006020828403121561299757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461297e57600080fd5b6000602082840312156129d957600080fd5b5035919050565b6000602082840312156129f257600080fd5b81356009811061297e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611a5457600080fd5b60008060408385031215612a3657600080fd5b823591506020830135612a4881612a01565b809150509250929050565b60005b83811015612a6e578181015183820152602001612a56565b50506000910152565b6020815260008251806020840152612a96816040850160208701612a53565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600080600080600060808688031215612ae057600080fd5b853567ffffffffffffffff80821115612af857600080fd5b818801915088601f830112612b0c57600080fd5b813581811115612b1b57600080fd5b8960208260051b8501011115612b3057600080fd5b60209283019a909950918801359760408101359750606001359550909350505050565b60008083601f840112612b6557600080fd5b50813567ffffffffffffffff811115612b7d57600080fd5b602083019150836020828501011115612b9557600080fd5b9250929050565b60008060008060008060008060e0898b031215612bb857600080fd5b8835612bc381612a01565b97506020890135612bd381612a01565b965060408901359550606089013594506080890135612bf181612a01565b935060a089013567ffffffffffffffff811115612c0d57600080fd5b612c198b828c01612b53565b999c989b50969995989497949560c00135949350505050565b60008083601f840112612c4457600080fd5b50813567ffffffffffffffff811115612c5c57600080fd5b6020830191508360208260061b8501011115612b9557600080fd5b600080600080600080600080600060c08a8c031215612c9557600080fd5b8935985060208a0135975060408a0135612cae81612a01565b965060608a013567ffffffffffffffff80821115612ccb57600080fd5b612cd78d838e01612c32565b909850965060808c0135915080821115612cf057600080fd5b612cfc8d838e01612c32565b909650945060a08c0135915080821115612d1557600080fd5b50612d228c828d01612c32565b915080935050809150509295985092959850929598565b60008060008060608587031215612d4f57600080fd5b8435612d5a81612a01565b935060208501359250604085013567ffffffffffffffff811115612d7d57600080fd5b612d8987828801612b53565b95989497509550505050565b60008060008060008060608789031215612dae57600080fd5b863567ffffffffffffffff80821115612dc657600080fd5b612dd28a838b01612c32565b90985096506020890135915080821115612deb57600080fd5b612df78a838b01612c32565b90965094506040890135915080821115612e1057600080fd5b50612e1d89828a01612c32565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60098110612e95577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b60208101610a068284612e5e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a0657610a06612ea7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612f4957612f49612ea7565b5060010190565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612f8957600080fd5b8260051b80856040850137919091016040019392505050565b8183823760009101908152919050565b80820180821115610a0657610a06612ea7565b8082028115828204841417610a0657610a06612ea7565b85815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101949350505050565b6040810161304c8285612e5e565b8260208301529392505050565b60006020828403121561306b57600080fd5b813561297e81612a01565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516130ae816017850160208801612a53565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516130eb816028840160208801612a53565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008161313557613135612ea7565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220470c39572685968d6ec85d8e7d7ed38ca849845528f9e12455980a8581d1854164736f6c63430008130033", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c6200002c565b620000266200002c565b620000ed565b600054610100900460ff1615620000995760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000eb576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61307a80620000fd6000396000f3fe6080604052600436106102dc5760003560e01c80638994588311610184578063b9174ba3116100d6578063c1dc0f071161008a578063d547741f11610064578063d547741f14610913578063e196fb5d14610933578063f866aa131461095357600080fd5b8063c1dc0f0714610899578063cc5782f6146108af578063cc6f7251146108df57600080fd5b8063bcbd6fcd116100bb578063bcbd6fcd1461081b578063bf3e75051461084f578063c0729ab11461088357600080fd5b8063b9174ba3146107c7578063bc61e733146107fb57600080fd5b80639ac25d0811610138578063ad422ff011610112578063ad422ff014610785578063aea4f7451461079b578063b837dbe9146107b057600080fd5b80639ac25d08146107295780639f3ce55a1461075d578063a217fddf1461077057600080fd5b806391d148541161016957806391d14854146106aa57806391f7b901146106fd5780639340a1d11461071257600080fd5b8063899458831461065f5780638de494871461067657600080fd5b806348922ab71161023d57806367e404ce116101f157806374377a34116101cb57806374377a34146105e85780637d1e8c551461061c5780637fe335d31461063157600080fd5b806367e404ce1461055e578063687a6fe0146105945780636a906b80146105b457600080fd5b80635230eef2116102225780635230eef2146104f4578063557eac7314610528578063587944561461054857600080fd5b806348922ab7146104ad578063491e0936146104d457600080fd5b80632f2ff15d1161029457806338b903331161027957806338b90333146104035780633b12eccb146104595780633c3621461461048d57600080fd5b80632f2ff15d146103c357806336568abe146103e357600080fd5b80631065a399116102c55780631065a39914610351578063182a750614610373578063248a9ca31461039357600080fd5b806301ffc9a7146102e15780630f6893ca14610316575b600080fd5b3480156102ed57600080fd5b506103016102fc366004612891565b610973565b60405190151581526020015b60405180910390f35b34801561032257600080fd5b506103436103313660046128d3565b60b06020526000908152604090205481565b60405190815260200161030d565b34801561035d57600080fd5b5061037161036c3660046128ec565b610a0c565b005b34801561037f57600080fd5b5061037161038e3660046128d3565b610b17565b34801561039f57600080fd5b506103436103ae3660046128d3565b60009081526065602052604090206001015490565b3480156103cf57600080fd5b506103716103de36600461292f565b610b8a565b3480156103ef57600080fd5b506103716103fe36600461292f565b610bb4565b34801561040f57600080fd5b5061044c6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405161030d9190612983565b34801561046557600080fd5b506103437fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b34801561049957600080fd5b506103716104a83660046129d4565b610c4d565b3480156104b957600080fd5b506104c2600181565b60405160ff909116815260200161030d565b3480156104e057600080fd5b506103716104ef366004612aa8565b610f48565b34801561050057600080fd5b506103437f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b34801561053457600080fd5b506103716105433660046128d3565b611251565b34801561055457600080fd5b5061034360995481565b34801561056a57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b3480156105a057600080fd5b506103716105af366004612b83565b611319565b3480156105c057600080fd5b506103437fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b3480156105f457600080fd5b506103437f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b34801561062857600080fd5b506104c2600081565b34801561063d57600080fd5b5061034361064c3660046128d3565b6101196020526000908152604090205481565b34801561066b57600080fd5b506103436101175481565b34801561068257600080fd5b506103437fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b3480156106b657600080fd5b506103016106c536600461292f565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561070957600080fd5b506104c2600281565b34801561071e57600080fd5b506103436101185481565b34801561073557600080fd5b506103437f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b61037161076b366004612c45565b611569565b34801561077c57600080fd5b50610343600081565b34801561079157600080fd5b5061034360985481565b3480156107a757600080fd5b50610371611784565b3480156107bc57600080fd5b506103436101165481565b3480156107d357600080fd5b506103437f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b34801561080757600080fd5b506103016108163660046128ec565b6117e0565b34801561082757600080fd5b506103437fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561085b57600080fd5b506103437f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b34801561088f57600080fd5b50610343609a5481565b3480156108a557600080fd5b5061034360975481565b3480156108bb57600080fd5b506103016108ca3660046128d3565b60a56020526000908152604090205460ff1681565b3480156108eb57600080fd5b506103437fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b34801561091f57600080fd5b5061037161092e36600461292f565b611805565b34801561093f57600080fd5b5061037161094e3660046128ec565b61182a565b34801561095f57600080fd5b5061037161096e366004612ca1565b611904565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a0657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60a86000826008811115610a2257610a22612d3b565b6008811115610a3357610a33612d3b565b815260200190815260200160002054610a4b81611a46565b610a54826117e0565b610a9557816040517f18659654000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b60405180910390fd5b816008811115610aa757610aa7612d3b565b60a68054600190921b199091169055816008811115610ac857610ac8612d3b565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba2610b4181611a46565b610117805490839055604080518281526020810185905233917f6d8040017e56a6d91bb242def14af5d7eae1eaff7475e45c678dac5d49d35498910160405180910390a2505050565b600082815260656020526040902060010154610ba581611a46565b610baf8383611a53565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c3f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a8c565b610c498282611b47565b5050565b6001610c5881611c02565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd67415610c8281611a46565b6000869003610cbd576040517f6446cc9c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6064861115610cfb576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101879052602401610a8c565b6000839003610d36576040517f36a4bb9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101185480610d46600188612dda565b14610d9357610d56600187612dda565b6040517fd39e75f9000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610a8c565b6000818152610119602052604081205490805b89811015610e2b578a8a82818110610dc057610dc0612ded565b905060200201359150600060ff1660b060008481526020019081526020016000205403610e1b57600082815260b06020526040902060019055610e0d838360009182526020526040902090565b9250610e1884612e1c565b93505b610e2481612e1c565b9050610da6565b50868314610e6f576040517fd39e75f90000000000000000000000000000000000000000000000000000000081526004810188905260248101849052604401610a8c565b818614610eb2576040517f7557a60a0000000000000000000000000000000000000000000000000000000081526004810187905260248101839052604401610a8c565b610118548314610f3c576101188390556000838152610119602052604090819020839055517f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb90610f06908c908c90612e54565b60405180910390a1604051829084907f99b65a4301b38c09fb6a5f27052d73e8372bbe8f6779d678bfe8a41b66cce7ac90600090a35b50505050505050505050565b610f50611c44565b858784848760005a9050610f646002611c9d565b6000610f758f8f8f8f8c8f8f611d2f565b9050610f8081611d8a565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051610fed929190612ea6565b60006040518083038185875af1925050503d806000811461102a576040519150601f19603f3d011682016040523d82523d6000602084013e61102f565b606091505b509150915081611099578051156110495780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610a8c919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a25050861590506112375785600084900361118357853b158015611181573a5a61111e61ae3486612eb6565b6111289190612dda565b6111329190612ec9565b91508188111561117d5773ffffffffffffffffffffffffffffffffffffffff87166108fc611160848b612dda565b6040518115909202916000818181858888f1935050505050611181565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff8416156111a757836111a9565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050905080611233576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610a8c565b5050505b505050505050611247600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261127b81611a46565b60008060004260995410156112a2576097546112979042612eb6565b6099555060016112b4565b609a548510156112b457849250600191505b609885905580806112c25750815b156112cd57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b600054610100900460ff16158080156113395750600054600160ff909116105b806113535750303b158015611353575060005460ff166001145b6113c55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561142357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61142b611df0565b611433611df0565b61143b611df0565b6114458a8a611e6f565b61144d611fc5565b6114598585858561204a565b73ffffffffffffffffffffffffffffffffffffffff88166114a6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114b1600089611a53565b6114bb87876122fb565b60016101165561011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055655af3107a4000610117558015610f3c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050505050565b6115736003611c9d565b73ffffffffffffffffffffffffffffffffffffffff84166115c0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348311156115fa576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015611638576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806116458387612dda565b91506116518634612dda565b6101168054919250600091908261166783612e1c565b90915550905061167f61167a8484612eb6565b6124af565b6000611690338a8686868c8c611d2f565b9050808973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8787878d8d6040516116f8959493929190612ee0565b60405180910390a4604051600090419087908381818185875af1925050503d8060008114611742576040519150601f19603f3d011682016040523d82523d6000602084013e611747565b606091505b5050905080610f3c576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610a8c565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf96117ae81611a46565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b60008160088111156117f4576117f4612d3b565b60a654600190911b16151592915050565b60008281526065602052604090206001015461182081611a46565b610baf8383611b47565b60a7600082600881111561184057611840612d3b565b600881111561185157611851612d3b565b81526020019081526020016000205461186981611a46565b611872826117e0565b156118ab57816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b8160088111156118bd576118bd612d3b565b60a68054600190921b90911790558160088111156118dd576118dd612d3b565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933610aeb565b600054600290610100900460ff16158015611926575060005460ff8083169116105b6119985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556119d387876122fb565b6119df8585858561204a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b611a508133612525565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c4957600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611ae93390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c4957600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b611c0b816117e0565b15611a5057806040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b600260b15403611c965760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a8c565b600260b155565b60a654816008811115611cb257611cb2612d3b565b6001901b811615611cf157816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b6002811615610c495760016040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b600060405188815287602082015286604082015285606082015284608082015260c060a08201528260c08201526020830660008115611d6f578160200390505b848660e085013790930160e001902098975050505050505050565b600081815260b06020526040902054600114611dd5576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b600090815260b06020526040902060029055565b600160b155565b600054610100900460ff16611e6d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b565b600054610100900460ff16611eec5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b81600003611f26576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611f60576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611f748242612eb6565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b600054610100900460ff166120425760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b611e6d6125c5565b600054610100900460ff166120c75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b60005b838110156121dd578484828181106120e4576120e4612ded565b9050604002016020013560a7600087878581811061210457612104612ded565b61211a92602060409092020190810191506128ec565b600881111561212b5761212b612d3b565b600881111561213c5761213c612d3b565b815260208101919091526040016000205584848281811061215f5761215f612ded565b9050604002016020013585858381811061217b5761217b612ded565b61219192602060409092020190810191506128ec565b60088111156121a2576121a2612d3b565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609190600090a3806121d581612e1c565b9150506120ca565b5060005b818110156122f4578282828181106121fb576121fb612ded565b9050604002016020013560a8600085858581811061221b5761221b612ded565b61223192602060409092020190810191506128ec565b600881111561224257612242612d3b565b600881111561225357612253612d3b565b815260208101919091526040016000205582828281811061227657612276612ded565b9050604002016020013583838381811061229257612292612ded565b6122a892602060409092020190810191506128ec565b60088111156122b9576122b9612d3b565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c290600090a3806122ec81612e1c565b9150506121e1565b5050505050565b600054610100900460ff166123785760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b60005b81811015610baf57600083838381811061239757612397612ded565b6123ad9260206040909202019081019150612f42565b73ffffffffffffffffffffffffffffffffffffffff16036123fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82828281811061240c5761240c612ded565b905060400201602001356000801b03612451576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61249d83838381811061246657612466612ded565b9050604002016020013584848481811061248257612482612ded565b6124989260206040909202019081019150612f42565b611a53565b806124a781612e1c565b91505061237b565b8015611a50574260995410156124d4576097546124cc9042612eb6565b6099556124e4565b609a546124e19082612eb6565b90505b609854811115612520576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c495761256581612642565b612570836020612661565b604051602001612581929190612f5f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262461bcd60e51b8252610a8c91600401612983565b600054610100900460ff16611de95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b6060610a0673ffffffffffffffffffffffffffffffffffffffff831660145b60606000612670836002612ec9565b61267b906002612eb6565b67ffffffffffffffff81111561269357612693612fe0565b6040519080825280601f01601f1916602001820160405280156126bd576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106126f4576126f4612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061275757612757612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612793846002612ec9565b61279e906001612eb6565b90505b600181111561283b577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106127df576127df612ded565b1a60f81b8282815181106127f5576127f5612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936128348161300f565b90506127a1565b50831561288a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a8c565b9392505050565b6000602082840312156128a357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461288a57600080fd5b6000602082840312156128e557600080fd5b5035919050565b6000602082840312156128fe57600080fd5b81356009811061288a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611a5057600080fd5b6000806040838503121561294257600080fd5b8235915060208301356129548161290d565b809150509250929050565b60005b8381101561297a578181015183820152602001612962565b50506000910152565b60208152600082518060208401526129a281604085016020870161295f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806000806000608086880312156129ec57600080fd5b853567ffffffffffffffff80821115612a0457600080fd5b818801915088601f830112612a1857600080fd5b813581811115612a2757600080fd5b8960208260051b8501011115612a3c57600080fd5b60209283019a909950918801359760408101359750606001359550909350505050565b60008083601f840112612a7157600080fd5b50813567ffffffffffffffff811115612a8957600080fd5b602083019150836020828501011115612aa157600080fd5b9250929050565b60008060008060008060008060e0898b031215612ac457600080fd5b8835612acf8161290d565b97506020890135612adf8161290d565b965060408901359550606089013594506080890135612afd8161290d565b935060a089013567ffffffffffffffff811115612b1957600080fd5b612b258b828c01612a5f565b999c989b50969995989497949560c00135949350505050565b60008083601f840112612b5057600080fd5b50813567ffffffffffffffff811115612b6857600080fd5b6020830191508360208260061b8501011115612aa157600080fd5b600080600080600080600080600060c08a8c031215612ba157600080fd5b8935985060208a0135975060408a0135612bba8161290d565b965060608a013567ffffffffffffffff80821115612bd757600080fd5b612be38d838e01612b3e565b909850965060808c0135915080821115612bfc57600080fd5b612c088d838e01612b3e565b909650945060a08c0135915080821115612c2157600080fd5b50612c2e8c828d01612b3e565b915080935050809150509295985092959850929598565b60008060008060608587031215612c5b57600080fd5b8435612c668161290d565b935060208501359250604085013567ffffffffffffffff811115612c8957600080fd5b612c9587828801612a5f565b95989497509550505050565b60008060008060008060608789031215612cba57600080fd5b863567ffffffffffffffff80821115612cd257600080fd5b612cde8a838b01612b3e565b90985096506020890135915080821115612cf757600080fd5b612d038a838b01612b3e565b90965094506040890135915080821115612d1c57600080fd5b50612d2989828a01612b3e565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160098310612da5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a0657610a06612dab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e4d57612e4d612dab565b5060010190565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612e8d57600080fd5b8260051b80856040850137919091016040019392505050565b8183823760009101908152919050565b80820180821115610a0657610a06612dab565b8082028115828204841417610a0657610a06612dab565b85815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101949350505050565b600060208284031215612f5457600080fd5b813561288a8161290d565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f9781601785016020880161295f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612fd481602884016020880161295f565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008161301e5761301e612dab565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220379188afc68564e5496052c3170f33fe9018531330cf07ced3cefe2795ce8dca64736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106102dc5760003560e01c80638994588311610184578063b9174ba3116100d6578063c1dc0f071161008a578063d547741f11610064578063d547741f14610913578063e196fb5d14610933578063f866aa131461095357600080fd5b8063c1dc0f0714610899578063cc5782f6146108af578063cc6f7251146108df57600080fd5b8063bcbd6fcd116100bb578063bcbd6fcd1461081b578063bf3e75051461084f578063c0729ab11461088357600080fd5b8063b9174ba3146107c7578063bc61e733146107fb57600080fd5b80639ac25d0811610138578063ad422ff011610112578063ad422ff014610785578063aea4f7451461079b578063b837dbe9146107b057600080fd5b80639ac25d08146107295780639f3ce55a1461075d578063a217fddf1461077057600080fd5b806391d148541161016957806391d14854146106aa57806391f7b901146106fd5780639340a1d11461071257600080fd5b8063899458831461065f5780638de494871461067657600080fd5b806348922ab71161023d57806367e404ce116101f157806374377a34116101cb57806374377a34146105e85780637d1e8c551461061c5780637fe335d31461063157600080fd5b806367e404ce1461055e578063687a6fe0146105945780636a906b80146105b457600080fd5b80635230eef2116102225780635230eef2146104f4578063557eac7314610528578063587944561461054857600080fd5b806348922ab7146104ad578063491e0936146104d457600080fd5b80632f2ff15d1161029457806338b903331161027957806338b90333146104035780633b12eccb146104595780633c3621461461048d57600080fd5b80632f2ff15d146103c357806336568abe146103e357600080fd5b80631065a399116102c55780631065a39914610351578063182a750614610373578063248a9ca31461039357600080fd5b806301ffc9a7146102e15780630f6893ca14610316575b600080fd5b3480156102ed57600080fd5b506103016102fc366004612891565b610973565b60405190151581526020015b60405180910390f35b34801561032257600080fd5b506103436103313660046128d3565b60b06020526000908152604090205481565b60405190815260200161030d565b34801561035d57600080fd5b5061037161036c3660046128ec565b610a0c565b005b34801561037f57600080fd5b5061037161038e3660046128d3565b610b17565b34801561039f57600080fd5b506103436103ae3660046128d3565b60009081526065602052604090206001015490565b3480156103cf57600080fd5b506103716103de36600461292f565b610b8a565b3480156103ef57600080fd5b506103716103fe36600461292f565b610bb4565b34801561040f57600080fd5b5061044c6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405161030d9190612983565b34801561046557600080fd5b506103437fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b34801561049957600080fd5b506103716104a83660046129d4565b610c4d565b3480156104b957600080fd5b506104c2600181565b60405160ff909116815260200161030d565b3480156104e057600080fd5b506103716104ef366004612aa8565b610f48565b34801561050057600080fd5b506103437f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b34801561053457600080fd5b506103716105433660046128d3565b611251565b34801561055457600080fd5b5061034360995481565b34801561056a57600080fd5b506101155460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b3480156105a057600080fd5b506103716105af366004612b83565b611319565b3480156105c057600080fd5b506103437fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b3480156105f457600080fd5b506103437f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd6741581565b34801561062857600080fd5b506104c2600081565b34801561063d57600080fd5b5061034361064c3660046128d3565b6101196020526000908152604090205481565b34801561066b57600080fd5b506103436101175481565b34801561068257600080fd5b506103437fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b3480156106b657600080fd5b506103016106c536600461292f565b600091825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561070957600080fd5b506104c2600281565b34801561071e57600080fd5b506103436101185481565b34801561073557600080fd5b506103437f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b61037161076b366004612c45565b611569565b34801561077c57600080fd5b50610343600081565b34801561079157600080fd5b5061034360985481565b3480156107a757600080fd5b50610371611784565b3480156107bc57600080fd5b506103436101165481565b3480156107d357600080fd5b506103437f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b34801561080757600080fd5b506103016108163660046128ec565b6117e0565b34801561082757600080fd5b506103437fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba281565b34801561085b57600080fd5b506103437f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b34801561088f57600080fd5b50610343609a5481565b3480156108a557600080fd5b5061034360975481565b3480156108bb57600080fd5b506103016108ca3660046128d3565b60a56020526000908152604090205460ff1681565b3480156108eb57600080fd5b506103437fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b34801561091f57600080fd5b5061037161092e36600461292f565b611805565b34801561093f57600080fd5b5061037161094e3660046128ec565b61182a565b34801561095f57600080fd5b5061037161096e366004612ca1565b611904565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610a0657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60a86000826008811115610a2257610a22612d3b565b6008811115610a3357610a33612d3b565b815260200190815260200160002054610a4b81611a46565b610a54826117e0565b610a9557816040517f18659654000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b60405180910390fd5b816008811115610aa757610aa7612d3b565b60a68054600190921b199091169055816008811115610ac857610ac8612d3b565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7fcc6ce8bb749b4b07d2f635ce95747506096d0737f9abf10cc8f4a14384603ba2610b4181611a46565b610117805490839055604080518281526020810185905233917f6d8040017e56a6d91bb242def14af5d7eae1eaff7475e45c678dac5d49d35498910160405180910390a2505050565b600082815260656020526040902060010154610ba581611a46565b610baf8383611a53565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610c3f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a8c565b610c498282611b47565b5050565b6001610c5881611c02565b7f4705265620026983c754c5288b65446d794a03174326ec6d7c0b5c7f1fd67415610c8281611a46565b6000869003610cbd576040517f6446cc9c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6064861115610cfb576040517f3b17443400000000000000000000000000000000000000000000000000000000815260048101879052602401610a8c565b6000839003610d36576040517f36a4bb9400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101185480610d46600188612dda565b14610d9357610d56600187612dda565b6040517fd39e75f9000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610a8c565b6000818152610119602052604081205490805b89811015610e2b578a8a82818110610dc057610dc0612ded565b905060200201359150600060ff1660b060008481526020019081526020016000205403610e1b57600082815260b06020526040902060019055610e0d838360009182526020526040902090565b9250610e1884612e1c565b93505b610e2481612e1c565b9050610da6565b50868314610e6f576040517fd39e75f90000000000000000000000000000000000000000000000000000000081526004810188905260248101849052604401610a8c565b818614610eb2576040517f7557a60a0000000000000000000000000000000000000000000000000000000081526004810187905260248101839052604401610a8c565b610118548314610f3c576101188390556000838152610119602052604090819020839055517f9995fb3da0c2de4012f2b814b6fc29ce7507571dcb20b8d0bd38621a842df1eb90610f06908c908c90612e54565b60405180910390a1604051829084907f99b65a4301b38c09fb6a5f27052d73e8372bbe8f6779d678bfe8a41b66cce7ac90600090a35b50505050505050505050565b610f50611c44565b858784848760005a9050610f646002611c9d565b6000610f758f8f8f8f8c8f8f611d2f565b9050610f8081611d8a565b8e61011560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d604051610fed929190612ea6565b60006040518083038185875af1925050503d806000811461102a576040519150601f19603f3d011682016040523d82523d6000602084013e61102f565b606091505b509150915081611099578051156110495780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610a8c919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd1517905560405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e90600090a25050861590506112375785600084900361118357853b158015611181573a5a61111e61ae3486612eb6565b6111289190612dda565b6111329190612ec9565b91508188111561117d5773ffffffffffffffffffffffffffffffffffffffff87166108fc611160848b612dda565b6040518115909202916000818181858888f1935050505050611181565b8791505b505b600073ffffffffffffffffffffffffffffffffffffffff8416156111a757836111a9565b335b905060008173ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050905080611233576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610a8c565b5050505b505050505050611247600160b155565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261127b81611a46565b60008060004260995410156112a2576097546112979042612eb6565b6099555060016112b4565b609a548510156112b457849250600191505b609885905580806112c25750815b156112cd57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b600054610100900460ff16158080156113395750600054600160ff909116105b806113535750303b158015611353575060005460ff166001145b6113c55760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561142357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61142b611df0565b611433611df0565b61143b611df0565b6114458a8a611e6f565b61144d611fc5565b6114598585858561204a565b73ffffffffffffffffffffffffffffffffffffffff88166114a6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6114b1600089611a53565b6114bb87876122fb565b60016101165561011580547fffffffffffffffffffffffff00000000000000000000000000000000000000001663075bcd15179055655af3107a4000610117558015610f3c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050505050565b6115736003611c9d565b73ffffffffffffffffffffffffffffffffffffffff84166115c0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348311156115fa576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101175480841015611638576040517f732f941300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806116458387612dda565b91506116518634612dda565b6101168054919250600091908261166783612e1c565b90915550905061167f61167a8484612eb6565b6124af565b6000611690338a8686868c8c611d2f565b9050808973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8787878d8d6040516116f8959493929190612ee0565b60405180910390a4604051600090419087908381818185875af1925050503d8060008114611742576040519150601f19603f3d011682016040523d82523d6000602084013e611747565b606091505b5050905080610f3c576040517fa57c4df4000000000000000000000000000000000000000000000000000000008152416004820152602401610a8c565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf96117ae81611a46565b6000609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b60008160088111156117f4576117f4612d3b565b60a654600190911b16151592915050565b60008281526065602052604090206001015461182081611a46565b610baf8383611b47565b60a7600082600881111561184057611840612d3b565b600881111561185157611851612d3b565b81526020019081526020016000205461186981611a46565b611872826117e0565b156118ab57816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b8160088111156118bd576118bd612d3b565b60a68054600190921b90911790558160088111156118dd576118dd612d3b565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933610aeb565b600054600290610100900460ff16158015611926575060005460ff8083169116105b6119985760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610a8c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556119d387876122fb565b6119df8585858561204a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b611a508133612525565b50565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c4957600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611ae93390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610c4957600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b611c0b816117e0565b15611a5057806040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b600260b15403611c965760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a8c565b600260b155565b60a654816008811115611cb257611cb2612d3b565b6001901b811615611cf157816040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b6002811615610c495760016040517fc0a71b58000000000000000000000000000000000000000000000000000000008152600401610a8c9190612d6a565b600060405188815287602082015286604082015285606082015284608082015260c060a08201528260c08201526020830660008115611d6f578160200390505b848660e085013790930160e001902098975050505050505050565b600081815260b06020526040902054600114611dd5576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610a8c565b600090815260b06020526040902060029055565b600160b155565b600054610100900460ff16611e6d5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b565b600054610100900460ff16611eec5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b81600003611f26576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611f60576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055611f748242612eb6565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b600054610100900460ff166120425760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b611e6d6125c5565b600054610100900460ff166120c75760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b60005b838110156121dd578484828181106120e4576120e4612ded565b9050604002016020013560a7600087878581811061210457612104612ded565b61211a92602060409092020190810191506128ec565b600881111561212b5761212b612d3b565b600881111561213c5761213c612d3b565b815260208101919091526040016000205584848281811061215f5761215f612ded565b9050604002016020013585858381811061217b5761217b612ded565b61219192602060409092020190810191506128ec565b60088111156121a2576121a2612d3b565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609190600090a3806121d581612e1c565b9150506120ca565b5060005b818110156122f4578282828181106121fb576121fb612ded565b9050604002016020013560a8600085858581811061221b5761221b612ded565b61223192602060409092020190810191506128ec565b600881111561224257612242612d3b565b600881111561225357612253612d3b565b815260208101919091526040016000205582828281811061227657612276612ded565b9050604002016020013583838381811061229257612292612ded565b6122a892602060409092020190810191506128ec565b60088111156122b9576122b9612d3b565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c290600090a3806122ec81612e1c565b9150506121e1565b5050505050565b600054610100900460ff166123785760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b60005b81811015610baf57600083838381811061239757612397612ded565b6123ad9260206040909202019081019150612f42565b73ffffffffffffffffffffffffffffffffffffffff16036123fa576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82828281811061240c5761240c612ded565b905060400201602001356000801b03612451576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61249d83838381811061246657612466612ded565b9050604002016020013584848481811061248257612482612ded565b6124989260206040909202019081019150612f42565b611a53565b806124a781612e1c565b91505061237b565b8015611a50574260995410156124d4576097546124cc9042612eb6565b6099556124e4565b609a546124e19082612eb6565b90505b609854811115612520576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b600082815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610c495761256581612642565b612570836020612661565b604051602001612581929190612f5f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905262461bcd60e51b8252610a8c91600401612983565b600054610100900460ff16611de95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610a8c565b6060610a0673ffffffffffffffffffffffffffffffffffffffff831660145b60606000612670836002612ec9565b61267b906002612eb6565b67ffffffffffffffff81111561269357612693612fe0565b6040519080825280601f01601f1916602001820160405280156126bd576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106126f4576126f4612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061275757612757612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612793846002612ec9565b61279e906001612eb6565b90505b600181111561283b577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106127df576127df612ded565b1a60f81b8282815181106127f5576127f5612ded565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936128348161300f565b90506127a1565b50831561288a5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a8c565b9392505050565b6000602082840312156128a357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461288a57600080fd5b6000602082840312156128e557600080fd5b5035919050565b6000602082840312156128fe57600080fd5b81356009811061288a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff81168114611a5057600080fd5b6000806040838503121561294257600080fd5b8235915060208301356129548161290d565b809150509250929050565b60005b8381101561297a578181015183820152602001612962565b50506000910152565b60208152600082518060208401526129a281604085016020870161295f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6000806000806000608086880312156129ec57600080fd5b853567ffffffffffffffff80821115612a0457600080fd5b818801915088601f830112612a1857600080fd5b813581811115612a2757600080fd5b8960208260051b8501011115612a3c57600080fd5b60209283019a909950918801359760408101359750606001359550909350505050565b60008083601f840112612a7157600080fd5b50813567ffffffffffffffff811115612a8957600080fd5b602083019150836020828501011115612aa157600080fd5b9250929050565b60008060008060008060008060e0898b031215612ac457600080fd5b8835612acf8161290d565b97506020890135612adf8161290d565b965060408901359550606089013594506080890135612afd8161290d565b935060a089013567ffffffffffffffff811115612b1957600080fd5b612b258b828c01612a5f565b999c989b50969995989497949560c00135949350505050565b60008083601f840112612b5057600080fd5b50813567ffffffffffffffff811115612b6857600080fd5b6020830191508360208260061b8501011115612aa157600080fd5b600080600080600080600080600060c08a8c031215612ba157600080fd5b8935985060208a0135975060408a0135612bba8161290d565b965060608a013567ffffffffffffffff80821115612bd757600080fd5b612be38d838e01612b3e565b909850965060808c0135915080821115612bfc57600080fd5b612c088d838e01612b3e565b909650945060a08c0135915080821115612c2157600080fd5b50612c2e8c828d01612b3e565b915080935050809150509295985092959850929598565b60008060008060608587031215612c5b57600080fd5b8435612c668161290d565b935060208501359250604085013567ffffffffffffffff811115612c8957600080fd5b612c9587828801612a5f565b95989497509550505050565b60008060008060008060608789031215612cba57600080fd5b863567ffffffffffffffff80821115612cd257600080fd5b612cde8a838b01612b3e565b90985096506020890135915080821115612cf757600080fd5b612d038a838b01612b3e565b90965094506040890135915080821115612d1c57600080fd5b50612d2989828a01612b3e565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160098310612da5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610a0657610a06612dab565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e4d57612e4d612dab565b5060010190565b6020815281602082015260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115612e8d57600080fd5b8260051b80856040850137919091016040019392505050565b8183823760009101908152919050565b80820180821115610a0657610a06612dab565b8082028115828204841417610a0657610a06612dab565b85815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101949350505050565b600060208284031215612f5457600080fd5b813561288a8161290d565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612f9781601785016020880161295f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351612fd481602884016020880161295f565b01602801949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008161301e5761301e612dab565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220379188afc68564e5496052c3170f33fe9018531330cf07ced3cefe2795ce8dca64736f6c63430008130033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV6.json b/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV6.json index 67aa6542..cd78b1e2 100644 --- a/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV6.json +++ b/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV6.json @@ -88,6 +88,17 @@ "name": "FeeTooLow", "type": "error" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "shnarf", + "type": "bytes32" + } + ], + "name": "FinalBlobNotSubmitted", + "type": "error" + }, { "inputs": [ { @@ -323,6 +334,11 @@ "name": "MissingRollingHashForMessageNumber", "type": "error" }, + { + "inputs": [], + "name": "OnlyNonFallbackOperator", + "type": "error" + }, { "inputs": [ { @@ -407,6 +423,22 @@ "name": "ReentrantCall", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, { "inputs": [], "name": "StartingRootHashDoesNotMatch", @@ -701,13 +733,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "pauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -864,13 +896,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "unPauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -1877,7 +1909,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "isClaimed", "type": "bool" } ], @@ -1896,7 +1928,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "pauseTypeIsPaused", "type": "bool" } ], @@ -2080,12 +2112,12 @@ "inputs": [ { "internalType": "bytes32", - "name": "role", + "name": "_role", "type": "bytes32" }, { "internalType": "address", - "name": "account", + "name": "_account", "type": "address" } ], @@ -2180,7 +2212,7 @@ "outputs": [ { "internalType": "address", - "name": "addr", + "name": "originalSender", "type": "address" } ], @@ -2415,8 +2447,8 @@ "type": "function" } ], - "bytecode": "0x6080604052348015600e575f80fd5b5060156019565b60d3565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161460d1575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615619806100e05f395ff3fe60806040526004361061049d575f3560e01c806373bd07b71161026b578063b837dbe911610156578063cc5782f6116100d1578063d5d4b83511610087578063e196fb5d1161006d578063e196fb5d14610ed4578063e97a1e9e14610ef3578063f5b541a614610f65575f80fd5b8063d5d4b83514610e8b578063d722bbfc14610ea1575f80fd5b8063cd9b9e9a116100b7578063cd9b9e9a14610e29578063cf5b276414610e3f578063d547741f14610e6c575f80fd5b8063cc5782f614610dc8578063cc6f725114610df6575f80fd5b8063bf3e750511610126578063c0c4e5841161010c578063c0c4e58414610d75578063c1dc0f0714610d94578063c211697414610da9575f80fd5b8063bf3e750514610d2d578063c0729ab114610d60575f80fd5b8063b837dbe914610ca7578063b9174ba314610cbc578063bc61e73314610cef578063bcc3003d14610d0e575f80fd5b80639ac25d08116101e6578063a98e773d116101b6578063ad422ff01161019c578063ad422ff014610c4b578063aea4f74514610c60578063b59faa6014610c74575f80fd5b8063a98e773d14610bea578063ac1eff6814610c09575f80fd5b80639ac25d0814610b725780639ee8b21114610ba55780639f3ce55a14610bc4578063a217fddf14610bd7575f80fd5b8063914e57eb1161023b578063921b278e11610221578063921b278e14610b3d578063986fcddd14610a4e57806399467a3514610b53575f80fd5b8063914e57eb14610ac057806391d1485414610aec575f80fd5b806373bd07b714610a3a5780637d1e8c5514610a4e5780638be745d114610a615780638de4948714610a8d575f80fd5b80634cdd389b1161038b57806360e83cf31161030657806367e404ce116102d6578063695378f5116102bc578063695378f5146109be5780636a906b80146109d45780636e67384314610a07575f80fd5b806367e404ce146109665780636854f6bc1461099f575f80fd5b806360e83cf3146108bc57806363213155146108e85780636463fb2a1461091b57806366f96e981461093a575f80fd5b8063587944561161035b5780635c721a0c116103415780635c721a0c146108395780635ed73ceb146108645780636078bfd814610890575f80fd5b806358794456146108245780635b7eb4bd14610742575f80fd5b80634cdd389b146107875780635230eef2146107b3578063557eac73146107e65780635603c65f14610805575f80fd5b8063289581741161041b57806338b90333116103eb5780633fc08b65116103d15780633fc08b651461071757806348922ab714610742578063491e093614610768575f80fd5b806338b903331461068f5780633b12eccb146106e4575f80fd5b8063289581741461061c5780632c70645c1461063b5780632f2ff15d1461065157806336568abe14610670575f80fd5b806312d3fa9a116104705780631f443da0116104565780631f443da0146105965780632130d812146105c2578063248a9ca3146105ee575f80fd5b806312d3fa9a1461054d5780631e2ff94f14610580575f80fd5b806301ffc9a7146104a157806303134d1d146104d557806305861180146105165780631065a3991461052c575b5f80fd5b3480156104ac575f80fd5b506104c06104bb3660046148d2565b610f98565b60405190151581526020015b60405180910390f35b3480156104e0575f80fd5b506105087f1ab87f7458c0e3d07e9881c14ee67f0141703614fd48ea5b15ed987e5f4b030e81565b6040519081526020016104cc565b348015610521575f80fd5b506105086101bb5481565b348015610537575f80fd5b5061054b610546366004614911565b611030565b005b348015610558575f80fd5b506105087f67c2dca7476ee0fe1dd3cba13428c6760bfe2599a6dfe26a9ad7ef27317c6e7781565b34801561058b575f80fd5b506105086101185481565b3480156105a1575f80fd5b506105086105b036600461492f565b6101b96020525f908152604090205481565b3480156105cd575f80fd5b506105086105dc36600461492f565b6101be6020525f908152604090205481565b3480156105f9575f80fd5b5061050861060836600461492f565b5f9081526065602052604090206001015490565b348015610627575f80fd5b5061054b61063636600461492f565b611139565b348015610646575f80fd5b506105086101835481565b34801561065c575f80fd5b5061054b61066b366004614967565b6111f9565b34801561067b575f80fd5b5061054b61068a366004614967565b611222565b34801561069a575f80fd5b506106d76040518060400160405280600381526020017f362e30000000000000000000000000000000000000000000000000000000000081525081565b6040516104cc9190614995565b3480156106ef575f80fd5b506105087fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b348015610722575f80fd5b5061050861073136600461492f565b60a56020525f908152604090205481565b34801561074d575f80fd5b50610756600181565b60405160ff90911681526020016104cc565b348015610773575f80fd5b5061054b610782366004614a2d565b6112d5565b348015610792575f80fd5b506105086107a136600461492f565b6101b76020525f908152604090205481565b3480156107be575f80fd5b506105087f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b3480156107f1575f80fd5b5061054b61080036600461492f565b6115d9565b348015610810575f80fd5b5061054b61081f366004614abd565b61169f565b34801561082f575f80fd5b5061050860995481565b348015610844575f80fd5b5061050861085336600461492f565b60a66020525f908152604090205481565b34801561086f575f80fd5b5061050861087e36600461492f565b6101ba6020525f908152604090205481565b34801561089b575f80fd5b506105086108aa36600461492f565b6101b66020525f908152604090205481565b3480156108c7575f80fd5b506105086108d636600461492f565b6101506020525f908152604090205481565b3480156108f3575f80fd5b506105087fe37c272ea30e2bb381ad7cf89ae754b49153250609f36d0cbdad8b64c184bb5c81565b348015610926575f80fd5b5061054b610935366004614b35565b611797565b348015610945575f80fd5b5061050861095436600461492f565b6101b86020525f908152604090205481565b348015610971575f80fd5b5061097a611c3e565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016104cc565b3480156109aa575f80fd5b5061054b6109b9366004614b6d565b611c76565b3480156109c9575f80fd5b506105086101195481565b3480156109df575f80fd5b506105087fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015610a12575f80fd5b506105087f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b348015610a45575f80fd5b50610756600281565b348015610a59575f80fd5b506107565f81565b348015610a6c575f80fd5b50610508610a7b36600461492f565b61011a6020525f908152604090205481565b348015610a98575f80fd5b506105087fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b348015610acb575f80fd5b50610508610ada36600461492f565b61014e6020525f908152604090205481565b348015610af7575f80fd5b506104c0610b06366004614967565b5f91825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610b48575f80fd5b506105086101bf5481565b348015610b5e575f80fd5b5061054b610b6d366004614bbb565b611e6c565b348015610b7d575f80fd5b506105087f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015610bb0575f80fd5b506104c0610bbf36600461492f565b612152565b61054b610bd2366004614c38565b612175565b348015610be2575f80fd5b506105085f81565b348015610bf5575f80fd5b5061054b610c04366004614c90565b6122be565b348015610c14575f80fd5b5061097a610c2336600461492f565b61011b6020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610c56575f80fd5b5061050860985481565b348015610c6b575f80fd5b5061054b612731565b348015610c7f575f80fd5b506105087fe4831f9e4316ac2c65117d1f602fbf56d38128a9973d5e3fdbc5b77265c18d4081565b348015610cb2575f80fd5b5061050860e45481565b348015610cc7575f80fd5b506105087f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b348015610cfa575f80fd5b506104c0610d09366004614911565b61278c565b348015610d19575f80fd5b5061054b610d28366004614cc8565b6127b0565b348015610d38575f80fd5b506105087f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610d6b575f80fd5b50610508609a5481565b348015610d80575f80fd5b5061054b610d8f366004614d32565b6128fa565b348015610d9f575f80fd5b5061050860975481565b348015610db4575f80fd5b5061054b610dc3366004614de4565b612b2d565b348015610dd3575f80fd5b506104c0610de236600461492f565b60d96020525f908152604090205460ff1681565b348015610e01575f80fd5b506105087fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b348015610e34575f80fd5b506105086101bd5481565b348015610e4a575f80fd5b506101c05461097a9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610e77575f80fd5b5061054b610e86366004614967565b612c5a565b348015610e96575f80fd5b506105086101bc5481565b348015610eac575f80fd5b506105087f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a81565b348015610edf575f80fd5b5061054b610eee366004614911565b612c7e565b348015610efe575f80fd5b50610508604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610f70575f80fd5b506105087f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061102a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60dc5f82600881111561104557611045614e0e565b600881111561105657611056614e0e565b81526020019081526020015f205461106d81612d56565b6110768261278c565b6110b757816040517f186596540000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b60405180910390fd5b8160088111156110c9576110c9614e0e565b60da8054600190921b1990911690558160088111156110ea576110ea614e0e565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a61116381612d56565b5f82815261011b6020908152604080832054905173ffffffffffffffffffffffffffffffffffffffff90911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f8281526065602052604090206001015461121381612d56565b61121d8383612d60565b505050565b73ffffffffffffffffffffffffffffffffffffffff811633146112c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016110ae565b6112d18282612e52565b5050565b6112dd612f0b565b85878484875f5a90506112f06003612fa8565b61132461131e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b8f61303a565b5f6113348f8f8f8f8c8f8f613041565b905061133f8161309a565b61135161134c8d8f614ec2565b6130f4565b5f808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d60405161137b929190614ed5565b5f6040518083038185875af1925050503d805f81146113b5576040519150601f19603f3d011682016040523d82523d5f602084013e6113ba565b606091505b509150915081611424578051156113d45780518082602001fd5b8f6040517f546134430000000000000000000000000000000000000000000000000000000081526004016110ae919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61145861145260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b5f61303a565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a25050861590506115c157855f84900361151057853b15801561150e573a5a6114ac61bc7c86614ec2565b6114b69190614eaf565b6114c09190614ee4565b91508188111561150a5773ffffffffffffffffffffffffffffffffffffffff87166108fc6114ee848b614eaf565b6040518115909202915f818181858888f193505050505061150e565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff8416156115335783611535565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f193505050509050806115bd576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016110ae565b5050505b5050505050506115cf61316a565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261160381612d56565b5f805f4260995410156116285760975461161d9042614ec2565b60995550600161163a565b609a5485101561163a57849250600191505b609885905580806116485750815b1561165357609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b60066116aa81612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296116d481612d56565b5f85900361170e576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a602052604090205484351461175a576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd545f6117698684613198565b90505f61177d878484878b6020013561343b565b905061178b81898c8c6134be565b50505050505050505050565b61179f612f0b565b60a081018035906117b39060808401614efb565b6117c1610120840184614f16565b6117d2610100860160e08701614efb565b5f5a90506117e06003612fa8565b6101008701355f90815261015060205260408120549081900361182f576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118398880614f77565b90508114611888578061184c8980614f77565b6040517f5e3fd6ad00000000000000000000000000000000000000000000000000000000815260048101939093526024830152506044016110ae565b611895886020013561375a565b6118aa61134c60c08a013560a08b0135614ec2565b5f6118f36118be60808b0160608c01614efb565b6118ce60a08c0160808d01614efb565b8b60a001358c60c001358d602001358e8061012001906118ee9190614f16565b613041565b905061191e816119038b80614f77565b61191360608e0160408f01614fdb565b8d61010001356137d2565b611954576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61199761198260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b61199260808c0160608d01614efb565b61303a565b5f806119a960a08c0160808d01614efb565b73ffffffffffffffffffffffffffffffffffffffff1660c08c01356119d26101208e018e614f16565b6040516119e0929190614ed5565b5f6040518083038185875af1925050503d805f8114611a1a576040519150601f19603f3d011682016040523d82523d5f602084013e611a1f565b606091505b509150915081611a9457805115611a395780518082602001fd5b611a4960a08c0160808d01614efb565b6040517f5461344300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016110ae565b611ac261145260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611c2d57855f849003611b7c57853b158015611b7a573a5a611b1861bc7c86614ec2565b611b229190614eaf565b611b2c9190614ee4565b915081881115611b765773ffffffffffffffffffffffffffffffffffffffff87166108fc611b5a848b614eaf565b6040518115909202915f818181858888f1935050505050611b7a565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff841615611b9f5783611ba1565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611c29576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016110ae565b5050505b505050505050611c3b61316a565b50565b5f611c71611c6d60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b5c90565b905090565b6005611c8181612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611cab81612d56565b611cb86040860186614f16565b90505f03611cf2576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611d006040870187614f16565b604051611d0e929190614ed5565b604051809103902090505f611d308760200135835f9182526020526040902090565b90505f611d7c8760208a01358a3585611d55611d4f60408f018f614f16565b896138d7565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b9050808614611dc1576040517fd3664fb300000000000000000000000000000000000000000000000000000000815260048101879052602481018290526044016110ae565b5f8181526101be602052604090205415611e0a576040517f0f06cd15000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f8181526101be602052604090819020600190555181907f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee07231990611e5a908a908c3590918252602082015260400190565b60405180910390a25050505050505050565b6004611e7781612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611ea181612d56565b845f819003611edc576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b804915611f18576040517f8019aff7000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b6040805160a0810182525f8082526060602083018190529282018390529181018290526080810182905281905f8881526101be60205260408120549003611f8e576040517f6e5424c2000000000000000000000000000000000000000000000000000000008152600481018990526024016110ae565b875f5b85811015612067578b8b82818110611fab57611fab614ffe565b9050602002810190611fbd919061502b565b611fc690615166565b81499450925083612006576040517fc0e41e1d000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b60808301515f818152602086905260409020955061203485875f1c865f0151876020015188604001516139d8565b6060848101518551604080519687526020870194909452928501528301869052608083015260a090912090600101611f91565b508088146120ab576040517fd3664fb300000000000000000000000000000000000000000000000000000000815260048101899052602481018290526044016110ae565b5f8181526101be6020526040902054156120f4576040517f0f06cd15000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f8181526101be602090815260409182902060019055606084015182518c81529182015282917f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319910160405180910390a25050505050505050505050565b600881901c5f90815261014f6020526040812054600160ff84161b16151561102a565b600261218081612fa8565b73ffffffffffffffffffffffffffffffffffffffff85166121cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34841115612207576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f9182612217836151f3565b9091555090505f6122288634614eaf565b90505f61223a33898985878b8b613041565b90506122468382613ba5565b808873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516122ac959493929190615271565b60405180910390a45050505050505050565b5f54610100900460ff16158080156122dc57505f54600160ff909116105b806122f55750303b1580156122f557505f5460ff166001145b612381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016110ae565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156123dd575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f6123ee6080840160608501614efb565b73ffffffffffffffffffffffffffffffffffffffff160361243b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61245e61244b60e08401846152a1565b6124596101008601866152a1565b613c21565b61247082608001358360a00135613ed0565b61248b5f61248661016085016101408601614efb565b612d60565b6124a061249b60c08401846152a1565b613f91565b6124b06080830160608401614efb565b5f805261011b6020527f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561252f61014083016101208401614efb565b6101c080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561258761014083016101208401614efb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f60405160405180910390a36020828101356101198190555f90815261011a825260408082208535905580518084018390528082018390527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830185905260a08084018690528451808503909101815260c08401855280519087012085526101be86528385206001905560e0830185905261010083018590526101208301919091526101408201849052610160808301859052835180840390910181526101808301808552815191909601206101bd558385526101a0820193909352908501356101c09091015290206101bf5580156112d1575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf961275b81612d56565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b5f81600881111561279f5761279f614e0e565b60da54600190911b16151592915050565b6127bd62f099c082614ec2565b4210156127f6576040517f4306cbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805184815260208101849052908101829052606090206101bf541461286e576101bf546040805185815260208101859052908101839052606090206040517fbc5aad11000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016110ae565b6101c05473ffffffffffffffffffffffffffffffffffffffff166128b27f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92982612d60565b60405173ffffffffffffffffffffffffffffffffffffffff82169033907f9fc8868f8577b31b805ee65bb52325782b5e2708dbdb7f04c7467c6785fccb30905f90a350505050565b5f54600690610100900460ff1615801561291a57505f5460ff8083169116105b6129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016110ae565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556129e08888613f91565b6129ec86868686613c21565b6101c080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915560405133907f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f905f90a36040517f362e300000000000000000000000000000000000000000000000000000000000907f352e300000000000000000000000000000000000000000000000000000000000907f2f8492a7a430cf917798dfb60bc5af634f68e6c40287947df0ea6f7ec0669bd8905f90a35f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c612b5781612d56565b73ffffffffffffffffffffffffffffffffffffffff8316612ba4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b602090815260409182902054915173ffffffffffffffffffffffffffffffffffffffff928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f82815260656020526040902060010154612c7481612d56565b61121d8383612e52565b60db5f826008811115612c9357612c93614e0e565b6008811115612ca457612ca4614e0e565b81526020019081526020015f2054612cbb81612d56565b612cc48261278c565b15612cfd57816040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b816008811115612d0f57612d0f614e0e565b60da8054600190921b9091179055816008811115612d2f57612d2f614e0e565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593361110d565b611c3b8133614153565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166112d1575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612df43390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156112d1575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b5f612f3a611c6d60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b14612f71576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa6612f9f60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b600161303a565b565b60da54816008811115612fbd57612fbd614e0e565b6001901b811615612ffc57816040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b60028116156112d15760016040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b80825d5050565b5f60405188815287602082015286604082015285606082015284608082015260c060a08201528260c0820152602083065f811561307f578160200390505b848660e085013790930160e001902098975050505050505050565b5f81815260a660205260409020546001146130e4576040517f992d87c3000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f90815260a66020526040812055565b8015611c3b57426099541015613119576097546131119042614ec2565b609955613129565b609a546131269082614ec2565b90505b609854811115613165576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b612fa661145260017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b5f818360200135116131e3576040517f7061440500000000000000000000000000000000000000000000000000000000815260208401356004820152602481018390526044016110ae565b6131f783610180013584610140013561420c565b6101bf54604080516101608601358152610120860135602082015260e086013591810191909152606090201461328d57604080516101608501358152610120850135602082015260e085013591810191909152606090206101bf546040517fbc5aad11000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016110ae565b42836101000135106132d8576040517fbf81c6e000000000000000000000000000000000000000000000000000000000815261010084013560048201524260248201526044016110ae565b6080830135613313576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61335660408401356060850135608086013560a087013560c0880135604080519586526020860194909452928401919091526060830152608082015260a0902090565b90506133746133696101c0850185614f77565b856101a001356142d9565b61338b6133856101e0850185614f16565b846143df565b6020808401355f81815261011a909252604090912060808501359055610119556101bd8190556133e0610180840135610140850135610100860135604080519384526020840192909252908201526060902090565b6101bf558060208401356133f3846151f3565b60408051873581526080880135602082015291955085917fa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb910160405180910390a492915050565b5f604051858152846020820152604060e0880160408301378360808201528260a082015260a0610120880160c08301376101808101610200880135602081026102208a018337602002902061016082015261018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190069695505050505050565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106134f2576134f2614ffe565b6020908102919091018101919091525f85815261011b909152604090205473ffffffffffffffffffffffffffffffffffffffff168061355d576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808273ffffffffffffffffffffffffffffffffffffffff16637e4f7a8a60e01b87878760405160240161359393929190615305565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161361c9190615376565b5f604051808303815f865af19150503d805f8114613655576040519150601f19603f3d011682016040523d82523d5f602084013e61365a565b606091505b5091509150816137015780511561369f57602081017bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81511663ca389c4460e01b178152815181fd5b6040517fca389c4400000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f556e6b6e6f776e0000000000000000000000000000000000000000000000000060448201526064016110ae565b5f818060200190518101906137169190615381565b90508061374f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600881901c5f90815261014f6020526040902054600160ff83161b16156137b0576040517f335a4a90000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f8060016137e18660026154c1565b6137eb9190614eaf565b90508063ffffffff168463ffffffff161115613843576040517ff7ec909700000000000000000000000000000000000000000000000000000000815263ffffffff8086166004830152821660248201526044016110ae565b865f5b868110156138c957600163ffffffff8716821c811690036138935761388c88888381811061387657613876614ffe565b90506020020135835f9182526020526040902090565b91506138c1565b6138be828989848181106138a9576138a9614ffe565b905060200201355f9182526020526040902090565b91505b600101613846565b509092149695505050505050565b5f6138e36020846154cc565b1561391a576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b80156139cf57602081039050808601357fff0000000000000000000000000000000000000000000000000000000000000081161561398057604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061393d565b50509392505050565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a73ffffffffffffffffffffffffffffffffffffffff168787878787604051602001613a30959493929190615504565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052613a6891615376565b5f60405180830381855afa9150503d805f8114613aa0576040519150601f19603f3d011682016040523d82523d5f602084013e613aa5565b606091505b509150915081613ae1576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040815114613b29578051604080517ff75db3810000000000000000000000000000000000000000000000000000000081526110ae9290600401918252602082015260400190565b6020810151604082015161100082141580613b6457507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b1561374f576040517f68dcad5f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016110ae565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f54610100900460ff16613cb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b825f5b81811015613dbe57858582818110613cd457613cd4614ffe565b9050604002016020013560db5f888885818110613cf357613cf3614ffe565b613d099260206040909202019081019150614911565b6008811115613d1a57613d1a614e0e565b6008811115613d2b57613d2b614e0e565b815260208101919091526040015f20557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec6091868683818110613d6e57613d6e614ffe565b613d849260206040909202019081019150614911565b878784818110613d9657613d96614ffe565b90506040020160200135604051613dae92919061552a565b60405180910390a1600101613cba565b508190505f5b81811015613ec857838382818110613dde57613dde614ffe565b9050604002016020013560dc5f868685818110613dfd57613dfd614ffe565b613e139260206040909202019081019150614911565b6008811115613e2457613e24614e0e565b6008811115613e3557613e35614e0e565b815260208101919091526040015f20557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c2848483818110613e7857613e78614ffe565b613e8e9260206040909202019081019150614911565b858584818110613ea057613ea0614ffe565b90506040020160200135604051613eb892919061552a565b60405180910390a1600101613dc4565b505050505050565b5f54610100900460ff16613f66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b613f6e614473565b613f76614473565b613f7e614473565b613f888282614509565b5050600160e455565b5f54610100900460ff16614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b805f5b8181101561414d575f84848381811061404557614045614ffe565b61405b9260206040909202019081019150614efb565b73ffffffffffffffffffffffffffffffffffffffff16036140a8576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383828181106140ba576140ba614ffe565b905060400201602001355f801b036140fe576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61414584848381811061411357614113614ffe565b9050604002016020013585858481811061412f5761412f614ffe565b6124869260206040909202019081019150614efb565b60010161402a565b50505050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166112d1576141928161466f565b61419d83602061468e565b6040516020016141ae929190615545565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526110ae91600401614995565b815f0361424e5780156112d1576040517f0c256592000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b80614288576040517f5228f4c8000000000000000000000000000000000000000000000000000000008152600481018390526024016110ae565b5f82815261014e602052604090205481146112d1576040517f36459fa000000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016110ae565b5f5b8281101561414d576101505f8585848181106142f9576142f9614ffe565b9050602002013581526020019081526020015f20545f146143625783838281811061432657614326614ffe565b905060200201356040517fe5d144250000000000000000000000000000000000000000000000000000000081526004016110ae91815260200190565b816101505f86868581811061437957614379614ffe565b9050602002013581526020019081526020015f2081905550818484838181106143a4576143a4614ffe565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a36001016142db565b6143ea6002836154cc565b15614424576040517f0c91d776000000000000000000000000000000000000000000000000000000008152600481018390526024016110ae565b5f805b8381101561446c576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a2600201614427565b5050505050565b5f54610100900460ff16612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b5f54610100900460ff1661459f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b815f036145d8576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f03614611576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609782905560988190556146258242614ec2565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a990606001612725565b606061102a73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61469c836002614ee4565b6146a7906002614ec2565b67ffffffffffffffff8111156146bf576146bf615067565b6040519080825280601f01601f1916602001820160405280156146e9576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061471f5761471f614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061478157614781614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6147bb846002614ee4565b6147c6906001614ec2565b90505b6001811115614862577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061480757614807614ffe565b1a60f81b82828151811061481d5761481d614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c9361485b816155af565b90506147c9565b5083156148cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016110ae565b9392505050565b5f602082840312156148e2575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146148cb575f80fd5b5f60208284031215614921575f80fd5b8135600981106148cb575f80fd5b5f6020828403121561493f575f80fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c3b575f80fd5b5f8060408385031215614978575f80fd5b82359150602083013561498a81614946565b809150509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f8083601f8401126149f8575f80fd5b50813567ffffffffffffffff811115614a0f575f80fd5b602083019150836020828501011115614a26575f80fd5b9250929050565b5f805f805f805f8060e0898b031215614a44575f80fd5b8835614a4f81614946565b97506020890135614a5f81614946565b965060408901359550606089013594506080890135614a7d81614946565b935060a089013567ffffffffffffffff811115614a98575f80fd5b614aa48b828c016149e8565b999c989b50969995989497949560c00135949350505050565b5f805f8060608587031215614ad0575f80fd5b843567ffffffffffffffff811115614ae6575f80fd5b614af2878288016149e8565b90955093505060208501359150604085013567ffffffffffffffff811115614b18575f80fd5b85016102008188031215614b2a575f80fd5b939692955090935050565b5f60208284031215614b45575f80fd5b813567ffffffffffffffff811115614b5b575f80fd5b820161014081850312156148cb575f80fd5b5f805f60608486031215614b7f575f80fd5b833567ffffffffffffffff811115614b95575f80fd5b840160608187031215614ba6575f80fd5b95602085013595506040909401359392505050565b5f805f8060608587031215614bce575f80fd5b843567ffffffffffffffff811115614be4575f80fd5b8501601f81018713614bf4575f80fd5b803567ffffffffffffffff811115614c0a575f80fd5b8760208260051b8401011115614c1e575f80fd5b602091820198909750908601359560400135945092505050565b5f805f8060608587031215614c4b575f80fd5b8435614c5681614946565b935060208501359250604085013567ffffffffffffffff811115614c78575f80fd5b614c84878288016149e8565b95989497509550505050565b5f60208284031215614ca0575f80fd5b813567ffffffffffffffff811115614cb6575f80fd5b820161016081850312156148cb575f80fd5b5f805f60608486031215614cda575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112614d01575f80fd5b50813567ffffffffffffffff811115614d18575f80fd5b6020830191508360208260061b8501011115614a26575f80fd5b5f805f805f805f6080888a031215614d48575f80fd5b873567ffffffffffffffff811115614d5e575f80fd5b614d6a8a828b01614cf1565b909850965050602088013567ffffffffffffffff811115614d89575f80fd5b614d958a828b01614cf1565b909650945050604088013567ffffffffffffffff811115614db4575f80fd5b614dc08a828b01614cf1565b9094509250506060880135614dd481614946565b8091505092959891949750929550565b5f8060408385031215614df5575f80fd5b8235614e0081614946565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60098110614e70577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b6020810161102a8284614e3b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561102a5761102a614e82565b8082018082111561102a5761102a614e82565b818382375f9101908152919050565b808202811582820484141761102a5761102a614e82565b5f60208284031215614f0b575f80fd5b81356148cb81614946565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f49575f80fd5b83018035915067ffffffffffffffff821115614f63575f80fd5b602001915036819003821315614a26575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614faa575f80fd5b83018035915067ffffffffffffffff821115614fc4575f80fd5b6020019150600581901b3603821315614a26575f80fd5b5f60208284031215614feb575f80fd5b813563ffffffff811681146148cb575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261505d575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160a0810167ffffffffffffffff811182821017156150b7576150b7615067565b60405290565b5f82601f8301126150cc575f80fd5b813567ffffffffffffffff8111156150e6576150e6615067565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810167ffffffffffffffff8111828210171561513357615133615067565b60405281815283820160200185101561514a575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60a08236031215615176575f80fd5b61517e615094565b82358152602083013567ffffffffffffffff81111561519b575f80fd5b6151a7368286016150bd565b602083015250604083013567ffffffffffffffff8111156151c6575f80fd5b6151d2368286016150bd565b60408301525060608381013590820152608092830135928101929092525090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361522357615223614e82565b5060010190565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b858152846020820152836040820152608060608201525f61529660808301848661522a565b979650505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126152d4575f80fd5b83018035915067ffffffffffffffff8211156152ee575f80fd5b6020019150600681901b3603821315614a26575f80fd5b604081525f61531860408301858761522a565b82810360208401528084518083526020830191506020860192505f5b81811015615352578351835260209384019390920191600101615334565b5090979650505050505050565b5f81518060208401855e5f93019283525090919050565b5f6148cb828461535f565b5f60208284031215615391575f80fd5b815180151581146148cb575f80fd5b6001815b60018411156153db578085048111156153bf576153bf614e82565b60018416156153cd57908102905b60019390931c9280026153a4565b935093915050565b5f826153f15750600161102a565b816153fd57505f61102a565b8160018114615413576002811461541d57615439565b600191505061102a565b60ff84111561542e5761542e614e82565b50506001821b61102a565b5060208310610133831016604e8410600b841016171561545c575081810a61102a565b6154877fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846153a0565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156154b9576154b9614e82565b029392505050565b5f6148cb83836153e3565b5f826154ff577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b8581528460208201528360408201525f615296615524606084018661535f565b8461535f565b604081016155388285614e3b565b8260208301529392505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f615576601783018561535f565b7f206973206d697373696e6720726f6c652000000000000000000000000000000081526155a6601182018561535f565b95945050505050565b5f816155bd576155bd614e82565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122093c0899fafcb326651661ea44d0d07175683e620b7aad7944aa1dbdd20f50bf064736f6c634300081a0033", - "deployedBytecode": "0x60806040526004361061049d575f3560e01c806373bd07b71161026b578063b837dbe911610156578063cc5782f6116100d1578063d5d4b83511610087578063e196fb5d1161006d578063e196fb5d14610ed4578063e97a1e9e14610ef3578063f5b541a614610f65575f80fd5b8063d5d4b83514610e8b578063d722bbfc14610ea1575f80fd5b8063cd9b9e9a116100b7578063cd9b9e9a14610e29578063cf5b276414610e3f578063d547741f14610e6c575f80fd5b8063cc5782f614610dc8578063cc6f725114610df6575f80fd5b8063bf3e750511610126578063c0c4e5841161010c578063c0c4e58414610d75578063c1dc0f0714610d94578063c211697414610da9575f80fd5b8063bf3e750514610d2d578063c0729ab114610d60575f80fd5b8063b837dbe914610ca7578063b9174ba314610cbc578063bc61e73314610cef578063bcc3003d14610d0e575f80fd5b80639ac25d08116101e6578063a98e773d116101b6578063ad422ff01161019c578063ad422ff014610c4b578063aea4f74514610c60578063b59faa6014610c74575f80fd5b8063a98e773d14610bea578063ac1eff6814610c09575f80fd5b80639ac25d0814610b725780639ee8b21114610ba55780639f3ce55a14610bc4578063a217fddf14610bd7575f80fd5b8063914e57eb1161023b578063921b278e11610221578063921b278e14610b3d578063986fcddd14610a4e57806399467a3514610b53575f80fd5b8063914e57eb14610ac057806391d1485414610aec575f80fd5b806373bd07b714610a3a5780637d1e8c5514610a4e5780638be745d114610a615780638de4948714610a8d575f80fd5b80634cdd389b1161038b57806360e83cf31161030657806367e404ce116102d6578063695378f5116102bc578063695378f5146109be5780636a906b80146109d45780636e67384314610a07575f80fd5b806367e404ce146109665780636854f6bc1461099f575f80fd5b806360e83cf3146108bc57806363213155146108e85780636463fb2a1461091b57806366f96e981461093a575f80fd5b8063587944561161035b5780635c721a0c116103415780635c721a0c146108395780635ed73ceb146108645780636078bfd814610890575f80fd5b806358794456146108245780635b7eb4bd14610742575f80fd5b80634cdd389b146107875780635230eef2146107b3578063557eac73146107e65780635603c65f14610805575f80fd5b8063289581741161041b57806338b90333116103eb5780633fc08b65116103d15780633fc08b651461071757806348922ab714610742578063491e093614610768575f80fd5b806338b903331461068f5780633b12eccb146106e4575f80fd5b8063289581741461061c5780632c70645c1461063b5780632f2ff15d1461065157806336568abe14610670575f80fd5b806312d3fa9a116104705780631f443da0116104565780631f443da0146105965780632130d812146105c2578063248a9ca3146105ee575f80fd5b806312d3fa9a1461054d5780631e2ff94f14610580575f80fd5b806301ffc9a7146104a157806303134d1d146104d557806305861180146105165780631065a3991461052c575b5f80fd5b3480156104ac575f80fd5b506104c06104bb3660046148d2565b610f98565b60405190151581526020015b60405180910390f35b3480156104e0575f80fd5b506105087f1ab87f7458c0e3d07e9881c14ee67f0141703614fd48ea5b15ed987e5f4b030e81565b6040519081526020016104cc565b348015610521575f80fd5b506105086101bb5481565b348015610537575f80fd5b5061054b610546366004614911565b611030565b005b348015610558575f80fd5b506105087f67c2dca7476ee0fe1dd3cba13428c6760bfe2599a6dfe26a9ad7ef27317c6e7781565b34801561058b575f80fd5b506105086101185481565b3480156105a1575f80fd5b506105086105b036600461492f565b6101b96020525f908152604090205481565b3480156105cd575f80fd5b506105086105dc36600461492f565b6101be6020525f908152604090205481565b3480156105f9575f80fd5b5061050861060836600461492f565b5f9081526065602052604090206001015490565b348015610627575f80fd5b5061054b61063636600461492f565b611139565b348015610646575f80fd5b506105086101835481565b34801561065c575f80fd5b5061054b61066b366004614967565b6111f9565b34801561067b575f80fd5b5061054b61068a366004614967565b611222565b34801561069a575f80fd5b506106d76040518060400160405280600381526020017f362e30000000000000000000000000000000000000000000000000000000000081525081565b6040516104cc9190614995565b3480156106ef575f80fd5b506105087fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b348015610722575f80fd5b5061050861073136600461492f565b60a56020525f908152604090205481565b34801561074d575f80fd5b50610756600181565b60405160ff90911681526020016104cc565b348015610773575f80fd5b5061054b610782366004614a2d565b6112d5565b348015610792575f80fd5b506105086107a136600461492f565b6101b76020525f908152604090205481565b3480156107be575f80fd5b506105087f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b3480156107f1575f80fd5b5061054b61080036600461492f565b6115d9565b348015610810575f80fd5b5061054b61081f366004614abd565b61169f565b34801561082f575f80fd5b5061050860995481565b348015610844575f80fd5b5061050861085336600461492f565b60a66020525f908152604090205481565b34801561086f575f80fd5b5061050861087e36600461492f565b6101ba6020525f908152604090205481565b34801561089b575f80fd5b506105086108aa36600461492f565b6101b66020525f908152604090205481565b3480156108c7575f80fd5b506105086108d636600461492f565b6101506020525f908152604090205481565b3480156108f3575f80fd5b506105087fe37c272ea30e2bb381ad7cf89ae754b49153250609f36d0cbdad8b64c184bb5c81565b348015610926575f80fd5b5061054b610935366004614b35565b611797565b348015610945575f80fd5b5061050861095436600461492f565b6101b86020525f908152604090205481565b348015610971575f80fd5b5061097a611c3e565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016104cc565b3480156109aa575f80fd5b5061054b6109b9366004614b6d565b611c76565b3480156109c9575f80fd5b506105086101195481565b3480156109df575f80fd5b506105087fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015610a12575f80fd5b506105087f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b348015610a45575f80fd5b50610756600281565b348015610a59575f80fd5b506107565f81565b348015610a6c575f80fd5b50610508610a7b36600461492f565b61011a6020525f908152604090205481565b348015610a98575f80fd5b506105087fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b348015610acb575f80fd5b50610508610ada36600461492f565b61014e6020525f908152604090205481565b348015610af7575f80fd5b506104c0610b06366004614967565b5f91825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b348015610b48575f80fd5b506105086101bf5481565b348015610b5e575f80fd5b5061054b610b6d366004614bbb565b611e6c565b348015610b7d575f80fd5b506105087f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015610bb0575f80fd5b506104c0610bbf36600461492f565b612152565b61054b610bd2366004614c38565b612175565b348015610be2575f80fd5b506105085f81565b348015610bf5575f80fd5b5061054b610c04366004614c90565b6122be565b348015610c14575f80fd5b5061097a610c2336600461492f565b61011b6020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610c56575f80fd5b5061050860985481565b348015610c6b575f80fd5b5061054b612731565b348015610c7f575f80fd5b506105087fe4831f9e4316ac2c65117d1f602fbf56d38128a9973d5e3fdbc5b77265c18d4081565b348015610cb2575f80fd5b5061050860e45481565b348015610cc7575f80fd5b506105087f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b348015610cfa575f80fd5b506104c0610d09366004614911565b61278c565b348015610d19575f80fd5b5061054b610d28366004614cc8565b6127b0565b348015610d38575f80fd5b506105087f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610d6b575f80fd5b50610508609a5481565b348015610d80575f80fd5b5061054b610d8f366004614d32565b6128fa565b348015610d9f575f80fd5b5061050860975481565b348015610db4575f80fd5b5061054b610dc3366004614de4565b612b2d565b348015610dd3575f80fd5b506104c0610de236600461492f565b60d96020525f908152604090205460ff1681565b348015610e01575f80fd5b506105087fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b348015610e34575f80fd5b506105086101bd5481565b348015610e4a575f80fd5b506101c05461097a9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610e77575f80fd5b5061054b610e86366004614967565b612c5a565b348015610e96575f80fd5b506105086101bc5481565b348015610eac575f80fd5b506105087f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a81565b348015610edf575f80fd5b5061054b610eee366004614911565b612c7e565b348015610efe575f80fd5b50610508604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610f70575f80fd5b506105087f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061102a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60dc5f82600881111561104557611045614e0e565b600881111561105657611056614e0e565b81526020019081526020015f205461106d81612d56565b6110768261278c565b6110b757816040517f186596540000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b60405180910390fd5b8160088111156110c9576110c9614e0e565b60da8054600190921b1990911690558160088111156110ea576110ea614e0e565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a61116381612d56565b5f82815261011b6020908152604080832054905173ffffffffffffffffffffffffffffffffffffffff90911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f8281526065602052604090206001015461121381612d56565b61121d8383612d60565b505050565b73ffffffffffffffffffffffffffffffffffffffff811633146112c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016110ae565b6112d18282612e52565b5050565b6112dd612f0b565b85878484875f5a90506112f06003612fa8565b61132461131e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b8f61303a565b5f6113348f8f8f8f8c8f8f613041565b905061133f8161309a565b61135161134c8d8f614ec2565b6130f4565b5f808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d60405161137b929190614ed5565b5f6040518083038185875af1925050503d805f81146113b5576040519150601f19603f3d011682016040523d82523d5f602084013e6113ba565b606091505b509150915081611424578051156113d45780518082602001fd5b8f6040517f546134430000000000000000000000000000000000000000000000000000000081526004016110ae919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b61145861145260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b5f61303a565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a25050861590506115c157855f84900361151057853b15801561150e573a5a6114ac61bc7c86614ec2565b6114b69190614eaf565b6114c09190614ee4565b91508188111561150a5773ffffffffffffffffffffffffffffffffffffffff87166108fc6114ee848b614eaf565b6040518115909202915f818181858888f193505050505061150e565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff8416156115335783611535565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f193505050509050806115bd576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016110ae565b5050505b5050505050506115cf61316a565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261160381612d56565b5f805f4260995410156116285760975461161d9042614ec2565b60995550600161163a565b609a5485101561163a57849250600191505b609885905580806116485750815b1561165357609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b60066116aa81612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296116d481612d56565b5f85900361170e576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a602052604090205484351461175a576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd545f6117698684613198565b90505f61177d878484878b6020013561343b565b905061178b81898c8c6134be565b50505050505050505050565b61179f612f0b565b60a081018035906117b39060808401614efb565b6117c1610120840184614f16565b6117d2610100860160e08701614efb565b5f5a90506117e06003612fa8565b6101008701355f90815261015060205260408120549081900361182f576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118398880614f77565b90508114611888578061184c8980614f77565b6040517f5e3fd6ad00000000000000000000000000000000000000000000000000000000815260048101939093526024830152506044016110ae565b611895886020013561375a565b6118aa61134c60c08a013560a08b0135614ec2565b5f6118f36118be60808b0160608c01614efb565b6118ce60a08c0160808d01614efb565b8b60a001358c60c001358d602001358e8061012001906118ee9190614f16565b613041565b905061191e816119038b80614f77565b61191360608e0160408f01614fdb565b8d61010001356137d2565b611954576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61199761198260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b61199260808c0160608d01614efb565b61303a565b5f806119a960a08c0160808d01614efb565b73ffffffffffffffffffffffffffffffffffffffff1660c08c01356119d26101208e018e614f16565b6040516119e0929190614ed5565b5f6040518083038185875af1925050503d805f8114611a1a576040519150601f19603f3d011682016040523d82523d5f602084013e611a1f565b606091505b509150915081611a9457805115611a395780518082602001fd5b611a4960a08c0160808d01614efb565b6040517f5461344300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016110ae565b611ac261145260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611c2d57855f849003611b7c57853b158015611b7a573a5a611b1861bc7c86614ec2565b611b229190614eaf565b611b2c9190614ee4565b915081881115611b765773ffffffffffffffffffffffffffffffffffffffff87166108fc611b5a848b614eaf565b6040518115909202915f818181858888f1935050505050611b7a565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff841615611b9f5783611ba1565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611c29576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016110ae565b5050505b505050505050611c3b61316a565b50565b5f611c71611c6d60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614eaf565b5c90565b905090565b6005611c8181612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611cab81612d56565b611cb86040860186614f16565b90505f03611cf2576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f611d006040870187614f16565b604051611d0e929190614ed5565b604051809103902090505f611d308760200135835f9182526020526040902090565b90505f611d7c8760208a01358a3585611d55611d4f60408f018f614f16565b896138d7565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b9050808614611dc1576040517fd3664fb300000000000000000000000000000000000000000000000000000000815260048101879052602481018290526044016110ae565b5f8181526101be602052604090205415611e0a576040517f0f06cd15000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f8181526101be602052604090819020600190555181907f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee07231990611e5a908a908c3590918252602082015260400190565b60405180910390a25050505050505050565b6004611e7781612fa8565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611ea181612d56565b845f819003611edc576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b804915611f18576040517f8019aff7000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b6040805160a0810182525f8082526060602083018190529282018390529181018290526080810182905281905f8881526101be60205260408120549003611f8e576040517f6e5424c2000000000000000000000000000000000000000000000000000000008152600481018990526024016110ae565b875f5b85811015612067578b8b82818110611fab57611fab614ffe565b9050602002810190611fbd919061502b565b611fc690615166565b81499450925083612006576040517fc0e41e1d000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b60808301515f818152602086905260409020955061203485875f1c865f0151876020015188604001516139d8565b6060848101518551604080519687526020870194909452928501528301869052608083015260a090912090600101611f91565b508088146120ab576040517fd3664fb300000000000000000000000000000000000000000000000000000000815260048101899052602481018290526044016110ae565b5f8181526101be6020526040902054156120f4576040517f0f06cd15000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f8181526101be602090815260409182902060019055606084015182518c81529182015282917f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319910160405180910390a25050505050505050505050565b600881901c5f90815261014f6020526040812054600160ff84161b16151561102a565b600261218081612fa8565b73ffffffffffffffffffffffffffffffffffffffff85166121cd576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34841115612207576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f9182612217836151f3565b9091555090505f6122288634614eaf565b90505f61223a33898985878b8b613041565b90506122468382613ba5565b808873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516122ac959493929190615271565b60405180910390a45050505050505050565b5f54610100900460ff16158080156122dc57505f54600160ff909116105b806122f55750303b1580156122f557505f5460ff166001145b612381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016110ae565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156123dd575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f6123ee6080840160608501614efb565b73ffffffffffffffffffffffffffffffffffffffff160361243b576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61245e61244b60e08401846152a1565b6124596101008601866152a1565b613c21565b61247082608001358360a00135613ed0565b61248b5f61248661016085016101408601614efb565b612d60565b6124a061249b60c08401846152a1565b613f91565b6124b06080830160608401614efb565b5f805261011b6020527f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561252f61014083016101208401614efb565b6101c080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561258761014083016101208401614efb565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f60405160405180910390a36020828101356101198190555f90815261011a825260408082208535905580518084018390528082018390527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830185905260a08084018690528451808503909101815260c08401855280519087012085526101be86528385206001905560e0830185905261010083018590526101208301919091526101408201849052610160808301859052835180840390910181526101808301808552815191909601206101bd558385526101a0820193909352908501356101c09091015290206101bf5580156112d1575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf961275b81612d56565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b5f81600881111561279f5761279f614e0e565b60da54600190911b16151592915050565b6127bd62f099c082614ec2565b4210156127f6576040517f4306cbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805184815260208101849052908101829052606090206101bf541461286e576101bf546040805185815260208101859052908101839052606090206040517fbc5aad11000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016110ae565b6101c05473ffffffffffffffffffffffffffffffffffffffff166128b27f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92982612d60565b60405173ffffffffffffffffffffffffffffffffffffffff82169033907f9fc8868f8577b31b805ee65bb52325782b5e2708dbdb7f04c7467c6785fccb30905f90a350505050565b5f54600690610100900460ff1615801561291a57505f5460ff8083169116105b6129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016110ae565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556129e08888613f91565b6129ec86868686613c21565b6101c080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841690811790915560405133907f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f905f90a36040517f362e300000000000000000000000000000000000000000000000000000000000907f352e300000000000000000000000000000000000000000000000000000000000907f2f8492a7a430cf917798dfb60bc5af634f68e6c40287947df0ea6f7ec0669bd8905f90a35f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c612b5781612d56565b73ffffffffffffffffffffffffffffffffffffffff8316612ba4576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b602090815260409182902054915173ffffffffffffffffffffffffffffffffffffffff928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b5f82815260656020526040902060010154612c7481612d56565b61121d8383612e52565b60db5f826008811115612c9357612c93614e0e565b6008811115612ca457612ca4614e0e565b81526020019081526020015f2054612cbb81612d56565b612cc48261278c565b15612cfd57816040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b816008811115612d0f57612d0f614e0e565b60da8054600190921b9091179055816008811115612d2f57612d2f614e0e565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593361110d565b611c3b8133614153565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166112d1575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612df43390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156112d1575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b5f612f3a611c6d60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b14612f71576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fa6612f9f60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b600161303a565b565b60da54816008811115612fbd57612fbd614e0e565b6001901b811615612ffc57816040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b60028116156112d15760016040517fc0a71b580000000000000000000000000000000000000000000000000000000081526004016110ae9190614e74565b80825d5050565b5f60405188815287602082015286604082015285606082015284608082015260c060a08201528260c0820152602083065f811561307f578160200390505b848660e085013790930160e001902098975050505050505050565b5f81815260a660205260409020546001146130e4576040517f992d87c3000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b5f90815260a66020526040812055565b8015611c3b57426099541015613119576097546131119042614ec2565b609955613129565b609a546131269082614ec2565b90505b609854811115613165576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b612fa661145260017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614eaf565b5f818360200135116131e3576040517f7061440500000000000000000000000000000000000000000000000000000000815260208401356004820152602481018390526044016110ae565b6131f783610180013584610140013561420c565b6101bf54604080516101608601358152610120860135602082015260e086013591810191909152606090201461328d57604080516101608501358152610120850135602082015260e085013591810191909152606090206101bf546040517fbc5aad11000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016110ae565b42836101000135106132d8576040517fbf81c6e000000000000000000000000000000000000000000000000000000000815261010084013560048201524260248201526044016110ae565b6080830135613313576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61335660408401356060850135608086013560a087013560c0880135604080519586526020860194909452928401919091526060830152608082015260a0902090565b90506133746133696101c0850185614f77565b856101a001356142d9565b61338b6133856101e0850185614f16565b846143df565b6020808401355f81815261011a909252604090912060808501359055610119556101bd8190556133e0610180840135610140850135610100860135604080519384526020840192909252908201526060902090565b6101bf558060208401356133f3846151f3565b60408051873581526080880135602082015291955085917fa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb910160405180910390a492915050565b5f604051858152846020820152604060e0880160408301378360808201528260a082015260a0610120880160c08301376101808101610200880135602081026102208a018337602002902061016082015261018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190069695505050505050565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106134f2576134f2614ffe565b6020908102919091018101919091525f85815261011b909152604090205473ffffffffffffffffffffffffffffffffffffffff168061355d576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808273ffffffffffffffffffffffffffffffffffffffff16637e4f7a8a60e01b87878760405160240161359393929190615305565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161361c9190615376565b5f604051808303815f865af19150503d805f8114613655576040519150601f19603f3d011682016040523d82523d5f602084013e61365a565b606091505b5091509150816137015780511561369f57602081017bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81511663ca389c4460e01b178152815181fd5b6040517fca389c4400000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f556e6b6e6f776e0000000000000000000000000000000000000000000000000060448201526064016110ae565b5f818060200190518101906137169190615381565b90508061374f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600881901c5f90815261014f6020526040902054600160ff83161b16156137b0576040517f335a4a90000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f8060016137e18660026154c1565b6137eb9190614eaf565b90508063ffffffff168463ffffffff161115613843576040517ff7ec909700000000000000000000000000000000000000000000000000000000815263ffffffff8086166004830152821660248201526044016110ae565b865f5b868110156138c957600163ffffffff8716821c811690036138935761388c88888381811061387657613876614ffe565b90506020020135835f9182526020526040902090565b91506138c1565b6138be828989848181106138a9576138a9614ffe565b905060200201355f9182526020526040902090565b91505b600101613846565b509092149695505050505050565b5f6138e36020846154cc565b1561391a576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b80156139cf57602081039050808601357fff0000000000000000000000000000000000000000000000000000000000000081161561398057604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061393d565b50509392505050565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a73ffffffffffffffffffffffffffffffffffffffff168787878787604051602001613a30959493929190615504565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052613a6891615376565b5f60405180830381855afa9150503d805f8114613aa0576040519150601f19603f3d011682016040523d82523d5f602084013e613aa5565b606091505b509150915081613ae1576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040815114613b29578051604080517ff75db3810000000000000000000000000000000000000000000000000000000081526110ae9290600401918252602082015260400190565b6020810151604082015161100082141580613b6457507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b1561374f576040517f68dcad5f00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016110ae565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f54610100900460ff16613cb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b825f5b81811015613dbe57858582818110613cd457613cd4614ffe565b9050604002016020013560db5f888885818110613cf357613cf3614ffe565b613d099260206040909202019081019150614911565b6008811115613d1a57613d1a614e0e565b6008811115613d2b57613d2b614e0e565b815260208101919091526040015f20557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec6091868683818110613d6e57613d6e614ffe565b613d849260206040909202019081019150614911565b878784818110613d9657613d96614ffe565b90506040020160200135604051613dae92919061552a565b60405180910390a1600101613cba565b508190505f5b81811015613ec857838382818110613dde57613dde614ffe565b9050604002016020013560dc5f868685818110613dfd57613dfd614ffe565b613e139260206040909202019081019150614911565b6008811115613e2457613e24614e0e565b6008811115613e3557613e35614e0e565b815260208101919091526040015f20557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c2848483818110613e7857613e78614ffe565b613e8e9260206040909202019081019150614911565b858584818110613ea057613ea0614ffe565b90506040020160200135604051613eb892919061552a565b60405180910390a1600101613dc4565b505050505050565b5f54610100900460ff16613f66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b613f6e614473565b613f76614473565b613f7e614473565b613f888282614509565b5050600160e455565b5f54610100900460ff16614027576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b805f5b8181101561414d575f84848381811061404557614045614ffe565b61405b9260206040909202019081019150614efb565b73ffffffffffffffffffffffffffffffffffffffff16036140a8576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8383828181106140ba576140ba614ffe565b905060400201602001355f801b036140fe576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61414584848381811061411357614113614ffe565b9050604002016020013585858481811061412f5761412f614ffe565b6124869260206040909202019081019150614efb565b60010161402a565b50505050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166112d1576141928161466f565b61419d83602061468e565b6040516020016141ae929190615545565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526110ae91600401614995565b815f0361424e5780156112d1576040517f0c256592000000000000000000000000000000000000000000000000000000008152600481018290526024016110ae565b80614288576040517f5228f4c8000000000000000000000000000000000000000000000000000000008152600481018390526024016110ae565b5f82815261014e602052604090205481146112d1576040517f36459fa000000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016110ae565b5f5b8281101561414d576101505f8585848181106142f9576142f9614ffe565b9050602002013581526020019081526020015f20545f146143625783838281811061432657614326614ffe565b905060200201356040517fe5d144250000000000000000000000000000000000000000000000000000000081526004016110ae91815260200190565b816101505f86868581811061437957614379614ffe565b9050602002013581526020019081526020015f2081905550818484838181106143a4576143a4614ffe565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a36001016142db565b6143ea6002836154cc565b15614424576040517f0c91d776000000000000000000000000000000000000000000000000000000008152600481018390526024016110ae565b5f805b8381101561446c576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a2600201614427565b5050505050565b5f54610100900460ff16612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b5f54610100900460ff1661459f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016110ae565b815f036145d8576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f03614611576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609782905560988190556146258242614ec2565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a990606001612725565b606061102a73ffffffffffffffffffffffffffffffffffffffff831660145b60605f61469c836002614ee4565b6146a7906002614ec2565b67ffffffffffffffff8111156146bf576146bf615067565b6040519080825280601f01601f1916602001820160405280156146e9576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f8151811061471f5761471f614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061478157614781614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6147bb846002614ee4565b6147c6906001614ec2565b90505b6001811115614862577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061480757614807614ffe565b1a60f81b82828151811061481d5761481d614ffe565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c9361485b816155af565b90506147c9565b5083156148cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016110ae565b9392505050565b5f602082840312156148e2575f80fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146148cb575f80fd5b5f60208284031215614921575f80fd5b8135600981106148cb575f80fd5b5f6020828403121561493f575f80fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c3b575f80fd5b5f8060408385031215614978575f80fd5b82359150602083013561498a81614946565b809150509250929050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f8083601f8401126149f8575f80fd5b50813567ffffffffffffffff811115614a0f575f80fd5b602083019150836020828501011115614a26575f80fd5b9250929050565b5f805f805f805f8060e0898b031215614a44575f80fd5b8835614a4f81614946565b97506020890135614a5f81614946565b965060408901359550606089013594506080890135614a7d81614946565b935060a089013567ffffffffffffffff811115614a98575f80fd5b614aa48b828c016149e8565b999c989b50969995989497949560c00135949350505050565b5f805f8060608587031215614ad0575f80fd5b843567ffffffffffffffff811115614ae6575f80fd5b614af2878288016149e8565b90955093505060208501359150604085013567ffffffffffffffff811115614b18575f80fd5b85016102008188031215614b2a575f80fd5b939692955090935050565b5f60208284031215614b45575f80fd5b813567ffffffffffffffff811115614b5b575f80fd5b820161014081850312156148cb575f80fd5b5f805f60608486031215614b7f575f80fd5b833567ffffffffffffffff811115614b95575f80fd5b840160608187031215614ba6575f80fd5b95602085013595506040909401359392505050565b5f805f8060608587031215614bce575f80fd5b843567ffffffffffffffff811115614be4575f80fd5b8501601f81018713614bf4575f80fd5b803567ffffffffffffffff811115614c0a575f80fd5b8760208260051b8401011115614c1e575f80fd5b602091820198909750908601359560400135945092505050565b5f805f8060608587031215614c4b575f80fd5b8435614c5681614946565b935060208501359250604085013567ffffffffffffffff811115614c78575f80fd5b614c84878288016149e8565b95989497509550505050565b5f60208284031215614ca0575f80fd5b813567ffffffffffffffff811115614cb6575f80fd5b820161016081850312156148cb575f80fd5b5f805f60608486031215614cda575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112614d01575f80fd5b50813567ffffffffffffffff811115614d18575f80fd5b6020830191508360208260061b8501011115614a26575f80fd5b5f805f805f805f6080888a031215614d48575f80fd5b873567ffffffffffffffff811115614d5e575f80fd5b614d6a8a828b01614cf1565b909850965050602088013567ffffffffffffffff811115614d89575f80fd5b614d958a828b01614cf1565b909650945050604088013567ffffffffffffffff811115614db4575f80fd5b614dc08a828b01614cf1565b9094509250506060880135614dd481614946565b8091505092959891949750929550565b5f8060408385031215614df5575f80fd5b8235614e0081614946565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60098110614e70577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b6020810161102a8284614e3b565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8181038181111561102a5761102a614e82565b8082018082111561102a5761102a614e82565b818382375f9101908152919050565b808202811582820484141761102a5761102a614e82565b5f60208284031215614f0b575f80fd5b81356148cb81614946565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614f49575f80fd5b83018035915067ffffffffffffffff821115614f63575f80fd5b602001915036819003821315614a26575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614faa575f80fd5b83018035915067ffffffffffffffff821115614fc4575f80fd5b6020019150600581901b3603821315614a26575f80fd5b5f60208284031215614feb575f80fd5b813563ffffffff811681146148cb575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6183360301811261505d575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160a0810167ffffffffffffffff811182821017156150b7576150b7615067565b60405290565b5f82601f8301126150cc575f80fd5b813567ffffffffffffffff8111156150e6576150e6615067565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810167ffffffffffffffff8111828210171561513357615133615067565b60405281815283820160200185101561514a575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60a08236031215615176575f80fd5b61517e615094565b82358152602083013567ffffffffffffffff81111561519b575f80fd5b6151a7368286016150bd565b602083015250604083013567ffffffffffffffff8111156151c6575f80fd5b6151d2368286016150bd565b60408301525060608381013590820152608092830135928101929092525090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361522357615223614e82565b5060010190565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b858152846020820152836040820152608060608201525f61529660808301848661522a565b979650505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126152d4575f80fd5b83018035915067ffffffffffffffff8211156152ee575f80fd5b6020019150600681901b3603821315614a26575f80fd5b604081525f61531860408301858761522a565b82810360208401528084518083526020830191506020860192505f5b81811015615352578351835260209384019390920191600101615334565b5090979650505050505050565b5f81518060208401855e5f93019283525090919050565b5f6148cb828461535f565b5f60208284031215615391575f80fd5b815180151581146148cb575f80fd5b6001815b60018411156153db578085048111156153bf576153bf614e82565b60018416156153cd57908102905b60019390931c9280026153a4565b935093915050565b5f826153f15750600161102a565b816153fd57505f61102a565b8160018114615413576002811461541d57615439565b600191505061102a565b60ff84111561542e5761542e614e82565b50506001821b61102a565b5060208310610133831016604e8410600b841016171561545c575081810a61102a565b6154877fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846153a0565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156154b9576154b9614e82565b029392505050565b5f6148cb83836153e3565b5f826154ff577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b8581528460208201528360408201525f615296615524606084018661535f565b8461535f565b604081016155388285614e3b565b8260208301529392505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f615576601783018561535f565b7f206973206d697373696e6720726f6c652000000000000000000000000000000081526155a6601182018561535f565b95945050505050565b5f816155bd576155bd614e82565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122093c0899fafcb326651661ea44d0d07175683e620b7aad7944aa1dbdd20f50bf064736f6c634300081a0033", + "bytecode": "0x6080604052348015600e575f80fd5b5060156019565b60d3565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff9081161460d1575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615462806100e05f395ff3fe60806040526004361061049d575f3560e01c806373bd07b71161026b578063b837dbe911610156578063cc5782f6116100d1578063d5d4b83511610087578063e196fb5d1161006d578063e196fb5d14610ea0578063e97a1e9e14610ebf578063f5b541a614610f31575f80fd5b8063d5d4b83514610e57578063d722bbfc14610e6d575f80fd5b8063cd9b9e9a116100b7578063cd9b9e9a14610e02578063cf5b276414610e18578063d547741f14610e38575f80fd5b8063cc5782f614610da1578063cc6f725114610dcf575f80fd5b8063bf3e750511610126578063c0c4e5841161010c578063c0c4e58414610d4e578063c1dc0f0714610d6d578063c211697414610d82575f80fd5b8063bf3e750514610d06578063c0729ab114610d39575f80fd5b8063b837dbe914610c80578063b9174ba314610c95578063bc61e73314610cc8578063bcc3003d14610ce7575f80fd5b80639ac25d08116101e6578063a98e773d116101b6578063ad422ff01161019c578063ad422ff014610c24578063aea4f74514610c39578063b59faa6014610c4d575f80fd5b8063a98e773d14610bd0578063ac1eff6814610bef575f80fd5b80639ac25d0814610b585780639ee8b21114610b8b5780639f3ce55a14610baa578063a217fddf14610bbd575f80fd5b8063914e57eb1161023b578063921b278e11610221578063921b278e14610b23578063986fcddd14610a4157806399467a3514610b39575f80fd5b8063914e57eb14610ab357806391d1485414610adf575f80fd5b806373bd07b714610a2d5780637d1e8c5514610a415780638be745d114610a545780638de4948714610a80575f80fd5b80634cdd389b1161038b57806360e83cf31161030657806367e404ce116102d6578063695378f5116102bc578063695378f5146109b15780636a906b80146109c75780636e673843146109fa575f80fd5b806367e404ce146109665780636854f6bc14610992575f80fd5b806360e83cf3146108bc57806363213155146108e85780636463fb2a1461091b57806366f96e981461093a575f80fd5b8063587944561161035b5780635c721a0c116103415780635c721a0c146108395780635ed73ceb146108645780636078bfd814610890575f80fd5b806358794456146108245780635b7eb4bd14610742575f80fd5b80634cdd389b146107875780635230eef2146107b3578063557eac73146107e65780635603c65f14610805575f80fd5b8063289581741161041b57806338b90333116103eb5780633fc08b65116103d15780633fc08b651461071757806348922ab714610742578063491e093614610768575f80fd5b806338b903331461068f5780633b12eccb146106e4575f80fd5b8063289581741461061c5780632c70645c1461063b5780632f2ff15d1461065157806336568abe14610670575f80fd5b806312d3fa9a116104705780631f443da0116104565780631f443da0146105965780632130d812146105c2578063248a9ca3146105ee575f80fd5b806312d3fa9a1461054d5780631e2ff94f14610580575f80fd5b806301ffc9a7146104a157806303134d1d146104d557806305861180146105165780631065a3991461052c575b5f80fd5b3480156104ac575f80fd5b506104c06104bb3660046147a5565b610f64565b60405190151581526020015b60405180910390f35b3480156104e0575f80fd5b506105087f1ab87f7458c0e3d07e9881c14ee67f0141703614fd48ea5b15ed987e5f4b030e81565b6040519081526020016104cc565b348015610521575f80fd5b506105086101bb5481565b348015610537575f80fd5b5061054b6105463660046147e4565b610ffc565b005b348015610558575f80fd5b506105087f67c2dca7476ee0fe1dd3cba13428c6760bfe2599a6dfe26a9ad7ef27317c6e7781565b34801561058b575f80fd5b506105086101185481565b3480156105a1575f80fd5b506105086105b0366004614802565b6101b96020525f908152604090205481565b3480156105cd575f80fd5b506105086105dc366004614802565b6101be6020525f908152604090205481565b3480156105f9575f80fd5b50610508610608366004614802565b5f9081526065602052604090206001015490565b348015610627575f80fd5b5061054b610636366004614802565b6110f8565b348015610646575f80fd5b506105086101835481565b34801561065c575f80fd5b5061054b61066b36600461482d565b6111ab565b34801561067b575f80fd5b5061054b61068a36600461482d565b6111d4565b34801561069a575f80fd5b506106d76040518060400160405280600381526020017f362e30000000000000000000000000000000000000000000000000000000000081525081565b6040516104cc919061485b565b3480156106ef575f80fd5b506105087fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b348015610722575f80fd5b50610508610731366004614802565b60a56020525f908152604090205481565b34801561074d575f80fd5b50610756600181565b60405160ff90911681526020016104cc565b348015610773575f80fd5b5061054b6107823660046148d5565b61122b565b348015610792575f80fd5b506105086107a1366004614802565b6101b76020525f908152604090205481565b3480156107be575f80fd5b506105087f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b3480156107f1575f80fd5b5061054b610800366004614802565b6114e1565b348015610810575f80fd5b5061054b61081f366004614965565b6115a7565b34801561082f575f80fd5b5061050860995481565b348015610844575f80fd5b50610508610853366004614802565b60a66020525f908152604090205481565b34801561086f575f80fd5b5061050861087e366004614802565b6101ba6020525f908152604090205481565b34801561089b575f80fd5b506105086108aa366004614802565b6101b66020525f908152604090205481565b3480156108c7575f80fd5b506105086108d6366004614802565b6101506020525f908152604090205481565b3480156108f3575f80fd5b506105087fe37c272ea30e2bb381ad7cf89ae754b49153250609f36d0cbdad8b64c184bb5c81565b348015610926575f80fd5b5061054b6109353660046149dd565b61169f565b348015610945575f80fd5b50610508610954366004614802565b6101b86020525f908152604090205481565b348015610971575f80fd5b5061097a611af8565b6040516001600160a01b0390911681526020016104cc565b34801561099d575f80fd5b5061054b6109ac366004614a15565b611b30565b3480156109bc575f80fd5b506105086101195481565b3480156109d2575f80fd5b506105087fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015610a05575f80fd5b506105087f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b348015610a38575f80fd5b50610756600281565b348015610a4c575f80fd5b506107565f81565b348015610a5f575f80fd5b50610508610a6e366004614802565b61011a6020525f908152604090205481565b348015610a8b575f80fd5b506105087fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b348015610abe575f80fd5b50610508610acd366004614802565b61014e6020525f908152604090205481565b348015610aea575f80fd5b506104c0610af936600461482d565b5f9182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610b2e575f80fd5b506105086101bf5481565b348015610b44575f80fd5b5061054b610b53366004614a63565b611d70565b348015610b63575f80fd5b506105087f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015610b96575f80fd5b506104c0610ba5366004614802565b612054565b61054b610bb8366004614ae0565b612077565b348015610bc8575f80fd5b506105085f81565b348015610bdb575f80fd5b5061054b610bea366004614b38565b612199565b348015610bfa575f80fd5b5061097a610c09366004614802565b61011b6020525f90815260409020546001600160a01b031681565b348015610c2f575f80fd5b5061050860985481565b348015610c44575f80fd5b5061054b6125cb565b348015610c58575f80fd5b506105087fe4831f9e4316ac2c65117d1f602fbf56d38128a9973d5e3fdbc5b77265c18d4081565b348015610c8b575f80fd5b5061050860e45481565b348015610ca0575f80fd5b506105087f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b348015610cd3575f80fd5b506104c0610ce23660046147e4565b612626565b348015610cf2575f80fd5b5061054b610d01366004614b70565b61264a565b348015610d11575f80fd5b506105087f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610d44575f80fd5b50610508609a5481565b348015610d59575f80fd5b5061054b610d68366004614bda565b61277a565b348015610d78575f80fd5b5061050860975481565b348015610d8d575f80fd5b5061054b610d9c366004614c8c565b6129e0565b348015610dac575f80fd5b506104c0610dbb366004614802565b60d96020525f908152604090205460ff1681565b348015610dda575f80fd5b506105087fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b348015610e0d575f80fd5b506105086101bd5481565b348015610e23575f80fd5b506101c05461097a906001600160a01b031681565b348015610e43575f80fd5b5061054b610e5236600461482d565b612ae6565b348015610e62575f80fd5b506105086101bc5481565b348015610e78575f80fd5b506105087f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a81565b348015610eab575f80fd5b5061054b610eba3660046147e4565b612b0a565b348015610eca575f80fd5b50610508604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610f3c575f80fd5b506105087f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610ff657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60dc5f82600881111561101157611011614cb6565b600881111561102257611022614cb6565b81526020019081526020015f205461103981612be2565b61104282612626565b61108357816040517f1865965400000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b60405180910390fd5b81600881111561109557611095614cb6565b60da8054600190921b1990911690558160088111156110b6576110b6614cb6565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b6040516001600160a01b03909116815260200160405180910390a25050565b7f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a61112281612be2565b5f82815261011b602090815260408083205490516001600160a01b0390911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f828152606560205260409020600101546111c581612be2565b6111cf8383612bec565b505050565b6101c0546001600160a01b039081169082160361121d576040517f7f7497e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112278282612caa565b5050565b611233612d4c565b85878484875f5a90506112466003612de9565b61127a61127460017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b8f612e7b565b5f61128a8f8f8f8f8c8f8f612e82565b905061129581612edb565b6112a76112a28d8f614d62565b612f35565b5f808f6001600160a01b03168e8d8d6040516112c4929190614d75565b5f6040518083038185875af1925050503d805f81146112fe576040519150601f19603f3d011682016040523d82523d5f602084013e611303565b606091505b5091509150816113605780511561131d5780518082602001fd5b8f6040517f5461344300000000000000000000000000000000000000000000000000000000815260040161107a91906001600160a01b0391909116815260200190565b61139461138e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b5f612e7b565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a25050861590506114c957855f84900361143f57853b15801561143d573a5a6113e861bc7c86614d62565b6113f29190614d4f565b6113fc9190614d84565b915081881115611439576001600160a01b0387166108fc61141d848b614d4f565b6040518115909202915f818181858888f193505050505061143d565b8791505b505b5f6001600160a01b038416156114555783611457565b335b90505f816001600160a01b03166108fc8490811502906040515f60405180830381858888f193505050509050806114c5576040517fa57c4df40000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161107a565b5050505b5050505050506114d7612fab565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261150b81612be2565b5f805f426099541015611530576097546115259042614d62565b609955506001611542565b609a5485101561154257849250600191505b609885905580806115505750815b1561155b57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b60066115b281612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296115dc81612be2565b5f859003611616576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a6020526040902054843514611662576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd545f6116718684612fd9565b90505f611685878484878b602001356132c6565b905061169381898c8c61334e565b50505050505050505050565b6116a7612d4c565b60a081018035906116bb9060808401614d9b565b6116c9610120840184614db6565b6116da610100860160e08701614d9b565b5f5a90506116e86003612de9565b6101008701355f908152610150602052604081205490819003611737576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117418880614e17565b9050811461179057806117548980614e17565b6040517f5e3fd6ad000000000000000000000000000000000000000000000000000000008152600481019390935260248301525060440161107a565b61179d88602001356135b2565b6117b26112a260c08a013560a08b0135614d62565b5f6117fb6117c660808b0160608c01614d9b565b6117d660a08c0160808d01614d9b565b8b60a001358c60c001358d602001358e8061012001906117f69190614db6565b612e82565b90506118268161180b8b80614e17565b61181b60608e0160408f01614e7b565b8d610100013561362a565b61185c576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61189f61188a60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b61189a60808c0160608d01614d9b565b612e7b565b5f806118b160a08c0160808d01614d9b565b6001600160a01b031660c08c01356118cd6101208e018e614db6565b6040516118db929190614d75565b5f6040518083038185875af1925050503d805f8114611915576040519150601f19603f3d011682016040523d82523d5f602084013e61191a565b606091505b509150915081611982578051156119345780518082602001fd5b61194460a08c0160808d01614d9b565b6040517f546134430000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015260240161107a565b6119b061138e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611ae757855f849003611a5d57853b158015611a5b573a5a611a0661bc7c86614d62565b611a109190614d4f565b611a1a9190614d84565b915081881115611a57576001600160a01b0387166108fc611a3b848b614d4f565b6040518115909202915f818181858888f1935050505050611a5b565b8791505b505b5f6001600160a01b03841615611a735783611a75565b335b90505f816001600160a01b03166108fc8490811502906040515f60405180830381858888f19350505050905080611ae3576040517fa57c4df40000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161107a565b5050505b505050505050611af5612fab565b50565b5f611b2b611b2760017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b5c90565b905090565b6005611b3b81612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611b6581612be2565b611b726040860186614db6565b90505f03611bac576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381526101be602052604090205415611bf5576040517f0f06cd150000000000000000000000000000000000000000000000000000000081526004810184905260240161107a565b5f8481526101be60205260408120549003611c3f576040517f6e5424c20000000000000000000000000000000000000000000000000000000081526004810185905260240161107a565b5f611c4d6040870187614db6565b604051611c5b929190614d75565b604051809103902090505f611c7d8760200135835f9182526020526040902090565b90505f611cc98760208a01358a3585611ca2611c9c60408f018f614db6565b89613737565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b9050808614611d0e576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018790526024810182905260440161107a565b5f8181526101be602052604090819020600190555181907f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee07231990611d5e908a908c3590918252602082015260400190565b60405180910390a25050505050505050565b6004611d7b81612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611da581612be2565b5f859003611ddf576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b844915611e1b576040517f8019aff70000000000000000000000000000000000000000000000000000000081526004810186905260240161107a565b5f8481526101be60205260408120549003611e65576040517f6e5424c20000000000000000000000000000000000000000000000000000000081526004810185905260240161107a565b5f8381526101be602052604090205415611eae576040517f0f06cd150000000000000000000000000000000000000000000000000000000081526004810184905260240161107a565b6040805160a0810182525f808252606060208301819052928201839052918101829052608081018290528190865f5b89811015611fb3578a8a82818110611ef757611ef7614e9e565b9050602002810190611f099190614ecb565b611f1290614fe8565b81499450925083611f52576040517fc0e41e1d0000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b60808301515f8181526020869052604090209550611f8085875f1c865f015187602001518860400151613838565b6060848101518551604080519687526020870194909452928501528301869052608083015260a090912090600101611edd565b50808714611ff7576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018890526024810182905260440161107a565b5f8181526101be602090815260409182902060019055606084015182518b81529182015282917f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319910160405180910390a250505050505050505050565b600881901c5f90815261014f6020526040812054600160ff84161b161515610ff6565b600261208281612de9565b6001600160a01b0385166120c2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348411156120fc576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f918261210c83615075565b9091555090505f61211d8634614d4f565b90505f61212f33898985878b8b612e82565b905061213b83826139da565b80886001600160a01b0316336001600160a01b03167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516121879594939291906150d5565b60405180910390a45050505050505050565b5f54610100900460ff16158080156121b757505f54600160ff909116105b806121d05750303b1580156121d057505f5460ff166001145b61225c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161107a565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156122b8575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f6122c96080840160608501614d9b565b6001600160a01b031603612309576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61232c61231960e0840184615105565b612327610100860186615105565b613a56565b61233e82608001358360a00135613d04565b6123595f61235461016085016101408601614d9b565b612bec565b61236e61236960c0840184615105565b613dc5565b61237e6080830160608401614d9b565b5f805261011b6020527f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790556123f061014083016101208401614d9b565b6101c080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561243b61014083016101208401614d9b565b6001600160a01b0316336001600160a01b03167f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f60405160405180910390a36020828101356101198190555f90815261011a825260408082208535905580518084018390528082018390527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830185905260a08084018690528451808503909101815260c08401855280519087012085526101be86528385206001905560e0830185905261010083018590526101208301919091526101408201849052610160808301859052835180840390910181526101808301808552815191909601206101bd558385526101a0820193909352908501356101c09091015290206101bf558015611227575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf96125f581612be2565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b5f81600881111561263957612639614cb6565b60da54600190911b16151592915050565b61265762f099c082614d62565b421015612690576040517f4306cbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805184815260208101849052908101829052606090206101bf5414612708576101bf546040805185815260208101859052908101839052606090206040517fbc5aad110000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161107a565b6101c0546001600160a01b031661273f7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92982612bec565b6040516001600160a01b0382169033907f9fc8868f8577b31b805ee65bb52325782b5e2708dbdb7f04c7467c6785fccb30905f90a350505050565b5f54600690610100900460ff1615801561279a57505f5460ff8083169116105b612826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161107a565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556128608888613dc5565b61286c86868686613a56565b6001600160a01b0382166128ac576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101c080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03841690811790915560405133907f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f905f90a36040517f362e300000000000000000000000000000000000000000000000000000000000907f352e300000000000000000000000000000000000000000000000000000000000907f2f8492a7a430cf917798dfb60bc5af634f68e6c40287947df0ea6f7ec0669bd8905f90a35f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c612a0a81612be2565b6001600160a01b038316612a4a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b60209081526040918290205491516001600160a01b03928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b5f82815260656020526040902060010154612b0081612be2565b6111cf8383613f73565b60db5f826008811115612b1f57612b1f614cb6565b6008811115612b3057612b30614cb6565b81526020019081526020015f2054612b4781612be2565b612b5082612626565b15612b8957816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b816008811115612b9b57612b9b614cb6565b60da8054600190921b9091179055816008811115612bbb57612bbb614cb6565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d4559336110d9565b611af58133614012565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff16611227575f8281526065602090815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612c663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b0381163314612d42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161107a565b6112278282613f73565b5f612d7b611b2760017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b14612db2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612de7612de060017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b6001612e7b565b565b60da54816008811115612dfe57612dfe614cb6565b6001901b811615612e3d57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b60028116156112275760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b80825d5050565b5f60405188815287602082015286604082015285606082015284608082015260c060a08201528260c0820152602083065f8115612ec0578160200390505b848660e085013790930160e001902098975050505050505050565b5f81815260a66020526040902054600114612f25576040517f992d87c30000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b5f90815260a66020526040812055565b8015611af557426099541015612f5a57609754612f529042614d62565b609955612f6a565b609a54612f679082614d62565b90505b609854811115612fa6576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b612de761138e60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b5f81836020013511613024576040517f70614405000000000000000000000000000000000000000000000000000000008152602084013560048201526024810183905260440161107a565b6130388361018001358461014001356140a0565b6101bf54604080516101608601358152610120860135602082015260e08601359181019190915260609020146130ce57604080516101608501358152610120850135602082015260e085013591810191909152606090206101bf546040517fbc5aad110000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161107a565b4283610100013510613119576040517fbf81c6e0000000000000000000000000000000000000000000000000000000008152610100840135600482015242602482015260440161107a565b6080830135613154576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61319760408401356060850135608086013560a087013560c0880135604080519586526020860194909452928401919091526060830152608082015260a0902090565b5f8181526101be6020526040812054919250036131e3576040517fedeae83c0000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b6131ff6131f46101c0850185614e17565b856101a0013561416d565b6132166132106101e0850185614db6565b84614279565b6020808401355f81815261011a909252604090912060808501359055610119556101bd81905561326b610180840135610140850135610100860135604080519384526020840192909252908201526060902090565b6101bf5580602084013561327e84615075565b60408051873581526080880135602082015291955085917fa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb910160405180910390a492915050565b5f604051858152846020820152604060e0880160408301378360808201528260a082015260a0610120880160c083013761018081016101c088013588018035602081026020830184376020029091206101608301525061018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190069695505050505050565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061338257613382614e9e565b6020908102919091018101919091525f85815261011b90915260409020546001600160a01b0316806133e0576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80826001600160a01b0316637e4f7a8a60e01b87878760405160240161340993929190615169565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161347491906151da565b5f604051808303815f865af19150503d805f81146134ad576040519150601f19603f3d011682016040523d82523d5f602084013e6134b2565b606091505b509150915081613559578051156134f757602081017bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81511663ca389c4460e01b178152815181fd5b6040517fca389c4400000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f556e6b6e6f776e00000000000000000000000000000000000000000000000000604482015260640161107a565b5f8180602001905181019061356e91906151e5565b9050806135a7576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600881901c5f90815261014f6020526040902054600160ff83161b1615613608576040517f335a4a900000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f8061364b600161363c876002615325565b6136469190614d4f565b614306565b90508063ffffffff168463ffffffff1611156136a3576040517ff7ec909700000000000000000000000000000000000000000000000000000000815263ffffffff80861660048301528216602482015260440161107a565b865f5b8681101561372957600163ffffffff8716821c811690036136f3576136ec8888838181106136d6576136d6614e9e565b90506020020135835f9182526020526040902090565b9150613721565b61371e8289898481811061370957613709614e9e565b905060200201355f9182526020526040902090565b91505b6001016136a6565b509092149695505050505050565b5f613743602084615330565b1561377a576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b801561382f57602081039050808601357fff000000000000000000000000000000000000000000000000000000000000008116156137e057604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061379d565b50509392505050565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a6001600160a01b03168787878787604051602001613883959493929190615368565b60408051601f198184030181529082905261389d916151da565b5f60405180830381855afa9150503d805f81146138d5576040519150601f19603f3d011682016040523d82523d5f602084013e6138da565b606091505b509150915081613916576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604081511461395e578051604080517ff75db38100000000000000000000000000000000000000000000000000000000815261107a9290600401918252602082015260400190565b602081015160408201516110008214158061399957507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b156135a7576040517f68dcad5f000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161107a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f54610100900460ff16613aec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f5b83811015613bf457848482818110613b0857613b08614e9e565b9050604002016020013560db5f878785818110613b2757613b27614e9e565b613b3d92602060409092020190810191506147e4565b6008811115613b4e57613b4e614cb6565b6008811115613b5f57613b5f614cb6565b815260208101919091526040015f2055848482818110613b8157613b81614e9e565b90506040020160200135858583818110613b9d57613b9d614e9e565b613bb392602060409092020190810191506147e4565b6008811115613bc457613bc4614cb6565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec6091905f90a3600101613aee565b505f5b81811015613cfd57828282818110613c1157613c11614e9e565b9050604002016020013560dc5f858585818110613c3057613c30614e9e565b613c4692602060409092020190810191506147e4565b6008811115613c5757613c57614cb6565b6008811115613c6857613c68614cb6565b815260208101919091526040015f2055828282818110613c8a57613c8a614e9e565b90506040020160200135838383818110613ca657613ca6614e9e565b613cbc92602060409092020190810191506147e4565b6008811115613ccd57613ccd614cb6565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c2905f90a3600101613bf7565b5050505050565b5f54610100900460ff16613d9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b613da2614353565b613daa614353565b613db2614353565b613dbc82826143e9565b5050600160e455565b5f54610100900460ff16613e5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f5b818110156111cf575f838383818110613e7857613e78614e9e565b613e8e9260206040909202019081019150614d9b565b6001600160a01b031603613ece576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828282818110613ee057613ee0614e9e565b905060400201602001355f801b03613f24576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613f6b838383818110613f3957613f39614e9e565b90506040020160200135848484818110613f5557613f55614e9e565b6123549260206040909202019081019150614d9b565b600101613e5d565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff1615611227575f8281526065602090815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff16611227576140448161454f565b61404f836020614561565b60405160200161406092919061538e565b60408051601f19818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261107a9160040161485b565b815f036140e2578015611227576040517f0c2565920000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b8061411c576040517f5228f4c80000000000000000000000000000000000000000000000000000000081526004810183905260240161107a565b5f82815261014e60205260409020548114611227576040517f36459fa0000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161107a565b5f5b82811015614273576101505f85858481811061418d5761418d614e9e565b9050602002013581526020019081526020015f20545f146141f6578383828181106141ba576141ba614e9e565b905060200201356040517fe5d1442500000000000000000000000000000000000000000000000000000000815260040161107a91815260200190565b816101505f86868581811061420d5761420d614e9e565b9050602002013581526020019081526020015f20819055508184848381811061423857614238614e9e565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a360010161416f565b50505050565b614284600283615330565b156142be576040517f0c91d7760000000000000000000000000000000000000000000000000000000081526004810183905260240161107a565b5f805b83811015613cfd576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a26002016142c1565b5f63ffffffff82111561434f576040517f6dfcc650000000000000000000000000000000000000000000000000000000008152602060048201526024810183905260440161107a565b5090565b5f54610100900460ff16612de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f54610100900460ff1661447f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b815f036144b8576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f036144f1576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609782905560988190556145058242614d62565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a9906060016125bf565b6060610ff66001600160a01b03831660145b60605f61456f836002614d84565b61457a906002614d62565b67ffffffffffffffff81111561459257614592614f07565b6040519080825280601f01601f1916602001820160405280156145bc576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106145f2576145f2614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061465457614654614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f61468e846002614d84565b614699906001614d62565b90505b6001811115614735577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106146da576146da614e9e565b1a60f81b8282815181106146f0576146f0614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c9361472e816153f8565b905061469c565b50831561479e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161107a565b9392505050565b5f602082840312156147b5575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461479e575f80fd5b5f602082840312156147f4575f80fd5b81356009811061479e575f80fd5b5f60208284031215614812575f80fd5b5035919050565b6001600160a01b0381168114611af5575f80fd5b5f806040838503121561483e575f80fd5b82359150602083013561485081614819565b809150509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f8083601f8401126148a0575f80fd5b50813567ffffffffffffffff8111156148b7575f80fd5b6020830191508360208285010111156148ce575f80fd5b9250929050565b5f805f805f805f8060e0898b0312156148ec575f80fd5b88356148f781614819565b9750602089013561490781614819565b96506040890135955060608901359450608089013561492581614819565b935060a089013567ffffffffffffffff811115614940575f80fd5b61494c8b828c01614890565b999c989b50969995989497949560c00135949350505050565b5f805f8060608587031215614978575f80fd5b843567ffffffffffffffff81111561498e575f80fd5b61499a87828801614890565b90955093505060208501359150604085013567ffffffffffffffff8111156149c0575f80fd5b850161020081880312156149d2575f80fd5b939692955090935050565b5f602082840312156149ed575f80fd5b813567ffffffffffffffff811115614a03575f80fd5b8201610140818503121561479e575f80fd5b5f805f60608486031215614a27575f80fd5b833567ffffffffffffffff811115614a3d575f80fd5b840160608187031215614a4e575f80fd5b95602085013595506040909401359392505050565b5f805f8060608587031215614a76575f80fd5b843567ffffffffffffffff811115614a8c575f80fd5b8501601f81018713614a9c575f80fd5b803567ffffffffffffffff811115614ab2575f80fd5b8760208260051b8401011115614ac6575f80fd5b602091820198909750908601359560400135945092505050565b5f805f8060608587031215614af3575f80fd5b8435614afe81614819565b935060208501359250604085013567ffffffffffffffff811115614b20575f80fd5b614b2c87828801614890565b95989497509550505050565b5f60208284031215614b48575f80fd5b813567ffffffffffffffff811115614b5e575f80fd5b8201610160818503121561479e575f80fd5b5f805f60608486031215614b82575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112614ba9575f80fd5b50813567ffffffffffffffff811115614bc0575f80fd5b6020830191508360208260061b85010111156148ce575f80fd5b5f805f805f805f6080888a031215614bf0575f80fd5b873567ffffffffffffffff811115614c06575f80fd5b614c128a828b01614b99565b909850965050602088013567ffffffffffffffff811115614c31575f80fd5b614c3d8a828b01614b99565b909650945050604088013567ffffffffffffffff811115614c5c575f80fd5b614c688a828b01614b99565b9094509250506060880135614c7c81614819565b8091505092959891949750929550565b5f8060408385031215614c9d575f80fd5b8235614ca881614819565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020810160098310614d1c577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b91905290565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610ff657610ff6614d22565b80820180821115610ff657610ff6614d22565b818382375f9101908152919050565b8082028115828204841417610ff657610ff6614d22565b5f60208284031215614dab575f80fd5b813561479e81614819565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614de9575f80fd5b83018035915067ffffffffffffffff821115614e03575f80fd5b6020019150368190038213156148ce575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614e4a575f80fd5b83018035915067ffffffffffffffff821115614e64575f80fd5b6020019150600581901b36038213156148ce575f80fd5b5f60208284031215614e8b575f80fd5b813563ffffffff8116811461479e575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112614efd575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715614f5757614f57614f07565b60405290565b5f82601f830112614f6c575f80fd5b813567ffffffffffffffff811115614f8657614f86614f07565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715614fb557614fb5614f07565b604052818152838201602001851015614fcc575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60a08236031215614ff8575f80fd5b615000614f34565b82358152602083013567ffffffffffffffff81111561501d575f80fd5b61502936828601614f5d565b602083015250604083013567ffffffffffffffff811115615048575f80fd5b61505436828601614f5d565b60408301525060608381013590820152608092830135928101929092525090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150a5576150a5614d22565b5060010190565b81835281816020850137505f602082840101525f6020601f19601f840116840101905092915050565b858152846020820152836040820152608060608201525f6150fa6080830184866150ac565b979650505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615138575f80fd5b83018035915067ffffffffffffffff821115615152575f80fd5b6020019150600681901b36038213156148ce575f80fd5b604081525f61517c6040830185876150ac565b82810360208401528084518083526020830191506020860192505f5b818110156151b6578351835260209384019390920191600101615198565b5090979650505050505050565b5f81518060208401855e5f93019283525090919050565b5f61479e82846151c3565b5f602082840312156151f5575f80fd5b8151801515811461479e575f80fd5b6001815b600184111561523f5780850481111561522357615223614d22565b600184161561523157908102905b60019390931c928002615208565b935093915050565b5f8261525557506001610ff6565b8161526157505f610ff6565b816001811461527757600281146152815761529d565b6001915050610ff6565b60ff84111561529257615292614d22565b50506001821b610ff6565b5060208310610133831016604e8410600b84101617156152c0575081810a610ff6565b6152eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484615204565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561531d5761531d614d22565b029392505050565b5f61479e8383615247565b5f82615363577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b8581528460208201528360408201525f6150fa61538860608401866151c3565b846151c3565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f6153bf60178301856151c3565b7f206973206d697373696e6720726f6c652000000000000000000000000000000081526153ef60118201856151c3565b95945050505050565b5f8161540657615406614d22565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122017fa9362d0392993ac5f756a12c21940cf721259b8b8bc02053fb03e1c986a6364736f6c634300081a0033", + "deployedBytecode": "0x60806040526004361061049d575f3560e01c806373bd07b71161026b578063b837dbe911610156578063cc5782f6116100d1578063d5d4b83511610087578063e196fb5d1161006d578063e196fb5d14610ea0578063e97a1e9e14610ebf578063f5b541a614610f31575f80fd5b8063d5d4b83514610e57578063d722bbfc14610e6d575f80fd5b8063cd9b9e9a116100b7578063cd9b9e9a14610e02578063cf5b276414610e18578063d547741f14610e38575f80fd5b8063cc5782f614610da1578063cc6f725114610dcf575f80fd5b8063bf3e750511610126578063c0c4e5841161010c578063c0c4e58414610d4e578063c1dc0f0714610d6d578063c211697414610d82575f80fd5b8063bf3e750514610d06578063c0729ab114610d39575f80fd5b8063b837dbe914610c80578063b9174ba314610c95578063bc61e73314610cc8578063bcc3003d14610ce7575f80fd5b80639ac25d08116101e6578063a98e773d116101b6578063ad422ff01161019c578063ad422ff014610c24578063aea4f74514610c39578063b59faa6014610c4d575f80fd5b8063a98e773d14610bd0578063ac1eff6814610bef575f80fd5b80639ac25d0814610b585780639ee8b21114610b8b5780639f3ce55a14610baa578063a217fddf14610bbd575f80fd5b8063914e57eb1161023b578063921b278e11610221578063921b278e14610b23578063986fcddd14610a4157806399467a3514610b39575f80fd5b8063914e57eb14610ab357806391d1485414610adf575f80fd5b806373bd07b714610a2d5780637d1e8c5514610a415780638be745d114610a545780638de4948714610a80575f80fd5b80634cdd389b1161038b57806360e83cf31161030657806367e404ce116102d6578063695378f5116102bc578063695378f5146109b15780636a906b80146109c75780636e673843146109fa575f80fd5b806367e404ce146109665780636854f6bc14610992575f80fd5b806360e83cf3146108bc57806363213155146108e85780636463fb2a1461091b57806366f96e981461093a575f80fd5b8063587944561161035b5780635c721a0c116103415780635c721a0c146108395780635ed73ceb146108645780636078bfd814610890575f80fd5b806358794456146108245780635b7eb4bd14610742575f80fd5b80634cdd389b146107875780635230eef2146107b3578063557eac73146107e65780635603c65f14610805575f80fd5b8063289581741161041b57806338b90333116103eb5780633fc08b65116103d15780633fc08b651461071757806348922ab714610742578063491e093614610768575f80fd5b806338b903331461068f5780633b12eccb146106e4575f80fd5b8063289581741461061c5780632c70645c1461063b5780632f2ff15d1461065157806336568abe14610670575f80fd5b806312d3fa9a116104705780631f443da0116104565780631f443da0146105965780632130d812146105c2578063248a9ca3146105ee575f80fd5b806312d3fa9a1461054d5780631e2ff94f14610580575f80fd5b806301ffc9a7146104a157806303134d1d146104d557806305861180146105165780631065a3991461052c575b5f80fd5b3480156104ac575f80fd5b506104c06104bb3660046147a5565b610f64565b60405190151581526020015b60405180910390f35b3480156104e0575f80fd5b506105087f1ab87f7458c0e3d07e9881c14ee67f0141703614fd48ea5b15ed987e5f4b030e81565b6040519081526020016104cc565b348015610521575f80fd5b506105086101bb5481565b348015610537575f80fd5b5061054b6105463660046147e4565b610ffc565b005b348015610558575f80fd5b506105087f67c2dca7476ee0fe1dd3cba13428c6760bfe2599a6dfe26a9ad7ef27317c6e7781565b34801561058b575f80fd5b506105086101185481565b3480156105a1575f80fd5b506105086105b0366004614802565b6101b96020525f908152604090205481565b3480156105cd575f80fd5b506105086105dc366004614802565b6101be6020525f908152604090205481565b3480156105f9575f80fd5b50610508610608366004614802565b5f9081526065602052604090206001015490565b348015610627575f80fd5b5061054b610636366004614802565b6110f8565b348015610646575f80fd5b506105086101835481565b34801561065c575f80fd5b5061054b61066b36600461482d565b6111ab565b34801561067b575f80fd5b5061054b61068a36600461482d565b6111d4565b34801561069a575f80fd5b506106d76040518060400160405280600381526020017f362e30000000000000000000000000000000000000000000000000000000000081525081565b6040516104cc919061485b565b3480156106ef575f80fd5b506105087fb6cc65f42901ed602aec1619cc1ead29d487cd489094a37615153eaeb991d77081565b348015610722575f80fd5b50610508610731366004614802565b60a56020525f908152604090205481565b34801561074d575f80fd5b50610756600181565b60405160ff90911681526020016104cc565b348015610773575f80fd5b5061054b6107823660046148d5565b61122b565b348015610792575f80fd5b506105086107a1366004614802565b6101b76020525f908152604090205481565b3480156107be575f80fd5b506105087f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf981565b3480156107f1575f80fd5b5061054b610800366004614802565b6114e1565b348015610810575f80fd5b5061054b61081f366004614965565b6115a7565b34801561082f575f80fd5b5061050860995481565b348015610844575f80fd5b50610508610853366004614802565b60a66020525f908152604090205481565b34801561086f575f80fd5b5061050861087e366004614802565b6101ba6020525f908152604090205481565b34801561089b575f80fd5b506105086108aa366004614802565b6101b66020525f908152604090205481565b3480156108c7575f80fd5b506105086108d6366004614802565b6101506020525f908152604090205481565b3480156108f3575f80fd5b506105087fe37c272ea30e2bb381ad7cf89ae754b49153250609f36d0cbdad8b64c184bb5c81565b348015610926575f80fd5b5061054b6109353660046149dd565b61169f565b348015610945575f80fd5b50610508610954366004614802565b6101b86020525f908152604090205481565b348015610971575f80fd5b5061097a611af8565b6040516001600160a01b0390911681526020016104cc565b34801561099d575f80fd5b5061054b6109ac366004614a15565b611b30565b3480156109bc575f80fd5b506105086101195481565b3480156109d2575f80fd5b506105087fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015610a05575f80fd5b506105087f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b348015610a38575f80fd5b50610756600281565b348015610a4c575f80fd5b506107565f81565b348015610a5f575f80fd5b50610508610a6e366004614802565b61011a6020525f908152604090205481565b348015610a8b575f80fd5b506105087fe1fce82838dd7a42cfe783f60dc6233c8aa2c4fc66e77817805e767ec5e349b681565b348015610abe575f80fd5b50610508610acd366004614802565b61014e6020525f908152604090205481565b348015610aea575f80fd5b506104c0610af936600461482d565b5f9182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610b2e575f80fd5b506105086101bf5481565b348015610b44575f80fd5b5061054b610b53366004614a63565b611d70565b348015610b63575f80fd5b506105087f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015610b96575f80fd5b506104c0610ba5366004614802565b612054565b61054b610bb8366004614ae0565b612077565b348015610bc8575f80fd5b506105085f81565b348015610bdb575f80fd5b5061054b610bea366004614b38565b612199565b348015610bfa575f80fd5b5061097a610c09366004614802565b61011b6020525f90815260409020546001600160a01b031681565b348015610c2f575f80fd5b5061050860985481565b348015610c44575f80fd5b5061054b6125cb565b348015610c58575f80fd5b506105087fe4831f9e4316ac2c65117d1f602fbf56d38128a9973d5e3fdbc5b77265c18d4081565b348015610c8b575f80fd5b5061050860e45481565b348015610ca0575f80fd5b506105087f430a7f0cb00b5ebbe63cecc96e82cf959a883e7c13a95110854f1fa6b3fbf59881565b348015610cd3575f80fd5b506104c0610ce23660046147e4565b612626565b348015610cf2575f80fd5b5061054b610d01366004614b70565b61264a565b348015610d11575f80fd5b506105087f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610d44575f80fd5b50610508609a5481565b348015610d59575f80fd5b5061054b610d68366004614bda565b61277a565b348015610d78575f80fd5b5061050860975481565b348015610d8d575f80fd5b5061054b610d9c366004614c8c565b6129e0565b348015610dac575f80fd5b506104c0610dbb366004614802565b60d96020525f908152604090205460ff1681565b348015610dda575f80fd5b506105087fe8cb6172fcf5cbaae022b7c910224a4f0c20d53227e630056efff182155a5abc81565b348015610e0d575f80fd5b506105086101bd5481565b348015610e23575f80fd5b506101c05461097a906001600160a01b031681565b348015610e43575f80fd5b5061054b610e5236600461482d565b612ae6565b348015610e62575f80fd5b506105086101bc5481565b348015610e78575f80fd5b506105087f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a81565b348015610eab575f80fd5b5061054b610eba3660046147e4565b612b0a565b348015610eca575f80fd5b50610508604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610f3c575f80fd5b506105087f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610ff657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60dc5f82600881111561101157611011614cb6565b600881111561102257611022614cb6565b81526020019081526020015f205461103981612be2565b61104282612626565b61108357816040517f1865965400000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b60405180910390fd5b81600881111561109557611095614cb6565b60da8054600190921b1990911690558160088111156110b6576110b6614cb6565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b6040516001600160a01b03909116815260200160405180910390a25050565b7f6b5661ddfbd1fbd525c902a513e0f47d9c74f1c1ee8a2d4f1937ad305fb8f41a61112281612be2565b5f82815261011b602090815260408083205490516001600160a01b0390911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f828152606560205260409020600101546111c581612be2565b6111cf8383612bec565b505050565b6101c0546001600160a01b039081169082160361121d576040517f7f7497e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112278282612caa565b5050565b611233612d4c565b85878484875f5a90506112466003612de9565b61127a61127460017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b8f612e7b565b5f61128a8f8f8f8f8c8f8f612e82565b905061129581612edb565b6112a76112a28d8f614d62565b612f35565b5f808f6001600160a01b03168e8d8d6040516112c4929190614d75565b5f6040518083038185875af1925050503d805f81146112fe576040519150601f19603f3d011682016040523d82523d5f602084013e611303565b606091505b5091509150816113605780511561131d5780518082602001fd5b8f6040517f5461344300000000000000000000000000000000000000000000000000000000815260040161107a91906001600160a01b0391909116815260200190565b61139461138e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b5f612e7b565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a25050861590506114c957855f84900361143f57853b15801561143d573a5a6113e861bc7c86614d62565b6113f29190614d4f565b6113fc9190614d84565b915081881115611439576001600160a01b0387166108fc61141d848b614d4f565b6040518115909202915f818181858888f193505050505061143d565b8791505b505b5f6001600160a01b038416156114555783611457565b335b90505f816001600160a01b03166108fc8490811502906040515f60405180830381858888f193505050509050806114c5576040517fa57c4df40000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161107a565b5050505b5050505050506114d7612fab565b5050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8261150b81612be2565b5f805f426099541015611530576097546115259042614d62565b609955506001611542565b609a5485101561154257849250600191505b609885905580806115505750815b1561155b57609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b60066115b281612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9296115dc81612be2565b5f859003611616576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a6020526040902054843514611662576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd545f6116718684612fd9565b90505f611685878484878b602001356132c6565b905061169381898c8c61334e565b50505050505050505050565b6116a7612d4c565b60a081018035906116bb9060808401614d9b565b6116c9610120840184614db6565b6116da610100860160e08701614d9b565b5f5a90506116e86003612de9565b6101008701355f908152610150602052604081205490819003611737576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117418880614e17565b9050811461179057806117548980614e17565b6040517f5e3fd6ad000000000000000000000000000000000000000000000000000000008152600481019390935260248301525060440161107a565b61179d88602001356135b2565b6117b26112a260c08a013560a08b0135614d62565b5f6117fb6117c660808b0160608c01614d9b565b6117d660a08c0160808d01614d9b565b8b60a001358c60c001358d602001358e8061012001906117f69190614db6565b612e82565b90506118268161180b8b80614e17565b61181b60608e0160408f01614e7b565b8d610100013561362a565b61185c576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61189f61188a60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b61189a60808c0160608d01614d9b565b612e7b565b5f806118b160a08c0160808d01614d9b565b6001600160a01b031660c08c01356118cd6101208e018e614db6565b6040516118db929190614d75565b5f6040518083038185875af1925050503d805f8114611915576040519150601f19603f3d011682016040523d82523d5f602084013e61191a565b606091505b509150915081611982578051156119345780518082602001fd5b61194460a08c0160808d01614d9b565b6040517f546134430000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015260240161107a565b6119b061138e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611ae757855f849003611a5d57853b158015611a5b573a5a611a0661bc7c86614d62565b611a109190614d4f565b611a1a9190614d84565b915081881115611a57576001600160a01b0387166108fc611a3b848b614d4f565b6040518115909202915f818181858888f1935050505050611a5b565b8791505b505b5f6001600160a01b03841615611a735783611a75565b335b90505f816001600160a01b03166108fc8490811502906040515f60405180830381858888f19350505050905080611ae3576040517fa57c4df40000000000000000000000000000000000000000000000000000000081526001600160a01b038316600482015260240161107a565b5050505b505050505050611af5612fab565b50565b5f611b2b611b2760017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614d4f565b5c90565b905090565b6005611b3b81612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611b6581612be2565b611b726040860186614db6565b90505f03611bac576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8381526101be602052604090205415611bf5576040517f0f06cd150000000000000000000000000000000000000000000000000000000081526004810184905260240161107a565b5f8481526101be60205260408120549003611c3f576040517f6e5424c20000000000000000000000000000000000000000000000000000000081526004810185905260240161107a565b5f611c4d6040870187614db6565b604051611c5b929190614d75565b604051809103902090505f611c7d8760200135835f9182526020526040902090565b90505f611cc98760208a01358a3585611ca2611c9c60408f018f614db6565b89613737565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b9050808614611d0e576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018790526024810182905260440161107a565b5f8181526101be602052604090819020600190555181907f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee07231990611d5e908a908c3590918252602082015260400190565b60405180910390a25050505050505050565b6004611d7b81612de9565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929611da581612be2565b5f859003611ddf576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b844915611e1b576040517f8019aff70000000000000000000000000000000000000000000000000000000081526004810186905260240161107a565b5f8481526101be60205260408120549003611e65576040517f6e5424c20000000000000000000000000000000000000000000000000000000081526004810185905260240161107a565b5f8381526101be602052604090205415611eae576040517f0f06cd150000000000000000000000000000000000000000000000000000000081526004810184905260240161107a565b6040805160a0810182525f808252606060208301819052928201839052918101829052608081018290528190865f5b89811015611fb3578a8a82818110611ef757611ef7614e9e565b9050602002810190611f099190614ecb565b611f1290614fe8565b81499450925083611f52576040517fc0e41e1d0000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b60808301515f8181526020869052604090209550611f8085875f1c865f015187602001518860400151613838565b6060848101518551604080519687526020870194909452928501528301869052608083015260a090912090600101611edd565b50808714611ff7576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018890526024810182905260440161107a565b5f8181526101be602090815260409182902060019055606084015182518b81529182015282917f55f4c645c36aa5cd3f443d6be44d7a7a5df9d2100d7139dfc69d4289ee072319910160405180910390a250505050505050505050565b600881901c5f90815261014f6020526040812054600160ff84161b161515610ff6565b600261208281612de9565b6001600160a01b0385166120c2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b348411156120fc576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f918261210c83615075565b9091555090505f61211d8634614d4f565b90505f61212f33898985878b8b612e82565b905061213b83826139da565b80886001600160a01b0316336001600160a01b03167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516121879594939291906150d5565b60405180910390a45050505050505050565b5f54610100900460ff16158080156121b757505f54600160ff909116105b806121d05750303b1580156121d057505f5460ff166001145b61225c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161107a565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156122b8575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f6122c96080840160608501614d9b565b6001600160a01b031603612309576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61232c61231960e0840184615105565b612327610100860186615105565b613a56565b61233e82608001358360a00135613d04565b6123595f61235461016085016101408601614d9b565b612bec565b61236e61236960c0840184615105565b613dc5565b61237e6080830160608401614d9b565b5f805261011b6020527f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03929092169190911790556123f061014083016101208401614d9b565b6101c080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b039290921691909117905561243b61014083016101208401614d9b565b6001600160a01b0316336001600160a01b03167f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f60405160405180910390a36020828101356101198190555f90815261011a825260408082208535905580518084018390528082018390527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830185905260a08084018690528451808503909101815260c08401855280519087012085526101be86528385206001905560e0830185905261010083018590526101208301919091526101408201849052610160808301859052835180840390910181526101808301808552815191909601206101bd558385526101a0820193909352908501356101c09091015290206101bf558015611227575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b7f0cf0d2deb70d7bdac2fa48c4ac99bc558170be0ce5fcb994caefa4bf7b96edf96125f581612be2565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b5f81600881111561263957612639614cb6565b60da54600190911b16151592915050565b61265762f099c082614d62565b421015612690576040517f4306cbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805184815260208101849052908101829052606090206101bf5414612708576101bf546040805185815260208101859052908101839052606090206040517fbc5aad110000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161107a565b6101c0546001600160a01b031661273f7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92982612bec565b6040516001600160a01b0382169033907f9fc8868f8577b31b805ee65bb52325782b5e2708dbdb7f04c7467c6785fccb30905f90a350505050565b5f54600690610100900460ff1615801561279a57505f5460ff8083169116105b612826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161107a565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556128608888613dc5565b61286c86868686613a56565b6001600160a01b0382166128ac576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101c080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03841690811790915560405133907f1f82add12d98b5eaed4d6a6d5f74cfc7a85e5c90c335ab5562f77f220ed45d5f905f90a36040517f362e300000000000000000000000000000000000000000000000000000000000907f352e300000000000000000000000000000000000000000000000000000000000907f2f8492a7a430cf917798dfb60bc5af634f68e6c40287947df0ea6f7ec0669bd8905f90a35f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c612a0a81612be2565b6001600160a01b038316612a4a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b60209081526040918290205491516001600160a01b03928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b5f82815260656020526040902060010154612b0081612be2565b6111cf8383613f73565b60db5f826008811115612b1f57612b1f614cb6565b6008811115612b3057612b30614cb6565b81526020019081526020015f2054612b4781612be2565b612b5082612626565b15612b8957816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b816008811115612b9b57612b9b614cb6565b60da8054600190921b9091179055816008811115612bbb57612bbb614cb6565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d4559336110d9565b611af58133614012565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff16611227575f8281526065602090815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612c663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6001600160a01b0381163314612d42576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161107a565b6112278282613f73565b5f612d7b611b2760017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b14612db2576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612de7612de060017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b6001612e7b565b565b60da54816008811115612dfe57612dfe614cb6565b6001901b811615612e3d57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b60028116156112275760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040161107a9190614ce3565b80825d5050565b5f60405188815287602082015286604082015285606082015284608082015260c060a08201528260c0820152602083065f8115612ec0578160200390505b848660e085013790930160e001902098975050505050505050565b5f81815260a66020526040902054600114612f25576040517f992d87c30000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b5f90815260a66020526040812055565b8015611af557426099541015612f5a57609754612f529042614d62565b609955612f6a565b609a54612f679082614d62565b90505b609854811115612fa6576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a55565b612de761138e60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614d4f565b5f81836020013511613024576040517f70614405000000000000000000000000000000000000000000000000000000008152602084013560048201526024810183905260440161107a565b6130388361018001358461014001356140a0565b6101bf54604080516101608601358152610120860135602082015260e08601359181019190915260609020146130ce57604080516101608501358152610120850135602082015260e085013591810191909152606090206101bf546040517fbc5aad110000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161107a565b4283610100013510613119576040517fbf81c6e0000000000000000000000000000000000000000000000000000000008152610100840135600482015242602482015260440161107a565b6080830135613154576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61319760408401356060850135608086013560a087013560c0880135604080519586526020860194909452928401919091526060830152608082015260a0902090565b5f8181526101be6020526040812054919250036131e3576040517fedeae83c0000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b6131ff6131f46101c0850185614e17565b856101a0013561416d565b6132166132106101e0850185614db6565b84614279565b6020808401355f81815261011a909252604090912060808501359055610119556101bd81905561326b610180840135610140850135610100860135604080519384526020840192909252908201526060902090565b6101bf5580602084013561327e84615075565b60408051873581526080880135602082015291955085917fa0262dc79e4ccb71ceac8574ae906311ae338aa4a2044fd4ec4b99fad5ab60cb910160405180910390a492915050565b5f604051858152846020820152604060e0880160408301378360808201528260a082015260a0610120880160c083013761018081016101c088013588018035602081026020830184376020029091206101608301525061018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190069695505050505050565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061338257613382614e9e565b6020908102919091018101919091525f85815261011b90915260409020546001600160a01b0316806133e0576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80826001600160a01b0316637e4f7a8a60e01b87878760405160240161340993929190615169565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252905161347491906151da565b5f604051808303815f865af19150503d805f81146134ad576040519150601f19603f3d011682016040523d82523d5f602084013e6134b2565b606091505b509150915081613559578051156134f757602081017bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81511663ca389c4460e01b178152815181fd5b6040517fca389c4400000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f556e6b6e6f776e00000000000000000000000000000000000000000000000000604482015260640161107a565b5f8180602001905181019061356e91906151e5565b9050806135a7576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b600881901c5f90815261014f6020526040902054600160ff83161b1615613608576040517f335a4a900000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f8061364b600161363c876002615325565b6136469190614d4f565b614306565b90508063ffffffff168463ffffffff1611156136a3576040517ff7ec909700000000000000000000000000000000000000000000000000000000815263ffffffff80861660048301528216602482015260440161107a565b865f5b8681101561372957600163ffffffff8716821c811690036136f3576136ec8888838181106136d6576136d6614e9e565b90506020020135835f9182526020526040902090565b9150613721565b61371e8289898481811061370957613709614e9e565b905060200201355f9182526020526040902090565b91505b6001016136a6565b509092149695505050505050565b5f613743602084615330565b1561377a576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b801561382f57602081039050808601357fff000000000000000000000000000000000000000000000000000000000000008116156137e057604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061379d565b50509392505050565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a6001600160a01b03168787878787604051602001613883959493929190615368565b60408051601f198184030181529082905261389d916151da565b5f60405180830381855afa9150503d805f81146138d5576040519150601f19603f3d011682016040523d82523d5f602084013e6138da565b606091505b509150915081613916576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604081511461395e578051604080517ff75db38100000000000000000000000000000000000000000000000000000000815261107a9290600401918252602082015260400190565b602081015160408201516110008214158061399957507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b156135a7576040517f68dcad5f000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161107a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f54610100900460ff16613aec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f5b83811015613bf457848482818110613b0857613b08614e9e565b9050604002016020013560db5f878785818110613b2757613b27614e9e565b613b3d92602060409092020190810191506147e4565b6008811115613b4e57613b4e614cb6565b6008811115613b5f57613b5f614cb6565b815260208101919091526040015f2055848482818110613b8157613b81614e9e565b90506040020160200135858583818110613b9d57613b9d614e9e565b613bb392602060409092020190810191506147e4565b6008811115613bc457613bc4614cb6565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec6091905f90a3600101613aee565b505f5b81811015613cfd57828282818110613c1157613c11614e9e565b9050604002016020013560dc5f858585818110613c3057613c30614e9e565b613c4692602060409092020190810191506147e4565b6008811115613c5757613c57614cb6565b6008811115613c6857613c68614cb6565b815260208101919091526040015f2055828282818110613c8a57613c8a614e9e565b90506040020160200135838383818110613ca657613ca6614e9e565b613cbc92602060409092020190810191506147e4565b6008811115613ccd57613ccd614cb6565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c2905f90a3600101613bf7565b5050505050565b5f54610100900460ff16613d9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b613da2614353565b613daa614353565b613db2614353565b613dbc82826143e9565b5050600160e455565b5f54610100900460ff16613e5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f5b818110156111cf575f838383818110613e7857613e78614e9e565b613e8e9260206040909202019081019150614d9b565b6001600160a01b031603613ece576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828282818110613ee057613ee0614e9e565b905060400201602001355f801b03613f24576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613f6b838383818110613f3957613f39614e9e565b90506040020160200135848484818110613f5557613f55614e9e565b6123549260206040909202019081019150614d9b565b600101613e5d565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff1615611227575f8281526065602090815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b5f8281526065602090815260408083206001600160a01b038516845290915290205460ff16611227576140448161454f565b61404f836020614561565b60405160200161406092919061538e565b60408051601f19818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825261107a9160040161485b565b815f036140e2578015611227576040517f0c2565920000000000000000000000000000000000000000000000000000000081526004810182905260240161107a565b8061411c576040517f5228f4c80000000000000000000000000000000000000000000000000000000081526004810183905260240161107a565b5f82815261014e60205260409020548114611227576040517f36459fa0000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161107a565b5f5b82811015614273576101505f85858481811061418d5761418d614e9e565b9050602002013581526020019081526020015f20545f146141f6578383828181106141ba576141ba614e9e565b905060200201356040517fe5d1442500000000000000000000000000000000000000000000000000000000815260040161107a91815260200190565b816101505f86868581811061420d5761420d614e9e565b9050602002013581526020019081526020015f20819055508184848381811061423857614238614e9e565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a360010161416f565b50505050565b614284600283615330565b156142be576040517f0c91d7760000000000000000000000000000000000000000000000000000000081526004810183905260240161107a565b5f805b83811015613cfd576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a26002016142c1565b5f63ffffffff82111561434f576040517f6dfcc650000000000000000000000000000000000000000000000000000000008152602060048201526024810183905260440161107a565b5090565b5f54610100900460ff16612de7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b5f54610100900460ff1661447f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161107a565b815f036144b8576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f036144f1576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609782905560988190556145058242614d62565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a9906060016125bf565b6060610ff66001600160a01b03831660145b60605f61456f836002614d84565b61457a906002614d62565b67ffffffffffffffff81111561459257614592614f07565b6040519080825280601f01601f1916602001820160405280156145bc576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f815181106145f2576145f2614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061465457614654614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f61468e846002614d84565b614699906001614d62565b90505b6001811115614735577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106146da576146da614e9e565b1a60f81b8282815181106146f0576146f0614e9e565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c9361472e816153f8565b905061469c565b50831561479e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161107a565b9392505050565b5f602082840312156147b5575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461479e575f80fd5b5f602082840312156147f4575f80fd5b81356009811061479e575f80fd5b5f60208284031215614812575f80fd5b5035919050565b6001600160a01b0381168114611af5575f80fd5b5f806040838503121561483e575f80fd5b82359150602083013561485081614819565b809150509250929050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f8083601f8401126148a0575f80fd5b50813567ffffffffffffffff8111156148b7575f80fd5b6020830191508360208285010111156148ce575f80fd5b9250929050565b5f805f805f805f8060e0898b0312156148ec575f80fd5b88356148f781614819565b9750602089013561490781614819565b96506040890135955060608901359450608089013561492581614819565b935060a089013567ffffffffffffffff811115614940575f80fd5b61494c8b828c01614890565b999c989b50969995989497949560c00135949350505050565b5f805f8060608587031215614978575f80fd5b843567ffffffffffffffff81111561498e575f80fd5b61499a87828801614890565b90955093505060208501359150604085013567ffffffffffffffff8111156149c0575f80fd5b850161020081880312156149d2575f80fd5b939692955090935050565b5f602082840312156149ed575f80fd5b813567ffffffffffffffff811115614a03575f80fd5b8201610140818503121561479e575f80fd5b5f805f60608486031215614a27575f80fd5b833567ffffffffffffffff811115614a3d575f80fd5b840160608187031215614a4e575f80fd5b95602085013595506040909401359392505050565b5f805f8060608587031215614a76575f80fd5b843567ffffffffffffffff811115614a8c575f80fd5b8501601f81018713614a9c575f80fd5b803567ffffffffffffffff811115614ab2575f80fd5b8760208260051b8401011115614ac6575f80fd5b602091820198909750908601359560400135945092505050565b5f805f8060608587031215614af3575f80fd5b8435614afe81614819565b935060208501359250604085013567ffffffffffffffff811115614b20575f80fd5b614b2c87828801614890565b95989497509550505050565b5f60208284031215614b48575f80fd5b813567ffffffffffffffff811115614b5e575f80fd5b8201610160818503121561479e575f80fd5b5f805f60608486031215614b82575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112614ba9575f80fd5b50813567ffffffffffffffff811115614bc0575f80fd5b6020830191508360208260061b85010111156148ce575f80fd5b5f805f805f805f6080888a031215614bf0575f80fd5b873567ffffffffffffffff811115614c06575f80fd5b614c128a828b01614b99565b909850965050602088013567ffffffffffffffff811115614c31575f80fd5b614c3d8a828b01614b99565b909650945050604088013567ffffffffffffffff811115614c5c575f80fd5b614c688a828b01614b99565b9094509250506060880135614c7c81614819565b8091505092959891949750929550565b5f8060408385031215614c9d575f80fd5b8235614ca881614819565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6020810160098310614d1c577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b91905290565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610ff657610ff6614d22565b80820180821115610ff657610ff6614d22565b818382375f9101908152919050565b8082028115828204841417610ff657610ff6614d22565b5f60208284031215614dab575f80fd5b813561479e81614819565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614de9575f80fd5b83018035915067ffffffffffffffff821115614e03575f80fd5b6020019150368190038213156148ce575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614e4a575f80fd5b83018035915067ffffffffffffffff821115614e64575f80fd5b6020019150600581901b36038213156148ce575f80fd5b5f60208284031215614e8b575f80fd5b813563ffffffff8116811461479e575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61833603018112614efd575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160a0810167ffffffffffffffff81118282101715614f5757614f57614f07565b60405290565b5f82601f830112614f6c575f80fd5b813567ffffffffffffffff811115614f8657614f86614f07565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715614fb557614fb5614f07565b604052818152838201602001851015614fcc575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60a08236031215614ff8575f80fd5b615000614f34565b82358152602083013567ffffffffffffffff81111561501d575f80fd5b61502936828601614f5d565b602083015250604083013567ffffffffffffffff811115615048575f80fd5b61505436828601614f5d565b60408301525060608381013590820152608092830135928101929092525090565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036150a5576150a5614d22565b5060010190565b81835281816020850137505f602082840101525f6020601f19601f840116840101905092915050565b858152846020820152836040820152608060608201525f6150fa6080830184866150ac565b979650505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112615138575f80fd5b83018035915067ffffffffffffffff821115615152575f80fd5b6020019150600681901b36038213156148ce575f80fd5b604081525f61517c6040830185876150ac565b82810360208401528084518083526020830191506020860192505f5b818110156151b6578351835260209384019390920191600101615198565b5090979650505050505050565b5f81518060208401855e5f93019283525090919050565b5f61479e82846151c3565b5f602082840312156151f5575f80fd5b8151801515811461479e575f80fd5b6001815b600184111561523f5780850481111561522357615223614d22565b600184161561523157908102905b60019390931c928002615208565b935093915050565b5f8261525557506001610ff6565b8161526157505f610ff6565b816001811461527757600281146152815761529d565b6001915050610ff6565b60ff84111561529257615292614d22565b50506001821b610ff6565b5060208310610133831016604e8410600b84101617156152c0575081810a610ff6565b6152eb7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484615204565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561531d5761531d614d22565b029392505050565b5f61479e8383615247565b5f82615363577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b8581528460208201528360408201525f6150fa61538860608401866151c3565b846151c3565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f6153bf60178301856151c3565b7f206973206d697373696e6720726f6c652000000000000000000000000000000081526153ef60118201856151c3565b95945050505050565b5f8161540657615406614d22565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122017fa9362d0392993ac5f756a12c21940cf721259b8b8bc02053fb03e1c986a6364736f6c634300081a0033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/local-deployments-artifacts/dynamic-artifacts/TokenBridge.json b/contracts/local-deployments-artifacts/dynamic-artifacts/TokenBridge.json index e9558439..878f0dd7 100644 --- a/contracts/local-deployments-artifacts/dynamic-artifacts/TokenBridge.json +++ b/contracts/local-deployments-artifacts/dynamic-artifacts/TokenBridge.json @@ -171,6 +171,11 @@ "name": "StatusAddressNotAllowed", "type": "error" }, + { + "inputs": [], + "name": "TokenListEmpty", + "type": "error" + }, { "inputs": [ { @@ -445,13 +450,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "pauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -635,13 +640,13 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "enum IPauseManager.PauseType", "name": "unPauseType", "type": "uint8" }, { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "role", "type": "bytes32" @@ -893,7 +898,7 @@ "inputs": [ { "internalType": "address", - "name": "", + "name": "bridged", "type": "address" } ], @@ -901,7 +906,7 @@ "outputs": [ { "internalType": "address", - "name": "", + "name": "native", "type": "address" } ], @@ -1123,7 +1128,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "pauseTypeIsPaused", "type": "bool" } ], @@ -1147,12 +1152,12 @@ "inputs": [ { "internalType": "uint256", - "name": "", + "name": "chainId", "type": "uint256" }, { "internalType": "address", - "name": "", + "name": "native", "type": "address" } ], @@ -1160,7 +1165,7 @@ "outputs": [ { "internalType": "address", - "name": "", + "name": "bridged", "type": "address" } ], @@ -1467,8 +1472,8 @@ "type": "function" } ], - "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b615f4880620000f36000396000f3fe6080604052600436106200030b5760003560e01c806391d148541162000197578063ca41a24711620000e7578063d547741f1162000095578063e4d27451116200006c578063e4d274511462000a4e578063edc42a221462000a73578063fe3c50a01462000a9857600080fd5b8063d547741f14620009ed578063dfa96efb1462000a12578063e196fb5d1462000a2957600080fd5b8063ccf5a77c11620000ca578063ccf5a77c1462000962578063cdd914c51462000992578063cf4a720814620009b757600080fd5b8063ca41a24714620008e6578063cc5782f6146200092e57600080fd5b8063b3232bdf1162000145578063be46096f1162000128578063be46096f1462000855578063c483d838146200087a578063c986752a14620008b057600080fd5b8063b3232bdf146200080b578063bc61e733146200083057600080fd5b8063a217fddf116200017a578063a217fddf14620007a0578063a676e8ab14620007b7578063a6ef995f14620007dc57600080fd5b806391d1485414620007135780639ac25d08146200076a57600080fd5b80632f2ff15d116200025f578063522ea81a116200020d5780636a906b8011620001e45780636a906b80146200067857806380efb43a14620006ae5780638dae45dd14620006e457600080fd5b8063522ea81a14620005f55780635626fc25146200060c5780635a06a42a146200064257600080fd5b806336568abe116200024257806336568abe146200055f57806338b9033314620005845780634bf98dce14620005de57600080fd5b80632f2ff15d14620005045780633551237b146200052957600080fd5b80631544298e11620002bd578063248a9ca311620002a0578063248a9ca314620004755780632a564f3414620004a95780632e4c3fff14620004ce57600080fd5b80631544298e14620004375780631754f301146200045057600080fd5b80630f6f86ec11620002f25780630f6f86ec14620003715780631065a39914620003ea578063146ffb26146200040f57600080fd5b806301941d39146200031057806301ffc9a71462000337575b600080fd5b3480156200031d57600080fd5b50620003356200032f36600462004aff565b62000ace565b005b3480156200034457600080fd5b506200035c6200035636600462004bb8565b62000ca5565b60405190151581526020015b60405180910390f35b3480156200037e57600080fd5b50620003c46200039036600462004bfc565b61010860209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000368565b348015620003f757600080fd5b50620003356200040936600462004c2f565b62000d3f565b3480156200041c57600080fd5b506200042861010b5481565b60405190815260200162000368565b3480156200044457600080fd5b506200042861010a5481565b3480156200045d57600080fd5b50620003356200046f36600462004c52565b62000e54565b3480156200048257600080fd5b50620004286200049436600462004c85565b60009081526097602052604090206001015490565b348015620004b657600080fd5b5062000335620004c836600462004c9f565b62001237565b348015620004db57600080fd5b50620004287f8a7b208fd13ab36d18025be4f62b53d46aeb2cbe8958d2e13de74c040dddcddd81565b3480156200051157600080fd5b50620003356200052336600462004bfc565b62001496565b3480156200053657600080fd5b50620004287f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3581565b3480156200056c57600080fd5b50620003356200057e36600462004bfc565b620014bf565b3480156200059157600080fd5b50620005cf6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405162000368919062004d8b565b62000335620005ef36600462004e21565b62001576565b620003356200060636600462004ee0565b62001812565b3480156200061957600080fd5b50620004287f46e34517dc946faf87aabe65eb5b4fa06b974e5c8d72c5df73b9fb6ff7b6d80281565b3480156200064f57600080fd5b50620004287f50962b2d10066f5051f78d5ea04a3ab09b9c87dd1002962f0b1e30e66eeb80a581565b3480156200068557600080fd5b50620004287fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015620006bb57600080fd5b50620004287fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2481565b348015620006f157600080fd5b5060c954620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200072057600080fd5b506200035c6200073236600462004bfc565b600091825260976020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156200077757600080fd5b50620004287f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015620007ad57600080fd5b5062000428600081565b348015620007c457600080fd5b5062000335620007d636600462004f27565b62001f2e565b348015620007e957600080fd5b5060ca54620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200081857600080fd5b50620003356200082a36600462004f47565b6200201a565b3480156200083d57600080fd5b506200035c6200084f36600462004c2f565b6200252b565b3480156200086257600080fd5b50620003356200087436600462004f27565b62002553565b3480156200088757600080fd5b50620004287feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d81565b348015620008bd57600080fd5b50620004287f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe81565b348015620008f357600080fd5b50620003c46200090536600462004f27565b6101096020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200093b57600080fd5b506200035c6200094d36600462004c85565b60d56020526000908152604090205460ff1681565b3480156200096f57600080fd5b5061010754620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200099f57600080fd5b5062000335620009b136600462004f27565b62002649565b348015620009c457600080fd5b50620004287f3900d9d72d5177a154375317154fdc0e08377e3134a8a5d21cadccf831cc231c81565b348015620009fa57600080fd5b506200033562000a0c36600462004bfc565b6200280e565b6200033562000a2336600462004fcb565b62002837565b34801562000a3657600080fd5b506200033562000a4836600462004c2f565b6200285f565b34801562000a5b57600080fd5b506200033562000a6d36600462005046565b6200294d565b34801562000a8057600080fd5b506200033562000a9236600462004f27565b62002d87565b34801562000aa557600080fd5b50620004287f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce0081565b600054600290610100900460ff1615801562000af1575060005460ff8083169116105b62000b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905573ffffffffffffffffffffffffffffffffffffffff881662000c02576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000c0f60008962002f10565b6000606555600060d55562000c2362003006565b62000c3185858585620030ab565b62000c3d8787620033a7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148062000d3957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60d8600082600881111562000d585762000d58620050ca565b600881111562000d6c5762000d6c620050ca565b81526020019081526020016000205462000d86816200358a565b62000d91826200252b565b62000dcc57816040517f1865965400000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b81600881111562000de15762000de1620050ca565b60d68054600190921b19909116905581600881111562000e055762000e05620050ca565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b8173ffffffffffffffffffffffffffffffffffffffff811662000ea3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff811662000ef2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe62000f1e816200358a565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152610109602052604090205486911615158062000f8c575061010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529252909120541615155b1562000fdd576040517f12f3df0900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff85811660009081526101096020526040902054161562001057576040517ff8fb7c2700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8616600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff8516610222148062001095575073ffffffffffffffffffffffffffffffffffffffff8516610333145b80620010b8575073ffffffffffffffffffffffffffffffffffffffff8516610111145b1562001109576040517fd8ce8acb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8616600482015260240162000b7a565b61010b5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b81168552925290912054161562001191576040517f022bc84100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816600482015260240162000b7a565b60008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c168086529184528285208054918c167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155808652610109909452828520805490911682179055905133937f844cb5c635052898ad92bea4ece14519111765d835105e76aa1f77ad0d0aa81f91a450505050505050565b60c95473ffffffffffffffffffffffffffffffffffffffff16331462001289576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff93841693909216916367e404ce916004808201926020929091908290030181865afa15801562001301573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001327919062005145565b73ffffffffffffffffffffffffffffffffffffffff161462001375576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015620014915761010a5460009081526101086020526040812061033391858585818110620013ad57620013ad62005165565b9050602002016020810190620013c4919062004f27565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558282828181106200142f576200142f62005165565b905060200201602081019062001446919062004f27565b73ffffffffffffffffffffffffffffffffffffffff167f91d24864a084ab70b268a1f865e757ca12006cf298d763b6be697302ef86498c60405160405180910390a260010162001378565b505050565b600082815260976020526040902060010154620014b3816200358a565b62001491838362002f10565b73ffffffffffffffffffffffffffffffffffffffff8116331462001566576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840162000b7a565b62001572828262003599565b5050565b60005b81518110156200169a57600061010960008484815181106200159f576200159f62005165565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260400160002054169050806200164957828281518110620015f157620015f162005165565b60200260200101516040517fa5ea89da00000000000000000000000000000000000000000000000000000000815260040162000b7a919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b808383815181106200165f576200165f62005165565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250806200169181620051c3565b91505062001579565b5060c95460ca5460405173ffffffffffffffffffffffffffffffffffffffff92831692639f3ce55a9234929116908290620016da908790602401620051fe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2a564f3400000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b1681526200178b939291906004016200525a565b6000604051808303818588803b158015620017a557600080fd5b505af1158015620017ba573d6000803e3d6000fd5b50505050503373ffffffffffffffffffffffffffffffffffffffff167f59eab5b5f813ac9e0c10035dfb55b5e3419eff53c0f7a869fb3c22400ea036d682604051620018079190620051fe565b60405180910390a250565b8273ffffffffffffffffffffffffffffffffffffffff811662001861576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff8116620018b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8380600003620018f0576040517f4618044a0000000000000000000000000000000000000000000000000000000081526004810182905260240162000b7a565b620018fa62003655565b620019066007620036ca565b61010a5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c168552925290912054167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeef8101620019b0576040517f6dad9c7800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8916600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff80891660009081526101096020526040812054909116906060821562001a79576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8c1690639dc29fac90604401600060405180830381600087803b15801562001a5457600080fd5b505af115801562001a69573d6000803e3d6000fd5b5050505061010b54915062001d35565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190602401602060405180830381865afa15801562001ae7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b0d91906200529a565b905062001b3373ffffffffffffffffffffffffffffffffffffffff8d1633308e62003765565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff8e16906370a0823190602401602060405180830381865afa15801562001ba0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bc691906200529a565b62001bd29190620052b4565b9a508b935073ffffffffffffffffffffffffffffffffffffffff851662001cc957610222610108600088815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b73ffffffffffffffffffffffffffffffffffffffff167f0f53e2a811b6fd2d6cd965fd6c27b44fb924ca39f7a7f321115705c22366d62360405160405180910390a25b73ffffffffffffffffffffffffffffffffffffffff85166103331462001d305762001cf48c62003843565b62001cff8d62003963565b62001d0a8e62003a70565b60405160200162001d1e93929190620052ca565b60405160208183030381529060405291505b859250505b60c960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639f3ce55a3460ca60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1634878f8f898960405160240162001db395949392919062005307565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4d2745100000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001e64939291906004016200525a565b6000604051808303818588803b15801562001e7e57600080fd5b505af115801562001e93573d6000803e3d6000fd5b50505050508a73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8780a94875b70464f8ac6c28851501d32e7fd4ee574e4b94beb28923a3c42d9c8d60405162001f0f91815260200190565b60405180910390a4505050505062001f2660018055565b505050505050565b7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2462001f5a816200358a565b60ca5473ffffffffffffffffffffffffffffffffffffffff161562001fc85760ca546040517f94fbfd2e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240162000b7a565b62001fd38262003bb6565b604051339073ffffffffffffffffffffffffffffffffffffffff8416907fb044c1a1a05a729c402def784b4e4cb01612ff03eee6f0beb3eba0f0606260a190600090a35050565b6200202c604082016020830162004f27565b73ffffffffffffffffffffffffffffffffffffffff81166200207a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200208c606083016040840162004f27565b73ffffffffffffffffffffffffffffffffffffffff8116620020da576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015620020fb5750600054600160ff909116105b80620021175750303b15801562002117575060005460ff166001145b620021a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840162000b7a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200220457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6200222d6200221760e08601866200534e565b620022276101008801886200534e565b620030ab565b6200224962002243604086016020870162004f27565b62003c76565b6200225362003006565b6200226e600062002268602087018762004f27565b62002f10565b620022876200228160c08601866200534e565b620033a7565b62002299606085016040860162004f27565b61010780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055606084013561010a55608084013561010b5560005b6200230360a0860186620053b9565b9050811015620024c05760006200231e60a0870187620053b9565b8381811062002331576200233162005165565b905060200201602081019062002348919062004f27565b73ffffffffffffffffffffffffffffffffffffffff160362002396576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a5460009081526101086020526040812061011191620023bc60a0890189620053b9565b85818110620023cf57620023cf62005165565b9050602002016020810190620023e6919062004f27565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790556200244b60a0860186620053b9565b828181106200245e576200245e62005165565b905060200201602081019062002475919062004f27565b73ffffffffffffffffffffffffffffffffffffffff167f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe960405160405180910390a2600101620022f4565b5080156200252557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6000816008811115620025425762002542620050ca565b60d654600190911b16151592915050565b8073ffffffffffffffffffffffffffffffffffffffff8116620025a2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce00620025ce816200358a565b60c9805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff00000000000000000000000000000000000000008316811790935560405191169133918391907fc96d462e42a71473da49a1d58c1754b9b2d319786692d621dc7f921331c517e990600090a450505050565b8073ffffffffffffffffffffffffffffffffffffffff811662002698576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152610109602052604090205483911615158062002706575061010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529252909120541615155b1562002757576040517f12f3df0900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240162000b7a565b7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d62002783816200358a565b61010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816808552925280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166101111790555190917f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe991a250505050565b6000828152609760205260409020600101546200282b816200358a565b62001491838362003599565b80156200284b576200284b85838362003da4565b6200285885858562001812565b5050505050565b60d76000826008811115620028785762002878620050ca565b60088111156200288c576200288c620050ca565b815260200190815260200160002054620028a6816200358a565b620028b1826200252b565b15620028ed57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b816008811115620029025762002902620050ca565b60d68054600190921b9091179055816008811115620029255762002925620050ca565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593362000e28565b6200295762003655565b60c95473ffffffffffffffffffffffffffffffffffffffff163314620029a9576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff93841693909216916367e404ce916004808201926020929091908290030181865afa15801562002a21573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002a47919062005145565b73ffffffffffffffffffffffffffffffffffffffff161462002a95576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600862002aa281620036ca565b60008481526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c1685529252822054169061022282148062002afd575073ffffffffffffffffffffffffffffffffffffffff8216610333145b1562002b2c5762002b2673ffffffffffffffffffffffffffffffffffffffff8a16888a62004075565b62002cfb565b508073ffffffffffffffffffffffffffffffffffffffff811662002c705762002b5b89868661010a54620040cd565b90508861010960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610108600061010b54815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018a90528216906340c10f1990604401600060405180830381600087803b15801562002ce157600080fd5b505af115801562002cf6573d6000803e3d6000fd5b505050505b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f6ed06519caca659cdefa71015c79a561928d3cf8cc4a3e9739fde9fb5fb38d648b60405162002d7291815260200190565b60405180910390a450505062001f2660018055565b8073ffffffffffffffffffffffffffffffffffffffff811662002dd6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3562002e02816200358a565b61010a5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8881168552925290912054166101111462002e8d576040517f82f5d0a500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240162000b7a565b60008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816808552925280832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555190917f0145163d8d460d1ab21463758d147fdfe79d4b57c81ca3d1439996104ae6895991a250505050565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166200157257600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562002fa83390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600054610100900460ff166200309f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b620030a962004231565b565b600054610100900460ff1662003144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b8260005b81811015620032745785858281811062003166576200316662005165565b9050604002016020013560d7600088888581811062003189576200318962005165565b620031a1926020604090920201908101915062004c2f565b6008811115620031b557620031b5620050ca565b6008811115620031c957620031c9620050ca565b81526020810191909152604001600020557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609186868381811062003210576200321062005165565b62003228926020604090920201908101915062004c2f565b8787848181106200323d576200323d62005165565b905060400201602001356040516200325792919062005424565b60405180910390a1806200326b81620051c3565b91505062003148565b5081905060005b8181101562001f265783838281811062003299576200329962005165565b9050604002016020013560d86000868685818110620032bc57620032bc62005165565b620032d4926020604090920201908101915062004c2f565b6008811115620032e857620032e8620050ca565b6008811115620032fc57620032fc620050ca565b81526020810191909152604001600020557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c284848381811062003343576200334362005165565b6200335b926020604090920201908101915062004c2f565b85858481811062003370576200337062005165565b905060400201602001356040516200338a92919062005424565b60405180910390a1806200339e81620051c3565b9150506200327b565b600054610100900460ff1662003440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b8060005b818110156200252557600084848381811062003464576200346462005165565b6200347c926020604090920201908101915062004f27565b73ffffffffffffffffffffffffffffffffffffffff1603620034ca576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838382818110620034df57620034df62005165565b905060400201602001356000801b0362003525576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620035758484838181106200353e576200353e62005165565b905060400201602001358585848181106200355d576200355d62005165565b62002268926020604090920201908101915062004f27565b806200358181620051c3565b91505062003444565b620035968133620042ca565b50565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156200157257600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600260015403620036c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000b7a565b6002600155565b60d654816008811115620036e257620036e2620050ca565b6001901b8116156200372457816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b6002811615620015725760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620025259085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526200438d565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620038c7919062005441565b600060405180830381855afa9150503d806000811462003904576040519150601f19603f3d011682016040523d82523d6000602084013e62003909565b606091505b50915091508162003950576040518060400160405280600781526020017f4e4f5f4e414d45000000000000000000000000000000000000000000000000008152506200395b565b6200395b81620044a3565b949350505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620039e7919062005441565b600060405180830381855afa9150503d806000811462003a24576040519150601f19603f3d011682016040523d82523d6000602084013e62003a29565b606091505b50915091508162003950576040518060400160405280600981526020017f4e4f5f53594d424f4c00000000000000000000000000000000000000000000008152506200395b565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162003af3919062005441565b600060405180830381855afa9150503d806000811462003b30576040519150601f19603f3d011682016040523d82523d6000602084013e62003b35565b606091505b509150915081801562003b49575080516020145b1562003b6557808060200190518101906200395b91906200546f565b6040517fb5a2f1c600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240162000b7a565b60018055565b73ffffffffffffffffffffffffffffffffffffffff811662003c04576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040513391907fe68b208814fdb633b222cd15e73d5a27fb4ef9eef4cae78c623bc27702141d2890600090a350565b600054610100900460ff1662003d0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b73ffffffffffffffffffffffffffffffffffffffff811662003d5d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7fd505accf0000000000000000000000000000000000000000000000000000000062003dd56004600084866200548f565b62003de091620054bb565b7fffffffff00000000000000000000000000000000000000000000000000000000161462003ea15762003e186004600083856200548f565b62003e2391620054bb565b6040517fcf9e29460000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201527fd505accf00000000000000000000000000000000000000000000000000000000602482015260440162000b7a565b600080808080808062003eb8886004818c6200548f565b81019062003ec7919062005504565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161462003f54576040517f200688cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff8616301462003fbd576040517f2911594800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8716600482015260240162000b7a565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff8b169063d505accf9060e401600060405180830381600087803b1580156200405057600080fd5b505af115801562004065573d6000803e3d6000fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052620014919084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401620037c0565b60008181526020859052604081206101075460405173ffffffffffffffffffffffffffffffffffffffff90911690620041069062004a7f565b73ffffffffffffffffffffffffffffffffffffffff90911681526040602082018190526000908201526060018190604051809103906000f590508015801562004153573d6000803e3d6000fd5b50905060008080620041688688018862005621565b9250925092508373ffffffffffffffffffffffffffffffffffffffff16631624f6c68484846040518463ffffffff1660e01b8152600401620041ad93929190620052ca565b600060405180830381600087803b158015620041c857600080fd5b505af1158015620041dd573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff808c169350871691507fd5d4920bb61e6141c8499d50a7bd617dae2b1818c9d6b995d3f2ba4975e32ea490600090a3505050949350505050565b600054610100900460ff1662003bb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1662001572576200430d8162004676565b6200431a83602062004696565b6040516020016200432d92919062005697565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825262000b7a9160040162004d8b565b6000620043f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620048fe9092919063ffffffff16565b9050805160001480620044155750808060200190518101906200441591906200571c565b62001491576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000b7a565b60606040825110620044c5578180602001905181019062000d39919062005740565b81516020146200450857505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b60005b6020811080156200455657508281815181106200452c576200452c62005165565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562004565576001016200450b565b80600003620045a957505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff811115620045c757620045c762004da0565b6040519080825280601f01601f191660200182016040528015620045f2576020820181803683370190505b50905060005b828110156200466e5784818151811062004616576200461662005165565b602001015160f81c60f81b82828151811062004636576200463662005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101620045f8565b509392505050565b606062000d3973ffffffffffffffffffffffffffffffffffffffff831660145b60606000620046a7836002620057b7565b620046b4906002620057d1565b67ffffffffffffffff811115620046cf57620046cf62004da0565b6040519080825280601f01601f191660200182016040528015620046fa576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811062004734576200473462005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106200479a576200479a62005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000620047d8846002620057b7565b620047e5906001620057d1565b90505b60018111156200488c577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106200482a576200482a62005165565b1a60f81b82828151811062004843576200484362005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936200488481620057e7565b9050620047e8565b508315620048f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000b7a565b9392505050565b60606200395b8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405162004935919062005441565b60006040518083038185875af1925050503d806000811462004974576040519150601f19603f3d011682016040523d82523d6000602084013e62004979565b606091505b50915091506200498c8783838762004997565b979650505050505050565b6060831562004a3257825160000362004a2a5773ffffffffffffffffffffffffffffffffffffffff85163b62004a2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000b7a565b50816200395b565b6200395b838381511562004a495781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b7a919062004d8b565b6106f3806200582083390190565b73ffffffffffffffffffffffffffffffffffffffff811681146200359657600080fd5b60008083601f84011262004ac357600080fd5b50813567ffffffffffffffff81111562004adc57600080fd5b6020830191508360208260061b850101111562004af857600080fd5b9250929050565b60008060008060008060006080888a03121562004b1b57600080fd5b873562004b288162004a8d565b9650602088013567ffffffffffffffff8082111562004b4657600080fd5b62004b548b838c0162004ab0565b909850965060408a013591508082111562004b6e57600080fd5b62004b7c8b838c0162004ab0565b909650945060608a013591508082111562004b9657600080fd5b5062004ba58a828b0162004ab0565b989b979a50959850939692959293505050565b60006020828403121562004bcb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114620048f757600080fd5b6000806040838503121562004c1057600080fd5b82359150602083013562004c248162004a8d565b809150509250929050565b60006020828403121562004c4257600080fd5b813560098110620048f757600080fd5b6000806040838503121562004c6657600080fd5b823562004c738162004a8d565b9150602083013562004c248162004a8d565b60006020828403121562004c9857600080fd5b5035919050565b6000806020838503121562004cb357600080fd5b823567ffffffffffffffff8082111562004ccc57600080fd5b818501915085601f83011262004ce157600080fd5b81358181111562004cf157600080fd5b8660208260051b850101111562004d0757600080fd5b60209290920196919550909350505050565b60005b8381101562004d3657818101518382015260200162004d1c565b50506000910152565b6000815180845262004d5981602086016020860162004d19565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620048f7602083018462004d3f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562004e195762004e1962004da0565b604052919050565b6000602080838503121562004e3557600080fd5b823567ffffffffffffffff8082111562004e4e57600080fd5b818501915085601f83011262004e6357600080fd5b81358181111562004e785762004e7862004da0565b8060051b915062004e8b84830162004dcf565b818152918301840191848101908884111562004ea657600080fd5b938501935b8385101562004ed4578435925062004ec38362004a8d565b828252938501939085019062004eab565b98975050505050505050565b60008060006060848603121562004ef657600080fd5b833562004f038162004a8d565b925060208401359150604084013562004f1c8162004a8d565b809150509250925092565b60006020828403121562004f3a57600080fd5b8135620048f78162004a8d565b60006020828403121562004f5a57600080fd5b813567ffffffffffffffff81111562004f7257600080fd5b82016101208185031215620048f757600080fd5b60008083601f84011262004f9957600080fd5b50813567ffffffffffffffff81111562004fb257600080fd5b60208301915083602082850101111562004af857600080fd5b60008060008060006080868803121562004fe457600080fd5b853562004ff18162004a8d565b94506020860135935060408601356200500a8162004a8d565b9250606086013567ffffffffffffffff8111156200502757600080fd5b620050358882890162004f86565b969995985093965092949392505050565b60008060008060008060a087890312156200506057600080fd5b86356200506d8162004a8d565b9550602087013594506040870135620050868162004a8d565b935060608701359250608087013567ffffffffffffffff811115620050aa57600080fd5b620050b889828a0162004f86565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6009811062005131577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810162000d398284620050f9565b6000602082840312156200515857600080fd5b8151620048f78162004a8d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620051f757620051f762005194565b5060010190565b6020808252825182820181905260009190848201906040850190845b818110156200524e57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016200521a565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600062005291606083018462004d3f565b95945050505050565b600060208284031215620052ad57600080fd5b5051919050565b8181038181111562000d395762000d3962005194565b606081526000620052df606083018662004d3f565b8281036020840152620052f3818662004d3f565b91505060ff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525083606083015260a060808301526200498c60a083018462004d3f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126200538457600080fd5b83018035915067ffffffffffffffff821115620053a057600080fd5b6020019150600681901b360382131562004af857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112620053ef57600080fd5b83018035915067ffffffffffffffff8211156200540b57600080fd5b6020019150600581901b360382131562004af857600080fd5b60408101620054348285620050f9565b8260208301529392505050565b600082516200545581846020870162004d19565b9190910192915050565b60ff811681146200359657600080fd5b6000602082840312156200548257600080fd5b8151620048f7816200545f565b60008085851115620054a057600080fd5b83861115620054ae57600080fd5b5050820193919092039150565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015620054fc5780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a0312156200552057600080fd5b87356200552d8162004a8d565b965060208801356200553f8162004a8d565b9550604088013594506060880135935060808801356200555f816200545f565b9699959850939692959460a0840135945060c09093013592915050565b600067ffffffffffffffff82111562005599576200559962004da0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620055d757600080fd5b8135620055ee620055e8826200557c565b62004dcf565b8181528460208386010111156200560457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156200563757600080fd5b833567ffffffffffffffff808211156200565057600080fd5b6200565e87838801620055c5565b945060208601359150808211156200567557600080fd5b506200568486828701620055c5565b925050604084013562004f1c816200545f565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620056d181601785016020880162004d19565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516200571081602884016020880162004d19565b01602801949350505050565b6000602082840312156200572f57600080fd5b81518015158114620048f757600080fd5b6000602082840312156200575357600080fd5b815167ffffffffffffffff8111156200576b57600080fd5b8201601f810184136200577d57600080fd5b80516200578e620055e8826200557c565b818152856020838501011115620057a457600080fd5b6200529182602083016020860162004d19565b808202811582820484141762000d395762000d3962005194565b8082018082111562000d395762000d3962005194565b600081620057f957620057f962005194565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe60806040526040516106f33803806106f383398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106cc602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b610173806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100dc565b565b60006100697fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d79190610100565b905090565b3660008037600080366000845af43d6000803e8080156100fb573d6000f35b3d6000fd5b60006020828403121561011257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461013657600080fd5b939250505056fea2646970667358221220487f6f370ed71b7026944bbfbeff4c6a8abfbc1f686dbaab6010959808b5814564736f6c63430008130033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220de9804b67318a6cdb529d18b92fd51bf5512166da05a44c81a9aaec12a7bc66b64736f6c63430008130033", - "deployedBytecode": "0x6080604052600436106200030b5760003560e01c806391d148541162000197578063ca41a24711620000e7578063d547741f1162000095578063e4d27451116200006c578063e4d274511462000a4e578063edc42a221462000a73578063fe3c50a01462000a9857600080fd5b8063d547741f14620009ed578063dfa96efb1462000a12578063e196fb5d1462000a2957600080fd5b8063ccf5a77c11620000ca578063ccf5a77c1462000962578063cdd914c51462000992578063cf4a720814620009b757600080fd5b8063ca41a24714620008e6578063cc5782f6146200092e57600080fd5b8063b3232bdf1162000145578063be46096f1162000128578063be46096f1462000855578063c483d838146200087a578063c986752a14620008b057600080fd5b8063b3232bdf146200080b578063bc61e733146200083057600080fd5b8063a217fddf116200017a578063a217fddf14620007a0578063a676e8ab14620007b7578063a6ef995f14620007dc57600080fd5b806391d1485414620007135780639ac25d08146200076a57600080fd5b80632f2ff15d116200025f578063522ea81a116200020d5780636a906b8011620001e45780636a906b80146200067857806380efb43a14620006ae5780638dae45dd14620006e457600080fd5b8063522ea81a14620005f55780635626fc25146200060c5780635a06a42a146200064257600080fd5b806336568abe116200024257806336568abe146200055f57806338b9033314620005845780634bf98dce14620005de57600080fd5b80632f2ff15d14620005045780633551237b146200052957600080fd5b80631544298e11620002bd578063248a9ca311620002a0578063248a9ca314620004755780632a564f3414620004a95780632e4c3fff14620004ce57600080fd5b80631544298e14620004375780631754f301146200045057600080fd5b80630f6f86ec11620002f25780630f6f86ec14620003715780631065a39914620003ea578063146ffb26146200040f57600080fd5b806301941d39146200031057806301ffc9a71462000337575b600080fd5b3480156200031d57600080fd5b50620003356200032f36600462004aff565b62000ace565b005b3480156200034457600080fd5b506200035c6200035636600462004bb8565b62000ca5565b60405190151581526020015b60405180910390f35b3480156200037e57600080fd5b50620003c46200039036600462004bfc565b61010860209081526000928352604080842090915290825290205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200162000368565b348015620003f757600080fd5b50620003356200040936600462004c2f565b62000d3f565b3480156200041c57600080fd5b506200042861010b5481565b60405190815260200162000368565b3480156200044457600080fd5b506200042861010a5481565b3480156200045d57600080fd5b50620003356200046f36600462004c52565b62000e54565b3480156200048257600080fd5b50620004286200049436600462004c85565b60009081526097602052604090206001015490565b348015620004b657600080fd5b5062000335620004c836600462004c9f565b62001237565b348015620004db57600080fd5b50620004287f8a7b208fd13ab36d18025be4f62b53d46aeb2cbe8958d2e13de74c040dddcddd81565b3480156200051157600080fd5b50620003356200052336600462004bfc565b62001496565b3480156200053657600080fd5b50620004287f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3581565b3480156200056c57600080fd5b50620003356200057e36600462004bfc565b620014bf565b3480156200059157600080fd5b50620005cf6040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405162000368919062004d8b565b62000335620005ef36600462004e21565b62001576565b620003356200060636600462004ee0565b62001812565b3480156200061957600080fd5b50620004287f46e34517dc946faf87aabe65eb5b4fa06b974e5c8d72c5df73b9fb6ff7b6d80281565b3480156200064f57600080fd5b50620004287f50962b2d10066f5051f78d5ea04a3ab09b9c87dd1002962f0b1e30e66eeb80a581565b3480156200068557600080fd5b50620004287fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015620006bb57600080fd5b50620004287fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2481565b348015620006f157600080fd5b5060c954620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200072057600080fd5b506200035c6200073236600462004bfc565b600091825260976020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156200077757600080fd5b50620004287f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b348015620007ad57600080fd5b5062000428600081565b348015620007c457600080fd5b5062000335620007d636600462004f27565b62001f2e565b348015620007e957600080fd5b5060ca54620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200081857600080fd5b50620003356200082a36600462004f47565b6200201a565b3480156200083d57600080fd5b506200035c6200084f36600462004c2f565b6200252b565b3480156200086257600080fd5b50620003356200087436600462004f27565b62002553565b3480156200088757600080fd5b50620004287feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d81565b348015620008bd57600080fd5b50620004287f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe81565b348015620008f357600080fd5b50620003c46200090536600462004f27565b6101096020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156200093b57600080fd5b506200035c6200094d36600462004c85565b60d56020526000908152604090205460ff1681565b3480156200096f57600080fd5b5061010754620003c49073ffffffffffffffffffffffffffffffffffffffff1681565b3480156200099f57600080fd5b5062000335620009b136600462004f27565b62002649565b348015620009c457600080fd5b50620004287f3900d9d72d5177a154375317154fdc0e08377e3134a8a5d21cadccf831cc231c81565b348015620009fa57600080fd5b506200033562000a0c36600462004bfc565b6200280e565b6200033562000a2336600462004fcb565b62002837565b34801562000a3657600080fd5b506200033562000a4836600462004c2f565b6200285f565b34801562000a5b57600080fd5b506200033562000a6d36600462005046565b6200294d565b34801562000a8057600080fd5b506200033562000a9236600462004f27565b62002d87565b34801562000aa557600080fd5b50620004287f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce0081565b600054600290610100900460ff1615801562000af1575060005460ff8083169116105b62000b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff83161761010017905573ffffffffffffffffffffffffffffffffffffffff881662000c02576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62000c0f60008962002f10565b6000606555600060d55562000c2362003006565b62000c3185858585620030ab565b62000c3d8787620033a7565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148062000d3957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60d8600082600881111562000d585762000d58620050ca565b600881111562000d6c5762000d6c620050ca565b81526020019081526020016000205462000d86816200358a565b62000d91826200252b565b62000dcc57816040517f1865965400000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b81600881111562000de15762000de1620050ca565b60d68054600190921b19909116905581600881111562000e055762000e05620050ca565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b8173ffffffffffffffffffffffffffffffffffffffff811662000ea3576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff811662000ef2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe62000f1e816200358a565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152610109602052604090205486911615158062000f8c575061010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529252909120541615155b1562000fdd576040517f12f3df0900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff85811660009081526101096020526040902054161562001057576040517ff8fb7c2700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8616600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff8516610222148062001095575073ffffffffffffffffffffffffffffffffffffffff8516610333145b80620010b8575073ffffffffffffffffffffffffffffffffffffffff8516610111145b1562001109576040517fd8ce8acb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8616600482015260240162000b7a565b61010b5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8b81168552925290912054161562001191576040517f022bc84100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816600482015260240162000b7a565b60008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c168086529184528285208054918c167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155808652610109909452828520805490911682179055905133937f844cb5c635052898ad92bea4ece14519111765d835105e76aa1f77ad0d0aa81f91a450505050505050565b60c95473ffffffffffffffffffffffffffffffffffffffff16331462001289576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff93841693909216916367e404ce916004808201926020929091908290030181865afa15801562001301573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001327919062005145565b73ffffffffffffffffffffffffffffffffffffffff161462001375576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015620014915761010a5460009081526101086020526040812061033391858585818110620013ad57620013ad62005165565b9050602002016020810190620013c4919062004f27565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558282828181106200142f576200142f62005165565b905060200201602081019062001446919062004f27565b73ffffffffffffffffffffffffffffffffffffffff167f91d24864a084ab70b268a1f865e757ca12006cf298d763b6be697302ef86498c60405160405180910390a260010162001378565b505050565b600082815260976020526040902060010154620014b3816200358a565b62001491838362002f10565b73ffffffffffffffffffffffffffffffffffffffff8116331462001566576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840162000b7a565b62001572828262003599565b5050565b60005b81518110156200169a57600061010960008484815181106200159f576200159f62005165565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff90811683529082019290925260400160002054169050806200164957828281518110620015f157620015f162005165565b60200260200101516040517fa5ea89da00000000000000000000000000000000000000000000000000000000815260040162000b7a919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b808383815181106200165f576200165f62005165565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250806200169181620051c3565b91505062001579565b5060c95460ca5460405173ffffffffffffffffffffffffffffffffffffffff92831692639f3ce55a9234929116908290620016da908790602401620051fe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2a564f3400000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b1681526200178b939291906004016200525a565b6000604051808303818588803b158015620017a557600080fd5b505af1158015620017ba573d6000803e3d6000fd5b50505050503373ffffffffffffffffffffffffffffffffffffffff167f59eab5b5f813ac9e0c10035dfb55b5e3419eff53c0f7a869fb3c22400ea036d682604051620018079190620051fe565b60405180910390a250565b8273ffffffffffffffffffffffffffffffffffffffff811662001861576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff8116620018b0576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8380600003620018f0576040517f4618044a0000000000000000000000000000000000000000000000000000000081526004810182905260240162000b7a565b620018fa62003655565b620019066007620036ca565b61010a5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c168552925290912054167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeef8101620019b0576040517f6dad9c7800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8916600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff80891660009081526101096020526040812054909116906060821562001a79576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b905273ffffffffffffffffffffffffffffffffffffffff8c1690639dc29fac90604401600060405180830381600087803b15801562001a5457600080fd5b505af115801562001a69573d6000803e3d6000fd5b5050505061010b54915062001d35565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8d16906370a0823190602401602060405180830381865afa15801562001ae7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001b0d91906200529a565b905062001b3373ffffffffffffffffffffffffffffffffffffffff8d1633308e62003765565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff8e16906370a0823190602401602060405180830381865afa15801562001ba0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001bc691906200529a565b62001bd29190620052b4565b9a508b935073ffffffffffffffffffffffffffffffffffffffff851662001cc957610222610108600088815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b73ffffffffffffffffffffffffffffffffffffffff167f0f53e2a811b6fd2d6cd965fd6c27b44fb924ca39f7a7f321115705c22366d62360405160405180910390a25b73ffffffffffffffffffffffffffffffffffffffff85166103331462001d305762001cf48c62003843565b62001cff8d62003963565b62001d0a8e62003a70565b60405160200162001d1e93929190620052ca565b60405160208183030381529060405291505b859250505b60c960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639f3ce55a3460ca60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1634878f8f898960405160240162001db395949392919062005307565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4d2745100000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001e64939291906004016200525a565b6000604051808303818588803b15801562001e7e57600080fd5b505af115801562001e93573d6000803e3d6000fd5b50505050508a73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8780a94875b70464f8ac6c28851501d32e7fd4ee574e4b94beb28923a3c42d9c8d60405162001f0f91815260200190565b60405180910390a4505050505062001f2660018055565b505050505050565b7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2462001f5a816200358a565b60ca5473ffffffffffffffffffffffffffffffffffffffff161562001fc85760ca546040517f94fbfd2e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240162000b7a565b62001fd38262003bb6565b604051339073ffffffffffffffffffffffffffffffffffffffff8416907fb044c1a1a05a729c402def784b4e4cb01612ff03eee6f0beb3eba0f0606260a190600090a35050565b6200202c604082016020830162004f27565b73ffffffffffffffffffffffffffffffffffffffff81166200207a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200208c606083016040840162004f27565b73ffffffffffffffffffffffffffffffffffffffff8116620020da576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015620020fb5750600054600160ff909116105b80620021175750303b15801562002117575060005460ff166001145b620021a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840162000b7a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156200220457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6200222d6200221760e08601866200534e565b620022276101008801886200534e565b620030ab565b6200224962002243604086016020870162004f27565b62003c76565b6200225362003006565b6200226e600062002268602087018762004f27565b62002f10565b620022876200228160c08601866200534e565b620033a7565b62002299606085016040860162004f27565b61010780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055606084013561010a55608084013561010b5560005b6200230360a0860186620053b9565b9050811015620024c05760006200231e60a0870187620053b9565b8381811062002331576200233162005165565b905060200201602081019062002348919062004f27565b73ffffffffffffffffffffffffffffffffffffffff160362002396576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a5460009081526101086020526040812061011191620023bc60a0890189620053b9565b85818110620023cf57620023cf62005165565b9050602002016020810190620023e6919062004f27565b73ffffffffffffffffffffffffffffffffffffffff9081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790556200244b60a0860186620053b9565b828181106200245e576200245e62005165565b905060200201602081019062002475919062004f27565b73ffffffffffffffffffffffffffffffffffffffff167f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe960405160405180910390a2600101620022f4565b5080156200252557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b6000816008811115620025425762002542620050ca565b60d654600190911b16151592915050565b8073ffffffffffffffffffffffffffffffffffffffff8116620025a2576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce00620025ce816200358a565b60c9805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff00000000000000000000000000000000000000008316811790935560405191169133918391907fc96d462e42a71473da49a1d58c1754b9b2d319786692d621dc7f921331c517e990600090a450505050565b8073ffffffffffffffffffffffffffffffffffffffff811662002698576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152610109602052604090205483911615158062002706575061010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff85811685529252909120541615155b1562002757576040517f12f3df0900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240162000b7a565b7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d62002783816200358a565b61010a5460009081526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816808552925280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166101111790555190917f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe991a250505050565b6000828152609760205260409020600101546200282b816200358a565b62001491838362003599565b80156200284b576200284b85838362003da4565b6200285885858562001812565b5050505050565b60d76000826008811115620028785762002878620050ca565b60088111156200288c576200288c620050ca565b815260200190815260200160002054620028a6816200358a565b620028b1826200252b565b15620028ed57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b816008811115620029025762002902620050ca565b60d68054600190921b9091179055816008811115620029255762002925620050ca565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593362000e28565b6200295762003655565b60c95473ffffffffffffffffffffffffffffffffffffffff163314620029a9576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff93841693909216916367e404ce916004808201926020929091908290030181865afa15801562002a21573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002a47919062005145565b73ffffffffffffffffffffffffffffffffffffffff161462002a95576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600862002aa281620036ca565b60008481526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff808c1685529252822054169061022282148062002afd575073ffffffffffffffffffffffffffffffffffffffff8216610333145b1562002b2c5762002b2673ffffffffffffffffffffffffffffffffffffffff8a16888a62004075565b62002cfb565b508073ffffffffffffffffffffffffffffffffffffffff811662002c705762002b5b89868661010a54620040cd565b90508861010960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080610108600061010b54815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8881166004830152602482018a90528216906340c10f1990604401600060405180830381600087803b15801562002ce157600080fd5b505af115801562002cf6573d6000803e3d6000fd5b505050505b8673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f6ed06519caca659cdefa71015c79a561928d3cf8cc4a3e9739fde9fb5fb38d648b60405162002d7291815260200190565b60405180910390a450505062001f2660018055565b8073ffffffffffffffffffffffffffffffffffffffff811662002dd6576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3562002e02816200358a565b61010a5460008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8881168552925290912054166101111462002e8d576040517f82f5d0a500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240162000b7a565b60008181526101086020908152604080832073ffffffffffffffffffffffffffffffffffffffff8816808552925280832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555190917f0145163d8d460d1ab21463758d147fdfe79d4b57c81ca3d1439996104ae6895991a250505050565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166200157257600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905562002fa83390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600054610100900460ff166200309f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b620030a962004231565b565b600054610100900460ff1662003144576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b8260005b81811015620032745785858281811062003166576200316662005165565b9050604002016020013560d7600088888581811062003189576200318962005165565b620031a1926020604090920201908101915062004c2f565b6008811115620031b557620031b5620050ca565b6008811115620031c957620031c9620050ca565b81526020810191909152604001600020557f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609186868381811062003210576200321062005165565b62003228926020604090920201908101915062004c2f565b8787848181106200323d576200323d62005165565b905060400201602001356040516200325792919062005424565b60405180910390a1806200326b81620051c3565b91505062003148565b5081905060005b8181101562001f265783838281811062003299576200329962005165565b9050604002016020013560d86000868685818110620032bc57620032bc62005165565b620032d4926020604090920201908101915062004c2f565b6008811115620032e857620032e8620050ca565b6008811115620032fc57620032fc620050ca565b81526020810191909152604001600020557fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c284848381811062003343576200334362005165565b6200335b926020604090920201908101915062004c2f565b85858481811062003370576200337062005165565b905060400201602001356040516200338a92919062005424565b60405180910390a1806200339e81620051c3565b9150506200327b565b600054610100900460ff1662003440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b8060005b818110156200252557600084848381811062003464576200346462005165565b6200347c926020604090920201908101915062004f27565b73ffffffffffffffffffffffffffffffffffffffff1603620034ca576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838382818110620034df57620034df62005165565b905060400201602001356000801b0362003525576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620035758484838181106200353e576200353e62005165565b905060400201602001358585848181106200355d576200355d62005165565b62002268926020604090920201908101915062004f27565b806200358181620051c3565b91505062003444565b620035968133620042ca565b50565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156200157257600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600260015403620036c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000b7a565b6002600155565b60d654816008811115620036e257620036e2620050ca565b6001901b8116156200372457816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b6002811615620015725760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b7a919062005135565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052620025259085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526200438d565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde03000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620038c7919062005441565b600060405180830381855afa9150503d806000811462003904576040519150601f19603f3d011682016040523d82523d6000602084013e62003909565b606091505b50915091508162003950576040518060400160405280600781526020017f4e4f5f4e414d45000000000000000000000000000000000000000000000000008152506200395b565b6200395b81620044a3565b949350505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b41000000000000000000000000000000000000000000000000000000001790529051606091600091829173ffffffffffffffffffffffffffffffffffffffff861691620039e7919062005441565b600060405180830381855afa9150503d806000811462003a24576040519150601f19603f3d011682016040523d82523d6000602084013e62003a29565b606091505b50915091508162003950576040518060400160405280600981526020017f4e4f5f53594d424f4c00000000000000000000000000000000000000000000008152506200395b565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290516000918291829173ffffffffffffffffffffffffffffffffffffffff86169162003af3919062005441565b600060405180830381855afa9150503d806000811462003b30576040519150601f19603f3d011682016040523d82523d6000602084013e62003b35565b606091505b509150915081801562003b49575080516020145b1562003b6557808060200190518101906200395b91906200546f565b6040517fb5a2f1c600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240162000b7a565b60018055565b73ffffffffffffffffffffffffffffffffffffffff811662003c04576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040513391907fe68b208814fdb633b222cd15e73d5a27fb4ef9eef4cae78c623bc27702141d2890600090a350565b600054610100900460ff1662003d0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b73ffffffffffffffffffffffffffffffffffffffff811662003d5d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60c980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7fd505accf0000000000000000000000000000000000000000000000000000000062003dd56004600084866200548f565b62003de091620054bb565b7fffffffff00000000000000000000000000000000000000000000000000000000161462003ea15762003e186004600083856200548f565b62003e2391620054bb565b6040517fcf9e29460000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201527fd505accf00000000000000000000000000000000000000000000000000000000602482015260440162000b7a565b600080808080808062003eb8886004818c6200548f565b81019062003ec7919062005504565b96509650965096509650965096503373ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161462003f54576040517f200688cc00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8816600482015260240162000b7a565b73ffffffffffffffffffffffffffffffffffffffff8616301462003fbd576040517f2911594800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8716600482015260240162000b7a565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff8b169063d505accf9060e401600060405180830381600087803b1580156200405057600080fd5b505af115801562004065573d6000803e3d6000fd5b5050505050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052620014919084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401620037c0565b60008181526020859052604081206101075460405173ffffffffffffffffffffffffffffffffffffffff90911690620041069062004a7f565b73ffffffffffffffffffffffffffffffffffffffff90911681526040602082018190526000908201526060018190604051809103906000f590508015801562004153573d6000803e3d6000fd5b50905060008080620041688688018862005621565b9250925092508373ffffffffffffffffffffffffffffffffffffffff16631624f6c68484846040518463ffffffff1660e01b8152600401620041ad93929190620052ca565b600060405180830381600087803b158015620041c857600080fd5b505af1158015620041dd573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff808c169350871691507fd5d4920bb61e6141c8499d50a7bd617dae2b1818c9d6b995d3f2ba4975e32ea490600090a3505050949350505050565b600054610100900460ff1662003bb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b7a565b600082815260976020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1662001572576200430d8162004676565b6200431a83602062004696565b6040516020016200432d92919062005697565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a000000000000000000000000000000000000000000000000000000000825262000b7a9160040162004d8b565b6000620043f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16620048fe9092919063ffffffff16565b9050805160001480620044155750808060200190518101906200441591906200571c565b62001491576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000b7a565b60606040825110620044c5578180602001905181019062000d39919062005740565b81516020146200450857505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b60005b6020811080156200455657508281815181106200452c576200452c62005165565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562004565576001016200450b565b80600003620045a957505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff811115620045c757620045c762004da0565b6040519080825280601f01601f191660200182016040528015620045f2576020820181803683370190505b50905060005b828110156200466e5784818151811062004616576200461662005165565b602001015160f81c60f81b82828151811062004636576200463662005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101620045f8565b509392505050565b606062000d3973ffffffffffffffffffffffffffffffffffffffff831660145b60606000620046a7836002620057b7565b620046b4906002620057d1565b67ffffffffffffffff811115620046cf57620046cf62004da0565b6040519080825280601f01601f191660200182016040528015620046fa576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811062004734576200473462005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106200479a576200479a62005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000620047d8846002620057b7565b620047e5906001620057d1565b90505b60018111156200488c577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106200482a576200482a62005165565b1a60f81b82828151811062004843576200484362005165565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936200488481620057e7565b9050620047e8565b508315620048f7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000b7a565b9392505050565b60606200395b8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405162004935919062005441565b60006040518083038185875af1925050503d806000811462004974576040519150601f19603f3d011682016040523d82523d6000602084013e62004979565b606091505b50915091506200498c8783838762004997565b979650505050505050565b6060831562004a3257825160000362004a2a5773ffffffffffffffffffffffffffffffffffffffff85163b62004a2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000b7a565b50816200395b565b6200395b838381511562004a495781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b7a919062004d8b565b6106f3806200582083390190565b73ffffffffffffffffffffffffffffffffffffffff811681146200359657600080fd5b60008083601f84011262004ac357600080fd5b50813567ffffffffffffffff81111562004adc57600080fd5b6020830191508360208260061b850101111562004af857600080fd5b9250929050565b60008060008060008060006080888a03121562004b1b57600080fd5b873562004b288162004a8d565b9650602088013567ffffffffffffffff8082111562004b4657600080fd5b62004b548b838c0162004ab0565b909850965060408a013591508082111562004b6e57600080fd5b62004b7c8b838c0162004ab0565b909650945060608a013591508082111562004b9657600080fd5b5062004ba58a828b0162004ab0565b989b979a50959850939692959293505050565b60006020828403121562004bcb57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114620048f757600080fd5b6000806040838503121562004c1057600080fd5b82359150602083013562004c248162004a8d565b809150509250929050565b60006020828403121562004c4257600080fd5b813560098110620048f757600080fd5b6000806040838503121562004c6657600080fd5b823562004c738162004a8d565b9150602083013562004c248162004a8d565b60006020828403121562004c9857600080fd5b5035919050565b6000806020838503121562004cb357600080fd5b823567ffffffffffffffff8082111562004ccc57600080fd5b818501915085601f83011262004ce157600080fd5b81358181111562004cf157600080fd5b8660208260051b850101111562004d0757600080fd5b60209290920196919550909350505050565b60005b8381101562004d3657818101518382015260200162004d1c565b50506000910152565b6000815180845262004d5981602086016020860162004d19565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000620048f7602083018462004d3f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171562004e195762004e1962004da0565b604052919050565b6000602080838503121562004e3557600080fd5b823567ffffffffffffffff8082111562004e4e57600080fd5b818501915085601f83011262004e6357600080fd5b81358181111562004e785762004e7862004da0565b8060051b915062004e8b84830162004dcf565b818152918301840191848101908884111562004ea657600080fd5b938501935b8385101562004ed4578435925062004ec38362004a8d565b828252938501939085019062004eab565b98975050505050505050565b60008060006060848603121562004ef657600080fd5b833562004f038162004a8d565b925060208401359150604084013562004f1c8162004a8d565b809150509250925092565b60006020828403121562004f3a57600080fd5b8135620048f78162004a8d565b60006020828403121562004f5a57600080fd5b813567ffffffffffffffff81111562004f7257600080fd5b82016101208185031215620048f757600080fd5b60008083601f84011262004f9957600080fd5b50813567ffffffffffffffff81111562004fb257600080fd5b60208301915083602082850101111562004af857600080fd5b60008060008060006080868803121562004fe457600080fd5b853562004ff18162004a8d565b94506020860135935060408601356200500a8162004a8d565b9250606086013567ffffffffffffffff8111156200502757600080fd5b620050358882890162004f86565b969995985093965092949392505050565b60008060008060008060a087890312156200506057600080fd5b86356200506d8162004a8d565b9550602087013594506040870135620050868162004a8d565b935060608701359250608087013567ffffffffffffffff811115620050aa57600080fd5b620050b889828a0162004f86565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6009811062005131577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810162000d398284620050f9565b6000602082840312156200515857600080fd5b8151620048f78162004a8d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620051f757620051f762005194565b5060010190565b6020808252825182820181905260009190848201906040850190845b818110156200524e57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016200521a565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600062005291606083018462004d3f565b95945050505050565b600060208284031215620052ad57600080fd5b5051919050565b8181038181111562000d395762000d3962005194565b606081526000620052df606083018662004d3f565b8281036020840152620052f3818662004d3f565b91505060ff83166040830152949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835286602084015280861660408401525083606083015260a060808301526200498c60a083018462004d3f565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126200538457600080fd5b83018035915067ffffffffffffffff821115620053a057600080fd5b6020019150600681901b360382131562004af857600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112620053ef57600080fd5b83018035915067ffffffffffffffff8211156200540b57600080fd5b6020019150600581901b360382131562004af857600080fd5b60408101620054348285620050f9565b8260208301529392505050565b600082516200545581846020870162004d19565b9190910192915050565b60ff811681146200359657600080fd5b6000602082840312156200548257600080fd5b8151620048f7816200545f565b60008085851115620054a057600080fd5b83861115620054ae57600080fd5b5050820193919092039150565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015620054fc5780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a0312156200552057600080fd5b87356200552d8162004a8d565b965060208801356200553f8162004a8d565b9550604088013594506060880135935060808801356200555f816200545f565b9699959850939692959460a0840135945060c09093013592915050565b600067ffffffffffffffff82111562005599576200559962004da0565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112620055d757600080fd5b8135620055ee620055e8826200557c565b62004dcf565b8181528460208386010111156200560457600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156200563757600080fd5b833567ffffffffffffffff808211156200565057600080fd5b6200565e87838801620055c5565b945060208601359150808211156200567557600080fd5b506200568486828701620055c5565b925050604084013562004f1c816200545f565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351620056d181601785016020880162004d19565b7f206973206d697373696e6720726f6c652000000000000000000000000000000060179184019182015283516200571081602884016020880162004d19565b01602801949350505050565b6000602082840312156200572f57600080fd5b81518015158114620048f757600080fd5b6000602082840312156200575357600080fd5b815167ffffffffffffffff8111156200576b57600080fd5b8201601f810184136200577d57600080fd5b80516200578e620055e8826200557c565b818152856020838501011115620057a457600080fd5b6200529182602083016020860162004d19565b808202811582820484141762000d395762000d3962005194565b8082018082111562000d395762000d3962005194565b600081620057f957620057f962005194565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe60806040526040516106f33803806106f383398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106cc602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b610173806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100dc565b565b60006100697fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d79190610100565b905090565b3660008037600080366000845af43d6000803e8080156100fb573d6000f35b3d6000fd5b60006020828403121561011257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461013657600080fd5b939250505056fea2646970667358221220487f6f370ed71b7026944bbfbeff4c6a8abfbc1f686dbaab6010959808b5814564736f6c63430008130033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220de9804b67318a6cdb529d18b92fd51bf5512166da05a44c81a9aaec12a7bc66b64736f6c63430008130033", + "bytecode": "0x60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6155b380620000f36000396000f3fe6080604052600436106200030b5760003560e01c806391d148541162000197578063ca41a24711620000e7578063d547741f1162000095578063e4d27451116200006c578063e4d2745114620009f3578063edc42a221462000a18578063fe3c50a01462000a3d57600080fd5b8063d547741f1462000992578063dfa96efb14620009b7578063e196fb5d14620009ce57600080fd5b8063ccf5a77c11620000ca578063ccf5a77c1462000914578063cdd914c51462000937578063cf4a7208146200095c57600080fd5b8063ca41a24714620008a5578063cc5782f614620008e057600080fd5b8063b3232bdf1162000145578063be46096f1162000128578063be46096f1462000814578063c483d8381462000839578063c986752a146200086f57600080fd5b8063b3232bdf14620007ca578063bc61e73314620007ef57600080fd5b8063a217fddf116200017a578063a217fddf146200076c578063a676e8ab1462000783578063a6ef995f14620007a857600080fd5b806391d1485414620006ec5780639ac25d08146200073657600080fd5b80632f2ff15d116200025f578063522ea81a116200020d5780636a906b8011620001e45780636a906b80146200065e57806380efb43a14620006945780638dae45dd14620006ca57600080fd5b8063522ea81a14620005db5780635626fc2514620005f25780635a06a42a146200062857600080fd5b806336568abe116200024257806336568abe146200054557806338b90333146200056a5780634bf98dce14620005c457600080fd5b80632f2ff15d14620004ea5780633551237b146200050f57600080fd5b80631544298e11620002bd578063248a9ca311620002a0578063248a9ca3146200045b5780632a564f34146200048f5780632e4c3fff14620004b457600080fd5b80631544298e146200041d5780631754f301146200043657600080fd5b80630f6f86ec11620002f25780630f6f86ec14620003715780631065a39914620003d0578063146ffb2614620003f557600080fd5b806301941d39146200031057806301ffc9a71462000337575b600080fd5b3480156200031d57600080fd5b50620003356200032f36600462004212565b62000a73565b005b3480156200034457600080fd5b506200035c62000356366004620042cb565b62000c0a565b60405190151581526020015b60405180910390f35b3480156200037e57600080fd5b50620003b7620003903660046200430f565b6101086020908152600092835260408084209091529082529020546001600160a01b031681565b6040516001600160a01b03909116815260200162000368565b348015620003dd57600080fd5b5062000335620003ef36600462004342565b62000ca4565b3480156200040257600080fd5b506200040e61010b5481565b60405190815260200162000368565b3480156200042a57600080fd5b506200040e61010a5481565b3480156200044357600080fd5b50620003356200045536600462004365565b62000dad565b3480156200046857600080fd5b506200040e6200047a36600462004398565b60009081526097602052604090206001015490565b3480156200049c57600080fd5b5062000335620004ae366004620043b2565b620010a8565b348015620004c157600080fd5b506200040e7f8a7b208fd13ab36d18025be4f62b53d46aeb2cbe8958d2e13de74c040dddcddd81565b348015620004f757600080fd5b5062000335620005093660046200430f565b620012c7565b3480156200051c57600080fd5b506200040e7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3581565b3480156200055257600080fd5b5062000335620005643660046200430f565b620012f5565b3480156200057757600080fd5b50620005b56040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405162000368919062004480565b62000335620005d5366004620044f8565b62001385565b62000335620005ec366004620045b7565b620015f4565b348015620005ff57600080fd5b506200040e7f46e34517dc946faf87aabe65eb5b4fa06b974e5c8d72c5df73b9fb6ff7b6d80281565b3480156200063557600080fd5b506200040e7f50962b2d10066f5051f78d5ea04a3ab09b9c87dd1002962f0b1e30e66eeb80a581565b3480156200066b57600080fd5b506200040e7fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015620006a157600080fd5b506200040e7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2481565b348015620006d757600080fd5b5060c954620003b7906001600160a01b031681565b348015620006f957600080fd5b506200035c6200070b3660046200430f565b60009182526097602090815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156200074357600080fd5b506200040e7f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b3480156200077957600080fd5b506200040e600081565b3480156200079057600080fd5b5062000335620007a2366004620045fe565b62001ba2565b348015620007b557600080fd5b5060ca54620003b7906001600160a01b031681565b348015620007d757600080fd5b5062000335620007e93660046200461e565b62001c67565b348015620007fc57600080fd5b506200035c6200080e36600462004342565b620020c5565b3480156200082157600080fd5b506200033562000833366004620045fe565b620020ed565b3480156200084657600080fd5b506200040e7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d81565b3480156200087c57600080fd5b506200040e7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe81565b348015620008b257600080fd5b50620003b7620008c4366004620045fe565b610109602052600090815260409020546001600160a01b031681565b348015620008ed57600080fd5b506200035c620008ff36600462004398565b60d56020526000908152604090205460ff1681565b3480156200092157600080fd5b5061010754620003b7906001600160a01b031681565b3480156200094457600080fd5b506200033562000956366004620045fe565b620021b0565b3480156200096957600080fd5b506200040e7f3900d9d72d5177a154375317154fdc0e08377e3134a8a5d21cadccf831cc231c81565b3480156200099f57600080fd5b5062000335620009b13660046200430f565b6200231b565b62000335620009c8366004620046a2565b62002344565b348015620009db57600080fd5b5062000335620009ed36600462004342565b6200236c565b34801562000a0057600080fd5b506200033562000a123660046200471d565b6200245a565b34801562000a2557600080fd5b506200033562000a37366004620045fe565b6200279d565b34801562000a4a57600080fd5b506200040e7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce0081565b600054600290610100900460ff1615801562000a96575060005460ff8083169116105b62000b0e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556001600160a01b03881662000b67576040516342bcdf7f60e11b815260040160405180910390fd5b62000b74600089620028d9565b6000606555600060d55562000b886200299b565b62000b968585858562002a26565b62000ba2878762002d0c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148062000c9e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60d8600082600881111562000cbd5762000cbd620047a1565b600881111562000cd15762000cd1620047a1565b81526020019081526020016000205462000ceb8162002eae565b62000cf682620020c5565b62000d3157816040517f1865965400000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b81600881111562000d465762000d46620047a1565b60d68054600190921b19909116905581600881111562000d6a5762000d6a620047a1565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b6040516001600160a01b0390911681526020015b60405180910390a25050565b816001600160a01b03811662000dd6576040516342bcdf7f60e11b815260040160405180910390fd5b816001600160a01b03811662000dff576040516342bcdf7f60e11b815260040160405180910390fd5b7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe62000e2b8162002eae565b6001600160a01b038086166000908152610109602052604090205486911615158062000e7f575061010a546000908152610108602090815260408083206001600160a01b0385811685529252909120541615155b1562000ec3576040517f12f3df090000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240162000b05565b6001600160a01b0385811660009081526101096020526040902054161562000f23576040517ff8fb7c270000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260240162000b05565b6001600160a01b038516610222148062000f4757506001600160a01b038516610333145b8062000f5d57506001600160a01b038516610111145b1562000fa1576040517fd8ce8acb0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260240162000b05565b61010b546000818152610108602090815260408083206001600160a01b038b8116855292529091205416156200100f576040517f022bc8410000000000000000000000000000000000000000000000000000000081526001600160a01b038816600482015260240162000b05565b6000818152610108602090815260408083206001600160a01b03808c168086529184528285208054918c167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155808652610109909452828520805490911682179055905133937f844cb5c635052898ad92bea4ece14519111765d835105e76aa1f77ad0d0aa81f91a450505050505050565b60c9546001600160a01b03163314620010ed576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce00000000000000000000000000000000000000000000000000000000815290516001600160a01b0393841693909216916367e404ce916004808201926020929091908290030181865afa15801562001158573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200117e919062004812565b6001600160a01b031614620011bf576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a5460005b82811015620012c15760008281526101086020526040812061033391868685818110620011f757620011f762004832565b90506020020160208101906200120e9190620045fe565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558383828181106200126c576200126c62004832565b9050602002016020810190620012839190620045fe565b6001600160a01b03167f91d24864a084ab70b268a1f865e757ca12006cf298d763b6be697302ef86498c60405160405180910390a2600101620011c6565b50505050565b600082815260976020526040902060010154620012e48162002eae565b620012f08383620028d9565b505050565b6001600160a01b0381163314620013755760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840162000b05565b62001381828262002ebd565b5050565b80516000819003620013c3576040517f10cbd58300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015620014bf5760006101096000858481518110620013eb57620013eb62004832565b6020908102919091018101516001600160a01b0390811683529082019290925260400160002054169050806200147b5783828151811062001430576200143062004832565b60200260200101516040517fa5ea89da00000000000000000000000000000000000000000000000000000000815260040162000b0591906001600160a01b0391909116815260200190565b8084838151811062001491576200149162004832565b6001600160a01b03909216602092830291909101909101525080620014b68162004890565b915050620013c6565b5060c95460ca546040516001600160a01b0392831692639f3ce55a9234929116908290620014f2908890602401620048cb565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2a564f3400000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001585939291906004016200491a565b6000604051808303818588803b1580156200159f57600080fd5b505af1158015620015b4573d6000803e3d6000fd5b5050505050336001600160a01b03167f59eab5b5f813ac9e0c10035dfb55b5e3419eff53c0f7a869fb3c22400ea036d68360405162000da19190620048cb565b826001600160a01b0381166200161d576040516342bcdf7f60e11b815260040160405180910390fd5b816001600160a01b03811662001646576040516342bcdf7f60e11b815260040160405180910390fd5b838060000362001686576040517f4618044a0000000000000000000000000000000000000000000000000000000081526004810182905260240162000b05565b6200169062002f5f565b6200169c600762002fba565b61010a546000818152610108602090815260408083206001600160a01b03808c168552925290912054167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeef81016200172c576040517f6dad9c780000000000000000000000000000000000000000000000000000000081526001600160a01b038916600482015260240162000b05565b6001600160a01b03808916600090815261010960205260408120549091169060608215620017db576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b90526001600160a01b038c1690639dc29fac90604401600060405180830381600087803b158015620017b657600080fd5b505af1158015620017cb573d6000803e3d6000fd5b5050505061010b54915062001a15565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038d16906370a0823190602401602060405180830381865afa1580156200183c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200186291906200494d565b90506200187b6001600160a01b038d1633308e62003055565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281906001600160a01b038e16906370a0823190602401602060405180830381865afa158015620018db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200190191906200494d565b6200190d919062004967565b9a508b93506001600160a01b038516620019b657610222610108600088815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b6001600160a01b03167f0f53e2a811b6fd2d6cd965fd6c27b44fb924ca39f7a7f321115705c22366d62360405160405180910390a25b6001600160a01b0385166103331462001a1057620019d48c62003108565b620019df8d6200321b565b620019ea8e6200331b565b604051602001620019fe939291906200497d565b60405160208183030381529060405291505b859250505b60c960009054906101000a90046001600160a01b03166001600160a01b0316639f3ce55a3460ca60009054906101000a90046001600160a01b031634878f8f898960405160240162001a6c959493929190620049ba565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4d2745100000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001aff939291906004016200491a565b6000604051808303818588803b15801562001b1957600080fd5b505af115801562001b2e573d6000803e3d6000fd5b50505050508a6001600160a01b0316896001600160a01b0316336001600160a01b03167f8780a94875b70464f8ac6c28851501d32e7fd4ee574e4b94beb28923a3c42d9c8d60405162001b8391815260200190565b60405180910390a4505050505062001b9a60018055565b505050505050565b7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2462001bce8162002eae565b60ca546001600160a01b03161562001c225760ca546040517f94fbfd2e0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015260240162000b05565b62001c2d8262003447565b60405133906001600160a01b038416907fb044c1a1a05a729c402def784b4e4cb01612ff03eee6f0beb3eba0f0606260a190600090a35050565b62001c796040820160208301620045fe565b6001600160a01b03811662001ca1576040516342bcdf7f60e11b815260040160405180910390fd5b62001cb36060830160408401620045fe565b6001600160a01b03811662001cdb576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff161580801562001cfc5750600054600160ff909116105b8062001d185750303b15801562001d18575060005460ff166001145b62001d8c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840162000b05565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801562001deb57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b62001e1462001dfe60e0860186620049f4565b62001e0e610100880188620049f4565b62002a26565b62001e3062001e2a6040860160208701620045fe565b620034d4565b62001e3a6200299b565b62001e55600062001e4f6020870187620045fe565b620028d9565b62001e6e62001e6860c0860186620049f4565b62002d0c565b62001e806060850160408601620045fe565b61010780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055606084013561010a55608084013561010b5560005b62001edd60a086018662004a5f565b90508110156200205b57600062001ef860a087018762004a5f565b8381811062001f0b5762001f0b62004832565b905060200201602081019062001f229190620045fe565b6001600160a01b03160362001f4a576040516342bcdf7f60e11b815260040160405180910390fd5b60608501356000908152610108602052604081206101119162001f7160a089018962004a5f565b8581811062001f845762001f8462004832565b905060200201602081019062001f9b9190620045fe565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169290911691909117905562001ff360a086018662004a5f565b8281811062002006576200200662004832565b90506020020160208101906200201d9190620045fe565b6001600160a01b03167f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe960405160405180910390a260010162001ece565b508015620012c157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6000816008811115620020dc57620020dc620047a1565b60d654600190911b16151592915050565b806001600160a01b03811662002116576040516342bcdf7f60e11b815260040160405180910390fd5b7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce00620021428162002eae565b60c980546001600160a01b038581167fffffffffffffffffffffffff00000000000000000000000000000000000000008316811790935560405191169133918391907fc96d462e42a71473da49a1d58c1754b9b2d319786692d621dc7f921331c517e990600090a450505050565b806001600160a01b038116620021d9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808316600090815261010960205260409020548391161515806200222d575061010a546000908152610108602090815260408083206001600160a01b0385811685529252909120541615155b1562002271576040517f12f3df090000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240162000b05565b7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d6200229d8162002eae565b61010a546000908152610108602090815260408083206001600160a01b038816808552925280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166101111790555190917f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe991a250505050565b600082815260976020526040902060010154620023388162002eae565b620012f0838362002ebd565b8015620023585762002358858383620035b5565b62002365858585620015f4565b5050505050565b60d76000826008811115620023855762002385620047a1565b6008811115620023995762002399620047a1565b815260200190815260200160002054620023b38162002eae565b620023be82620020c5565b15620023fa57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b8160088111156200240f576200240f620047a1565b60d68054600190921b9091179055816008811115620024325762002432620047a1565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593362000d8d565b6200246462002f5f565b60c9546001600160a01b03163314620024a9576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce00000000000000000000000000000000000000000000000000000000815290516001600160a01b0393841693909216916367e404ce916004808201926020929091908290030181865afa15801562002514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200253a919062004812565b6001600160a01b0316146200257b576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008620025888162002fba565b6000848152610108602090815260408083206001600160a01b03808c16855292528220541690610222821480620025c957506001600160a01b038216610333145b15620025eb57620025e56001600160a01b038a16888a620038d1565b62002738565b50806001600160a01b038116620026ba576200260d89868661010a546200391c565b9050886101096000836001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080610108600061010b54815260200190815260200160002060008b6001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152602482018a90528216906340c10f1990604401600060405180830381600087803b1580156200271e57600080fd5b505af115801562002733573d6000803e3d6000fd5b505050505b866001600160a01b0316816001600160a01b03168a6001600160a01b03167f6ed06519caca659cdefa71015c79a561928d3cf8cc4a3e9739fde9fb5fb38d648b6040516200278891815260200190565b60405180910390a450505062001b9a60018055565b806001600160a01b038116620027c6576040516342bcdf7f60e11b815260040160405180910390fd5b7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a35620027f28162002eae565b61010a546000818152610108602090815260408083206001600160a01b038881168552925290912054166101111462002863576040517f82f5d0a50000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260240162000b05565b6000818152610108602090815260408083206001600160a01b038816808552925280832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555190917f0145163d8d460d1ab21463758d147fdfe79d4b57c81ca3d1439996104ae6895991a250505050565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff16620013815760008281526097602090815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055620029573390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600054610100900460ff1662002a1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b62002a2462003a4c565b565b600054610100900460ff1662002aa55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60005b8381101562002bd85784848281811062002ac65762002ac662004832565b9050604002016020013560d7600087878581811062002ae95762002ae962004832565b62002b01926020604090920201908101915062004342565b600881111562002b155762002b15620047a1565b600881111562002b295762002b29620047a1565b815260208101919091526040016000205584848281811062002b4f5762002b4f62004832565b9050604002016020013585858381811062002b6e5762002b6e62004832565b62002b86926020604090920201908101915062004342565b600881111562002b9a5762002b9a620047a1565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609190600090a38062002bcf8162004890565b91505062002aa8565b5060005b81811015620023655782828281811062002bfa5762002bfa62004832565b9050604002016020013560d8600085858581811062002c1d5762002c1d62004832565b62002c35926020604090920201908101915062004342565b600881111562002c495762002c49620047a1565b600881111562002c5d5762002c5d620047a1565b815260208101919091526040016000205582828281811062002c835762002c8362004832565b9050604002016020013583838381811062002ca25762002ca262004832565b62002cba926020604090920201908101915062004342565b600881111562002cce5762002cce620047a1565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c290600090a38062002d038162004890565b91505062002bdc565b600054610100900460ff1662002d8b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60005b81811015620012f057600083838381811062002dae5762002dae62004832565b62002dc69260206040909202019081019150620045fe565b6001600160a01b03160362002dee576040516342bcdf7f60e11b815260040160405180910390fd5b82828281811062002e035762002e0362004832565b905060400201602001356000801b0362002e49576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62002e9983838381811062002e625762002e6262004832565b9050604002016020013584848481811062002e815762002e8162004832565b62001e4f9260206040909202019081019150620045fe565b8062002ea58162004890565b91505062002d8e565b62002eba813362003acb565b50565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff1615620013815760008281526097602090815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60026001540362002fb35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000b05565b6002600155565b60d65481600881111562002fd25762002fd2620047a1565b6001901b8116156200301457816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b6002811615620013815760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b6040516001600160a01b0380851660248301528316604482015260648101829052620012c19085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262003b49565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde0300000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b038616916200317f919062004aca565b600060405180830381855afa9150503d8060008114620031bc576040519150601f19603f3d011682016040523d82523d6000602084013e620031c1565b606091505b50915091508162003208576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062003213565b620032138162003c38565b949350505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b4100000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b0386169162003292919062004aca565b600060405180830381855afa9150503d8060008114620032cf576040519150601f19603f3d011682016040523d82523d6000602084013e620032d4565b606091505b50915091508162003208576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062003213565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce567000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b0386169162003391919062004aca565b600060405180830381855afa9150503d8060008114620033ce576040519150601f19603f3d011682016040523d82523d6000602084013e620033d3565b606091505b5091509150818015620033e7575060208151145b1562003403578080602001905181019062003213919062004af8565b6040517fb5a2f1c60000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260240162000b05565b60018055565b6001600160a01b0381166200346f576040516342bcdf7f60e11b815260040160405180910390fd5b60ca80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040513391907fe68b208814fdb633b222cd15e73d5a27fb4ef9eef4cae78c623bc27702141d2890600090a350565b600054610100900460ff16620035535760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b6001600160a01b0381166200357b576040516342bcdf7f60e11b815260040160405180910390fd5b60c980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b7fd505accf00000000000000000000000000000000000000000000000000000000620035e660046000848662004b18565b620035f19162004b44565b7fffffffff000000000000000000000000000000000000000000000000000000001614620036b2576200362960046000838562004b18565b620036349162004b44565b6040517fcf9e29460000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201527fd505accf00000000000000000000000000000000000000000000000000000000602482015260440162000b05565b6000808080808080620036c9886004818c62004b18565b810190620036d8919062004b8d565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146200373e576040517f200688cc0000000000000000000000000000000000000000000000000000000081526001600160a01b038816600482015260240162000b05565b6001600160a01b03861630146200378d576040517f291159480000000000000000000000000000000000000000000000000000000081526001600160a01b038716600482015260240162000b05565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015287811660248301528691908c169063dd62ed3e90604401602060405180830381865afa158015620037f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200381e91906200494d565b1015620038c5576040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c481018290526001600160a01b038b169063d505accf9060e401600060405180830381600087803b158015620038ab57600080fd5b505af1158015620038c0573d6000803e3d6000fd5b505050505b50505050505050505050565b6040516001600160a01b038316602482015260448101829052620012f09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401620030a3565b6000818152602085905260408120610107546040516001600160a01b039091169062003948906200419f565b6001600160a01b0390911681526040602082018190526000908201526060018190604051809103906000f590508015801562003988573d6000803e3d6000fd5b509050600080806200399d8688018862004c8c565b925092509250836001600160a01b0316631624f6c68484846040518463ffffffff1660e01b8152600401620039d5939291906200497d565b600060405180830381600087803b158015620039f057600080fd5b505af115801562003a05573d6000803e3d6000fd5b50506040516001600160a01b03808c169350871691507fd5d4920bb61e6141c8499d50a7bd617dae2b1818c9d6b995d3f2ba4975e32ea490600090a3505050949350505050565b600054610100900460ff16620034415760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff16620013815762003b018162003e0b565b62003b0e83602062003e1e565b60405160200162003b2192919062004d02565b60408051601f198184030181529082905262461bcd60e51b825262000b059160040162004480565b600062003ba0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200406c9092919063ffffffff16565b905080516000148062003bc457508080602001905181019062003bc4919062004d87565b620012f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000b05565b6060604082511062003c5a578180602001905181019062000c9e919062004dab565b602082511462003c9d57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b60005b60208110801562003ceb575082818151811062003cc15762003cc162004832565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562003cfa5760010162003ca0565b8060000362003d3e57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003d5c5762003d5c62004495565b6040519080825280601f01601f19166020018201604052801562003d87576020820181803683370190505b50905060005b8281101562003e035784818151811062003dab5762003dab62004832565b602001015160f81c60f81b82828151811062003dcb5762003dcb62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010162003d8d565b509392505050565b606062000c9e6001600160a01b03831660145b6060600062003e2f83600262004e22565b62003e3c90600262004e3c565b67ffffffffffffffff81111562003e575762003e5762004495565b6040519080825280601f01601f19166020018201604052801562003e82576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811062003ebc5762003ebc62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811062003f225762003f2262004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600062003f6084600262004e22565b62003f6d90600162004e3c565b90505b600181111562004014577f303132333435363738396162636465660000000000000000000000000000000085600f166010811062003fb25762003fb262004832565b1a60f81b82828151811062003fcb5762003fcb62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936200400c8162004e52565b905062003f70565b508315620040655760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000b05565b9392505050565b606062003213848460008585600080866001600160a01b0316858760405162004096919062004aca565b60006040518083038185875af1925050503d8060008114620040d5576040519150601f19603f3d011682016040523d82523d6000602084013e620040da565b606091505b5091509150620040ed87838387620040f8565b979650505050505050565b606083156200416c57825160000362004164576001600160a01b0385163b620041645760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000b05565b508162003213565b620032138383815115620041835781518083602001fd5b8060405162461bcd60e51b815260040162000b05919062004480565b6106f38062004e8b83390190565b6001600160a01b038116811462002eba57600080fd5b60008083601f840112620041d657600080fd5b50813567ffffffffffffffff811115620041ef57600080fd5b6020830191508360208260061b85010111156200420b57600080fd5b9250929050565b60008060008060008060006080888a0312156200422e57600080fd5b87356200423b81620041ad565b9650602088013567ffffffffffffffff808211156200425957600080fd5b620042678b838c01620041c3565b909850965060408a01359150808211156200428157600080fd5b6200428f8b838c01620041c3565b909650945060608a0135915080821115620042a957600080fd5b50620042b88a828b01620041c3565b989b979a50959850939692959293505050565b600060208284031215620042de57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146200406557600080fd5b600080604083850312156200432357600080fd5b8235915060208301356200433781620041ad565b809150509250929050565b6000602082840312156200435557600080fd5b8135600981106200406557600080fd5b600080604083850312156200437957600080fd5b82356200438681620041ad565b915060208301356200433781620041ad565b600060208284031215620043ab57600080fd5b5035919050565b60008060208385031215620043c657600080fd5b823567ffffffffffffffff80821115620043df57600080fd5b818501915085601f830112620043f457600080fd5b8135818111156200440457600080fd5b8660208260051b85010111156200441a57600080fd5b60209290920196919550909350505050565b60005b83811015620044495781810151838201526020016200442f565b50506000910152565b600081518084526200446c8160208601602086016200442c565b601f01601f19169290920160200192915050565b60208152600062004065602083018462004452565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620044f057620044f062004495565b604052919050565b600060208083850312156200450c57600080fd5b823567ffffffffffffffff808211156200452557600080fd5b818501915085601f8301126200453a57600080fd5b8135818111156200454f576200454f62004495565b8060051b915062004562848301620044c4565b81815291830184019184810190888411156200457d57600080fd5b938501935b83851015620045ab57843592506200459a83620041ad565b828252938501939085019062004582565b98975050505050505050565b600080600060608486031215620045cd57600080fd5b8335620045da81620041ad565b9250602084013591506040840135620045f381620041ad565b809150509250925092565b6000602082840312156200461157600080fd5b81356200406581620041ad565b6000602082840312156200463157600080fd5b813567ffffffffffffffff8111156200464957600080fd5b820161012081850312156200406557600080fd5b60008083601f8401126200467057600080fd5b50813567ffffffffffffffff8111156200468957600080fd5b6020830191508360208285010111156200420b57600080fd5b600080600080600060808688031215620046bb57600080fd5b8535620046c881620041ad565b9450602086013593506040860135620046e181620041ad565b9250606086013567ffffffffffffffff811115620046fe57600080fd5b6200470c888289016200465d565b969995985093965092949392505050565b60008060008060008060a087890312156200473757600080fd5b86356200474481620041ad565b95506020870135945060408701356200475d81620041ad565b935060608701359250608087013567ffffffffffffffff8111156200478157600080fd5b6200478f89828a016200465d565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600983106200480c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000602082840312156200482557600080fd5b81516200406581620041ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620048c457620048c462004861565b5060010190565b6020808252825182820181905260009190848201906040850190845b818110156200490e5783516001600160a01b031683529284019291840191600101620048e7565b50909695505050505050565b6001600160a01b038416815282602082015260606040820152600062004944606083018462004452565b95945050505050565b6000602082840312156200496057600080fd5b5051919050565b8181038181111562000c9e5762000c9e62004861565b60608152600062004992606083018662004452565b8281036020840152620049a6818662004452565b91505060ff83166040830152949350505050565b60006001600160a01b03808816835286602084015280861660408401525083606083015260a06080830152620040ed60a083018462004452565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811262004a2a57600080fd5b83018035915067ffffffffffffffff82111562004a4657600080fd5b6020019150600681901b36038213156200420b57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811262004a9557600080fd5b83018035915067ffffffffffffffff82111562004ab157600080fd5b6020019150600581901b36038213156200420b57600080fd5b6000825162004ade8184602087016200442c565b9190910192915050565b60ff8116811462002eba57600080fd5b60006020828403121562004b0b57600080fd5b8151620040658162004ae8565b6000808585111562004b2957600080fd5b8386111562004b3757600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562004b855780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562004ba957600080fd5b873562004bb681620041ad565b9650602088013562004bc881620041ad565b95506040880135945060608801359350608088013562004be88162004ae8565b9699959850939692959460a0840135945060c09093013592915050565b600067ffffffffffffffff82111562004c225762004c2262004495565b50601f01601f191660200190565b600082601f83011262004c4257600080fd5b813562004c5962004c538262004c05565b620044c4565b81815284602083860101111562004c6f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562004ca257600080fd5b833567ffffffffffffffff8082111562004cbb57600080fd5b62004cc98783880162004c30565b9450602086013591508082111562004ce057600080fd5b5062004cef8682870162004c30565b9250506040840135620045f38162004ae8565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162004d3c8160178501602088016200442c565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835162004d7b8160288401602088016200442c565b01602801949350505050565b60006020828403121562004d9a57600080fd5b815180151581146200406557600080fd5b60006020828403121562004dbe57600080fd5b815167ffffffffffffffff81111562004dd657600080fd5b8201601f8101841362004de857600080fd5b805162004df962004c538262004c05565b81815285602083850101111562004e0f57600080fd5b620049448260208301602086016200442c565b808202811582820484141762000c9e5762000c9e62004861565b8082018082111562000c9e5762000c9e62004861565b60008162004e645762004e6462004861565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe60806040526040516106f33803806106f383398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106cc602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b610173806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100dc565b565b60006100697fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d79190610100565b905090565b3660008037600080366000845af43d6000803e8080156100fb573d6000f35b3d6000fd5b60006020828403121561011257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461013657600080fd5b939250505056fea2646970667358221220662c40b76fc0d477a291a78deacd27f4cddd7512dea18087244e38acb2fd99dd64736f6c63430008130033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122008b6c34a5d8997b54caed58d53678d49279942ee4709ef64c362fdb42f961e2064736f6c63430008130033", + "deployedBytecode": "0x6080604052600436106200030b5760003560e01c806391d148541162000197578063ca41a24711620000e7578063d547741f1162000095578063e4d27451116200006c578063e4d2745114620009f3578063edc42a221462000a18578063fe3c50a01462000a3d57600080fd5b8063d547741f1462000992578063dfa96efb14620009b7578063e196fb5d14620009ce57600080fd5b8063ccf5a77c11620000ca578063ccf5a77c1462000914578063cdd914c51462000937578063cf4a7208146200095c57600080fd5b8063ca41a24714620008a5578063cc5782f614620008e057600080fd5b8063b3232bdf1162000145578063be46096f1162000128578063be46096f1462000814578063c483d8381462000839578063c986752a146200086f57600080fd5b8063b3232bdf14620007ca578063bc61e73314620007ef57600080fd5b8063a217fddf116200017a578063a217fddf146200076c578063a676e8ab1462000783578063a6ef995f14620007a857600080fd5b806391d1485414620006ec5780639ac25d08146200073657600080fd5b80632f2ff15d116200025f578063522ea81a116200020d5780636a906b8011620001e45780636a906b80146200065e57806380efb43a14620006945780638dae45dd14620006ca57600080fd5b8063522ea81a14620005db5780635626fc2514620005f25780635a06a42a146200062857600080fd5b806336568abe116200024257806336568abe146200054557806338b90333146200056a5780634bf98dce14620005c457600080fd5b80632f2ff15d14620004ea5780633551237b146200050f57600080fd5b80631544298e11620002bd578063248a9ca311620002a0578063248a9ca3146200045b5780632a564f34146200048f5780632e4c3fff14620004b457600080fd5b80631544298e146200041d5780631754f301146200043657600080fd5b80630f6f86ec11620002f25780630f6f86ec14620003715780631065a39914620003d0578063146ffb2614620003f557600080fd5b806301941d39146200031057806301ffc9a71462000337575b600080fd5b3480156200031d57600080fd5b50620003356200032f36600462004212565b62000a73565b005b3480156200034457600080fd5b506200035c62000356366004620042cb565b62000c0a565b60405190151581526020015b60405180910390f35b3480156200037e57600080fd5b50620003b7620003903660046200430f565b6101086020908152600092835260408084209091529082529020546001600160a01b031681565b6040516001600160a01b03909116815260200162000368565b348015620003dd57600080fd5b5062000335620003ef36600462004342565b62000ca4565b3480156200040257600080fd5b506200040e61010b5481565b60405190815260200162000368565b3480156200042a57600080fd5b506200040e61010a5481565b3480156200044357600080fd5b50620003356200045536600462004365565b62000dad565b3480156200046857600080fd5b506200040e6200047a36600462004398565b60009081526097602052604090206001015490565b3480156200049c57600080fd5b5062000335620004ae366004620043b2565b620010a8565b348015620004c157600080fd5b506200040e7f8a7b208fd13ab36d18025be4f62b53d46aeb2cbe8958d2e13de74c040dddcddd81565b348015620004f757600080fd5b5062000335620005093660046200430f565b620012c7565b3480156200051c57600080fd5b506200040e7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a3581565b3480156200055257600080fd5b5062000335620005643660046200430f565b620012f5565b3480156200057757600080fd5b50620005b56040518060400160405280600381526020017f312e30000000000000000000000000000000000000000000000000000000000081525081565b60405162000368919062004480565b62000335620005d5366004620044f8565b62001385565b62000335620005ec366004620045b7565b620015f4565b348015620005ff57600080fd5b506200040e7f46e34517dc946faf87aabe65eb5b4fa06b974e5c8d72c5df73b9fb6ff7b6d80281565b3480156200063557600080fd5b506200040e7f50962b2d10066f5051f78d5ea04a3ab09b9c87dd1002962f0b1e30e66eeb80a581565b3480156200066b57600080fd5b506200040e7fd8b4c34c2ec1f3194471108c64ad2beda340c0337ee4ca35592f9ef270f4228b81565b348015620006a157600080fd5b506200040e7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2481565b348015620006d757600080fd5b5060c954620003b7906001600160a01b031681565b348015620006f957600080fd5b506200035c6200070b3660046200430f565b60009182526097602090815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156200074357600080fd5b506200040e7f56bdc3c9ec86cb7db110a7699b2ade72f0b8819727d9f7d906b012641505fa7781565b3480156200077957600080fd5b506200040e600081565b3480156200079057600080fd5b5062000335620007a2366004620045fe565b62001ba2565b348015620007b557600080fd5b5060ca54620003b7906001600160a01b031681565b348015620007d757600080fd5b5062000335620007e93660046200461e565b62001c67565b348015620007fc57600080fd5b506200035c6200080e36600462004342565b620020c5565b3480156200082157600080fd5b506200033562000833366004620045fe565b620020ed565b3480156200084657600080fd5b506200040e7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d81565b3480156200087c57600080fd5b506200040e7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe81565b348015620008b257600080fd5b50620003b7620008c4366004620045fe565b610109602052600090815260409020546001600160a01b031681565b348015620008ed57600080fd5b506200035c620008ff36600462004398565b60d56020526000908152604090205460ff1681565b3480156200092157600080fd5b5061010754620003b7906001600160a01b031681565b3480156200094457600080fd5b506200033562000956366004620045fe565b620021b0565b3480156200096957600080fd5b506200040e7f3900d9d72d5177a154375317154fdc0e08377e3134a8a5d21cadccf831cc231c81565b3480156200099f57600080fd5b5062000335620009b13660046200430f565b6200231b565b62000335620009c8366004620046a2565b62002344565b348015620009db57600080fd5b5062000335620009ed36600462004342565b6200236c565b34801562000a0057600080fd5b506200033562000a123660046200471d565b6200245a565b34801562000a2557600080fd5b506200033562000a37366004620045fe565b6200279d565b34801562000a4a57600080fd5b506200040e7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce0081565b600054600290610100900460ff1615801562000a96575060005460ff8083169116105b62000b0e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff8316176101001790556001600160a01b03881662000b67576040516342bcdf7f60e11b815260040160405180910390fd5b62000b74600089620028d9565b6000606555600060d55562000b886200299b565b62000b968585858562002a26565b62000ba2878762002d0c565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148062000c9e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60d8600082600881111562000cbd5762000cbd620047a1565b600881111562000cd15762000cd1620047a1565b81526020019081526020016000205462000ceb8162002eae565b62000cf682620020c5565b62000d3157816040517f1865965400000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b81600881111562000d465762000d46620047a1565b60d68054600190921b19909116905581600881111562000d6a5762000d6a620047a1565b7fd071d2b85dec4489435b541d2f0e2570db09b09db9efd8703948d44a433df65a335b6040516001600160a01b0390911681526020015b60405180910390a25050565b816001600160a01b03811662000dd6576040516342bcdf7f60e11b815260040160405180910390fd5b816001600160a01b03811662000dff576040516342bcdf7f60e11b815260040160405180910390fd5b7f550554a677c8e7b73b62db78b0ef06c5f237da4ef30b88196a899ccf591041fe62000e2b8162002eae565b6001600160a01b038086166000908152610109602052604090205486911615158062000e7f575061010a546000908152610108602090815260408083206001600160a01b0385811685529252909120541615155b1562000ec3576040517f12f3df090000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240162000b05565b6001600160a01b0385811660009081526101096020526040902054161562000f23576040517ff8fb7c270000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260240162000b05565b6001600160a01b038516610222148062000f4757506001600160a01b038516610333145b8062000f5d57506001600160a01b038516610111145b1562000fa1576040517fd8ce8acb0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260240162000b05565b61010b546000818152610108602090815260408083206001600160a01b038b8116855292529091205416156200100f576040517f022bc8410000000000000000000000000000000000000000000000000000000081526001600160a01b038816600482015260240162000b05565b6000818152610108602090815260408083206001600160a01b03808c168086529184528285208054918c167fffffffffffffffffffffffff00000000000000000000000000000000000000009283168117909155808652610109909452828520805490911682179055905133937f844cb5c635052898ad92bea4ece14519111765d835105e76aa1f77ad0d0aa81f91a450505050505050565b60c9546001600160a01b03163314620010ed576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce00000000000000000000000000000000000000000000000000000000815290516001600160a01b0393841693909216916367e404ce916004808201926020929091908290030181865afa15801562001158573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200117e919062004812565b6001600160a01b031614620011bf576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010a5460005b82811015620012c15760008281526101086020526040812061033391868685818110620011f757620011f762004832565b90506020020160208101906200120e9190620045fe565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff000000000000000000000000000000000000000016929091169190911790558383828181106200126c576200126c62004832565b9050602002016020810190620012839190620045fe565b6001600160a01b03167f91d24864a084ab70b268a1f865e757ca12006cf298d763b6be697302ef86498c60405160405180910390a2600101620011c6565b50505050565b600082815260976020526040902060010154620012e48162002eae565b620012f08383620028d9565b505050565b6001600160a01b0381163314620013755760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840162000b05565b62001381828262002ebd565b5050565b80516000819003620013c3576040517f10cbd58300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015620014bf5760006101096000858481518110620013eb57620013eb62004832565b6020908102919091018101516001600160a01b0390811683529082019290925260400160002054169050806200147b5783828151811062001430576200143062004832565b60200260200101516040517fa5ea89da00000000000000000000000000000000000000000000000000000000815260040162000b0591906001600160a01b0391909116815260200190565b8084838151811062001491576200149162004832565b6001600160a01b03909216602092830291909101909101525080620014b68162004890565b915050620013c6565b5060c95460ca546040516001600160a01b0392831692639f3ce55a9234929116908290620014f2908890602401620048cb565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f2a564f3400000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001585939291906004016200491a565b6000604051808303818588803b1580156200159f57600080fd5b505af1158015620015b4573d6000803e3d6000fd5b5050505050336001600160a01b03167f59eab5b5f813ac9e0c10035dfb55b5e3419eff53c0f7a869fb3c22400ea036d68360405162000da19190620048cb565b826001600160a01b0381166200161d576040516342bcdf7f60e11b815260040160405180910390fd5b816001600160a01b03811662001646576040516342bcdf7f60e11b815260040160405180910390fd5b838060000362001686576040517f4618044a0000000000000000000000000000000000000000000000000000000081526004810182905260240162000b05565b6200169062002f5f565b6200169c600762002fba565b61010a546000818152610108602090815260408083206001600160a01b03808c168552925290912054167ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeef81016200172c576040517f6dad9c780000000000000000000000000000000000000000000000000000000081526001600160a01b038916600482015260240162000b05565b6001600160a01b03808916600090815261010960205260408120549091169060608215620017db576040517f9dc29fac000000000000000000000000000000000000000000000000000000008152336004820152602481018b90526001600160a01b038c1690639dc29fac90604401600060405180830381600087803b158015620017b657600080fd5b505af1158015620017cb573d6000803e3d6000fd5b5050505061010b54915062001a15565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038d16906370a0823190602401602060405180830381865afa1580156200183c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200186291906200494d565b90506200187b6001600160a01b038d1633308e62003055565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281906001600160a01b038e16906370a0823190602401602060405180830381865afa158015620018db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200190191906200494d565b6200190d919062004967565b9a508b93506001600160a01b038516620019b657610222610108600088815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b6001600160a01b03167f0f53e2a811b6fd2d6cd965fd6c27b44fb924ca39f7a7f321115705c22366d62360405160405180910390a25b6001600160a01b0385166103331462001a1057620019d48c62003108565b620019df8d6200321b565b620019ea8e6200331b565b604051602001620019fe939291906200497d565b60405160208183030381529060405291505b859250505b60c960009054906101000a90046001600160a01b03166001600160a01b0316639f3ce55a3460ca60009054906101000a90046001600160a01b031634878f8f898960405160240162001a6c959493929190620049ba565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe4d2745100000000000000000000000000000000000000000000000000000000179052517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b16815262001aff939291906004016200491a565b6000604051808303818588803b15801562001b1957600080fd5b505af115801562001b2e573d6000803e3d6000fd5b50505050508a6001600160a01b0316896001600160a01b0316336001600160a01b03167f8780a94875b70464f8ac6c28851501d32e7fd4ee574e4b94beb28923a3c42d9c8d60405162001b8391815260200190565b60405180910390a4505050505062001b9a60018055565b505050505050565b7fbf094fe3c005c553ff0d33c7dff9d1273add12fb3f258b992f8d36224dd35b2462001bce8162002eae565b60ca546001600160a01b03161562001c225760ca546040517f94fbfd2e0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015260240162000b05565b62001c2d8262003447565b60405133906001600160a01b038416907fb044c1a1a05a729c402def784b4e4cb01612ff03eee6f0beb3eba0f0606260a190600090a35050565b62001c796040820160208301620045fe565b6001600160a01b03811662001ca1576040516342bcdf7f60e11b815260040160405180910390fd5b62001cb36060830160408401620045fe565b6001600160a01b03811662001cdb576040516342bcdf7f60e11b815260040160405180910390fd5b600054610100900460ff161580801562001cfc5750600054600160ff909116105b8062001d185750303b15801562001d18575060005460ff166001145b62001d8c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840162000b05565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801562001deb57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b62001e1462001dfe60e0860186620049f4565b62001e0e610100880188620049f4565b62002a26565b62001e3062001e2a6040860160208701620045fe565b620034d4565b62001e3a6200299b565b62001e55600062001e4f6020870187620045fe565b620028d9565b62001e6e62001e6860c0860186620049f4565b62002d0c565b62001e806060850160408601620045fe565b61010780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055606084013561010a55608084013561010b5560005b62001edd60a086018662004a5f565b90508110156200205b57600062001ef860a087018762004a5f565b8381811062001f0b5762001f0b62004832565b905060200201602081019062001f229190620045fe565b6001600160a01b03160362001f4a576040516342bcdf7f60e11b815260040160405180910390fd5b60608501356000908152610108602052604081206101119162001f7160a089018962004a5f565b8581811062001f845762001f8462004832565b905060200201602081019062001f9b9190620045fe565b6001600160a01b039081168252602082019290925260400160002080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169290911691909117905562001ff360a086018662004a5f565b8281811062002006576200200662004832565b90506020020160208101906200201d9190620045fe565b6001600160a01b03167f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe960405160405180910390a260010162001ece565b508015620012c157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b6000816008811115620020dc57620020dc620047a1565b60d654600190911b16151592915050565b806001600160a01b03811662002116576040516342bcdf7f60e11b815260040160405180910390fd5b7f77974cc9cb5bafc9bb265be792d93fa46355c05701895b82f6d3b4b448c8ce00620021428162002eae565b60c980546001600160a01b038581167fffffffffffffffffffffffff00000000000000000000000000000000000000008316811790935560405191169133918391907fc96d462e42a71473da49a1d58c1754b9b2d319786692d621dc7f921331c517e990600090a450505050565b806001600160a01b038116620021d9576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808316600090815261010960205260409020548391161515806200222d575061010a546000908152610108602090815260408083206001600160a01b0385811685529252909120541615155b1562002271576040517f12f3df090000000000000000000000000000000000000000000000000000000081526001600160a01b038216600482015260240162000b05565b7feaf25fcc6b7d45bda16c56628df3f435e20319ef53b065c11ee4510083f0ae2d6200229d8162002eae565b61010a546000908152610108602090815260408083206001600160a01b038816808552925280832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166101111790555190917f5e023c7a09fa0534ce3199f65fc3e635a5e851c5adc88ebda3b9d332ae07cbe991a250505050565b600082815260976020526040902060010154620023388162002eae565b620012f0838362002ebd565b8015620023585762002358858383620035b5565b62002365858585620015f4565b5050505050565b60d76000826008811115620023855762002385620047a1565b6008811115620023995762002399620047a1565b815260200190815260200160002054620023b38162002eae565b620023be82620020c5565b15620023fa57816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b8160088111156200240f576200240f620047a1565b60d68054600190921b9091179055816008811115620024325762002432620047a1565b7f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d45593362000d8d565b6200246462002f5f565b60c9546001600160a01b03163314620024a9576040517f8c56efb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ca5460c954604080517f67e404ce00000000000000000000000000000000000000000000000000000000815290516001600160a01b0393841693909216916367e404ce916004808201926020929091908290030181865afa15801562002514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200253a919062004812565b6001600160a01b0316146200257b576040517f79d1e58f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6008620025888162002fba565b6000848152610108602090815260408083206001600160a01b03808c16855292528220541690610222821480620025c957506001600160a01b038216610333145b15620025eb57620025e56001600160a01b038a16888a620038d1565b62002738565b50806001600160a01b038116620026ba576200260d89868661010a546200391c565b9050886101096000836001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555080610108600061010b54815260200190815260200160002060008b6001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152602482018a90528216906340c10f1990604401600060405180830381600087803b1580156200271e57600080fd5b505af115801562002733573d6000803e3d6000fd5b505050505b866001600160a01b0316816001600160a01b03168a6001600160a01b03167f6ed06519caca659cdefa71015c79a561928d3cf8cc4a3e9739fde9fb5fb38d648b6040516200278891815260200190565b60405180910390a450505062001b9a60018055565b806001600160a01b038116620027c6576040516342bcdf7f60e11b815260040160405180910390fd5b7f19bf281d118073c159a713666aba52e0d403520cd01e03f42e0f62a0b3bd4a35620027f28162002eae565b61010a546000818152610108602090815260408083206001600160a01b038881168552925290912054166101111462002863576040517f82f5d0a50000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260240162000b05565b6000818152610108602090815260408083206001600160a01b038816808552925280832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555190917f0145163d8d460d1ab21463758d147fdfe79d4b57c81ca3d1439996104ae6895991a250505050565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff16620013815760008281526097602090815260408083206001600160a01b0385168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055620029573390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600054610100900460ff1662002a1a5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b62002a2462003a4c565b565b600054610100900460ff1662002aa55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60005b8381101562002bd85784848281811062002ac65762002ac662004832565b9050604002016020013560d7600087878581811062002ae95762002ae962004832565b62002b01926020604090920201908101915062004342565b600881111562002b155762002b15620047a1565b600881111562002b295762002b29620047a1565b815260208101919091526040016000205584848281811062002b4f5762002b4f62004832565b9050604002016020013585858381811062002b6e5762002b6e62004832565b62002b86926020604090920201908101915062004342565b600881111562002b9a5762002b9a620047a1565b6040517f33aa8fd1ce49e1761bc8d27fd53414bfefc45d690feed0ce55019d7d3aec609190600090a38062002bcf8162004890565b91505062002aa8565b5060005b81811015620023655782828281811062002bfa5762002bfa62004832565b9050604002016020013560d8600085858581811062002c1d5762002c1d62004832565b62002c35926020604090920201908101915062004342565b600881111562002c495762002c49620047a1565b600881111562002c5d5762002c5d620047a1565b815260208101919091526040016000205582828281811062002c835762002c8362004832565b9050604002016020013583838381811062002ca25762002ca262004832565b62002cba926020604090920201908101915062004342565b600881111562002cce5762002cce620047a1565b6040517fe7bf4b8dc0c17a52dc9e52323a3ab61cb2079db35f969125b1f8a3d984c6f6c290600090a38062002d038162004890565b91505062002bdc565b600054610100900460ff1662002d8b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60005b81811015620012f057600083838381811062002dae5762002dae62004832565b62002dc69260206040909202019081019150620045fe565b6001600160a01b03160362002dee576040516342bcdf7f60e11b815260040160405180910390fd5b82828281811062002e035762002e0362004832565b905060400201602001356000801b0362002e49576040517f0742d05300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62002e9983838381811062002e625762002e6262004832565b9050604002016020013584848481811062002e815762002e8162004832565b62001e4f9260206040909202019081019150620045fe565b8062002ea58162004890565b91505062002d8e565b62002eba813362003acb565b50565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff1615620013815760008281526097602090815260408083206001600160a01b038516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60026001540362002fb35760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162000b05565b6002600155565b60d65481600881111562002fd25762002fd2620047a1565b6001901b8116156200301457816040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b6002811615620013815760016040517fc0a71b5800000000000000000000000000000000000000000000000000000000815260040162000b059190620047d0565b6040516001600160a01b0380851660248301528316604482015260648101829052620012c19085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915262003b49565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f06fdde0300000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b038616916200317f919062004aca565b600060405180830381855afa9150503d8060008114620031bc576040519150601f19603f3d011682016040523d82523d6000602084013e620031c1565b606091505b50915091508162003208576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062003213565b620032138162003c38565b949350505050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f95d89b4100000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b0386169162003292919062004aca565b600060405180830381855afa9150503d8060008114620032cf576040519150601f19603f3d011682016040523d82523d6000602084013e620032d4565b606091505b50915091508162003208576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062003213565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce567000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b0386169162003391919062004aca565b600060405180830381855afa9150503d8060008114620033ce576040519150601f19603f3d011682016040523d82523d6000602084013e620033d3565b606091505b5091509150818015620033e7575060208151145b1562003403578080602001905181019062003213919062004af8565b6040517fb5a2f1c60000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260240162000b05565b60018055565b6001600160a01b0381166200346f576040516342bcdf7f60e11b815260040160405180910390fd5b60ca80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040513391907fe68b208814fdb633b222cd15e73d5a27fb4ef9eef4cae78c623bc27702141d2890600090a350565b600054610100900460ff16620035535760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b6001600160a01b0381166200357b576040516342bcdf7f60e11b815260040160405180910390fd5b60c980547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b7fd505accf00000000000000000000000000000000000000000000000000000000620035e660046000848662004b18565b620035f19162004b44565b7fffffffff000000000000000000000000000000000000000000000000000000001614620036b2576200362960046000838562004b18565b620036349162004b44565b6040517fcf9e29460000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000090911660048201527fd505accf00000000000000000000000000000000000000000000000000000000602482015260440162000b05565b6000808080808080620036c9886004818c62004b18565b810190620036d8919062004b8d565b9650965096509650965096509650336001600160a01b0316876001600160a01b0316146200373e576040517f200688cc0000000000000000000000000000000000000000000000000000000081526001600160a01b038816600482015260240162000b05565b6001600160a01b03861630146200378d576040517f291159480000000000000000000000000000000000000000000000000000000081526001600160a01b038716600482015260240162000b05565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015287811660248301528691908c169063dd62ed3e90604401602060405180830381865afa158015620037f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200381e91906200494d565b1015620038c5576040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c481018290526001600160a01b038b169063d505accf9060e401600060405180830381600087803b158015620038ab57600080fd5b505af1158015620038c0573d6000803e3d6000fd5b505050505b50505050505050505050565b6040516001600160a01b038316602482015260448101829052620012f09084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401620030a3565b6000818152602085905260408120610107546040516001600160a01b039091169062003948906200419f565b6001600160a01b0390911681526040602082018190526000908201526060018190604051809103906000f590508015801562003988573d6000803e3d6000fd5b509050600080806200399d8688018862004c8c565b925092509250836001600160a01b0316631624f6c68484846040518463ffffffff1660e01b8152600401620039d5939291906200497d565b600060405180830381600087803b158015620039f057600080fd5b505af115801562003a05573d6000803e3d6000fd5b50506040516001600160a01b03808c169350871691507fd5d4920bb61e6141c8499d50a7bd617dae2b1818c9d6b995d3f2ba4975e32ea490600090a3505050949350505050565b600054610100900460ff16620034415760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840162000b05565b60008281526097602090815260408083206001600160a01b038516845290915290205460ff16620013815762003b018162003e0b565b62003b0e83602062003e1e565b60405160200162003b2192919062004d02565b60408051601f198184030181529082905262461bcd60e51b825262000b059160040162004480565b600062003ba0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200406c9092919063ffffffff16565b905080516000148062003bc457508080602001905181019062003bc4919062004d87565b620012f05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162000b05565b6060604082511062003c5a578180602001905181019062000c9e919062004dab565b602082511462003c9d57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b60005b60208110801562003ceb575082818151811062003cc15762003cc162004832565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562003cfa5760010162003ca0565b8060000362003d3e57505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562003d5c5762003d5c62004495565b6040519080825280601f01601f19166020018201604052801562003d87576020820181803683370190505b50905060005b8281101562003e035784818151811062003dab5762003dab62004832565b602001015160f81c60f81b82828151811062003dcb5762003dcb62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060010162003d8d565b509392505050565b606062000c9e6001600160a01b03831660145b6060600062003e2f83600262004e22565b62003e3c90600262004e3c565b67ffffffffffffffff81111562003e575762003e5762004495565b6040519080825280601f01601f19166020018201604052801562003e82576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811062003ebc5762003ebc62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811062003f225762003f2262004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600062003f6084600262004e22565b62003f6d90600162004e3c565b90505b600181111562004014577f303132333435363738396162636465660000000000000000000000000000000085600f166010811062003fb25762003fb262004832565b1a60f81b82828151811062003fcb5762003fcb62004832565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c936200400c8162004e52565b905062003f70565b508315620040655760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640162000b05565b9392505050565b606062003213848460008585600080866001600160a01b0316858760405162004096919062004aca565b60006040518083038185875af1925050503d8060008114620040d5576040519150601f19603f3d011682016040523d82523d6000602084013e620040da565b606091505b5091509150620040ed87838387620040f8565b979650505050505050565b606083156200416c57825160000362004164576001600160a01b0385163b620041645760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000b05565b508162003213565b620032138383815115620041835781518083602001fd5b8060405162461bcd60e51b815260040162000b05919062004480565b6106f38062004e8b83390190565b6001600160a01b038116811462002eba57600080fd5b60008083601f840112620041d657600080fd5b50813567ffffffffffffffff811115620041ef57600080fd5b6020830191508360208260061b85010111156200420b57600080fd5b9250929050565b60008060008060008060006080888a0312156200422e57600080fd5b87356200423b81620041ad565b9650602088013567ffffffffffffffff808211156200425957600080fd5b620042678b838c01620041c3565b909850965060408a01359150808211156200428157600080fd5b6200428f8b838c01620041c3565b909650945060608a0135915080821115620042a957600080fd5b50620042b88a828b01620041c3565b989b979a50959850939692959293505050565b600060208284031215620042de57600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146200406557600080fd5b600080604083850312156200432357600080fd5b8235915060208301356200433781620041ad565b809150509250929050565b6000602082840312156200435557600080fd5b8135600981106200406557600080fd5b600080604083850312156200437957600080fd5b82356200438681620041ad565b915060208301356200433781620041ad565b600060208284031215620043ab57600080fd5b5035919050565b60008060208385031215620043c657600080fd5b823567ffffffffffffffff80821115620043df57600080fd5b818501915085601f830112620043f457600080fd5b8135818111156200440457600080fd5b8660208260051b85010111156200441a57600080fd5b60209290920196919550909350505050565b60005b83811015620044495781810151838201526020016200442f565b50506000910152565b600081518084526200446c8160208601602086016200442c565b601f01601f19169290920160200192915050565b60208152600062004065602083018462004452565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715620044f057620044f062004495565b604052919050565b600060208083850312156200450c57600080fd5b823567ffffffffffffffff808211156200452557600080fd5b818501915085601f8301126200453a57600080fd5b8135818111156200454f576200454f62004495565b8060051b915062004562848301620044c4565b81815291830184019184810190888411156200457d57600080fd5b938501935b83851015620045ab57843592506200459a83620041ad565b828252938501939085019062004582565b98975050505050505050565b600080600060608486031215620045cd57600080fd5b8335620045da81620041ad565b9250602084013591506040840135620045f381620041ad565b809150509250925092565b6000602082840312156200461157600080fd5b81356200406581620041ad565b6000602082840312156200463157600080fd5b813567ffffffffffffffff8111156200464957600080fd5b820161012081850312156200406557600080fd5b60008083601f8401126200467057600080fd5b50813567ffffffffffffffff8111156200468957600080fd5b6020830191508360208285010111156200420b57600080fd5b600080600080600060808688031215620046bb57600080fd5b8535620046c881620041ad565b9450602086013593506040860135620046e181620041ad565b9250606086013567ffffffffffffffff811115620046fe57600080fd5b6200470c888289016200465d565b969995985093965092949392505050565b60008060008060008060a087890312156200473757600080fd5b86356200474481620041ad565b95506020870135945060408701356200475d81620041ad565b935060608701359250608087013567ffffffffffffffff8111156200478157600080fd5b6200478f89828a016200465d565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600983106200480c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b6000602082840312156200482557600080fd5b81516200406581620041ad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620048c457620048c462004861565b5060010190565b6020808252825182820181905260009190848201906040850190845b818110156200490e5783516001600160a01b031683529284019291840191600101620048e7565b50909695505050505050565b6001600160a01b038416815282602082015260606040820152600062004944606083018462004452565b95945050505050565b6000602082840312156200496057600080fd5b5051919050565b8181038181111562000c9e5762000c9e62004861565b60608152600062004992606083018662004452565b8281036020840152620049a6818662004452565b91505060ff83166040830152949350505050565b60006001600160a01b03808816835286602084015280861660408401525083606083015260a06080830152620040ed60a083018462004452565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811262004a2a57600080fd5b83018035915067ffffffffffffffff82111562004a4657600080fd5b6020019150600681901b36038213156200420b57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811262004a9557600080fd5b83018035915067ffffffffffffffff82111562004ab157600080fd5b6020019150600581901b36038213156200420b57600080fd5b6000825162004ade8184602087016200442c565b9190910192915050565b60ff8116811462002eba57600080fd5b60006020828403121562004b0b57600080fd5b8151620040658162004ae8565b6000808585111562004b2957600080fd5b8386111562004b3757600080fd5b5050820193919092039150565b7fffffffff00000000000000000000000000000000000000000000000000000000813581811691600485101562004b855780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562004ba957600080fd5b873562004bb681620041ad565b9650602088013562004bc881620041ad565b95506040880135945060608801359350608088013562004be88162004ae8565b9699959850939692959460a0840135945060c09093013592915050565b600067ffffffffffffffff82111562004c225762004c2262004495565b50601f01601f191660200190565b600082601f83011262004c4257600080fd5b813562004c5962004c538262004c05565b620044c4565b81815284602083860101111562004c6f57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121562004ca257600080fd5b833567ffffffffffffffff8082111562004cbb57600080fd5b62004cc98783880162004c30565b9450602086013591508082111562004ce057600080fd5b5062004cef8682870162004c30565b9250506040840135620045f38162004ae8565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835162004d3c8160178501602088016200442c565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835162004d7b8160288401602088016200442c565b01602801949350505050565b60006020828403121562004d9a57600080fd5b815180151581146200406557600080fd5b60006020828403121562004dbe57600080fd5b815167ffffffffffffffff81111562004dd657600080fd5b8201601f8101841362004de857600080fd5b805162004df962004c538262004c05565b81815285602083850101111562004e0f57600080fd5b620049448260208301602086016200442c565b808202811582820484141762000c9e5762000c9e62004861565b8082018082111562000c9e5762000c9e62004861565b60008162004e645762004e6462004861565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fe60806040526040516106f33803806106f383398101604081905261002291610420565b61002e82826000610035565b505061054a565b61003e836100f6565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100f1576100ef836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e991906104e0565b8361027a565b505b505050565b6001600160a01b0381163b6101605760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101d4816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c591906104e0565b6001600160a01b03163b151590565b6102395760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610157565b7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392909216919091179055565b606061029f83836040518060600160405280602781526020016106cc602791396102a6565b9392505050565b6060600080856001600160a01b0316856040516102c391906104fb565b600060405180830381855af49150503d80600081146102fe576040519150601f19603f3d011682016040523d82523d6000602084013e610303565b606091505b5090925090506103158683838761031f565b9695505050505050565b6060831561038e578251600003610387576001600160a01b0385163b6103875760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610157565b5081610398565b61039883836103a0565b949350505050565b8151156103b05781518083602001fd5b8060405162461bcd60e51b81526004016101579190610517565b80516001600160a01b03811681146103e157600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b838110156104175781810151838201526020016103ff565b50506000910152565b6000806040838503121561043357600080fd5b61043c836103ca565b60208401519092506001600160401b038082111561045957600080fd5b818501915085601f83011261046d57600080fd5b81518181111561047f5761047f6103e6565b604051601f8201601f19908116603f011681019083821181831017156104a7576104a76103e6565b816040528281528860208487010111156104c057600080fd5b6104d18360208301602088016103fc565b80955050505050509250929050565b6000602082840312156104f257600080fd5b61029f826103ca565b6000825161050d8184602087016103fc565b9190910192915050565b60208152600082518060208401526105368160408501602087016103fc565b601f01601f19169190910160400192915050565b610173806105596000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100dc565b565b60006100697fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d79190610100565b905090565b3660008037600080366000845af43d6000803e8080156100fb573d6000f35b3d6000fd5b60006020828403121561011257600080fd5b815173ffffffffffffffffffffffffffffffffffffffff8116811461013657600080fd5b939250505056fea2646970667358221220662c40b76fc0d477a291a78deacd27f4cddd7512dea18087244e38acb2fd99dd64736f6c63430008130033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122008b6c34a5d8997b54caed58d53678d49279942ee4709ef64c362fdb42f961e2064736f6c63430008130033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/package.json b/contracts/package.json index de797162..97ab10f9 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -50,5 +50,8 @@ "prettier-plugin-solidity": "1.3.1", "solhint": "4.5.4", "yargs": "17.7.2" + }, + "dependencies": { + "solidity-docgen": "0.6.0-beta.36" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62e8a722..d39c43f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,6 +167,10 @@ importers: version: 3.4.13(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)) contracts: + dependencies: + solidity-docgen: + specifier: 0.6.0-beta.36 + version: 0.6.0-beta.36(hardhat@2.22.11(bufferutil@4.0.8)(c-kzg@2.1.2)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)) devDependencies: '@ethereumjs/util': specifier: 9.0.3 @@ -253,6 +257,8 @@ importers: specifier: 17.7.2 version: 17.7.2 + contracts/lib/forge-std: {} + e2e: devDependencies: '@jest/globals': @@ -8342,6 +8348,11 @@ packages: peerDependencies: hardhat: ^2.11.0 + solidity-docgen@0.6.0-beta.36: + resolution: {integrity: sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==} + peerDependencies: + hardhat: ^2.8.0 + sonic-boom@2.8.0: resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} @@ -20097,6 +20108,12 @@ snapshots: shelljs: 0.8.5 web3-utils: 1.10.4 + solidity-docgen@0.6.0-beta.36(hardhat@2.22.11(bufferutil@4.0.8)(c-kzg@2.1.2)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10)): + dependencies: + handlebars: 4.7.8 + hardhat: 2.22.11(bufferutil@4.0.8)(c-kzg@2.1.2)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))(typescript@5.4.5)(utf-8-validate@5.0.10) + solidity-ast: 0.4.59 + sonic-boom@2.8.0: dependencies: atomic-sleep: 1.0.0