false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here
- We're indexing this chain right now. Some of the counts may be inaccurate.

Contract Address Details

0x95E4C7CeD2EF6A3986780eE98995018e938a736A

Contract Name
SupplyChain
Creator
0xd752fc–692b2b at 0x37387a–138804
Balance
0 ADVETH
Tokens
Fetching tokens...
Transactions
74 Transactions
Transfers
0 Transfers
Gas Used
11,693,166
Last Balance Update
56
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