Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- SupplyChain
- Optimization enabled
- false
- Compiler version
- v0.8.20+commit.a1b79de6
- EVM Version
- shanghai
- Verified at
- 2025-12-11T14:42:58.001035Z
src/SupplyChain.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import "./Authorized.sol";
import "./Commons.sol";
import "./SmartBinding.sol";
import "./SupplyOperations.sol";
/// @title SupplyChain
/// @author AlmavivA S.p.A.
/// @notice You can use this contract to record supply chain operations, from harvest
/// to product bottling
/// @dev This contract is the main contract of the Supply Chain Tracking
contract SupplyChain is Commons, Authorized, SupplyOperations, SmartBinding {
// ============================================================================================
// External functions for regulators
// ============================================================================================
/// @notice bind producer operation with operation
/// @param _operationTrackID Key that identify an operation off-chain
/// @param _producerOffChainIdentity Producer's off-chain public identity
/// @param _productIndex Index of the operation
/// @return success True if binding operation is successful
function startProductByRegulator(
string calldata _operationTrackID,
string calldata _producerOffChainIdentity,
int256 _productIndex
) external regulatorsOnly(getAddress(_producerOffChainIdentity)) returns (bool success) {
require(_productIndex >= 0, "The product's index is wrong");
address producer = getAddress(_producerOffChainIdentity);
bytes32 producerMappingID = keccak256(abi.encodePacked(_operationTrackID, producer));
// productions[producerMappingID].child = IndexElem(producerMappingID, _productIndex);
productions[producerMappingID][uint256(_productIndex)].parentList.push(IndexElem(producerMappingID, -1));
return true;
}
/// @notice Generic function used to manage the mapping key of product supply tracking
/// @dev Applies keccak to calculate the key mapping
/// @param _trackID Key that identify a unique production operation off-chain
/// @param _address Address (on-chain identity) of the trail's owner
/// @return mappingID Mapping ID
function getMappingID(string calldata _trackID, address _address) external pure returns (bytes32 mappingID) {
mappingID = keccak256(abi.encodePacked(_trackID, _address));
}
}
lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
src/Authorized.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
/// @title Authorized
/// @author AlmavivA S.p.A.
/// @notice This contract implements operations to set supply chain's actors
/// @dev This contract is part of the SupplyChain contract, and it is not meant to be used as
/// a standalone contract
contract Authorized is Ownable {
struct User {
string offChainIdentity;
bool isRegulator;
bool isProducer;
}
mapping(address => User) public onChainIdentities;
mapping(bytes32 => address) public onChainAddresses;
mapping(address => mapping(address => bool)) public regulatorAuthorized;
/// @notice Event for adding or updating supply chain's actor
/// @param account On-chain identity
/// @param oldOffChainIdentity Actor's old public off-chain identify
/// @param oldIsRegulator Old value of the regulator
/// @param oldIsProducer Old value of the producer
/// @param operationSender Operation's sender
event LogSetUser(
address account,
string oldOffChainIdentity,
bool oldIsProducer,
bool oldIsRegulator,
address indexed operationSender
);
/// @notice Event for adding or updating regulator actor
/// @param regulator Regulator's on-chain identify
/// @param producer Producer's on-chain identify
/// @param value New value for valid regulator
/// @param operationSender Operation's sender
event LogSetRegulator(address regulator, address producer, bool value, address indexed operationSender);
/// @notice Event for adding or updating producer actor
/// @param producer Producer's on-chain identify
/// @param oldValue Old value for valid producer
/// @param value New value for valid producer
/// @param operationSender Operation's sender
event LogSetProducer(address producer, bool oldValue, bool value, address indexed operationSender);
constructor() Ownable(msg.sender){}
/// @dev Throws if called by any account other than a producer
modifier producersOnly() {
require(onChainIdentities[msg.sender].isProducer, "This user isn't a Producer");
_;
}
/// @dev Throws if called by any account other than a regulator
modifier regulatorsOnly(address producer) {
require(onChainIdentities[msg.sender].isRegulator, "This User isn't a Regulator");
require(regulatorAuthorized[msg.sender][producer], "This user is not authorized");
_;
}
/// @notice Add supply chain's actor
/// @dev You can add or update supply chain's actor
/// @param _address On-chain identify
/// @param _offChainIdentity Actor's public off-chain identify
/// @param _isRegulator True if the actor should be a regulator
/// @param _isProducer True if the actor should be a producer
function setUser(address _address, string memory _offChainIdentity, bool _isRegulator, bool _isProducer)
public
onlyOwner
{
// TODO: one offChainIdentities could have multiple onChainIdenties.
onChainAddresses[keccak256(bytes(_offChainIdentity))] = _address;
onChainIdentities[_address].offChainIdentity = _offChainIdentity;
onChainIdentities[_address].isRegulator = _isRegulator;
onChainIdentities[_address].isProducer = _isProducer;
emit LogSetUser(
_address,
onChainIdentities[_address].offChainIdentity,
onChainIdentities[_address].isProducer,
onChainIdentities[_address].isRegulator,
msg.sender
);
}
/// @notice Get off-chain identify of an account
/// @param _address Actor's on-chain identify
function getOffChainIdentity(address _address) internal view returns (string memory offChainIdentity) {
return onChainIdentities[_address].offChainIdentity;
}
/// @notice Get actor's information
/// @param _address Actor's on-chain identify
/// @return offChainIdentity Actor's offchain identity
/// @return isRegulator true if Actor is a regulator
/// @return isProducer true if Actor is a producer
function getUser(address _address)
external
view
returns (string memory offChainIdentity, bool isRegulator, bool isProducer)
{
return (
onChainIdentities[_address].offChainIdentity,
onChainIdentities[_address].isRegulator,
onChainIdentities[_address].isProducer
);
}
/// @notice Get actor's on-chain identify
/// @param _offChainIdentity Off-chain identity of the account
function getAddress(string memory _offChainIdentity) public view returns (address) {
return onChainAddresses[keccak256(abi.encodePacked(_offChainIdentity))];
}
/// @notice Add or update regulator actor
/// @param _address Regulator's on-chain identify
/// @param _addressProducer Producer's on-chain identity
/// @param _newValue New value for valid regulator
function setRegulator(address _address, address _addressProducer, bool _newValue) external onlyOwner {
emit LogSetRegulator(_address, _addressProducer, _newValue, msg.sender);
// onChainIdentities[_address].isRegulator = _newValue;
regulatorAuthorized[_address][_addressProducer] = _newValue;
}
/// @notice Add or update producer actor
/// @param _address Producer's on-chain identify
/// @param _newValue New value for valid producer
function setProducer(address _address, bool _newValue) external onlyOwner {
emit LogSetProducer(_address, onChainIdentities[_address].isProducer, _newValue, msg.sender);
onChainIdentities[_address].isProducer = _newValue;
}
}
src/Commons.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
/// @title Commons
/// @author AlmavivA S.p.A.
/// @notice This contract implements common structures and elements for the supply chain
/// @dev This contract is part of the SupplyChain contract, and it is not meant to be used as
/// a standalone contract
contract Commons {
int256 constant INT256_MIN = int256((uint256(1) << 255));
int256 constant INT256_MAX = int256(~((uint256(1) << 255)));
uint256 constant UINT256_MIN = 0;
uint256 constant UINT256_MAX = ~uint256(0);
struct IndexElem {
bytes32 mappingId;
int256 nOp;
}
constructor() {}
}
src/SmartBinding.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import "./Authorized.sol";
/// @title SmartBinding
/// @author AlmavivA S.p.A.
/// @notice This contract implements operations to bind production trace with smartIdentity
/// @dev This contract is part of the SupplyChain contract, and it is not meant to be used as
/// a standalone contract
contract SmartBinding is Authorized {
mapping(bytes32 => bytes32) public bindingSmartIdentity;
/// @notice Event for binding smartIdentity to track production
/// @param _trackIDs Off-chain key for track production operation
/// @param operationSender Operation's sender
/// @param onChainIdentity Address of owner of a production's trail
/// @param smartIdentity Encoding of an off-chain unique file
event LogBindSmartIdentity(
string _trackIDs, address operationSender, address onChainIdentity, string smartIdentity
);
constructor() {}
// ============================================================================================
// External functions for producers
// ============================================================================================
/// @notice Bind smartIdentity to track actor by self
/// @dev You can add new binding or binding the smartIdentity to new track production
/// @param _trackIDs Off-chain key for track production operation
/// @param _smartIdentity Encoding of an off-chain unique file
function bindSmartIdentity(string calldata _trackIDs, string calldata _smartIdentity) external producersOnly {
bindingSmartIdentity[keccak256(abi.encodePacked(_smartIdentity, msg.sender))] =
keccak256(abi.encodePacked(_trackIDs, msg.sender));
emit LogBindSmartIdentity(_trackIDs, msg.sender, msg.sender, _smartIdentity);
}
// ============================================================================================
// External functions for regulators
// ============================================================================================
/// @notice Bind smartIdentity to track actor by regulator
/// @dev You can add new binding or binding the smartIdentity to new track producer
/// @param _trackIDs Off-chain key for track operation
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _smartIdentity Encoding of an off-chain unique file
function bindSmartIdentityByRegulator(
string calldata _trackIDs,
string calldata _offChainIdentity,
string calldata _smartIdentity
) external regulatorsOnly(getAddress(_offChainIdentity)) {
address producer = getAddress(_offChainIdentity);
bindingSmartIdentity[keccak256(abi.encodePacked(_smartIdentity, producer))] =
keccak256(abi.encodePacked(_trackIDs, producer));
emit LogBindSmartIdentity(_trackIDs, msg.sender, producer, _smartIdentity);
}
// ============================================================================================
// Helpers for ÐApps
// ============================================================================================
/// @notice Get on-chain mapping ID to identify a track producer
/// @param _smartIdentity Encoding of off-chain unique file
/// @param _offChainIdentity Producer's public off-chain identify
/// @return producerMappingID On-chain producer ID for that trail
function getProducerMappingID(string calldata _smartIdentity, string calldata _offChainIdentity)
external
view
returns (bytes32 producerMappingID)
{
bytes32 index = keccak256(abi.encodePacked((_smartIdentity), getAddress(_offChainIdentity)));
producerMappingID = bindingSmartIdentity[index];
}
}
src/SupplyOperations.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import "./Commons.sol";
import "./Authorized.sol";
/// @title SupplyOperations
/// @author AlmavivA S.p.A.
/// @notice This contract implements operations conducted by companies
/// @dev This contract is part of the SupplyChain contract, and it is not meant to be used as
/// a standalone contract
contract SupplyOperations is Commons, Authorized {
uint256 constant OPERATION_SEARCH_MAX = uint256(INT256_MAX);
struct SupplyOperation {
address operationSender;
string offChainIdentity;
string operationID;
string operationCode;
uint256 operationDate;
string additionalData;
string attributes;
Product[] prods;
IndexElem[] parentList;
IndexElem[] childList;
}
struct Product {
string productID;
string quantity;
string attributes;
}
/// @notice mapping to storage the supply operation
mapping(bytes32 => SupplyOperation[]) public productions;
/// @notice Event for new operation
/// @param _trackID Key generated for track operation off-chain
/// @param operationSender Operation's sender
/// @param onChainIdentity Address of owner's supply trace
/// @param operationID Operation's ID
/// @param index Index of the operation
event LogAddSupplyOperation(
string _trackID,
address indexed operationSender,
address indexed onChainIdentity,
string operationID,
uint256 index
);
/// @notice Event for new product operation
/// @param _mappingID Key generated for track operation on-chain
/// @param operationSender Operation's sender
/// @param onChainIdentity Address of owner's supply trace
/// @param operationID Operation ID
event LogAddProduct(
bytes32 _mappingID,
address operationSender,
address indexed onChainIdentity,
string indexed operationID,
string productID
);
// ============================================================================================
// External functions
// ============================================================================================
/// @notice add new operation by product owner
/// @param _trackID Key to identify unique track operation off-chain
/// @param _operationID Operation ID
/// @param _operationCode Operation's code
/// @param _operationDate Operation's date
/// @param _additionalData Stringified JSON containing arbitrary data that should be stored on-chain
/// @return success True if operation is successful
function addOperation(
string calldata _trackID,
string calldata _operationID,
string calldata _operationCode,
uint256 _operationDate,
address _userAddress,
string calldata _additionalData
) external producersOnly returns (bool success) {
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, msg.sender));
addOperation(
_mappingID,
msg.sender,
onChainIdentities[_userAddress].offChainIdentity,
_operationID,
_operationCode,
_operationDate,
_additionalData
);
emit LogAddSupplyOperation(_trackID, msg.sender, msg.sender, _operationID, productions[_mappingID].length);
return true;
}
/// @notice Add new production product operation by producer
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _index Index operation on track production operation
/// @param _productID Product ID
/// @param _quantity Quantity and measure of product
/// @param _attributes Payload (preferably values separated by `;`)
/// @return success True if the product is successfully added
function addProduct(
string calldata _trackID,
uint256 _index,
string calldata _productID,
string calldata _quantity,
string calldata _attributes
) external producersOnly returns (bool success) {
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, msg.sender));
addProduct(_mappingID, _index, _productID, _quantity, _attributes);
emit LogAddProduct(_mappingID, msg.sender, msg.sender, productions[_mappingID][_index].operationID, _productID);
return true;
}
/// @notice Bind two operation to menage the story of supply trace by producer
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _numCurOperation Index operation
/// @param _parentTrackID Key to identify unique parent track production operation on-chain
/// @param _parentProducer Parent account address on-chain
/// @param _numParent Parent's index of the production operation
/// @return success True if two operation are successfully bond
function addReferenceParentProducerOperation(
string calldata _trackID,
uint256 _numCurOperation,
string calldata _parentTrackID,
address _parentProducer,
int256 _numParent
) external producersOnly returns (bool success) {
addRelationshipBindingProducerOperation(
keccak256(abi.encodePacked(_trackID, msg.sender)),
_numCurOperation,
keccak256(abi.encodePacked(_parentTrackID, _parentProducer)),
_numParent
);
return true;
}
/// @notice Set payload to specific production operation
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _operationIndex Index operation on track production operation
/// @param attributes Payload (preferably values separated by `;`)
/// @return success True if the value is successful set
function setOperationAttributes(string calldata _trackID, uint256 _operationIndex, string calldata attributes)
external
producersOnly
returns (bool success)
{
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, msg.sender));
productions[_mappingID][_operationIndex].attributes = attributes;
return true;
}
/// @notice Set payload to specific producer product operation
/// @param _trackID Key to identify unique track producer operation off-chain
/// @param _operationIndex Index operation on track production operation
/// @param _productIndex Index of product
/// @param attributes Payload (preferably values separated by `;`)
/// @return success True if the value is successful set
function setProductAttributes(
string calldata _trackID,
uint256 _operationIndex,
uint256 _productIndex,
string calldata attributes
) external producersOnly returns (bool success) {
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, msg.sender));
productions[_mappingID][_operationIndex].prods[_productIndex].attributes = attributes;
return true;
}
// ============================================================================================
// External functions for regulators
// ============================================================================================
/// @notice Add new production operation by producer by regulator
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _operationID Identify off-chain operation
/// @param _operationCode Operation's code
/// @param _operationDate Operation's date
/// @param _additionalData Stringified JSON containing arbitrary data that should be stored on-chain
function addProductionOperationByRegulator(
string calldata _trackID,
string calldata _offChainIdentity,
string calldata _operationID,
string calldata _operationCode,
uint256 _operationDate,
string calldata _additionalData
) external regulatorsOnly(getAddress(_offChainIdentity)) {
address _producer = getAddress(_offChainIdentity);
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
addOperation(
_mappingID, msg.sender, _offChainIdentity, _operationID, _operationCode, _operationDate, _additionalData
);
emit LogAddSupplyOperation("_trackID", msg.sender, _producer, _operationID, productions[_mappingID].length);
}
/// @notice Add new production product operation by regulator
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _index Index operation on track production operation
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _productID Product's ID
/// @param _quantity Quantity and measure of product
/// @param _attributes Payload (preferably values separated by `;`)
function addProductByRegulator(
string calldata _trackID,
uint256 _index,
string calldata _offChainIdentity,
string calldata _productID,
string calldata _quantity,
string calldata _attributes
) external regulatorsOnly(getAddress(_offChainIdentity)) {
address _producer = getAddress(_offChainIdentity);
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
addProduct(_mappingID, _index, _productID, _quantity, _attributes);
emit LogAddProduct(_mappingID, msg.sender, _producer, productions[_mappingID][_index].operationID, _productID);
}
/// @notice Set payload to specific production operation by regulator
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _operationIndex Index operation on track production operation
/// @param attributes Payload (preferably values separated by `;`)
/// @return success True if the value is successful setted
function setOperationAttributesByRegulator(
string calldata _trackID,
string calldata _offChainIdentity,
uint256 _operationIndex,
string calldata attributes
) external regulatorsOnly(getAddress(_offChainIdentity)) returns (bool success) {
address _producer = getAddress(_offChainIdentity);
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
productions[_mappingID][_operationIndex].attributes = attributes;
return true;
}
/// @notice Set payload to specific production product operation by regulator
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _operationIndex Index operation on track production operation
/// @param _productIndex Index of product
/// @param attributes Payload (preferably values separated by `;`)
/// @return success True if the value is successful setted
function setProductAttributesByRegulator(
string calldata _trackID,
string calldata _offChainIdentity,
uint256 _operationIndex,
uint256 _productIndex,
string calldata attributes
) external regulatorsOnly(getAddress(_offChainIdentity)) returns (bool success) {
address _producer = getAddress(_offChainIdentity);
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
productions[_mappingID][_operationIndex].prods[_productIndex].attributes = attributes;
return true;
}
/// @notice Bind two operations to manage the story of supply trace by regulator
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _numCurOperation Index operation on track production operation
/// @param _parentTrackID Key to identify unique parent track production operation on-chain
/// @param _parentOffChainIdentity Parent's product public off-chain identify
/// @param _numParent Parent's index operation on track production operation
/// @return success True if two operations are successfully bond
function addReferenceParentProducerOperationByRegulator(
string calldata _trackID,
string calldata _offChainIdentity,
uint256 _numCurOperation,
string calldata _parentTrackID,
string calldata _parentOffChainIdentity,
int256 _numParent
) external regulatorsOnly(getAddress(_offChainIdentity)) returns (bool success) {
address _producer = getAddress(_offChainIdentity);
address _parentProducer = getAddress(_parentOffChainIdentity);
addRelationshipBindingProducerOperation(
keccak256(abi.encodePacked(_trackID, _producer)),
_numCurOperation,
keccak256(abi.encodePacked(_parentTrackID, _parentProducer)),
_numParent
);
return true;
}
// ============================================================================================
// Helpers for ÐApps
// ============================================================================================
/// @notice Get the operation's information
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _producer Producer's address on-chain identify
/// @param _index Index operation on track production operation
/// @return operationSender Operation's sender
/// @return offChainIdentity Operation's offchain identity
/// @return operationID Operation's ID
/// @return operationCode Operation's code
/// @return operationDate Operation's date
/// @return additionalData Operation's additionalData
/// @return attributes Operation's attributes
function getDataOperation(string calldata _trackID, address _producer, uint256 _index)
external
view
returns (
address operationSender,
string memory offChainIdentity,
string memory operationID,
string memory operationCode,
uint256 operationDate,
string memory additionalData,
string memory attributes
)
{
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
operationSender = productions[_mappingID][_index].operationSender;
offChainIdentity = productions[_mappingID][_index].offChainIdentity;
operationID = productions[_mappingID][_index].operationID;
operationCode = productions[_mappingID][_index].operationCode;
operationDate = productions[_mappingID][_index].operationDate;
additionalData = productions[_mappingID][_index].additionalData;
attributes = productions[_mappingID][_index].attributes;
}
/// @notice Get the product's information
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _producer Producer's address on-chain identify
/// @param _index Index operation on track production operation
/// @param _productIndex Index of product
/// @return productID Product's ID
/// @return quantity Product's quantity
/// @return attributes Product's attributes
function getProductOperation(string calldata _trackID, address _producer, uint256 _index, uint256 _productIndex)
external
view
returns (string memory productID, string memory quantity, string memory attributes)
{
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
require(productions[_mappingID].length > 0, "Product not exists yet");
productID = productions[_mappingID][_index].prods[_productIndex].productID;
quantity = productions[_mappingID][_index].prods[_productIndex].quantity;
attributes = productions[_mappingID][_index].prods[_productIndex].attributes;
}
/// @notice Get the index of the operation
/// @param _trackID Key to identify unique track production operation off-chain
/// @param _producer Producer's address on-chain identify
/// @param _operationID Identify off-chain operation
/// @return position Index of the operation
function getNumPositionOperation(string calldata _trackID, address _producer, string calldata _operationID)
external
view
returns (int256 position)
{
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
for (uint256 i = 0; i < productions[_mappingID].length && i < OPERATION_SEARCH_MAX; i++) {
if (
keccak256(abi.encodePacked(productions[_mappingID][i].operationID))
== keccak256(abi.encodePacked(_operationID))
) {
return int256(i);
}
}
return -1;
}
// ============================================================================================
// Private functions
// ============================================================================================
/// @notice Add new production operation
/// @param _mappingID Key to identify unique track production operation on-chain
/// @param _operationSender Sender operation address
/// @param _offChainIdentity Producer's public off-chain identify
/// @param _operationID Identify off-chain operation
/// @param _operationCode Operation's code
/// @param _operationDate Operation's date
/// @param _additionalData Stringified JSON containing arbitrary data that should be stored on-chain
function addOperation(
bytes32 _mappingID,
address _operationSender,
string memory _offChainIdentity,
string memory _operationID,
string memory _operationCode,
uint256 _operationDate,
string memory _additionalData
) private {
// Initialize the new operation into the array
productions[_mappingID].push();
uint256 size = productions[_mappingID].length;
SupplyOperation storage operation = productions[_mappingID][size - 1];
operation.operationSender = _operationSender;
operation.offChainIdentity = _offChainIdentity;
operation.operationID = _operationID;
operation.operationCode = _operationCode;
operation.operationDate = _operationDate;
operation.additionalData = _additionalData;
}
/// @notice Add new production product operation by producer
/// @param _mappingID Key to identify unique track production operation on-chain
/// @param _index Index operation on track production operation
/// @param _productID Product's ID
/// @param _quantity Quantity and measure of product
/// @param _attributes Payload (preferably values separated by `;`)
function addProduct(
bytes32 _mappingID,
uint256 _index,
string memory _productID,
string memory _quantity,
string memory _attributes
) private {
productions[_mappingID][_index].prods.push(Product(_productID, _quantity, _attributes));
}
/// @notice Bind two operations to manage the story of supply trace
/// @param _mappingID Key to identify unique track production operation on-chain
/// @param _numCurOperation Index operation on track production operation
/// @param _parentMappingID Key to identify unique parent track production operation on-chain
/// @param _numParent Parent index operation on track production operation
function addRelationshipBindingProducerOperation(
bytes32 _mappingID,
uint256 _numCurOperation,
bytes32 _parentMappingID,
int256 _numParent
) private {
require(_numCurOperation < OPERATION_SEARCH_MAX, "The current operation is wrong");
require(_numParent >= 0, "The parent operation is wrong");
uint256 _parentIndex = uint256(_numParent);
int256 _numCurOperationINT = int256(_numCurOperation);
productions[_mappingID][_numCurOperation].parentList.push(IndexElem(_parentMappingID, _numParent));
productions[_parentMappingID][_parentIndex].childList.push(IndexElem(_mappingID, _numCurOperationINT));
}
// @dev Test only method: don't use it!
function getIDChildRelationshipCountOperationParentProductPositionReferenceBinding(
string calldata _trackID,
address _producer,
uint256 _index,
uint256 _productIndex
) external view returns (string memory productID, string memory quantity, string memory attributes) {
bytes32 _mappingID = keccak256(abi.encodePacked(_trackID, _producer));
productID = productions[_mappingID][_index].prods[_productIndex].productID;
quantity = productions[_mappingID][_index].prods[_productIndex].quantity;
attributes = productions[_mappingID][_index].prods[_productIndex].attributes;
}
}
Compiler Settings
{"viaIR":false,"remappings":["@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/","@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/","ds-test/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/","openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/","openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/","solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":false},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
Contract ABI
[{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"LogAddProduct","inputs":[{"type":"bytes32","name":"_mappingID","internalType":"bytes32","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":false},{"type":"address","name":"onChainIdentity","internalType":"address","indexed":true},{"type":"string","name":"operationID","internalType":"string","indexed":true},{"type":"string","name":"productID","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"LogAddSupplyOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":true},{"type":"address","name":"onChainIdentity","internalType":"address","indexed":true},{"type":"string","name":"operationID","internalType":"string","indexed":false},{"type":"uint256","name":"index","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LogBindSmartIdentity","inputs":[{"type":"string","name":"_trackIDs","internalType":"string","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":false},{"type":"address","name":"onChainIdentity","internalType":"address","indexed":false},{"type":"string","name":"smartIdentity","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"LogSetProducer","inputs":[{"type":"address","name":"producer","internalType":"address","indexed":false},{"type":"bool","name":"oldValue","internalType":"bool","indexed":false},{"type":"bool","name":"value","internalType":"bool","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"LogSetRegulator","inputs":[{"type":"address","name":"regulator","internalType":"address","indexed":false},{"type":"address","name":"producer","internalType":"address","indexed":false},{"type":"bool","name":"value","internalType":"bool","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"LogSetUser","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false},{"type":"string","name":"oldOffChainIdentity","internalType":"string","indexed":false},{"type":"bool","name":"oldIsProducer","internalType":"bool","indexed":false},{"type":"bool","name":"oldIsRegulator","internalType":"bool","indexed":false},{"type":"address","name":"operationSender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"addOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"string","name":"_operationID","internalType":"string"},{"type":"string","name":"_operationCode","internalType":"string"},{"type":"uint256","name":"_operationDate","internalType":"uint256"},{"type":"address","name":"_userAddress","internalType":"address"},{"type":"string","name":"_additionalData","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"addProduct","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"uint256","name":"_index","internalType":"uint256"},{"type":"string","name":"_productID","internalType":"string"},{"type":"string","name":"_quantity","internalType":"string"},{"type":"string","name":"_attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addProductByRegulator","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"uint256","name":"_index","internalType":"uint256"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"string","name":"_productID","internalType":"string"},{"type":"string","name":"_quantity","internalType":"string"},{"type":"string","name":"_attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addProductionOperationByRegulator","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"string","name":"_operationID","internalType":"string"},{"type":"string","name":"_operationCode","internalType":"string"},{"type":"uint256","name":"_operationDate","internalType":"uint256"},{"type":"string","name":"_additionalData","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"addReferenceParentProducerOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"uint256","name":"_numCurOperation","internalType":"uint256"},{"type":"string","name":"_parentTrackID","internalType":"string"},{"type":"address","name":"_parentProducer","internalType":"address"},{"type":"int256","name":"_numParent","internalType":"int256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"addReferenceParentProducerOperationByRegulator","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"uint256","name":"_numCurOperation","internalType":"uint256"},{"type":"string","name":"_parentTrackID","internalType":"string"},{"type":"string","name":"_parentOffChainIdentity","internalType":"string"},{"type":"int256","name":"_numParent","internalType":"int256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"bindSmartIdentity","inputs":[{"type":"string","name":"_trackIDs","internalType":"string"},{"type":"string","name":"_smartIdentity","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"bindSmartIdentityByRegulator","inputs":[{"type":"string","name":"_trackIDs","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"string","name":"_smartIdentity","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"bindingSmartIdentity","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getAddress","inputs":[{"type":"string","name":"_offChainIdentity","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"operationSender","internalType":"address"},{"type":"string","name":"offChainIdentity","internalType":"string"},{"type":"string","name":"operationID","internalType":"string"},{"type":"string","name":"operationCode","internalType":"string"},{"type":"uint256","name":"operationDate","internalType":"uint256"},{"type":"string","name":"additionalData","internalType":"string"},{"type":"string","name":"attributes","internalType":"string"}],"name":"getDataOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"address","name":"_producer","internalType":"address"},{"type":"uint256","name":"_index","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"productID","internalType":"string"},{"type":"string","name":"quantity","internalType":"string"},{"type":"string","name":"attributes","internalType":"string"}],"name":"getIDChildRelationshipCountOperationParentProductPositionReferenceBinding","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"address","name":"_producer","internalType":"address"},{"type":"uint256","name":"_index","internalType":"uint256"},{"type":"uint256","name":"_productIndex","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"mappingID","internalType":"bytes32"}],"name":"getMappingID","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"position","internalType":"int256"}],"name":"getNumPositionOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"address","name":"_producer","internalType":"address"},{"type":"string","name":"_operationID","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"producerMappingID","internalType":"bytes32"}],"name":"getProducerMappingID","inputs":[{"type":"string","name":"_smartIdentity","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"productID","internalType":"string"},{"type":"string","name":"quantity","internalType":"string"},{"type":"string","name":"attributes","internalType":"string"}],"name":"getProductOperation","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"address","name":"_producer","internalType":"address"},{"type":"uint256","name":"_index","internalType":"uint256"},{"type":"uint256","name":"_productIndex","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"offChainIdentity","internalType":"string"},{"type":"bool","name":"isRegulator","internalType":"bool"},{"type":"bool","name":"isProducer","internalType":"bool"}],"name":"getUser","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"onChainAddresses","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"offChainIdentity","internalType":"string"},{"type":"bool","name":"isRegulator","internalType":"bool"},{"type":"bool","name":"isProducer","internalType":"bool"}],"name":"onChainIdentities","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"operationSender","internalType":"address"},{"type":"string","name":"offChainIdentity","internalType":"string"},{"type":"string","name":"operationID","internalType":"string"},{"type":"string","name":"operationCode","internalType":"string"},{"type":"uint256","name":"operationDate","internalType":"uint256"},{"type":"string","name":"additionalData","internalType":"string"},{"type":"string","name":"attributes","internalType":"string"}],"name":"productions","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"regulatorAuthorized","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"setOperationAttributes","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"uint256","name":"_operationIndex","internalType":"uint256"},{"type":"string","name":"attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"setOperationAttributesByRegulator","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"uint256","name":"_operationIndex","internalType":"uint256"},{"type":"string","name":"attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setProducer","inputs":[{"type":"address","name":"_address","internalType":"address"},{"type":"bool","name":"_newValue","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"setProductAttributes","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"uint256","name":"_operationIndex","internalType":"uint256"},{"type":"uint256","name":"_productIndex","internalType":"uint256"},{"type":"string","name":"attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"setProductAttributesByRegulator","inputs":[{"type":"string","name":"_trackID","internalType":"string"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"uint256","name":"_operationIndex","internalType":"uint256"},{"type":"uint256","name":"_productIndex","internalType":"uint256"},{"type":"string","name":"attributes","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRegulator","inputs":[{"type":"address","name":"_address","internalType":"address"},{"type":"address","name":"_addressProducer","internalType":"address"},{"type":"bool","name":"_newValue","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setUser","inputs":[{"type":"address","name":"_address","internalType":"address"},{"type":"string","name":"_offChainIdentity","internalType":"string"},{"type":"bool","name":"_isRegulator","internalType":"bool"},{"type":"bool","name":"_isProducer","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"startProductByRegulator","inputs":[{"type":"string","name":"_operationTrackID","internalType":"string"},{"type":"string","name":"_producerOffChainIdentity","internalType":"string"},{"type":"int256","name":"_productIndex","internalType":"int256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
Contract Creation Code
0x608060405234801562000010575f80fd5b50335f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000085575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016200007c9190620001a1565b60405180910390fd5b62000096816200009d60201b60201c565b50620001bc565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62000189826200015e565b9050919050565b6200019b816200017d565b82525050565b5f602082019050620001b65f83018462000190565b92915050565b6161a680620001ca5f395ff3fe608060405234801561000f575f80fd5b50600436106101ed575f3560e01c80636f77926b1161010d578063bf40fac1116100a0578063e0e494911161006f578063e0e4949114610679578063f2ea8b49146106a9578063f2fde38b146106df578063f7c42ac8146106fb576101ed565b8063bf40fac1146105f5578063cd22f53614610625578063cf46dca714610641578063dee730161461065d576101ed565b8063a099e663116100dc578063a099e66314610549578063a29f9fb914610565578063a8d03e2714610595578063a97f5089146105c5576101ed565b80636f77926b146104d3578063715018a61461050557806384d62f471461050f5780638da5cb5b1461052b576101ed565b80631c566ef2116101855780633328244211610154578063332824421461040d57806339c58a4f1461043d5780634562426014610473578063508cde13146104a3576101ed565b80631c566ef21461034b5780631c6383761461037b5780631dc436cd146103ab57806321cbed35146103dd576101ed565b806309d84fc4116101c157806309d84fc41461029d5780630eb51018146102cd57806311c0f931146102ff578063131b7b751461031b576101ed565b8062ba3e50146101f157806302879f9c1461022157806303a77c7a1461025157806308cad9911461026d575b5f80fd5b61020b600480360381019061020691906142b3565b61072d565b6040516102189190614370565b60405180910390f35b61023b60048036038101906102369190614389565b61085b565b6040516102489190614370565b60405180910390f35b61026b60048036038101906102669190614503565b610a9a565b005b61028760048036038101906102829190614553565b610b88565b6040516102949190614370565b60405180910390f35b6102b760048036038101906102b291906145c4565b610bb2565b6040516102c491906145fe565b60405180910390f35b6102e760048036038101906102e29190614617565b610bc7565b6040516102f693929190614725565b60405180910390f35b6103196004803603810190610314919061476f565b610eef565b005b61033560048036038101906103309190614820565b61102d565b6040516103429190614370565b60405180910390f35b6103656004803603810190610360919061492a565b6112dd565b6040516103729190614370565b60405180910390f35b610395600480360381019061039091906149bb565b6113e9565b6040516103a29190614370565b60405180910390f35b6103c560048036038101906103c09190614617565b611679565b6040516103d493929190614725565b60405180910390f35b6103f760048036038101906103f29190614a92565b61194b565b6040516104049190614370565b60405180910390f35b61042760048036038101906104229190614b56565b611bb9565b6040516104349190614370565b60405180910390f35b61045760048036038101906104529190614be7565b611ec7565b60405161046a9796959493929190614c43565b60405180910390f35b61048d60048036038101906104889190614cd3565b6121dc565b60405161049a9190614d73565b60405180910390f35b6104bd60048036038101906104b89190614d8c565b61230c565b6040516104ca91906145fe565b60405180910390f35b6104ed60048036038101906104e89190614de9565b612341565b6040516104fc93929190614e14565b60405180910390f35b61050d6124b6565b005b61052960048036038101906105249190614e50565b6124c9565b005b610533612769565b6040516105409190614f00565b60405180910390f35b610563600480360381019061055e9190615041565b612790565b005b61057f600480360381019061057a91906145c4565b612a1b565b60405161058c9190614f00565b60405180910390f35b6105af60048036038101906105aa91906150c1565b612a4b565b6040516105bc9190614370565b60405180910390f35b6105df60048036038101906105da919061476f565b612b48565b6040516105ec91906145fe565b60405180910390f35b61060f600480360381019061060a9190615178565b612bdf565b60405161061c9190614f00565b60405180910390f35b61063f600480360381019061063a91906151bf565b612c3e565b005b61065b600480360381019061065691906152e9565b612fd8565b005b61067760048036038101906106729190615327565b6130db565b005b610693600480360381019061068e9190615451565b61349c565b6040516106a09190614370565b60405180910390f35b6106c360048036038101906106be919061555b565b613789565b6040516106d69796959493929190614c43565b60405180910390f35b6106f960048036038101906106f49190614de9565b613bff565b005b61071560048036038101906107109190614de9565b613c83565b60405161072493929190614e14565b60405180910390f35b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff166107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290615616565b60405180910390fd5b5f8787336040516020016107d1939291906156a7565b604051602081830303815290604052805190602001209050838360045f8481526020019081526020015f20888154811061080e5761080d6156d0565b5b905f5260205f2090600a0201600701878154811061082f5761082e6156d0565b5b905f5260205f209060030201600201918261084b929190615901565b5060019150509695505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff166108e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e090615616565b60405180910390fd5b5f8a8a336040516020016108ff939291906156a7565b6040516020818303038152906040528051906020012090506109ed818a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613d48565b60045f8281526020019081526020015f208981548110610a1057610a0f6156d0565b5b905f5260205f2090600a0201600201604051610a2c9190615a4e565b60405180910390203373ffffffffffffffffffffffffffffffffffffffff167f1e81c50255627b70d2cbc97f39338856c4a3f3b9b5deb72cc5c10855ef268d7783338c8c604051610a809493929190615a90565b60405180910390a360019150509998505050505050505050565b610aa2613e04565b3373ffffffffffffffffffffffffffffffffffffffff167f66b612407219f373f9a77dff0cf18ba327db7261e48c9c345785df6ee8de2757848484604051610aec93929190615ace565b60405180910390a28060035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b6003602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b6005602052805f5260405f205f915090505481565b60608060605f888888604051602001610be2939291906156a7565b6040516020818303038152906040528051906020012090505f60045f8381526020019081526020015f208054905011610c50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4790615b4d565b60405180910390fd5b60045f8281526020019081526020015f208681548110610c7357610c726156d0565b5b905f5260205f2090600a02016007018581548110610c9457610c936156d0565b5b905f5260205f2090600302015f018054610cad90615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd990615734565b8015610d245780601f10610cfb57610100808354040283529160200191610d24565b820191905f5260205f20905b815481529060010190602001808311610d0757829003601f168201915b5050505050935060045f8281526020019081526020015f208681548110610d4e57610d4d6156d0565b5b905f5260205f2090600a02016007018581548110610d6f57610d6e6156d0565b5b905f5260205f2090600302016001018054610d8990615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610db590615734565b8015610e005780601f10610dd757610100808354040283529160200191610e00565b820191905f5260205f20905b815481529060010190602001808311610de357829003601f168201915b5050505050925060045f8281526020019081526020015f208681548110610e2a57610e296156d0565b5b905f5260205f2090600a02016007018581548110610e4b57610e4a6156d0565b5b905f5260205f2090600302016002018054610e6590615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9190615734565b8015610edc5780601f10610eb357610100808354040283529160200191610edc565b820191905f5260205f20905b815481529060010190602001808311610ebf57829003601f168201915b5050505050915050955095509592505050565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff16610f7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7390615616565b60405180910390fd5b838333604051602001610f91939291906156a7565b6040516020818303038152906040528051906020012060055f848433604051602001610fbf939291906156a7565b6040516020818303038152906040528051906020012081526020019081526020015f20819055507f2a32a3690bbbfacd5c1aa6ddac597f0068af35a0df62471960d6dd4b52a9036284843333868660405161101f96959493929190615b6b565b60405180910390a150505050565b5f61107a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fd90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166111ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111c190615c72565b60405180910390fd5b5f6112178b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f61126687878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90506112c88e8e84604051602001611280939291906156a7565b604051602081830303815290604052805190602001208b8b8b856040516020016112ac939291906156a7565b6040516020818303038152906040528051906020012088613e8b565b600193505050509a9950505050505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1661136b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136290615616565b60405180910390fd5b5f868633604051602001611381939291906156a7565b604051602081830303815290604052805190602001209050838360045f8481526020019081526020015f2087815481106113be576113bd6156d0565b5b905f5260205f2090600a020160060191826113da929190615901565b50600191505095945050505050565b5f61143687878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166114c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b990615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157d90615c72565b60405180910390fd5b5f6115d389898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8b8b836040516020016115eb939291906156a7565b604051602081830303815290604052805190602001209050858560045f8481526020019081526020015f208a81548110611628576116276156d0565b5b905f5260205f2090600a02016007018981548110611649576116486156d0565b5b905f5260205f2090600302016002019182611665929190615901565b506001935050505098975050505050505050565b60608060605f888888604051602001611694939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f2086815481106116cf576116ce6156d0565b5b905f5260205f2090600a020160070185815481106116f0576116ef6156d0565b5b905f5260205f2090600302015f01805461170990615734565b80601f016020809104026020016040519081016040528092919081815260200182805461173590615734565b80156117805780601f1061175757610100808354040283529160200191611780565b820191905f5260205f20905b81548152906001019060200180831161176357829003601f168201915b5050505050935060045f8281526020019081526020015f2086815481106117aa576117a96156d0565b5b905f5260205f2090600a020160070185815481106117cb576117ca6156d0565b5b905f5260205f20906003020160010180546117e590615734565b80601f016020809104026020016040519081016040528092919081815260200182805461181190615734565b801561185c5780601f106118335761010080835404028352916020019161185c565b820191905f5260205f20905b81548152906001019060200180831161183f57829003601f168201915b5050505050925060045f8281526020019081526020015f208681548110611886576118856156d0565b5b905f5260205f2090600a020160070185815481106118a7576118a66156d0565b5b905f5260205f20906003020160020180546118c190615734565b80601f01602080910402602001604051908101604052809291908181526020018280546118ed90615734565b80156119385780601f1061190f57610100808354040283529160200191611938565b820191905f5260205f20905b81548152906001019060200180831161191b57829003601f168201915b5050505050915050955095509592505050565b5f61199886868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611a24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1b90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611ae8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611adf90615c72565b60405180910390fd5b5f611b3588888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8a8a83604051602001611b4d939291906156a7565b604051602081830303815290604052805190602001209050858560045f8481526020019081526020015f208981548110611b8a57611b896156d0565b5b905f5260205f2090600a02016006019182611ba6929190615901565b5060019350505050979650505050505050565b5f611c0684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8990615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611d56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4d90615c72565b60405180910390fd5b5f831215611d99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9090615cda565b60405180910390fd5b5f611de686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f888883604051602001611dfe939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f208581548110611e3957611e386156d0565b5b905f5260205f2090600a020160080160405180604001604052808381526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f01556020820151816001015550506001935050505095945050505050565b6004602052815f5260405f208181548110611ee0575f80fd5b905f5260205f2090600a02015f9150915050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054611f2590615734565b80601f0160208091040260200160405190810160405280929190818152602001828054611f5190615734565b8015611f9c5780601f10611f7357610100808354040283529160200191611f9c565b820191905f5260205f20905b815481529060010190602001808311611f7f57829003601f168201915b505050505090806002018054611fb190615734565b80601f0160208091040260200160405190810160405280929190818152602001828054611fdd90615734565b80156120285780601f10611fff57610100808354040283529160200191612028565b820191905f5260205f20905b81548152906001019060200180831161200b57829003601f168201915b50505050509080600301805461203d90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461206990615734565b80156120b45780601f1061208b576101008083540402835291602001916120b4565b820191905f5260205f20905b81548152906001019060200180831161209757829003601f168201915b5050505050908060040154908060050180546120cf90615734565b80601f01602080910402602001604051908101604052809291908181526020018280546120fb90615734565b80156121465780601f1061211d57610100808354040283529160200191612146565b820191905f5260205f20905b81548152906001019060200180831161212957829003601f168201915b50505050509080600601805461215b90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461218790615734565b80156121d25780601f106121a9576101008083540402835291602001916121d2565b820191905f5260205f20905b8154815290600101906020018083116121b557829003601f168201915b5050505050905087565b5f808686866040516020016121f3939291906156a7565b6040516020818303038152906040528051906020012090505f5b60045f8381526020019081526020015f208054905081108015612235575060ff6001901b1981105b156122dd57848460405160200161224d929190615cf8565b6040516020818303038152906040528051906020012060045f8481526020019081526020015f208281548110612286576122856156d0565b5b905f5260205f2090600a02016002016040516020016122a59190615a4e565b60405160208183030381529060405280519060200120036122ca578092505050612303565b80806122d590615d3d565b91505061220d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9150505b95945050505050565b5f838383604051602001612322939291906156a7565b6040516020818303038152906040528051906020012090509392505050565b60605f8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff1660015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1682805461242b90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461245790615734565b80156124a25780601f10612479576101008083540402835291602001916124a2565b820191905f5260205f20905b81548152906001019060200180831161248557829003601f168201915b505050505092509250925092509193909250565b6124be613e04565b6124c75f614028565b565b61251584848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166125a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259890615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265c90615c72565b60405180910390fd5b5f6126b286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90508787826040516020016126c9939291906156a7565b6040516020818303038152906040528051906020012060055f8686856040516020016126f7939291906156a7565b6040516020818303038152906040528051906020012081526020019081526020015f20819055507f2a32a3690bbbfacd5c1aa6ddac597f0068af35a0df62471960d6dd4b52a9036288883384888860405161275796959493929190615b6b565b60405180910390a15050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612798613e04565b8360025f858051906020012081526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01908161283a9190615d84565b508160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f6101000a81548160ff0219169083151502179055508060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160016101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167faa5e30aa8966dd38781f44699ca9b159ef1ce13aa53aca0cfafce6ce9e0470b08560015f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1660015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16604051612a0d9493929190615ed4565b60405180910390a250505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff16612ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ad090615616565b60405180910390fd5b612b39888833604051602001612af1939291906156a7565b6040516020818303038152906040528051906020012087878787604051602001612b1d939291906156a7565b6040516020818303038152906040528051906020012085613e8b565b60019050979650505050505050565b5f808585612b9886868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b604051602001612baa939291906156a7565b60405160208183030381529060405280519060200120905060055f8281526020019081526020015f2054915050949350505050565b5f60025f83604051602001612bf49190615f4e565b6040516020818303038152906040528051906020012081526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b612c8a88888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16612d16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0d90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd190615c72565b60405180910390fd5b5f612e278a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8d8d83604051602001612e3f939291906156a7565b604051602081830303815290604052805190602001209050612f2d818d8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613d48565b60045f8281526020019081526020015f208c81548110612f5057612f4f6156d0565b5b905f5260205f2090600a0201600201604051612f6c9190615a4e565b60405180910390208273ffffffffffffffffffffffffffffffffffffffff167f1e81c50255627b70d2cbc97f39338856c4a3f3b9b5deb72cc5c10855ef268d7783338d8d604051612fc09493929190615a90565b60405180910390a35050505050505050505050505050565b612fe0613e04565b3373ffffffffffffffffffffffffffffffffffffffff167f26f57461703d2ce008105a644fd78ba5affe61badbeb36b793f3e0e0ea89004c8360015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff168460405161307793929190615f64565b60405180910390a28060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160016101000a81548160ff0219169083151502179055505050565b61312789898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166131b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131aa90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16613277576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326e90615c72565b60405180910390fd5b5f6132c48b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8d8d836040516020016132dc939291906156a7565b60405160208183030381529060405280519060200120905061340f81338e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506140e9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f175bdf9caf4deb84cee7a7b2d757504f3b4a9a914fc7cd8ca8c8a8a980581eba8c8c60045f8781526020019081526020015f208054905060405161348493929190615fe3565b60405180910390a35050505050505050505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1661352a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161352190615616565b60405180910390fd5b5f8b8b33604051602001613540939291906156a7565b6040516020818303038152906040528051906020012090506136f5813360015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0180546135a790615734565b80601f01602080910402602001604051908101604052809291908181526020018280546135d390615734565b801561361e5780601f106135f55761010080835404028352916020019161361e565b820191905f5260205f20905b81548152906001019060200180831161360157829003601f168201915b50505050508d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506140e9565b3373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f175bdf9caf4deb84cee7a7b2d757504f3b4a9a914fc7cd8ca8c8a8a980581eba8e8e8e8e60045f8981526020019081526020015f208054905060405161376e959493929190616026565b60405180910390a360019150509a9950505050505050505050565b5f60608060605f6060805f8b8b8b6040516020016137a9939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f2089815481106137e4576137e36156d0565b5b905f5260205f2090600a02015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16975060045f8281526020019081526020015f208981548110613837576138366156d0565b5b905f5260205f2090600a0201600101805461385190615734565b80601f016020809104026020016040519081016040528092919081815260200182805461387d90615734565b80156138c85780601f1061389f576101008083540402835291602001916138c8565b820191905f5260205f20905b8154815290600101906020018083116138ab57829003601f168201915b5050505050965060045f8281526020019081526020015f2089815481106138f2576138f16156d0565b5b905f5260205f2090600a0201600201805461390c90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461393890615734565b80156139835780601f1061395a57610100808354040283529160200191613983565b820191905f5260205f20905b81548152906001019060200180831161396657829003601f168201915b5050505050955060045f8281526020019081526020015f2089815481106139ad576139ac6156d0565b5b905f5260205f2090600a020160030180546139c790615734565b80601f01602080910402602001604051908101604052809291908181526020018280546139f390615734565b8015613a3e5780601f10613a1557610100808354040283529160200191613a3e565b820191905f5260205f20905b815481529060010190602001808311613a2157829003601f168201915b5050505050945060045f8281526020019081526020015f208981548110613a6857613a676156d0565b5b905f5260205f2090600a020160040154935060045f8281526020019081526020015f208981548110613a9d57613a9c6156d0565b5b905f5260205f2090600a02016005018054613ab790615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613ae390615734565b8015613b2e5780601f10613b0557610100808354040283529160200191613b2e565b820191905f5260205f20905b815481529060010190602001808311613b1157829003601f168201915b5050505050925060045f8281526020019081526020015f208981548110613b5857613b576156d0565b5b905f5260205f2090600a02016006018054613b7290615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613b9e90615734565b8015613be95780601f10613bc057610100808354040283529160200191613be9565b820191905f5260205f20905b815481529060010190602001808311613bcc57829003601f168201915b5050505050915050949950949992975094509450565b613c07613e04565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613c77575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401613c6e9190614f00565b60405180910390fd5b613c8081614028565b50565b6001602052805f5260405f205f91509050805f018054613ca290615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613cce90615734565b8015613d195780601f10613cf057610100808354040283529160200191613d19565b820191905f5260205f20905b815481529060010190602001808311613cfc57829003601f168201915b505050505090806001015f9054906101000a900460ff16908060010160019054906101000a900460ff16905083565b60045f8681526020019081526020015f208481548110613d6b57613d6a6156d0565b5b905f5260205f2090600a0201600701604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f019081613dce9190615d84565b506020820151816001019081613de49190615d84565b506040820151816002019081613dfa9190615d84565b5050505050505050565b613e0c614207565b73ffffffffffffffffffffffffffffffffffffffff16613e2a612769565b73ffffffffffffffffffffffffffffffffffffffff1614613e8957613e4d614207565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401613e809190614f00565b60405180910390fd5b565b60ff6001901b198310613ed3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eca906160b7565b60405180910390fd5b5f811215613f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613f0d9061611f565b60405180910390fd5b5f8190505f84905060045f8781526020019081526020015f208581548110613f4157613f406156d0565b5b905f5260205f2090600a0201600801604051806040016040528086815260200185815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f015560208201518160010155505060045f8581526020019081526020015f208281548110613fc257613fc16156d0565b5b905f5260205f2090600a0201600901604051806040016040528088815260200183815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f0155602082015181600101555050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60045f8881526020019081526020015f2060018160018154018082558091505003905f5260205f209050505f60045f8981526020019081526020015f208054905090505f60045f8a81526020019081526020015f2060018361414b919061613d565b8154811061415c5761415b6156d0565b5b905f5260205f2090600a0201905087815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550868160010190816141bc9190615d84565b50858160020190816141ce9190615d84565b50848160030190816141e09190615d84565b50838160040181905550828160050190816141fb9190615d84565b50505050505050505050565b5f33905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126142405761423f61421f565b5b8235905067ffffffffffffffff81111561425d5761425c614223565b5b60208301915083600182028301111561427957614278614227565b5b9250929050565b5f819050919050565b61429281614280565b811461429c575f80fd5b50565b5f813590506142ad81614289565b92915050565b5f805f805f80608087890312156142cd576142cc614217565b5b5f87013567ffffffffffffffff8111156142ea576142e961421b565b5b6142f689828a0161422b565b9650965050602061430989828a0161429f565b945050604061431a89828a0161429f565b935050606087013567ffffffffffffffff81111561433b5761433a61421b565b5b61434789828a0161422b565b92509250509295509295509295565b5f8115159050919050565b61436a81614356565b82525050565b5f6020820190506143835f830184614361565b92915050565b5f805f805f805f805f60a08a8c0312156143a6576143a5614217565b5b5f8a013567ffffffffffffffff8111156143c3576143c261421b565b5b6143cf8c828d0161422b565b995099505060206143e28c828d0161429f565b97505060408a013567ffffffffffffffff8111156144035761440261421b565b5b61440f8c828d0161422b565b965096505060608a013567ffffffffffffffff8111156144325761443161421b565b5b61443e8c828d0161422b565b945094505060808a013567ffffffffffffffff8111156144615761446061421b565b5b61446d8c828d0161422b565b92509250509295985092959850929598565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6144a88261447f565b9050919050565b6144b88161449e565b81146144c2575f80fd5b50565b5f813590506144d3816144af565b92915050565b6144e281614356565b81146144ec575f80fd5b50565b5f813590506144fd816144d9565b92915050565b5f805f6060848603121561451a57614519614217565b5b5f614527868287016144c5565b9350506020614538868287016144c5565b9250506040614549868287016144ef565b9150509250925092565b5f806040838503121561456957614568614217565b5b5f614576858286016144c5565b9250506020614587858286016144c5565b9150509250929050565b5f819050919050565b6145a381614591565b81146145ad575f80fd5b50565b5f813590506145be8161459a565b92915050565b5f602082840312156145d9576145d8614217565b5b5f6145e6848285016145b0565b91505092915050565b6145f881614591565b82525050565b5f6020820190506146115f8301846145ef565b92915050565b5f805f805f608086880312156146305761462f614217565b5b5f86013567ffffffffffffffff81111561464d5761464c61421b565b5b6146598882890161422b565b9550955050602061466c888289016144c5565b935050604061467d8882890161429f565b925050606061468e8882890161429f565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156146d25780820151818401526020810190506146b7565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6146f78261469b565b61470181856146a5565b93506147118185602086016146b5565b61471a816146dd565b840191505092915050565b5f6060820190508181035f83015261473d81866146ed565b9050818103602083015261475181856146ed565b9050818103604083015261476581846146ed565b9050949350505050565b5f805f806040858703121561478757614786614217565b5b5f85013567ffffffffffffffff8111156147a4576147a361421b565b5b6147b08782880161422b565b9450945050602085013567ffffffffffffffff8111156147d3576147d261421b565b5b6147df8782880161422b565b925092505092959194509250565b5f819050919050565b6147ff816147ed565b8114614809575f80fd5b50565b5f8135905061481a816147f6565b92915050565b5f805f805f805f805f8060c08b8d03121561483e5761483d614217565b5b5f8b013567ffffffffffffffff81111561485b5761485a61421b565b5b6148678d828e0161422b565b9a509a505060208b013567ffffffffffffffff81111561488a5761488961421b565b5b6148968d828e0161422b565b985098505060406148a98d828e0161429f565b96505060608b013567ffffffffffffffff8111156148ca576148c961421b565b5b6148d68d828e0161422b565b955095505060808b013567ffffffffffffffff8111156148f9576148f861421b565b5b6149058d828e0161422b565b935093505060a06149188d828e0161480c565b9150509295989b9194979a5092959850565b5f805f805f6060868803121561494357614942614217565b5b5f86013567ffffffffffffffff8111156149605761495f61421b565b5b61496c8882890161422b565b9550955050602061497f8882890161429f565b935050604086013567ffffffffffffffff8111156149a05761499f61421b565b5b6149ac8882890161422b565b92509250509295509295909350565b5f805f805f805f8060a0898b0312156149d7576149d6614217565b5b5f89013567ffffffffffffffff8111156149f4576149f361421b565b5b614a008b828c0161422b565b9850985050602089013567ffffffffffffffff811115614a2357614a2261421b565b5b614a2f8b828c0161422b565b96509650506040614a428b828c0161429f565b9450506060614a538b828c0161429f565b935050608089013567ffffffffffffffff811115614a7457614a7361421b565b5b614a808b828c0161422b565b92509250509295985092959890939650565b5f805f805f805f6080888a031215614aad57614aac614217565b5b5f88013567ffffffffffffffff811115614aca57614ac961421b565b5b614ad68a828b0161422b565b9750975050602088013567ffffffffffffffff811115614af957614af861421b565b5b614b058a828b0161422b565b95509550506040614b188a828b0161429f565b935050606088013567ffffffffffffffff811115614b3957614b3861421b565b5b614b458a828b0161422b565b925092505092959891949750929550565b5f805f805f60608688031215614b6f57614b6e614217565b5b5f86013567ffffffffffffffff811115614b8c57614b8b61421b565b5b614b988882890161422b565b9550955050602086013567ffffffffffffffff811115614bbb57614bba61421b565b5b614bc78882890161422b565b93509350506040614bda8882890161480c565b9150509295509295909350565b5f8060408385031215614bfd57614bfc614217565b5b5f614c0a858286016145b0565b9250506020614c1b8582860161429f565b9150509250929050565b614c2e8161449e565b82525050565b614c3d81614280565b82525050565b5f60e082019050614c565f83018a614c25565b8181036020830152614c6881896146ed565b90508181036040830152614c7c81886146ed565b90508181036060830152614c9081876146ed565b9050614c9f6080830186614c34565b81810360a0830152614cb181856146ed565b905081810360c0830152614cc581846146ed565b905098975050505050505050565b5f805f805f60608688031215614cec57614ceb614217565b5b5f86013567ffffffffffffffff811115614d0957614d0861421b565b5b614d158882890161422b565b95509550506020614d28888289016144c5565b935050604086013567ffffffffffffffff811115614d4957614d4861421b565b5b614d558882890161422b565b92509250509295509295909350565b614d6d816147ed565b82525050565b5f602082019050614d865f830184614d64565b92915050565b5f805f60408486031215614da357614da2614217565b5b5f84013567ffffffffffffffff811115614dc057614dbf61421b565b5b614dcc8682870161422b565b93509350506020614ddf868287016144c5565b9150509250925092565b5f60208284031215614dfe57614dfd614217565b5b5f614e0b848285016144c5565b91505092915050565b5f6060820190508181035f830152614e2c81866146ed565b9050614e3b6020830185614361565b614e486040830184614361565b949350505050565b5f805f805f8060608789031215614e6a57614e69614217565b5b5f87013567ffffffffffffffff811115614e8757614e8661421b565b5b614e9389828a0161422b565b9650965050602087013567ffffffffffffffff811115614eb657614eb561421b565b5b614ec289828a0161422b565b9450945050604087013567ffffffffffffffff811115614ee557614ee461421b565b5b614ef189828a0161422b565b92509250509295509295509295565b5f602082019050614f135f830184614c25565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614f53826146dd565b810181811067ffffffffffffffff82111715614f7257614f71614f1d565b5b80604052505050565b5f614f8461420e565b9050614f908282614f4a565b919050565b5f67ffffffffffffffff821115614faf57614fae614f1d565b5b614fb8826146dd565b9050602081019050919050565b828183375f83830152505050565b5f614fe5614fe084614f95565b614f7b565b90508281526020810184848401111561500157615000614f19565b5b61500c848285614fc5565b509392505050565b5f82601f8301126150285761502761421f565b5b8135615038848260208601614fd3565b91505092915050565b5f805f806080858703121561505957615058614217565b5b5f615066878288016144c5565b945050602085013567ffffffffffffffff8111156150875761508661421b565b5b61509387828801615014565b93505060406150a4878288016144ef565b92505060606150b5878288016144ef565b91505092959194509250565b5f805f805f805f60a0888a0312156150dc576150db614217565b5b5f88013567ffffffffffffffff8111156150f9576150f861421b565b5b6151058a828b0161422b565b975097505060206151188a828b0161429f565b955050604088013567ffffffffffffffff8111156151395761513861421b565b5b6151458a828b0161422b565b945094505060606151588a828b016144c5565b92505060806151698a828b0161480c565b91505092959891949750929550565b5f6020828403121561518d5761518c614217565b5b5f82013567ffffffffffffffff8111156151aa576151a961421b565b5b6151b684828501615014565b91505092915050565b5f805f805f805f805f805f60c08c8e0312156151de576151dd614217565b5b5f8c013567ffffffffffffffff8111156151fb576151fa61421b565b5b6152078e828f0161422b565b9b509b5050602061521a8e828f0161429f565b99505060408c013567ffffffffffffffff81111561523b5761523a61421b565b5b6152478e828f0161422b565b985098505060608c013567ffffffffffffffff81111561526a5761526961421b565b5b6152768e828f0161422b565b965096505060808c013567ffffffffffffffff8111156152995761529861421b565b5b6152a58e828f0161422b565b945094505060a08c013567ffffffffffffffff8111156152c8576152c761421b565b5b6152d48e828f0161422b565b92509250509295989b509295989b9093969950565b5f80604083850312156152ff576152fe614217565b5b5f61530c858286016144c5565b925050602061531d858286016144ef565b9150509250929050565b5f805f805f805f805f805f60c08c8e03121561534657615345614217565b5b5f8c013567ffffffffffffffff8111156153635761536261421b565b5b61536f8e828f0161422b565b9b509b505060208c013567ffffffffffffffff8111156153925761539161421b565b5b61539e8e828f0161422b565b995099505060408c013567ffffffffffffffff8111156153c1576153c061421b565b5b6153cd8e828f0161422b565b975097505060608c013567ffffffffffffffff8111156153f0576153ef61421b565b5b6153fc8e828f0161422b565b9550955050608061540f8e828f0161429f565b93505060a08c013567ffffffffffffffff8111156154305761542f61421b565b5b61543c8e828f0161422b565b92509250509295989b509295989b9093969950565b5f805f805f805f805f8060c08b8d03121561546f5761546e614217565b5b5f8b013567ffffffffffffffff81111561548c5761548b61421b565b5b6154988d828e0161422b565b9a509a505060208b013567ffffffffffffffff8111156154bb576154ba61421b565b5b6154c78d828e0161422b565b985098505060408b013567ffffffffffffffff8111156154ea576154e961421b565b5b6154f68d828e0161422b565b965096505060606155098d828e0161429f565b945050608061551a8d828e016144c5565b93505060a08b013567ffffffffffffffff81111561553b5761553a61421b565b5b6155478d828e0161422b565b92509250509295989b9194979a5092959850565b5f805f806060858703121561557357615572614217565b5b5f85013567ffffffffffffffff8111156155905761558f61421b565b5b61559c8782880161422b565b945094505060206155af878288016144c5565b92505060406155c08782880161429f565b91505092959194509250565b7f5468697320757365722069736e277420612050726f64756365720000000000005f82015250565b5f615600601a836146a5565b915061560b826155cc565b602082019050919050565b5f6020820190508181035f83015261562d816155f4565b9050919050565b5f81905092915050565b5f6156498385615634565b9350615656838584614fc5565b82840190509392505050565b5f8160601b9050919050565b5f61567882615662565b9050919050565b5f6156898261566e565b9050919050565b6156a161569c8261449e565b61567f565b82525050565b5f6156b382858761563e565b91506156bf8284615690565b601482019150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061574b57607f821691505b60208210810361575e5761575d615707565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026157c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615785565b6157ca8683615785565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6158056158006157fb84614280565b6157e2565b614280565b9050919050565b5f819050919050565b61581e836157eb565b61583261582a8261580c565b848454615791565b825550505050565b5f90565b61584661583a565b615851818484615815565b505050565b5b81811015615874576158695f8261583e565b600181019050615857565b5050565b601f8211156158b95761588a81615764565b61589384615776565b810160208510156158a2578190505b6158b66158ae85615776565b830182615856565b50505b505050565b5f82821c905092915050565b5f6158d95f19846008026158be565b1980831691505092915050565b5f6158f183836158ca565b9150826002028217905092915050565b61590b83836156fd565b67ffffffffffffffff81111561592457615923614f1d565b5b61592e8254615734565b615939828285615878565b5f601f831160018114615966575f8415615954578287013590505b61595e85826158e6565b8655506159c5565b601f19841661597486615764565b5f5b8281101561599b57848901358255600182019150602085019450602081019050615976565b868310156159b857848901356159b4601f8916826158ca565b8355505b6001600288020188555050505b50505050505050565b5f81546159da81615734565b6159e48186615634565b9450600182165f81146159fe5760018114615a1357615a45565b60ff1983168652811515820286019350615a45565b615a1c85615764565b5f5b83811015615a3d57815481890152600182019150602081019050615a1e565b838801955050505b50505092915050565b5f615a5982846159ce565b915081905092915050565b5f615a6f83856146a5565b9350615a7c838584614fc5565b615a85836146dd565b840190509392505050565b5f606082019050615aa35f8301876145ef565b615ab06020830186614c25565b8181036040830152615ac3818486615a64565b905095945050505050565b5f606082019050615ae15f830186614c25565b615aee6020830185614c25565b615afb6040830184614361565b949350505050565b7f50726f64756374206e6f742065786973747320796574000000000000000000005f82015250565b5f615b376016836146a5565b9150615b4282615b03565b602082019050919050565b5f6020820190508181035f830152615b6481615b2b565b9050919050565b5f6080820190508181035f830152615b8481888a615a64565b9050615b936020830187614c25565b615ba06040830186614c25565b8181036060830152615bb3818486615a64565b9050979650505050505050565b7f5468697320557365722069736e2774206120526567756c61746f7200000000005f82015250565b5f615bf4601b836146a5565b9150615bff82615bc0565b602082019050919050565b5f6020820190508181035f830152615c2181615be8565b9050919050565b7f546869732075736572206973206e6f7420617574686f72697a656400000000005f82015250565b5f615c5c601b836146a5565b9150615c6782615c28565b602082019050919050565b5f6020820190508181035f830152615c8981615c50565b9050919050565b7f5468652070726f64756374277320696e6465782069732077726f6e67000000005f82015250565b5f615cc4601c836146a5565b9150615ccf82615c90565b602082019050919050565b5f6020820190508181035f830152615cf181615cb8565b9050919050565b5f615d0482848661563e565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f615d4782614280565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615d7957615d78615d10565b5b600182019050919050565b615d8d8261469b565b67ffffffffffffffff811115615da657615da5614f1d565b5b615db08254615734565b615dbb828285615878565b5f60209050601f831160018114615dec575f8415615dda578287015190505b615de485826158e6565b865550615e4b565b601f198416615dfa86615764565b5f5b82811015615e2157848901518255600182019150602085019450602081019050615dfc565b86831015615e3e5784890151615e3a601f8916826158ca565b8355505b6001600288020188555050505b505050505050565b5f8154615e5f81615734565b615e6981866146a5565b9450600182165f8114615e835760018114615e9957615ecb565b60ff198316865281151560200286019350615ecb565b615ea285615764565b5f5b83811015615ec357815481890152600182019150602081019050615ea4565b808801955050505b50505092915050565b5f608082019050615ee75f830187614c25565b8181036020830152615ef98186615e53565b9050615f086040830185614361565b615f156060830184614361565b95945050505050565b5f615f288261469b565b615f328185615634565b9350615f428185602086016146b5565b80840191505092915050565b5f615f598284615f1e565b915081905092915050565b5f606082019050615f775f830186614c25565b615f846020830185614361565b615f916040830184614361565b949350505050565b7f5f747261636b49440000000000000000000000000000000000000000000000005f82015250565b5f615fcd6008836146a5565b9150615fd882615f99565b602082019050919050565b5f6060820190508181035f830152615ffa81615fc1565b9050818103602083015261600f818587615a64565b905061601e6040830184614c34565b949350505050565b5f6060820190508181035f83015261603f818789615a64565b90508181036020830152616054818587615a64565b90506160636040830184614c34565b9695505050505050565b7f5468652063757272656e74206f7065726174696f6e2069732077726f6e6700005f82015250565b5f6160a1601e836146a5565b91506160ac8261606d565b602082019050919050565b5f6020820190508181035f8301526160ce81616095565b9050919050565b7f54686520706172656e74206f7065726174696f6e2069732077726f6e670000005f82015250565b5f616109601d836146a5565b9150616114826160d5565b602082019050919050565b5f6020820190508181035f830152616136816160fd565b9050919050565b5f61614782614280565b915061615283614280565b925082820390508181111561616a57616169615d10565b5b9291505056fea26469706673582212208d62394dcce530f8adea8c8a4591a9b0dfc86aae87508c04861293a3d92f926a64736f6c63430008140033
Deployed ByteCode
0x608060405234801561000f575f80fd5b50600436106101ed575f3560e01c80636f77926b1161010d578063bf40fac1116100a0578063e0e494911161006f578063e0e4949114610679578063f2ea8b49146106a9578063f2fde38b146106df578063f7c42ac8146106fb576101ed565b8063bf40fac1146105f5578063cd22f53614610625578063cf46dca714610641578063dee730161461065d576101ed565b8063a099e663116100dc578063a099e66314610549578063a29f9fb914610565578063a8d03e2714610595578063a97f5089146105c5576101ed565b80636f77926b146104d3578063715018a61461050557806384d62f471461050f5780638da5cb5b1461052b576101ed565b80631c566ef2116101855780633328244211610154578063332824421461040d57806339c58a4f1461043d5780634562426014610473578063508cde13146104a3576101ed565b80631c566ef21461034b5780631c6383761461037b5780631dc436cd146103ab57806321cbed35146103dd576101ed565b806309d84fc4116101c157806309d84fc41461029d5780630eb51018146102cd57806311c0f931146102ff578063131b7b751461031b576101ed565b8062ba3e50146101f157806302879f9c1461022157806303a77c7a1461025157806308cad9911461026d575b5f80fd5b61020b600480360381019061020691906142b3565b61072d565b6040516102189190614370565b60405180910390f35b61023b60048036038101906102369190614389565b61085b565b6040516102489190614370565b60405180910390f35b61026b60048036038101906102669190614503565b610a9a565b005b61028760048036038101906102829190614553565b610b88565b6040516102949190614370565b60405180910390f35b6102b760048036038101906102b291906145c4565b610bb2565b6040516102c491906145fe565b60405180910390f35b6102e760048036038101906102e29190614617565b610bc7565b6040516102f693929190614725565b60405180910390f35b6103196004803603810190610314919061476f565b610eef565b005b61033560048036038101906103309190614820565b61102d565b6040516103429190614370565b60405180910390f35b6103656004803603810190610360919061492a565b6112dd565b6040516103729190614370565b60405180910390f35b610395600480360381019061039091906149bb565b6113e9565b6040516103a29190614370565b60405180910390f35b6103c560048036038101906103c09190614617565b611679565b6040516103d493929190614725565b60405180910390f35b6103f760048036038101906103f29190614a92565b61194b565b6040516104049190614370565b60405180910390f35b61042760048036038101906104229190614b56565b611bb9565b6040516104349190614370565b60405180910390f35b61045760048036038101906104529190614be7565b611ec7565b60405161046a9796959493929190614c43565b60405180910390f35b61048d60048036038101906104889190614cd3565b6121dc565b60405161049a9190614d73565b60405180910390f35b6104bd60048036038101906104b89190614d8c565b61230c565b6040516104ca91906145fe565b60405180910390f35b6104ed60048036038101906104e89190614de9565b612341565b6040516104fc93929190614e14565b60405180910390f35b61050d6124b6565b005b61052960048036038101906105249190614e50565b6124c9565b005b610533612769565b6040516105409190614f00565b60405180910390f35b610563600480360381019061055e9190615041565b612790565b005b61057f600480360381019061057a91906145c4565b612a1b565b60405161058c9190614f00565b60405180910390f35b6105af60048036038101906105aa91906150c1565b612a4b565b6040516105bc9190614370565b60405180910390f35b6105df60048036038101906105da919061476f565b612b48565b6040516105ec91906145fe565b60405180910390f35b61060f600480360381019061060a9190615178565b612bdf565b60405161061c9190614f00565b60405180910390f35b61063f600480360381019061063a91906151bf565b612c3e565b005b61065b600480360381019061065691906152e9565b612fd8565b005b61067760048036038101906106729190615327565b6130db565b005b610693600480360381019061068e9190615451565b61349c565b6040516106a09190614370565b60405180910390f35b6106c360048036038101906106be919061555b565b613789565b6040516106d69796959493929190614c43565b60405180910390f35b6106f960048036038101906106f49190614de9565b613bff565b005b61071560048036038101906107109190614de9565b613c83565b60405161072493929190614e14565b60405180910390f35b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff166107bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107b290615616565b60405180910390fd5b5f8787336040516020016107d1939291906156a7565b604051602081830303815290604052805190602001209050838360045f8481526020019081526020015f20888154811061080e5761080d6156d0565b5b905f5260205f2090600a0201600701878154811061082f5761082e6156d0565b5b905f5260205f209060030201600201918261084b929190615901565b5060019150509695505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff166108e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108e090615616565b60405180910390fd5b5f8a8a336040516020016108ff939291906156a7565b6040516020818303038152906040528051906020012090506109ed818a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505088888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613d48565b60045f8281526020019081526020015f208981548110610a1057610a0f6156d0565b5b905f5260205f2090600a0201600201604051610a2c9190615a4e565b60405180910390203373ffffffffffffffffffffffffffffffffffffffff167f1e81c50255627b70d2cbc97f39338856c4a3f3b9b5deb72cc5c10855ef268d7783338c8c604051610a809493929190615a90565b60405180910390a360019150509998505050505050505050565b610aa2613e04565b3373ffffffffffffffffffffffffffffffffffffffff167f66b612407219f373f9a77dff0cf18ba327db7261e48c9c345785df6ee8de2757848484604051610aec93929190615ace565b60405180910390a28060035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550505050565b6003602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b6005602052805f5260405f205f915090505481565b60608060605f888888604051602001610be2939291906156a7565b6040516020818303038152906040528051906020012090505f60045f8381526020019081526020015f208054905011610c50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4790615b4d565b60405180910390fd5b60045f8281526020019081526020015f208681548110610c7357610c726156d0565b5b905f5260205f2090600a02016007018581548110610c9457610c936156d0565b5b905f5260205f2090600302015f018054610cad90615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd990615734565b8015610d245780601f10610cfb57610100808354040283529160200191610d24565b820191905f5260205f20905b815481529060010190602001808311610d0757829003601f168201915b5050505050935060045f8281526020019081526020015f208681548110610d4e57610d4d6156d0565b5b905f5260205f2090600a02016007018581548110610d6f57610d6e6156d0565b5b905f5260205f2090600302016001018054610d8990615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610db590615734565b8015610e005780601f10610dd757610100808354040283529160200191610e00565b820191905f5260205f20905b815481529060010190602001808311610de357829003601f168201915b5050505050925060045f8281526020019081526020015f208681548110610e2a57610e296156d0565b5b905f5260205f2090600a02016007018581548110610e4b57610e4a6156d0565b5b905f5260205f2090600302016002018054610e6590615734565b80601f0160208091040260200160405190810160405280929190818152602001828054610e9190615734565b8015610edc5780601f10610eb357610100808354040283529160200191610edc565b820191905f5260205f20905b815481529060010190602001808311610ebf57829003601f168201915b5050505050915050955095509592505050565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff16610f7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f7390615616565b60405180910390fd5b838333604051602001610f91939291906156a7565b6040516020818303038152906040528051906020012060055f848433604051602001610fbf939291906156a7565b6040516020818303038152906040528051906020012081526020019081526020015f20819055507f2a32a3690bbbfacd5c1aa6ddac597f0068af35a0df62471960d6dd4b52a9036284843333868660405161101f96959493929190615b6b565b60405180910390a150505050565b5f61107a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110fd90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff166111ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111c190615c72565b60405180910390fd5b5f6112178b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f61126687878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90506112c88e8e84604051602001611280939291906156a7565b604051602081830303815290604052805190602001208b8b8b856040516020016112ac939291906156a7565b6040516020818303038152906040528051906020012088613e8b565b600193505050509a9950505050505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1661136b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136290615616565b60405180910390fd5b5f868633604051602001611381939291906156a7565b604051602081830303815290604052805190602001209050838360045f8481526020019081526020015f2087815481106113be576113bd6156d0565b5b905f5260205f2090600a020160060191826113da929190615901565b50600191505095945050505050565b5f61143687878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166114c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114b990615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611586576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157d90615c72565b60405180910390fd5b5f6115d389898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8b8b836040516020016115eb939291906156a7565b604051602081830303815290604052805190602001209050858560045f8481526020019081526020015f208a81548110611628576116276156d0565b5b905f5260205f2090600a02016007018981548110611649576116486156d0565b5b905f5260205f2090600302016002019182611665929190615901565b506001935050505098975050505050505050565b60608060605f888888604051602001611694939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f2086815481106116cf576116ce6156d0565b5b905f5260205f2090600a020160070185815481106116f0576116ef6156d0565b5b905f5260205f2090600302015f01805461170990615734565b80601f016020809104026020016040519081016040528092919081815260200182805461173590615734565b80156117805780601f1061175757610100808354040283529160200191611780565b820191905f5260205f20905b81548152906001019060200180831161176357829003601f168201915b5050505050935060045f8281526020019081526020015f2086815481106117aa576117a96156d0565b5b905f5260205f2090600a020160070185815481106117cb576117ca6156d0565b5b905f5260205f20906003020160010180546117e590615734565b80601f016020809104026020016040519081016040528092919081815260200182805461181190615734565b801561185c5780601f106118335761010080835404028352916020019161185c565b820191905f5260205f20905b81548152906001019060200180831161183f57829003601f168201915b5050505050925060045f8281526020019081526020015f208681548110611886576118856156d0565b5b905f5260205f2090600a020160070185815481106118a7576118a66156d0565b5b905f5260205f20906003020160020180546118c190615734565b80601f01602080910402602001604051908101604052809291908181526020018280546118ed90615734565b80156119385780601f1061190f57610100808354040283529160200191611938565b820191905f5260205f20905b81548152906001019060200180831161191b57829003601f168201915b5050505050915050955095509592505050565b5f61199886868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611a24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a1b90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611ae8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611adf90615c72565b60405180910390fd5b5f611b3588888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8a8a83604051602001611b4d939291906156a7565b604051602081830303815290604052805190602001209050858560045f8481526020019081526020015f208981548110611b8a57611b896156d0565b5b905f5260205f2090600a02016006019182611ba6929190615901565b5060019350505050979650505050505050565b5f611c0684848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16611c92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8990615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611d56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4d90615c72565b60405180910390fd5b5f831215611d99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9090615cda565b60405180910390fd5b5f611de686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f888883604051602001611dfe939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f208581548110611e3957611e386156d0565b5b905f5260205f2090600a020160080160405180604001604052808381526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f01556020820151816001015550506001935050505095945050505050565b6004602052815f5260405f208181548110611ee0575f80fd5b905f5260205f2090600a02015f9150915050805f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054611f2590615734565b80601f0160208091040260200160405190810160405280929190818152602001828054611f5190615734565b8015611f9c5780601f10611f7357610100808354040283529160200191611f9c565b820191905f5260205f20905b815481529060010190602001808311611f7f57829003601f168201915b505050505090806002018054611fb190615734565b80601f0160208091040260200160405190810160405280929190818152602001828054611fdd90615734565b80156120285780601f10611fff57610100808354040283529160200191612028565b820191905f5260205f20905b81548152906001019060200180831161200b57829003601f168201915b50505050509080600301805461203d90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461206990615734565b80156120b45780601f1061208b576101008083540402835291602001916120b4565b820191905f5260205f20905b81548152906001019060200180831161209757829003601f168201915b5050505050908060040154908060050180546120cf90615734565b80601f01602080910402602001604051908101604052809291908181526020018280546120fb90615734565b80156121465780601f1061211d57610100808354040283529160200191612146565b820191905f5260205f20905b81548152906001019060200180831161212957829003601f168201915b50505050509080600601805461215b90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461218790615734565b80156121d25780601f106121a9576101008083540402835291602001916121d2565b820191905f5260205f20905b8154815290600101906020018083116121b557829003601f168201915b5050505050905087565b5f808686866040516020016121f3939291906156a7565b6040516020818303038152906040528051906020012090505f5b60045f8381526020019081526020015f208054905081108015612235575060ff6001901b1981105b156122dd57848460405160200161224d929190615cf8565b6040516020818303038152906040528051906020012060045f8481526020019081526020015f208281548110612286576122856156d0565b5b905f5260205f2090600a02016002016040516020016122a59190615a4e565b60405160208183030381529060405280519060200120036122ca578092505050612303565b80806122d590615d3d565b91505061220d565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9150505b95945050505050565b5f838383604051602001612322939291906156a7565b6040516020818303038152906040528051906020012090509392505050565b60605f8060015f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff1660015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1682805461242b90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461245790615734565b80156124a25780601f10612479576101008083540402835291602001916124a2565b820191905f5260205f20905b81548152906001019060200180831161248557829003601f168201915b505050505092509250925092509193909250565b6124be613e04565b6124c75f614028565b565b61251584848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166125a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161259890615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612665576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265c90615c72565b60405180910390fd5b5f6126b286868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90508787826040516020016126c9939291906156a7565b6040516020818303038152906040528051906020012060055f8686856040516020016126f7939291906156a7565b6040516020818303038152906040528051906020012081526020019081526020015f20819055507f2a32a3690bbbfacd5c1aa6ddac597f0068af35a0df62471960d6dd4b52a9036288883384888860405161275796959493929190615b6b565b60405180910390a15050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612798613e04565b8360025f858051906020012081526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508260015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f01908161283a9190615d84565b508160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f6101000a81548160ff0219169083151502179055508060015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160016101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167faa5e30aa8966dd38781f44699ca9b159ef1ce13aa53aca0cfafce6ce9e0470b08560015f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0160015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1660015f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16604051612a0d9493929190615ed4565b60405180910390a250505050565b6002602052805f5260405f205f915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff16612ad9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ad090615616565b60405180910390fd5b612b39888833604051602001612af1939291906156a7565b6040516020818303038152906040528051906020012087878787604051602001612b1d939291906156a7565b6040516020818303038152906040528051906020012085613e8b565b60019050979650505050505050565b5f808585612b9886868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b604051602001612baa939291906156a7565b60405160208183030381529060405280519060200120905060055f8281526020019081526020015f2054915050949350505050565b5f60025f83604051602001612bf49190615f4e565b6040516020818303038152906040528051906020012081526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b612c8a88888080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff16612d16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d0d90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd190615c72565b60405180910390fd5b5f612e278a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8d8d83604051602001612e3f939291906156a7565b604051602081830303815290604052805190602001209050612f2d818d8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f8201169050808301925050505050505089898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050613d48565b60045f8281526020019081526020015f208c81548110612f5057612f4f6156d0565b5b905f5260205f2090600a0201600201604051612f6c9190615a4e565b60405180910390208273ffffffffffffffffffffffffffffffffffffffff167f1e81c50255627b70d2cbc97f39338856c4a3f3b9b5deb72cc5c10855ef268d7783338d8d604051612fc09493929190615a90565b60405180910390a35050505050505050505050505050565b612fe0613e04565b3373ffffffffffffffffffffffffffffffffffffffff167f26f57461703d2ce008105a644fd78ba5affe61badbeb36b793f3e0e0ea89004c8360015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff168460405161307793929190615f64565b60405180910390a28060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160016101000a81548160ff0219169083151502179055505050565b61312789898080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f9054906101000a900460ff166131b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131aa90615c0a565b60405180910390fd5b60035f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16613277576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326e90615c72565b60405180910390fd5b5f6132c48b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f82011690508083019250505050505050612bdf565b90505f8d8d836040516020016132dc939291906156a7565b60405160208183030381529060405280519060200120905061340f81338e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506140e9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f175bdf9caf4deb84cee7a7b2d757504f3b4a9a914fc7cd8ca8c8a8a980581eba8c8c60045f8781526020019081526020015f208054905060405161348493929190615fe3565b60405180910390a35050505050505050505050505050565b5f60015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010160019054906101000a900460ff1661352a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161352190615616565b60405180910390fd5b5f8b8b33604051602001613540939291906156a7565b6040516020818303038152906040528051906020012090506136f5813360015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f0180546135a790615734565b80601f01602080910402602001604051908101604052809291908181526020018280546135d390615734565b801561361e5780601f106135f55761010080835404028352916020019161361e565b820191905f5260205f20905b81548152906001019060200180831161360157829003601f168201915b50505050508d8d8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508b8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506140e9565b3373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f175bdf9caf4deb84cee7a7b2d757504f3b4a9a914fc7cd8ca8c8a8a980581eba8e8e8e8e60045f8981526020019081526020015f208054905060405161376e959493929190616026565b60405180910390a360019150509a9950505050505050505050565b5f60608060605f6060805f8b8b8b6040516020016137a9939291906156a7565b60405160208183030381529060405280519060200120905060045f8281526020019081526020015f2089815481106137e4576137e36156d0565b5b905f5260205f2090600a02015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16975060045f8281526020019081526020015f208981548110613837576138366156d0565b5b905f5260205f2090600a0201600101805461385190615734565b80601f016020809104026020016040519081016040528092919081815260200182805461387d90615734565b80156138c85780601f1061389f576101008083540402835291602001916138c8565b820191905f5260205f20905b8154815290600101906020018083116138ab57829003601f168201915b5050505050965060045f8281526020019081526020015f2089815481106138f2576138f16156d0565b5b905f5260205f2090600a0201600201805461390c90615734565b80601f016020809104026020016040519081016040528092919081815260200182805461393890615734565b80156139835780601f1061395a57610100808354040283529160200191613983565b820191905f5260205f20905b81548152906001019060200180831161396657829003601f168201915b5050505050955060045f8281526020019081526020015f2089815481106139ad576139ac6156d0565b5b905f5260205f2090600a020160030180546139c790615734565b80601f01602080910402602001604051908101604052809291908181526020018280546139f390615734565b8015613a3e5780601f10613a1557610100808354040283529160200191613a3e565b820191905f5260205f20905b815481529060010190602001808311613a2157829003601f168201915b5050505050945060045f8281526020019081526020015f208981548110613a6857613a676156d0565b5b905f5260205f2090600a020160040154935060045f8281526020019081526020015f208981548110613a9d57613a9c6156d0565b5b905f5260205f2090600a02016005018054613ab790615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613ae390615734565b8015613b2e5780601f10613b0557610100808354040283529160200191613b2e565b820191905f5260205f20905b815481529060010190602001808311613b1157829003601f168201915b5050505050925060045f8281526020019081526020015f208981548110613b5857613b576156d0565b5b905f5260205f2090600a02016006018054613b7290615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613b9e90615734565b8015613be95780601f10613bc057610100808354040283529160200191613be9565b820191905f5260205f20905b815481529060010190602001808311613bcc57829003601f168201915b5050505050915050949950949992975094509450565b613c07613e04565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613c77575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401613c6e9190614f00565b60405180910390fd5b613c8081614028565b50565b6001602052805f5260405f205f91509050805f018054613ca290615734565b80601f0160208091040260200160405190810160405280929190818152602001828054613cce90615734565b8015613d195780601f10613cf057610100808354040283529160200191613d19565b820191905f5260205f20905b815481529060010190602001808311613cfc57829003601f168201915b505050505090806001015f9054906101000a900460ff16908060010160019054906101000a900460ff16905083565b60045f8681526020019081526020015f208481548110613d6b57613d6a6156d0565b5b905f5260205f2090600a0201600701604051806060016040528085815260200184815260200183815250908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f019081613dce9190615d84565b506020820151816001019081613de49190615d84565b506040820151816002019081613dfa9190615d84565b5050505050505050565b613e0c614207565b73ffffffffffffffffffffffffffffffffffffffff16613e2a612769565b73ffffffffffffffffffffffffffffffffffffffff1614613e8957613e4d614207565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401613e809190614f00565b60405180910390fd5b565b60ff6001901b198310613ed3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613eca906160b7565b60405180910390fd5b5f811215613f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613f0d9061611f565b60405180910390fd5b5f8190505f84905060045f8781526020019081526020015f208581548110613f4157613f406156d0565b5b905f5260205f2090600a0201600801604051806040016040528086815260200185815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f015560208201518160010155505060045f8581526020019081526020015f208281548110613fc257613fc16156d0565b5b905f5260205f2090600a0201600901604051806040016040528088815260200183815250908060018154018082558091505060019003905f5260205f2090600202015f909190919091505f820151815f0155602082015181600101555050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60045f8881526020019081526020015f2060018160018154018082558091505003905f5260205f209050505f60045f8981526020019081526020015f208054905090505f60045f8a81526020019081526020015f2060018361414b919061613d565b8154811061415c5761415b6156d0565b5b905f5260205f2090600a0201905087815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550868160010190816141bc9190615d84565b50858160020190816141ce9190615d84565b50848160030190816141e09190615d84565b50838160040181905550828160050190816141fb9190615d84565b50505050505050505050565b5f33905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f8083601f8401126142405761423f61421f565b5b8235905067ffffffffffffffff81111561425d5761425c614223565b5b60208301915083600182028301111561427957614278614227565b5b9250929050565b5f819050919050565b61429281614280565b811461429c575f80fd5b50565b5f813590506142ad81614289565b92915050565b5f805f805f80608087890312156142cd576142cc614217565b5b5f87013567ffffffffffffffff8111156142ea576142e961421b565b5b6142f689828a0161422b565b9650965050602061430989828a0161429f565b945050604061431a89828a0161429f565b935050606087013567ffffffffffffffff81111561433b5761433a61421b565b5b61434789828a0161422b565b92509250509295509295509295565b5f8115159050919050565b61436a81614356565b82525050565b5f6020820190506143835f830184614361565b92915050565b5f805f805f805f805f60a08a8c0312156143a6576143a5614217565b5b5f8a013567ffffffffffffffff8111156143c3576143c261421b565b5b6143cf8c828d0161422b565b995099505060206143e28c828d0161429f565b97505060408a013567ffffffffffffffff8111156144035761440261421b565b5b61440f8c828d0161422b565b965096505060608a013567ffffffffffffffff8111156144325761443161421b565b5b61443e8c828d0161422b565b945094505060808a013567ffffffffffffffff8111156144615761446061421b565b5b61446d8c828d0161422b565b92509250509295985092959850929598565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6144a88261447f565b9050919050565b6144b88161449e565b81146144c2575f80fd5b50565b5f813590506144d3816144af565b92915050565b6144e281614356565b81146144ec575f80fd5b50565b5f813590506144fd816144d9565b92915050565b5f805f6060848603121561451a57614519614217565b5b5f614527868287016144c5565b9350506020614538868287016144c5565b9250506040614549868287016144ef565b9150509250925092565b5f806040838503121561456957614568614217565b5b5f614576858286016144c5565b9250506020614587858286016144c5565b9150509250929050565b5f819050919050565b6145a381614591565b81146145ad575f80fd5b50565b5f813590506145be8161459a565b92915050565b5f602082840312156145d9576145d8614217565b5b5f6145e6848285016145b0565b91505092915050565b6145f881614591565b82525050565b5f6020820190506146115f8301846145ef565b92915050565b5f805f805f608086880312156146305761462f614217565b5b5f86013567ffffffffffffffff81111561464d5761464c61421b565b5b6146598882890161422b565b9550955050602061466c888289016144c5565b935050604061467d8882890161429f565b925050606061468e8882890161429f565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156146d25780820151818401526020810190506146b7565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6146f78261469b565b61470181856146a5565b93506147118185602086016146b5565b61471a816146dd565b840191505092915050565b5f6060820190508181035f83015261473d81866146ed565b9050818103602083015261475181856146ed565b9050818103604083015261476581846146ed565b9050949350505050565b5f805f806040858703121561478757614786614217565b5b5f85013567ffffffffffffffff8111156147a4576147a361421b565b5b6147b08782880161422b565b9450945050602085013567ffffffffffffffff8111156147d3576147d261421b565b5b6147df8782880161422b565b925092505092959194509250565b5f819050919050565b6147ff816147ed565b8114614809575f80fd5b50565b5f8135905061481a816147f6565b92915050565b5f805f805f805f805f8060c08b8d03121561483e5761483d614217565b5b5f8b013567ffffffffffffffff81111561485b5761485a61421b565b5b6148678d828e0161422b565b9a509a505060208b013567ffffffffffffffff81111561488a5761488961421b565b5b6148968d828e0161422b565b985098505060406148a98d828e0161429f565b96505060608b013567ffffffffffffffff8111156148ca576148c961421b565b5b6148d68d828e0161422b565b955095505060808b013567ffffffffffffffff8111156148f9576148f861421b565b5b6149058d828e0161422b565b935093505060a06149188d828e0161480c565b9150509295989b9194979a5092959850565b5f805f805f6060868803121561494357614942614217565b5b5f86013567ffffffffffffffff8111156149605761495f61421b565b5b61496c8882890161422b565b9550955050602061497f8882890161429f565b935050604086013567ffffffffffffffff8111156149a05761499f61421b565b5b6149ac8882890161422b565b92509250509295509295909350565b5f805f805f805f8060a0898b0312156149d7576149d6614217565b5b5f89013567ffffffffffffffff8111156149f4576149f361421b565b5b614a008b828c0161422b565b9850985050602089013567ffffffffffffffff811115614a2357614a2261421b565b5b614a2f8b828c0161422b565b96509650506040614a428b828c0161429f565b9450506060614a538b828c0161429f565b935050608089013567ffffffffffffffff811115614a7457614a7361421b565b5b614a808b828c0161422b565b92509250509295985092959890939650565b5f805f805f805f6080888a031215614aad57614aac614217565b5b5f88013567ffffffffffffffff811115614aca57614ac961421b565b5b614ad68a828b0161422b565b9750975050602088013567ffffffffffffffff811115614af957614af861421b565b5b614b058a828b0161422b565b95509550506040614b188a828b0161429f565b935050606088013567ffffffffffffffff811115614b3957614b3861421b565b5b614b458a828b0161422b565b925092505092959891949750929550565b5f805f805f60608688031215614b6f57614b6e614217565b5b5f86013567ffffffffffffffff811115614b8c57614b8b61421b565b5b614b988882890161422b565b9550955050602086013567ffffffffffffffff811115614bbb57614bba61421b565b5b614bc78882890161422b565b93509350506040614bda8882890161480c565b9150509295509295909350565b5f8060408385031215614bfd57614bfc614217565b5b5f614c0a858286016145b0565b9250506020614c1b8582860161429f565b9150509250929050565b614c2e8161449e565b82525050565b614c3d81614280565b82525050565b5f60e082019050614c565f83018a614c25565b8181036020830152614c6881896146ed565b90508181036040830152614c7c81886146ed565b90508181036060830152614c9081876146ed565b9050614c9f6080830186614c34565b81810360a0830152614cb181856146ed565b905081810360c0830152614cc581846146ed565b905098975050505050505050565b5f805f805f60608688031215614cec57614ceb614217565b5b5f86013567ffffffffffffffff811115614d0957614d0861421b565b5b614d158882890161422b565b95509550506020614d28888289016144c5565b935050604086013567ffffffffffffffff811115614d4957614d4861421b565b5b614d558882890161422b565b92509250509295509295909350565b614d6d816147ed565b82525050565b5f602082019050614d865f830184614d64565b92915050565b5f805f60408486031215614da357614da2614217565b5b5f84013567ffffffffffffffff811115614dc057614dbf61421b565b5b614dcc8682870161422b565b93509350506020614ddf868287016144c5565b9150509250925092565b5f60208284031215614dfe57614dfd614217565b5b5f614e0b848285016144c5565b91505092915050565b5f6060820190508181035f830152614e2c81866146ed565b9050614e3b6020830185614361565b614e486040830184614361565b949350505050565b5f805f805f8060608789031215614e6a57614e69614217565b5b5f87013567ffffffffffffffff811115614e8757614e8661421b565b5b614e9389828a0161422b565b9650965050602087013567ffffffffffffffff811115614eb657614eb561421b565b5b614ec289828a0161422b565b9450945050604087013567ffffffffffffffff811115614ee557614ee461421b565b5b614ef189828a0161422b565b92509250509295509295509295565b5f602082019050614f135f830184614c25565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b614f53826146dd565b810181811067ffffffffffffffff82111715614f7257614f71614f1d565b5b80604052505050565b5f614f8461420e565b9050614f908282614f4a565b919050565b5f67ffffffffffffffff821115614faf57614fae614f1d565b5b614fb8826146dd565b9050602081019050919050565b828183375f83830152505050565b5f614fe5614fe084614f95565b614f7b565b90508281526020810184848401111561500157615000614f19565b5b61500c848285614fc5565b509392505050565b5f82601f8301126150285761502761421f565b5b8135615038848260208601614fd3565b91505092915050565b5f805f806080858703121561505957615058614217565b5b5f615066878288016144c5565b945050602085013567ffffffffffffffff8111156150875761508661421b565b5b61509387828801615014565b93505060406150a4878288016144ef565b92505060606150b5878288016144ef565b91505092959194509250565b5f805f805f805f60a0888a0312156150dc576150db614217565b5b5f88013567ffffffffffffffff8111156150f9576150f861421b565b5b6151058a828b0161422b565b975097505060206151188a828b0161429f565b955050604088013567ffffffffffffffff8111156151395761513861421b565b5b6151458a828b0161422b565b945094505060606151588a828b016144c5565b92505060806151698a828b0161480c565b91505092959891949750929550565b5f6020828403121561518d5761518c614217565b5b5f82013567ffffffffffffffff8111156151aa576151a961421b565b5b6151b684828501615014565b91505092915050565b5f805f805f805f805f805f60c08c8e0312156151de576151dd614217565b5b5f8c013567ffffffffffffffff8111156151fb576151fa61421b565b5b6152078e828f0161422b565b9b509b5050602061521a8e828f0161429f565b99505060408c013567ffffffffffffffff81111561523b5761523a61421b565b5b6152478e828f0161422b565b985098505060608c013567ffffffffffffffff81111561526a5761526961421b565b5b6152768e828f0161422b565b965096505060808c013567ffffffffffffffff8111156152995761529861421b565b5b6152a58e828f0161422b565b945094505060a08c013567ffffffffffffffff8111156152c8576152c761421b565b5b6152d48e828f0161422b565b92509250509295989b509295989b9093969950565b5f80604083850312156152ff576152fe614217565b5b5f61530c858286016144c5565b925050602061531d858286016144ef565b9150509250929050565b5f805f805f805f805f805f60c08c8e03121561534657615345614217565b5b5f8c013567ffffffffffffffff8111156153635761536261421b565b5b61536f8e828f0161422b565b9b509b505060208c013567ffffffffffffffff8111156153925761539161421b565b5b61539e8e828f0161422b565b995099505060408c013567ffffffffffffffff8111156153c1576153c061421b565b5b6153cd8e828f0161422b565b975097505060608c013567ffffffffffffffff8111156153f0576153ef61421b565b5b6153fc8e828f0161422b565b9550955050608061540f8e828f0161429f565b93505060a08c013567ffffffffffffffff8111156154305761542f61421b565b5b61543c8e828f0161422b565b92509250509295989b509295989b9093969950565b5f805f805f805f805f8060c08b8d03121561546f5761546e614217565b5b5f8b013567ffffffffffffffff81111561548c5761548b61421b565b5b6154988d828e0161422b565b9a509a505060208b013567ffffffffffffffff8111156154bb576154ba61421b565b5b6154c78d828e0161422b565b985098505060408b013567ffffffffffffffff8111156154ea576154e961421b565b5b6154f68d828e0161422b565b965096505060606155098d828e0161429f565b945050608061551a8d828e016144c5565b93505060a08b013567ffffffffffffffff81111561553b5761553a61421b565b5b6155478d828e0161422b565b92509250509295989b9194979a5092959850565b5f805f806060858703121561557357615572614217565b5b5f85013567ffffffffffffffff8111156155905761558f61421b565b5b61559c8782880161422b565b945094505060206155af878288016144c5565b92505060406155c08782880161429f565b91505092959194509250565b7f5468697320757365722069736e277420612050726f64756365720000000000005f82015250565b5f615600601a836146a5565b915061560b826155cc565b602082019050919050565b5f6020820190508181035f83015261562d816155f4565b9050919050565b5f81905092915050565b5f6156498385615634565b9350615656838584614fc5565b82840190509392505050565b5f8160601b9050919050565b5f61567882615662565b9050919050565b5f6156898261566e565b9050919050565b6156a161569c8261449e565b61567f565b82525050565b5f6156b382858761563e565b91506156bf8284615690565b601482019150819050949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061574b57607f821691505b60208210810361575e5761575d615707565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026157c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615785565b6157ca8683615785565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6158056158006157fb84614280565b6157e2565b614280565b9050919050565b5f819050919050565b61581e836157eb565b61583261582a8261580c565b848454615791565b825550505050565b5f90565b61584661583a565b615851818484615815565b505050565b5b81811015615874576158695f8261583e565b600181019050615857565b5050565b601f8211156158b95761588a81615764565b61589384615776565b810160208510156158a2578190505b6158b66158ae85615776565b830182615856565b50505b505050565b5f82821c905092915050565b5f6158d95f19846008026158be565b1980831691505092915050565b5f6158f183836158ca565b9150826002028217905092915050565b61590b83836156fd565b67ffffffffffffffff81111561592457615923614f1d565b5b61592e8254615734565b615939828285615878565b5f601f831160018114615966575f8415615954578287013590505b61595e85826158e6565b8655506159c5565b601f19841661597486615764565b5f5b8281101561599b57848901358255600182019150602085019450602081019050615976565b868310156159b857848901356159b4601f8916826158ca565b8355505b6001600288020188555050505b50505050505050565b5f81546159da81615734565b6159e48186615634565b9450600182165f81146159fe5760018114615a1357615a45565b60ff1983168652811515820286019350615a45565b615a1c85615764565b5f5b83811015615a3d57815481890152600182019150602081019050615a1e565b838801955050505b50505092915050565b5f615a5982846159ce565b915081905092915050565b5f615a6f83856146a5565b9350615a7c838584614fc5565b615a85836146dd565b840190509392505050565b5f606082019050615aa35f8301876145ef565b615ab06020830186614c25565b8181036040830152615ac3818486615a64565b905095945050505050565b5f606082019050615ae15f830186614c25565b615aee6020830185614c25565b615afb6040830184614361565b949350505050565b7f50726f64756374206e6f742065786973747320796574000000000000000000005f82015250565b5f615b376016836146a5565b9150615b4282615b03565b602082019050919050565b5f6020820190508181035f830152615b6481615b2b565b9050919050565b5f6080820190508181035f830152615b8481888a615a64565b9050615b936020830187614c25565b615ba06040830186614c25565b8181036060830152615bb3818486615a64565b9050979650505050505050565b7f5468697320557365722069736e2774206120526567756c61746f7200000000005f82015250565b5f615bf4601b836146a5565b9150615bff82615bc0565b602082019050919050565b5f6020820190508181035f830152615c2181615be8565b9050919050565b7f546869732075736572206973206e6f7420617574686f72697a656400000000005f82015250565b5f615c5c601b836146a5565b9150615c6782615c28565b602082019050919050565b5f6020820190508181035f830152615c8981615c50565b9050919050565b7f5468652070726f64756374277320696e6465782069732077726f6e67000000005f82015250565b5f615cc4601c836146a5565b9150615ccf82615c90565b602082019050919050565b5f6020820190508181035f830152615cf181615cb8565b9050919050565b5f615d0482848661563e565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f615d4782614280565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615d7957615d78615d10565b5b600182019050919050565b615d8d8261469b565b67ffffffffffffffff811115615da657615da5614f1d565b5b615db08254615734565b615dbb828285615878565b5f60209050601f831160018114615dec575f8415615dda578287015190505b615de485826158e6565b865550615e4b565b601f198416615dfa86615764565b5f5b82811015615e2157848901518255600182019150602085019450602081019050615dfc565b86831015615e3e5784890151615e3a601f8916826158ca565b8355505b6001600288020188555050505b505050505050565b5f8154615e5f81615734565b615e6981866146a5565b9450600182165f8114615e835760018114615e9957615ecb565b60ff198316865281151560200286019350615ecb565b615ea285615764565b5f5b83811015615ec357815481890152600182019150602081019050615ea4565b808801955050505b50505092915050565b5f608082019050615ee75f830187614c25565b8181036020830152615ef98186615e53565b9050615f086040830185614361565b615f156060830184614361565b95945050505050565b5f615f288261469b565b615f328185615634565b9350615f428185602086016146b5565b80840191505092915050565b5f615f598284615f1e565b915081905092915050565b5f606082019050615f775f830186614c25565b615f846020830185614361565b615f916040830184614361565b949350505050565b7f5f747261636b49440000000000000000000000000000000000000000000000005f82015250565b5f615fcd6008836146a5565b9150615fd882615f99565b602082019050919050565b5f6060820190508181035f830152615ffa81615fc1565b9050818103602083015261600f818587615a64565b905061601e6040830184614c34565b949350505050565b5f6060820190508181035f83015261603f818789615a64565b90508181036020830152616054818587615a64565b90506160636040830184614c34565b9695505050505050565b7f5468652063757272656e74206f7065726174696f6e2069732077726f6e6700005f82015250565b5f6160a1601e836146a5565b91506160ac8261606d565b602082019050919050565b5f6020820190508181035f8301526160ce81616095565b9050919050565b7f54686520706172656e74206f7065726174696f6e2069732077726f6e670000005f82015250565b5f616109601d836146a5565b9150616114826160d5565b602082019050919050565b5f6020820190508181035f830152616136816160fd565b9050919050565b5f61614782614280565b915061615283614280565b925082820390508181111561616a57616169615d10565b5b9291505056fea26469706673582212208d62394dcce530f8adea8c8a4591a9b0dfc86aae87508c04861293a3d92f926a64736f6c63430008140033