ETH Price: $2,266.71 (-6.47%)
Gas: 0.75 Gwei

Transaction Decoder

Block:
17525569 at Jun-21-2023 04:10:11 AM +UTC
Transaction Fee:
0.004410674940129624 ETH $10.00
Gas Used:
322,008 Gas / 13.697407953 Gwei

Emitted Events:

211 Holographer.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000579263329ee32bb5d0648c2bea4c81ed334c5fdb, 0x0000000000000000000000000000000000000000000000000000000000000005 )
212 HolographRegistryProxy.0xb4d3a3f85e85fdbd1d39f939d8c75355ec33ef437522432fe1a7b8b20bb4fab4( 0xb4d3a3f85e85fdbd1d39f939d8c75355ec33ef437522432fe1a7b8b20bb4fab4, 0x000000000000000000000000ba395f673df3ab856d8990097f704c34a4757b28, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000080, 351b8d13789e4d8d2717631559251955685881a31494dd0b8b19b4ef8530bb6d, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000579263329ee32bb5d0648c2bea4c81ed334c5fdb, 0000000000000000000000000000000000000000000000000000000000000005 )
213 HolographDropERC721Proxy.0x4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a90( 0x4e26b0356a15833a75d497ecc40ebbb716b99466ed0dba9454f1fff451e25a90, 0x000000000000000000000000579263329ee32bb5d0648c2bea4c81ed334c5fdb, 0x0000000000000000000000000000000000000000000000000000000000000001, 0x0000000000000000000000000000000000000000000000000013ac36b6349984, 0000000000000000000000000000000000000000000000000000000000000005 )

Account State Difference:

  Address   Before After State Difference Code
0x45E4B427...8AA822a23
0.022841997831470488 Eth0.028379373374084892 Eth0.005537375542614404
0x57926332...d334C5FDB
0.030821834207901327 Eth
Nonce: 2
0.020873783725157299 Eth
Nonce: 3
0.009948050482744028
0xbA395f67...4a4757b28
(Fee Recipient: 0xF0...C61)
15.651758037486244327 Eth15.651790238286244327 Eth0.0000322008

Execution Trace

ETH 0.005814211031239953 Holographer.efef39a1( )
  • Holograph.STATICCALL( )
  • HolographRegistryProxy.74b7510c( )
    • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
    • ETH 0.005814211031239953 HolographERC721.efef39a1( )
      • Holograph.STATICCALL( )
      • HolographInterfaces.supportsInterface( interfaceType=4, interfaceId=System.Byte[] ) => ( False )
      • ETH 0.005814211031239953 HolographDropERC721Proxy.efef39a1( )
        • HolographRegistryProxy.cc2913f9( )
          • HolographRegistry.getContractTypeAddress( contractType=00000000000000000000000000486F6C6F677261706844726F70455243373231 ) => ( 0x2372129cf57Cdb51bf9AB9f73a5Ad6AbE97Ab8A5 )
          • ETH 0.005814211031239953 HolographDropERC721.purchase( quantity=1 ) => ( 5 )
            • DropsPriceOracleProxy.f5d78161( )
              • DropsPriceOracleEthereum.convertUsdToWei( usdAmount=10000000 ) => ( weiAmount=5537375542614404 )
                • UniswapV2Pair.STATICCALL( )
                • UniswapV2Pair.STATICCALL( )
                • UniswapV2Pair.STATICCALL( )
                • UniswapV2Pair.STATICCALL( )
                • Holographer.STATICCALL( )
                  • Holograph.STATICCALL( )
                  • HolographRegistryProxy.74b7510c( )
                    • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
                    • HolographERC721.DELEGATECALL( )
                      • Holographer.STATICCALL( )
                      • Holograph.STATICCALL( )
                      • Holographer.STATICCALL( )
                      • Holographer.4f558e79( )
                        • Holograph.STATICCALL( )
                        • HolographRegistryProxy.74b7510c( )
                          • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
                          • HolographERC721.exists( tokenId=5 ) => ( False )
                          • Holographer.23250cae( )
                            • Holograph.STATICCALL( )
                            • HolographRegistryProxy.74b7510c( )
                              • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
                              • HolographERC721.burned( tokenId=5 ) => ( False )
                              • Holographer.3b4f1b26( )
                                • Holograph.STATICCALL( )
                                • HolographRegistryProxy.74b7510c( )
                                  • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
                                  • HolographERC721.sourceMint( to=0x579263329eE32bB5D0648c2BEA4C81ed334C5FDB, tokenId=5 )
                                    • Holographer.STATICCALL( )
                                    • Holograph.STATICCALL( )
                                    • Holographer.STATICCALL( )
                                    • Holograph.STATICCALL( )
                                    • HolographRegistryProxy.afa5886e( )
                                    • Holographer.STATICCALL( )
                                      • Holograph.STATICCALL( )
                                      • HolographRegistryProxy.74b7510c( )
                                        • HolographRegistry.getReservedContractTypeAddress( contractType=0000000000000000000000000000000000486F6C6F6772617068455243373231 ) => ( contractTypeAddress=0x91684155D5aCb612Ee16c8B5280442c6bBb4685b )
                                        • HolographERC721.DELEGATECALL( )
                                          • Holographer.STATICCALL( )
                                          • Holograph.STATICCALL( )
                                          • Holographer.STATICCALL( )
                                          • ETH 0.000276835488625549 0x579263329ee32bb5d0648c2bea4c81ed334c5fdb.CALL( )
                                            File 1 of 14: Holographer
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../abstract/Admin.sol";
                                            import "../abstract/Initializable.sol";
                                            import "../interface/HolographInterface.sol";
                                            import "../interface/HolographerInterface.sol";
                                            import "../interface/HolographRegistryInterface.sol";
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @dev This contract is a binder. It puts together all the variables to make the underlying contracts functional and be bridgeable.
                                             */
                                            contract Holographer is Admin, Initializable, HolographerInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.originChain')) - 1)
                                               */
                                              bytes32 constant _originChainSlot = 0xd49ffd6af8249d6e6b5963d9d2b22c6db30ad594cb468453047a14e1c1bcde4d;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.holograph')) - 1)
                                               */
                                              bytes32 constant _holographSlot = 0xb4107f746e9496e8452accc7de63d1c5e14c19f510932daa04077cd49e8bd77a;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.contractType')) - 1)
                                               */
                                              bytes32 constant _contractTypeSlot = 0x0b671eb65810897366dd82c4cbb7d9dff8beda8484194956e81e89b8a361d9c7;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.sourceContract')) - 1)
                                               */
                                              bytes32 constant _sourceContractSlot = 0x27d542086d1e831d40b749e7f5509a626c3047a36d160781c40d5acc83e5b074;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.blockHeight')) - 1)
                                               */
                                              bytes32 constant _blockHeightSlot = 0x9172848b0f1df776dc924b58e7fa303087ae0409bbf611608529e7f747d55de3;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPHER: already initialized");
                                                (bytes memory encoded, bytes memory initCode) = abi.decode(initPayload, (bytes, bytes));
                                                (uint32 originChain, address holograph, bytes32 contractType, address sourceContract) = abi.decode(
                                                  encoded,
                                                  (uint32, address, bytes32, address)
                                                );
                                                assembly {
                                                  sstore(_adminSlot, caller())
                                                  sstore(_blockHeightSlot, number())
                                                  sstore(_contractTypeSlot, contractType)
                                                  sstore(_holographSlot, holograph)
                                                  sstore(_originChainSlot, originChain)
                                                  sstore(_sourceContractSlot, sourceContract)
                                                }
                                                (bool success, bytes memory returnData) = HolographRegistryInterface(HolographInterface(holograph).getRegistry())
                                                  .getReservedContractTypeAddress(contractType)
                                                  .delegatecall(abi.encodeWithSelector(InitializableInterface.init.selector, initCode));
                                                bytes4 selector = abi.decode(returnData, (bytes4));
                                                require(success && selector == InitializableInterface.init.selector, "HOLOGRAPH: initialization failed");
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              /**
                                               * @dev Returns the contract type that is used for loading the Enforcer
                                               */
                                              function getContractType() external view returns (bytes32 contractType) {
                                                assembly {
                                                  contractType := sload(_contractTypeSlot)
                                                }
                                              }
                                              /**
                                               * @dev Returns the block height of when the smart contract was deployed. Useful for retrieving deployment config for re-deployment on other EVM-compatible chains.
                                               */
                                              function getDeploymentBlock() external view returns (uint256 deploymentBlock) {
                                                assembly {
                                                  deploymentBlock := sload(_blockHeightSlot)
                                                }
                                              }
                                              /**
                                               * @dev Returns a hardcoded address for the Holograph smart contract.
                                               */
                                              function getHolograph() external view returns (address holograph) {
                                                assembly {
                                                  holograph := sload(_holographSlot)
                                                }
                                              }
                                              /**
                                               * @dev Returns a hardcoded address for the Holograph smart contract that controls and enforces the ERC standards.
                                               */
                                              function getHolographEnforcer() public view returns (address) {
                                                HolographInterface holograph;
                                                bytes32 contractType;
                                                assembly {
                                                  holograph := sload(_holographSlot)
                                                  contractType := sload(_contractTypeSlot)
                                                }
                                                return HolographRegistryInterface(holograph.getRegistry()).getReservedContractTypeAddress(contractType);
                                              }
                                              /**
                                               * @dev Returns the original chain that contract was deployed on.
                                               */
                                              function getOriginChain() external view returns (uint32 originChain) {
                                                assembly {
                                                  originChain := sload(_originChainSlot)
                                                }
                                              }
                                              /**
                                               * @dev Returns a hardcoded address for the custom secure storage contract deployed in parallel with this contract deployment.
                                               */
                                              function getSourceContract() external view returns (address sourceContract) {
                                                assembly {
                                                  sourceContract := sload(_sourceContractSlot)
                                                }
                                              }
                                              /**
                                               * @dev Purposefully left empty, to prevent running out of gas errors when receiving native token payments.
                                               */
                                              receive() external payable {}
                                              /**
                                               * @dev This takes the Enforcer's source code, runs it, and uses current address for storage slots.
                                               */
                                              fallback() external payable {
                                                address holographEnforcer = getHolographEnforcer();
                                                assembly {
                                                  calldatacopy(0, 0, calldatasize())
                                                  let result := delegatecall(gas(), holographEnforcer, 0, calldatasize(), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            interface HolographInterface {
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge);
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external;
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId);
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory);
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external;
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId);
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces);
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external;
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator);
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external;
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry);
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external;
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury);
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external;
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken);
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographerInterface {
                                              function getContractType() external view returns (bytes32 contractType);
                                              function getDeploymentBlock() external view returns (uint256 deploymentBlock);
                                              function getHolograph() external view returns (address holograph);
                                              function getHolographEnforcer() external view returns (address);
                                              function getOriginChain() external view returns (uint32 originChain);
                                              function getSourceContract() external view returns (address sourceContract);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographRegistryInterface {
                                              function isHolographedContract(address smartContract) external view returns (bool);
                                              function isHolographedHashDeployed(bytes32 hash) external view returns (bool);
                                              function referenceContractTypeAddress(address contractAddress) external returns (bytes32);
                                              function getContractTypeAddress(bytes32 contractType) external view returns (address);
                                              function setContractTypeAddress(bytes32 contractType, address contractAddress) external;
                                              function getHolograph() external view returns (address holograph);
                                              function setHolograph(address holograph) external;
                                              function getHolographableContracts(uint256 index, uint256 length) external view returns (address[] memory contracts);
                                              function getHolographableContractsLength() external view returns (uint256);
                                              function getHolographedHashAddress(bytes32 hash) external view returns (address);
                                              function setHolographedHashAddress(bytes32 hash, address contractAddress) external;
                                              function getHToken(uint32 chainId) external view returns (address);
                                              function setHToken(uint32 chainId, address hToken) external;
                                              function getReservedContractTypeAddress(bytes32 contractType) external view returns (address contractTypeAddress);
                                              function setReservedContractTypeAddress(bytes32 hash, bool reserved) external;
                                              function setReservedContractTypeAddresses(bytes32[] calldata hashes, bool[] calldata reserved) external;
                                              function getUtilityToken() external view returns (address utilityToken);
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 2 of 14: HolographRegistryProxy
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../abstract/Admin.sol";
                                            import "../abstract/Initializable.sol";
                                            import "../interface/InitializableInterface.sol";
                                            contract HolographRegistryProxy is Admin, Initializable {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.registry')) - 1)
                                               */
                                              bytes32 constant _registrySlot = 0xce8e75d5c5227ce29a4ee170160bb296e5dea6934b80a9bd723f7ef1e7c850e7;
                                              constructor() {}
                                              function init(bytes memory data) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                (address registry, bytes memory initCode) = abi.decode(data, (address, bytes));
                                                assembly {
                                                  sstore(_adminSlot, origin())
                                                  sstore(_registrySlot, registry)
                                                }
                                                (bool success, bytes memory returnData) = registry.delegatecall(abi.encodeWithSignature("init(bytes)", initCode));
                                                bytes4 selector = abi.decode(returnData, (bytes4));
                                                require(success && selector == InitializableInterface.init.selector, "initialization failed");
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              function getRegistry() external view returns (address registry) {
                                                assembly {
                                                  registry := sload(_registrySlot)
                                                }
                                              }
                                              function setRegistry(address registry) external onlyAdmin {
                                                assembly {
                                                  sstore(_registrySlot, registry)
                                                }
                                              }
                                              receive() external payable {}
                                              fallback() external payable {
                                                assembly {
                                                  let registry := sload(_registrySlot)
                                                  calldatacopy(0, 0, calldatasize())
                                                  let result := delegatecall(gas(), registry, 0, calldatasize(), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 3 of 14: HolographDropERC721Proxy
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../../abstract/Admin.sol";
                                            import "../../abstract/Initializable.sol";
                                            import "../../interface/HolographRegistryInterface.sol";
                                            contract HolographDropERC721Proxy is Admin, Initializable {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.contractType')) - 1)
                                               */
                                              bytes32 constant _contractTypeSlot = 0x0b671eb65810897366dd82c4cbb7d9dff8beda8484194956e81e89b8a361d9c7;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.registry')) - 1)
                                               */
                                              bytes32 constant _registrySlot = 0xce8e75d5c5227ce29a4ee170160bb296e5dea6934b80a9bd723f7ef1e7c850e7;
                                              constructor() {}
                                              function init(bytes memory data) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                (bytes32 contractType, address registry, bytes memory initCode) = abi.decode(data, (bytes32, address, bytes));
                                                assembly {
                                                  sstore(_contractTypeSlot, contractType)
                                                  sstore(_registrySlot, registry)
                                                }
                                                (bool success, bytes memory returnData) = getHolographDropERC721Source().delegatecall(
                                                  abi.encodeWithSignature("init(bytes)", initCode)
                                                );
                                                bytes4 selector = abi.decode(returnData, (bytes4));
                                                require(success && selector == Initializable.init.selector, "initialization failed");
                                                _setInitialized();
                                                return Initializable.init.selector;
                                              }
                                              function getHolographDropERC721Source() public view returns (address) {
                                                HolographRegistryInterface registry;
                                                bytes32 contractType;
                                                assembly {
                                                  registry := sload(_registrySlot)
                                                  contractType := sload(_contractTypeSlot)
                                                }
                                                return registry.getContractTypeAddress(contractType);
                                              }
                                              receive() external payable {}
                                              fallback() external payable {
                                                address HolographDropERC721Source = getHolographDropERC721Source();
                                                assembly {
                                                  calldatacopy(0, 0, calldatasize())
                                                  let result := delegatecall(gas(), HolographDropERC721Source, 0, calldatasize(), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographRegistryInterface {
                                              function isHolographedContract(address smartContract) external view returns (bool);
                                              function isHolographedHashDeployed(bytes32 hash) external view returns (bool);
                                              function referenceContractTypeAddress(address contractAddress) external returns (bytes32);
                                              function getContractTypeAddress(bytes32 contractType) external view returns (address);
                                              function setContractTypeAddress(bytes32 contractType, address contractAddress) external;
                                              function getHolograph() external view returns (address holograph);
                                              function setHolograph(address holograph) external;
                                              function getHolographableContracts(uint256 index, uint256 length) external view returns (address[] memory contracts);
                                              function getHolographableContractsLength() external view returns (uint256);
                                              function getHolographedHashAddress(bytes32 hash) external view returns (address);
                                              function setHolographedHashAddress(bytes32 hash, address contractAddress) external;
                                              function getHToken(uint32 chainId) external view returns (address);
                                              function setHToken(uint32 chainId, address hToken) external;
                                              function getReservedContractTypeAddress(bytes32 contractType) external view returns (address contractTypeAddress);
                                              function setReservedContractTypeAddress(bytes32 hash, bool reserved) external;
                                              function setReservedContractTypeAddresses(bytes32[] calldata hashes, bool[] calldata reserved) external;
                                              function getUtilityToken() external view returns (address utilityToken);
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 4 of 14: Holograph
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./abstract/Admin.sol";
                                            import "./abstract/Initializable.sol";
                                            import "./interface/InitializableInterface.sol";
                                            import "./interface/HolographInterface.sol";
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            contract Holograph is Admin, Initializable, HolographInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.bridge')) - 1)
                                               */
                                              bytes32 constant _bridgeSlot = 0xeb87cbb21687feb327e3d58c6c16d552231d12c7a0e8115042a4165fac8a77f9;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.chainId')) - 1)
                                               */
                                              bytes32 constant _chainIdSlot = 0x7651bfc11f7485d07ab2b41c1312e2007c8cb7efb0f7352a6dee4a1153eebab2;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.factory')) - 1)
                                               */
                                              bytes32 constant _factorySlot = 0xa49f20855ba576e09d13c8041c8039fa655356ea27f6c40f1ec46a4301cd5b23;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.holographChainId')) - 1)
                                               */
                                              bytes32 constant _holographChainIdSlot = 0xd840a780c26e07edc6e1ee2eaa6f134ed5488dbd762614116653cee8542a3844;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.interfaces')) - 1)
                                               */
                                              bytes32 constant _interfacesSlot = 0xbd3084b8c09da87ad159c247a60e209784196be2530cecbbd8f337fdd1848827;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.operator')) - 1)
                                               */
                                              bytes32 constant _operatorSlot = 0x7caba557ad34138fa3b7e43fb574e0e6cc10481c3073e0dffbc560db81b5c60f;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.registry')) - 1)
                                               */
                                              bytes32 constant _registrySlot = 0xce8e75d5c5227ce29a4ee170160bb296e5dea6934b80a9bd723f7ef1e7c850e7;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.treasury')) - 1)
                                               */
                                              bytes32 constant _treasurySlot = 0x4215e7a38d75164ca078bbd61d0992cdeb1ba16f3b3ead5944966d3e4080e8b6;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.utilityToken')) - 1)
                                               */
                                              bytes32 constant _utilityTokenSlot = 0xbf76518d46db472b71aa7677a0908b8016f3dee568415ffa24055f9a670f9c37;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                (
                                                  uint32 holographChainId,
                                                  address bridge,
                                                  address factory,
                                                  address interfaces,
                                                  address operator,
                                                  address registry,
                                                  address treasury,
                                                  address utilityToken
                                                ) = abi.decode(initPayload, (uint32, address, address, address, address, address, address, address));
                                                assembly {
                                                  sstore(_adminSlot, origin())
                                                  sstore(_chainIdSlot, chainid())
                                                  sstore(_holographChainIdSlot, holographChainId)
                                                  sstore(_bridgeSlot, bridge)
                                                  sstore(_factorySlot, factory)
                                                  sstore(_interfacesSlot, interfaces)
                                                  sstore(_operatorSlot, operator)
                                                  sstore(_registrySlot, registry)
                                                  sstore(_treasurySlot, treasury)
                                                  sstore(_utilityTokenSlot, utilityToken)
                                                }
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge) {
                                                assembly {
                                                  bridge := sload(_bridgeSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external onlyAdmin {
                                                assembly {
                                                  sstore(_bridgeSlot, bridge)
                                                }
                                              }
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId) {
                                                assembly {
                                                  chainId := sload(_chainIdSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external onlyAdmin {
                                                assembly {
                                                  sstore(_chainIdSlot, chainId)
                                                }
                                              }
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory) {
                                                assembly {
                                                  factory := sload(_factorySlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external onlyAdmin {
                                                assembly {
                                                  sstore(_factorySlot, factory)
                                                }
                                              }
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId) {
                                                assembly {
                                                  holographChainId := sload(_holographChainIdSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external onlyAdmin {
                                                assembly {
                                                  sstore(_holographChainIdSlot, holographChainId)
                                                }
                                              }
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces) {
                                                assembly {
                                                  interfaces := sload(_interfacesSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external onlyAdmin {
                                                assembly {
                                                  sstore(_interfacesSlot, interfaces)
                                                }
                                              }
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator) {
                                                assembly {
                                                  operator := sload(_operatorSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external onlyAdmin {
                                                assembly {
                                                  sstore(_operatorSlot, operator)
                                                }
                                              }
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry) {
                                                assembly {
                                                  registry := sload(_registrySlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external onlyAdmin {
                                                assembly {
                                                  sstore(_registrySlot, registry)
                                                }
                                              }
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury) {
                                                assembly {
                                                  treasury := sload(_treasurySlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external onlyAdmin {
                                                assembly {
                                                  sstore(_treasurySlot, treasury)
                                                }
                                              }
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken) {
                                                assembly {
                                                  utilityToken := sload(_utilityTokenSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external onlyAdmin {
                                                assembly {
                                                  sstore(_utilityTokenSlot, utilityToken)
                                                }
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent having any type of ether transfered into the contract
                                               */
                                              receive() external payable {
                                                revert();
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent any calls to undefined functions
                                               */
                                              fallback() external payable {
                                                revert();
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            interface HolographInterface {
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge);
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external;
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId);
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory);
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external;
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId);
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces);
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external;
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator);
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external;
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry);
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external;
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury);
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external;
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken);
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            

                                            File 5 of 14: HolographRegistry
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./abstract/Admin.sol";
                                            import "./abstract/Initializable.sol";
                                            import "./interface/HolographInterface.sol";
                                            import "./interface/HolographRegistryInterface.sol";
                                            import "./interface/InitializableInterface.sol";
                                            /**
                                             * @title Holograph Registry
                                             * @author https://github.com/holographxyz
                                             * @notice View and validate all deployed holographable contracts
                                             * @dev Use this to: validate that contracts are Holograph Protocol compliant, get source code for supported standards, and interact with hTokens
                                             */
                                            contract HolographRegistry is Admin, Initializable, HolographRegistryInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.holograph')) - 1)
                                               */
                                              bytes32 constant _holographSlot = 0xb4107f746e9496e8452accc7de63d1c5e14c19f510932daa04077cd49e8bd77a;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.utilityToken')) - 1)
                                               */
                                              bytes32 constant _utilityTokenSlot = 0xbf76518d46db472b71aa7677a0908b8016f3dee568415ffa24055f9a670f9c37;
                                              /**
                                               * @dev Array of all Holographable contracts that were ever deployed on this chain
                                               */
                                              address[] private _holographableContracts;
                                              /**
                                               * @dev A mapping of hashes to contract addresses
                                               */
                                              mapping(bytes32 => address) private _holographedContractsHashMap;
                                              /**
                                               * @dev Storage slot for saving contract type to contract address references
                                               */
                                              mapping(bytes32 => address) private _contractTypeAddresses;
                                              /**
                                               * @dev Reserved type addresses for Admin
                                               *  Note: this is used for defining default contracts
                                               */
                                              mapping(bytes32 => bool) private _reservedTypes;
                                              /**
                                               * @dev A list of smart contracts that are guaranteed secure and holographable
                                               */
                                              mapping(address => bool) private _holographedContracts;
                                              /**
                                               * @dev Mapping of all hTokens available for the different EVM chains
                                               */
                                              mapping(uint32 => address) private _hTokens;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                (address holograph, bytes32[] memory reservedTypes) = abi.decode(initPayload, (address, bytes32[]));
                                                assembly {
                                                  sstore(_adminSlot, origin())
                                                  sstore(_holographSlot, holograph)
                                                }
                                                for (uint256 i = 0; i < reservedTypes.length; i++) {
                                                  _reservedTypes[reservedTypes[i]] = true;
                                                }
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              function isHolographedContract(address smartContract) external view returns (bool) {
                                                return _holographedContracts[smartContract];
                                              }
                                              function isHolographedHashDeployed(bytes32 hash) external view returns (bool) {
                                                return _holographedContractsHashMap[hash] != address(0);
                                              }
                                              function holographableEvent(bytes calldata payload) external {
                                                require(_holographedContracts[msg.sender], "HOLOGRAPH: not holographed");
                                                emit HolographableContractEvent(msg.sender, payload);
                                              }
                                              /**
                                               * @dev Allows to reference a deployed smart contract, and use it's code as reference inside of Holographers
                                               */
                                              function referenceContractTypeAddress(address contractAddress) external returns (bytes32) {
                                                bytes32 contractType;
                                                assembly {
                                                  contractType := extcodehash(contractAddress)
                                                }
                                                require((contractType != 0x0 && contractType != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470), "HOLOGRAPH: empty contract");
                                                require(_contractTypeAddresses[contractType] == address(0), "HOLOGRAPH: contract already set");
                                                require(!_reservedTypes[contractType], "HOLOGRAPH: reserved address type");
                                                _contractTypeAddresses[contractType] = contractAddress;
                                                return contractType;
                                              }
                                              /**
                                               * @dev Returns the contract address for a contract type
                                               */
                                              function getContractTypeAddress(bytes32 contractType) external view returns (address) {
                                                return _contractTypeAddresses[contractType];
                                              }
                                              /**
                                               * @dev Sets the contract address for a contract type
                                               */
                                              function setContractTypeAddress(bytes32 contractType, address contractAddress) external onlyAdmin {
                                                require(_reservedTypes[contractType], "HOLOGRAPH: not reserved type");
                                                _contractTypeAddresses[contractType] = contractAddress;
                                              }
                                              /**
                                               * @notice Get the Holograph Protocol contract
                                               * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                               */
                                              function getHolograph() external view returns (address holograph) {
                                                assembly {
                                                  holograph := sload(_holographSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Protocol contract address
                                               * @param holograph address of the Holograph Protocol smart contract to use
                                               */
                                              function setHolograph(address holograph) external onlyAdmin {
                                                assembly {
                                                  sstore(_holographSlot, holograph)
                                                }
                                              }
                                              /**
                                               * @notice Get set length list, starting from index, for all holographable contracts
                                               * @param index The index to start enumeration from
                                               * @param length The length of returned results
                                               * @return contracts address[] Returns a set length array of holographable contracts deployed
                                               */
                                              function getHolographableContracts(uint256 index, uint256 length) external view returns (address[] memory contracts) {
                                                uint256 supply = _holographableContracts.length;
                                                if (index + length > supply) {
                                                  length = supply - index;
                                                }
                                                contracts = new address[](length);
                                                for (uint256 i = 0; i < length; i++) {
                                                  contracts[i] = _holographableContracts[index + i];
                                                }
                                              }
                                              /**
                                               * @notice Get total number of deployed holographable contracts
                                               */
                                              function getHolographableContractsLength() external view returns (uint256) {
                                                return _holographableContracts.length;
                                              }
                                              /**
                                               * @dev Returns the address for a holographed hash
                                               */
                                              function getHolographedHashAddress(bytes32 hash) external view returns (address) {
                                                return _holographedContractsHashMap[hash];
                                              }
                                              /**
                                               * @dev Allows Holograph Factory to register a deployed contract, referenced with deployment hash
                                               */
                                              function setHolographedHashAddress(bytes32 hash, address contractAddress) external {
                                                address holograph;
                                                assembly {
                                                  holograph := sload(_holographSlot)
                                                }
                                                require(msg.sender == HolographInterface(holograph).getFactory(), "HOLOGRAPH: factory only function");
                                                _holographedContractsHashMap[hash] = contractAddress;
                                                _holographedContracts[contractAddress] = true;
                                                _holographableContracts.push(contractAddress);
                                              }
                                              /**
                                               * @dev Returns the hToken address for a given chain id
                                               */
                                              function getHToken(uint32 chainId) external view returns (address) {
                                                return _hTokens[chainId];
                                              }
                                              /**
                                               * @dev Sets the hToken address for a specific chain id
                                               */
                                              function setHToken(uint32 chainId, address hToken) external onlyAdmin {
                                                _hTokens[chainId] = hToken;
                                              }
                                              /**
                                               * @dev Returns the reserved contract address for a contract type
                                               */
                                              function getReservedContractTypeAddress(bytes32 contractType) external view returns (address contractTypeAddress) {
                                                if (_reservedTypes[contractType]) {
                                                  contractTypeAddress = _contractTypeAddresses[contractType];
                                                }
                                              }
                                              /**
                                               * @dev Allows admin to update or toggle reserved type
                                               */
                                              function setReservedContractTypeAddress(bytes32 hash, bool reserved) external onlyAdmin {
                                                _reservedTypes[hash] = reserved;
                                              }
                                              /**
                                               * @dev Allows admin to update or toggle reserved types
                                               */
                                              function setReservedContractTypeAddresses(bytes32[] calldata hashes, bool[] calldata reserved) external onlyAdmin {
                                                for (uint256 i = 0; i < hashes.length; i++) {
                                                  _reservedTypes[hashes[i]] = reserved[i];
                                                }
                                              }
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken) {
                                                assembly {
                                                  utilityToken := sload(_utilityTokenSlot)
                                                }
                                              }
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external onlyAdmin {
                                                assembly {
                                                  sstore(_utilityTokenSlot, utilityToken)
                                                }
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent having any type of ether transfered into the contract
                                               */
                                              receive() external payable {
                                                revert();
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent any calls to undefined functions
                                               */
                                              fallback() external payable {
                                                revert();
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            interface HolographInterface {
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge);
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external;
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId);
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory);
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external;
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId);
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces);
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external;
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator);
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external;
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry);
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external;
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury);
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external;
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken);
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographRegistryInterface {
                                              event HolographableContractEvent(address indexed _holographableContract, bytes _payload);
                                              function isHolographedContract(address smartContract) external view returns (bool);
                                              function isHolographedHashDeployed(bytes32 hash) external view returns (bool);
                                              function referenceContractTypeAddress(address contractAddress) external returns (bytes32);
                                              function getContractTypeAddress(bytes32 contractType) external view returns (address);
                                              function setContractTypeAddress(bytes32 contractType, address contractAddress) external;
                                              function getHolograph() external view returns (address holograph);
                                              function setHolograph(address holograph) external;
                                              function getHolographableContracts(uint256 index, uint256 length) external view returns (address[] memory contracts);
                                              function getHolographableContractsLength() external view returns (uint256);
                                              function getHolographedHashAddress(bytes32 hash) external view returns (address);
                                              function setHolographedHashAddress(bytes32 hash, address contractAddress) external;
                                              function getHToken(uint32 chainId) external view returns (address);
                                              function setHToken(uint32 chainId, address hToken) external;
                                              function getReservedContractTypeAddress(bytes32 contractType) external view returns (address contractTypeAddress);
                                              function setReservedContractTypeAddress(bytes32 hash, bool reserved) external;
                                              function setReservedContractTypeAddresses(bytes32[] calldata hashes, bool[] calldata reserved) external;
                                              function getUtilityToken() external view returns (address utilityToken);
                                              function setUtilityToken(address utilityToken) external;
                                              function holographableEvent(bytes calldata payload) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 6 of 14: HolographERC721
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Owner {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.owner')) - 1)
                                               */
                                              bytes32 constant _ownerSlot = 0xb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf772777;
                                              /**
                                               * @dev Event emitted when contract owner is changed.
                                               */
                                              event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                                              modifier onlyOwner() virtual {
                                                require(msg.sender == getOwner(), "HOLOGRAPH: owner only function");
                                                _;
                                              }
                                              function owner() external view virtual returns (address) {
                                                return getOwner();
                                              }
                                              constructor() {}
                                              function getOwner() public view returns (address ownerAddress) {
                                                assembly {
                                                  ownerAddress := sload(_ownerSlot)
                                                }
                                              }
                                              function setOwner(address ownerAddress) public virtual onlyOwner {
                                                address previousOwner = getOwner();
                                                assembly {
                                                  sstore(_ownerSlot, ownerAddress)
                                                }
                                                emit OwnershipTransferred(previousOwner, ownerAddress);
                                              }
                                              function transferOwnership(address newOwner) public onlyOwner {
                                                require(newOwner != address(0), "HOLOGRAPH: zero address");
                                                assembly {
                                                  sstore(_ownerSlot, newOwner)
                                                }
                                              }
                                              function ownerCall(address target, bytes calldata data) external payable onlyOwner {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../abstract/Admin.sol";
                                            import "../abstract/Initializable.sol";
                                            import "../abstract/Owner.sol";
                                            import "../enum/HolographERC721Event.sol";
                                            import "../enum/InterfaceType.sol";
                                            import "../interface/ERC165.sol";
                                            import "../interface/ERC721.sol";
                                            import "../interface/HolographERC721Interface.sol";
                                            import "../interface/ERC721Metadata.sol";
                                            import "../interface/ERC721TokenReceiver.sol";
                                            import "../interface/Holographable.sol";
                                            import "../interface/HolographedERC721.sol";
                                            import "../interface/HolographInterface.sol";
                                            import "../interface/HolographerInterface.sol";
                                            import "../interface/HolographRegistryInterface.sol";
                                            import "../interface/InitializableInterface.sol";
                                            import "../interface/HolographInterfacesInterface.sol";
                                            import "../interface/HolographRoyaltiesInterface.sol";
                                            import "../interface/Ownable.sol";
                                            /**
                                             * @title Holograph Bridgeable ERC-721 Collection
                                             * @author Holograph Foundation
                                             * @notice A smart contract for minting and managing Holograph Bridgeable ERC721 NFTs.
                                             * @dev The entire logic and functionality of the smart contract is self-contained.
                                             */
                                            contract HolographERC721 is Admin, Owner, HolographERC721Interface, Initializable {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.holograph')) - 1)
                                               */
                                              bytes32 constant _holographSlot = 0xb4107f746e9496e8452accc7de63d1c5e14c19f510932daa04077cd49e8bd77a;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.sourceContract')) - 1)
                                               */
                                              bytes32 constant _sourceContractSlot = 0x27d542086d1e831d40b749e7f5509a626c3047a36d160781c40d5acc83e5b074;
                                              /**
                                               * @dev Configuration for events to trigger for source smart contract.
                                               */
                                              uint256 private _eventConfig;
                                              /**
                                               * @dev Collection name.
                                               */
                                              string private _name;
                                              /**
                                               * @dev Collection symbol.
                                               */
                                              string private _symbol;
                                              /**
                                               * @dev Collection royalty base points.
                                               */
                                              uint16 private _bps;
                                              /**
                                               * @dev Array of all token ids in collection.
                                               */
                                              uint256[] private _allTokens;
                                              /**
                                               * @dev Map of token id to array index of _ownedTokens.
                                               */
                                              mapping(uint256 => uint256) private _ownedTokensIndex;
                                              /**
                                               * @dev Token id to wallet (owner) address map.
                                               */
                                              mapping(uint256 => address) private _tokenOwner;
                                              /**
                                               * @dev 1-to-1 map of token id that was assigned an approved operator address.
                                               */
                                              mapping(uint256 => address) private _tokenApprovals;
                                              /**
                                               * @dev Map of total tokens owner by a specific address.
                                               */
                                              mapping(address => uint256) private _ownedTokensCount;
                                              /**
                                               * @dev Map of array of token ids owned by a specific address.
                                               */
                                              mapping(address => uint256[]) private _ownedTokens;
                                              /**
                                               * @notice Map of full operator approval for a particular address.
                                               * @dev Usually utilised for supporting marketplace proxy wallets.
                                               */
                                              mapping(address => mapping(address => bool)) private _operatorApprovals;
                                              /**
                                               * @dev Mapping from token id to position in the allTokens array.
                                               */
                                              mapping(uint256 => uint256) private _allTokensIndex;
                                              /**
                                               * @dev Mapping of all token ids that have been burned. This is to prevent re-minting of same token ids.
                                               */
                                              mapping(uint256 => bool) private _burnedTokens;
                                              /**
                                               * @notice Only allow calls from bridge smart contract.
                                               */
                                              modifier onlyBridge() {
                                                require(msg.sender == _holograph().getBridge(), "ERC721: bridge only call");
                                                _;
                                              }
                                              /**
                                               * @notice Only allow calls from source smart contract.
                                               */
                                              modifier onlySource() {
                                                address sourceContract;
                                                assembly {
                                                  sourceContract := sload(_sourceContractSlot)
                                                }
                                                require(msg.sender == sourceContract, "ERC721: source only call");
                                                _;
                                              }
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "ERC721: already initialized");
                                                InitializableInterface sourceContract;
                                                assembly {
                                                  sstore(_ownerSlot, caller())
                                                  sourceContract := sload(_sourceContractSlot)
                                                }
                                                (
                                                  string memory contractName,
                                                  string memory contractSymbol,
                                                  uint16 contractBps,
                                                  uint256 eventConfig,
                                                  bool skipInit,
                                                  bytes memory initCode
                                                ) = abi.decode(initPayload, (string, string, uint16, uint256, bool, bytes));
                                                _name = contractName;
                                                _symbol = contractSymbol;
                                                _bps = contractBps;
                                                _eventConfig = eventConfig;
                                                if (!skipInit) {
                                                  require(sourceContract.init(initCode) == InitializableInterface.init.selector, "ERC721: could not init source");
                                                  (bool success, bytes memory returnData) = _royalties().delegatecall(
                                                    abi.encodeWithSelector(
                                                      HolographRoyaltiesInterface.initHolographRoyalties.selector,
                                                      abi.encode(uint256(contractBps), uint256(0))
                                                    )
                                                  );
                                                  bytes4 selector = abi.decode(returnData, (bytes4));
                                                  require(success && selector == InitializableInterface.init.selector, "ERC721: could not init royalties");
                                                }
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              /**
                                               * @notice Gets a base64 encoded contract JSON file.
                                               * @return string The URI.
                                               */
                                              function contractURI() external view returns (string memory) {
                                                if (_isEventRegistered(HolographERC721Event.customContractURI)) {
                                                  assembly {
                                                    calldatacopy(0, 0, calldatasize())
                                                    mstore(calldatasize(), caller())
                                                    let result := staticcall(gas(), sload(_sourceContractSlot), 0, add(calldatasize(), 0x20), 0, 0)
                                                    returndatacopy(0, 0, returndatasize())
                                                    switch result
                                                    case 0 {
                                                      revert(0, returndatasize())
                                                    }
                                                    default {
                                                      return(0, returndatasize())
                                                    }
                                                  }
                                                }
                                                return HolographInterfacesInterface(_interfaces()).contractURI(_name, "", "", _bps, address(this));
                                              }
                                              /**
                                               * @notice Gets the name of the collection.
                                               * @return string The collection name.
                                               */
                                              function name() external view returns (string memory) {
                                                return _name;
                                              }
                                              /**
                                               * @notice Shows the interfaces the contracts support
                                               * @dev Must add new 4 byte interface Ids here to acknowledge support
                                               * @param interfaceId ERC165 style 4 byte interfaceId.
                                               * @return bool True if supported.
                                               */
                                              function supportsInterface(bytes4 interfaceId) external view returns (bool) {
                                                HolographInterfacesInterface interfaces = HolographInterfacesInterface(_interfaces());
                                                ERC165 erc165Contract;
                                                assembly {
                                                  erc165Contract := sload(_sourceContractSlot)
                                                }
                                                if (
                                                  interfaces.supportsInterface(InterfaceType.ERC721, interfaceId) || // check global interfaces
                                                  interfaces.supportsInterface(InterfaceType.ROYALTIES, interfaceId) || // check if royalties supports interface
                                                  erc165Contract.supportsInterface(interfaceId) // check if source supports interface
                                                ) {
                                                  return true;
                                                } else {
                                                  return false;
                                                }
                                              }
                                              /**
                                               * @notice Gets the collection's symbol.
                                               * @return string The symbol.
                                               */
                                              function symbol() external view returns (string memory) {
                                                return _symbol;
                                              }
                                              /**
                                               * @notice Get's the URI of the token.
                                               * @dev Defaults the the Arweave URI
                                               * @return string The URI.
                                               */
                                              function tokenURI(uint256 tokenId) external view returns (string memory) {
                                                require(_exists(tokenId), "ERC721: token does not exist");
                                                assembly {
                                                  calldatacopy(0, 0, calldatasize())
                                                  mstore(calldatasize(), caller())
                                                  let result := staticcall(gas(), sload(_sourceContractSlot), 0, add(calldatasize(), 0x20), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                              /**
                                               * @notice Get list of tokens owned by wallet.
                                               * @param wallet The wallet address to get tokens for.
                                               * @return uint256[] Returns an array of token ids owned by wallet.
                                               */
                                              function tokensOfOwner(address wallet) external view returns (uint256[] memory) {
                                                return _ownedTokens[wallet];
                                              }
                                              /**
                                               * @notice Get set length list, starting from index, for tokens owned by wallet.
                                               * @param wallet The wallet address to get tokens for.
                                               * @param index The index to start enumeration from.
                                               * @param length The length of returned results.
                                               * @return tokenIds uint256[] Returns a set length array of token ids owned by wallet.
                                               */
                                              function tokensOfOwner(
                                                address wallet,
                                                uint256 index,
                                                uint256 length
                                              ) external view returns (uint256[] memory tokenIds) {
                                                uint256 supply = _ownedTokensCount[wallet];
                                                if (index + length > supply) {
                                                  length = supply - index;
                                                }
                                                tokenIds = new uint256[](length);
                                                for (uint256 i = 0; i < length; i++) {
                                                  tokenIds[i] = _ownedTokens[wallet][index + i];
                                                }
                                              }
                                              /**
                                               * @notice Adds a new address to the token's approval list.
                                               * @dev Requires the sender to be in the approved addresses.
                                               * @param to The address to approve.
                                               * @param tokenId The affected token.
                                               */
                                              function approve(address to, uint256 tokenId) external payable {
                                                address tokenOwner = _tokenOwner[tokenId];
                                                require(to != tokenOwner, "ERC721: cannot approve self");
                                                require(_isApprovedStrict(msg.sender, tokenId), "ERC721: not approved sender");
                                                if (_isEventRegistered(HolographERC721Event.beforeApprove)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.beforeApprove.selector, tokenOwner, to, tokenId)));
                                                }
                                                _tokenApprovals[tokenId] = to;
                                                emit Approval(tokenOwner, to, tokenId);
                                                if (_isEventRegistered(HolographERC721Event.afterApprove)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.afterApprove.selector, tokenOwner, to, tokenId)));
                                                }
                                              }
                                              /**
                                               * @notice Burns the token.
                                               * @dev The sender must be the owner or approved.
                                               * @param tokenId The token to burn.
                                               */
                                              function burn(uint256 tokenId) external {
                                                require(_isApproved(msg.sender, tokenId), "ERC721: not approved sender");
                                                address wallet = _tokenOwner[tokenId];
                                                if (_isEventRegistered(HolographERC721Event.beforeBurn)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.beforeBurn.selector, wallet, tokenId)));
                                                }
                                                _burn(wallet, tokenId);
                                                if (_isEventRegistered(HolographERC721Event.afterBurn)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.afterBurn.selector, wallet, tokenId)));
                                                }
                                              }
                                              function bridgeIn(uint32 fromChain, bytes calldata payload) external onlyBridge returns (bytes4) {
                                                (address from, address to, uint256 tokenId, bytes memory data) = abi.decode(
                                                  payload,
                                                  (address, address, uint256, bytes)
                                                );
                                                require(!_exists(tokenId), "ERC721: token already exists");
                                                delete _burnedTokens[tokenId];
                                                _mint(to, tokenId);
                                                if (_isEventRegistered(HolographERC721Event.bridgeIn)) {
                                                  require(
                                                    _sourceCall(abi.encodeWithSelector(HolographedERC721.bridgeIn.selector, fromChain, from, to, tokenId, data)),
                                                    "HOLOGRAPH: bridge in failed"
                                                  );
                                                }
                                                return Holographable.bridgeIn.selector;
                                              }
                                              function bridgeOut(
                                                uint32 toChain,
                                                address sender,
                                                bytes calldata payload
                                              ) external onlyBridge returns (bytes4 selector, bytes memory data) {
                                                (address from, address to, uint256 tokenId) = abi.decode(payload, (address, address, uint256));
                                                require(to != address(0), "ERC721: zero address");
                                                require(_isApproved(sender, tokenId), "ERC721: sender not approved");
                                                require(from == _tokenOwner[tokenId], "ERC721: from is not owner");
                                                if (_isEventRegistered(HolographERC721Event.bridgeOut)) {
                                                  /*
                                                   * @dev making a bridgeOut call to source contract
                                                   *      assembly is used so that msg.sender can be injected in the calldata
                                                   */
                                                  bytes memory sourcePayload = abi.encodeWithSelector(
                                                    HolographedERC721.bridgeOut.selector,
                                                    toChain,
                                                    from,
                                                    to,
                                                    tokenId
                                                  );
                                                  assembly {
                                                    // it is important to add 32 bytes in order to accommodate the first 32 bytes being used for storing length of bytes
                                                    mstore(add(sourcePayload, add(mload(sourcePayload), 0x20)), caller())
                                                    let result := call(
                                                      gas(),
                                                      sload(_sourceContractSlot),
                                                      callvalue(),
                                                      // start reading data from memory position, plus 32 bytes, to skip bytes length indicator
                                                      add(sourcePayload, 0x20),
                                                      // add an additional 32 bytes to bytes length to include the appended caller address
                                                      add(mload(sourcePayload), 0x20),
                                                      0,
                                                      0
                                                    )
                                                    // when reading back data, skip the first 32 bytes which is used to indicate bytes position in calldata
                                                    // also subtract 32 bytes from returndatasize to accomodate the skipped first 32 bytes
                                                    returndatacopy(data, 0x20, sub(returndatasize(), 0x20))
                                                    switch result
                                                    case 0 {
                                                      revert(0, returndatasize())
                                                    }
                                                  }
                                                }
                                                _burn(from, tokenId);
                                                return (Holographable.bridgeOut.selector, abi.encode(from, to, tokenId, data));
                                              }
                                              /**
                                               * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
                                               * are aware of the ERC721 protocol to prevent tokens from being forever locked.
                                               * @param from cannot be the zero address.
                                               * @param to cannot be the zero address.
                                               * @param tokenId token must exist and be owned by `from`.
                                               */
                                              function safeTransferFrom(address from, address to, uint256 tokenId) external payable {
                                                safeTransferFrom(from, to, tokenId, "");
                                              }
                                              /**
                                               * @notice Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
                                               * @dev Since it's not being used, the _data variable is commented out to avoid compiler warnings.
                                               * are aware of the ERC721 protocol to prevent tokens from being forever locked.
                                               * @param from cannot be the zero address.
                                               * @param to cannot be the zero address.
                                               * @param tokenId token must exist and be owned by `from`.
                                               */
                                              function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable {
                                                require(_isApproved(msg.sender, tokenId), "ERC721: not approved sender");
                                                if (_isEventRegistered(HolographERC721Event.beforeSafeTransfer)) {
                                                  require(
                                                    _sourceCall(abi.encodeWithSelector(HolographedERC721.beforeSafeTransfer.selector, from, to, tokenId, data))
                                                  );
                                                }
                                                _transferFrom(from, to, tokenId);
                                                if (_isContract(to)) {
                                                  require(
                                                    ERC721TokenReceiver(to).onERC721Received(msg.sender, from, tokenId, data) ==
                                                      ERC721TokenReceiver.onERC721Received.selector,
                                                    "ERC721: onERC721Received fail"
                                                  );
                                                }
                                                if (_isEventRegistered(HolographERC721Event.afterSafeTransfer)) {
                                                  require(
                                                    _sourceCall(abi.encodeWithSelector(HolographedERC721.afterSafeTransfer.selector, from, to, tokenId, data))
                                                  );
                                                }
                                              }
                                              /**
                                               * @notice Adds a new approved operator.
                                               * @dev Allows platforms to sell/transfer all your NFTs. Used with proxy contracts like OpenSea/Rarible.
                                               * @param to The address to approve.
                                               * @param approved Turn on or off approval status.
                                               */
                                              function setApprovalForAll(address to, bool approved) external {
                                                require(to != msg.sender, "ERC721: cannot approve self");
                                                if (_isEventRegistered(HolographERC721Event.beforeApprovalAll)) {
                                                  require(
                                                    _sourceCall(abi.encodeWithSelector(HolographedERC721.beforeApprovalAll.selector, msg.sender, to, approved))
                                                  );
                                                }
                                                _operatorApprovals[msg.sender][to] = approved;
                                                emit ApprovalForAll(msg.sender, to, approved);
                                                if (_isEventRegistered(HolographERC721Event.afterApprovalAll)) {
                                                  require(
                                                    _sourceCall(abi.encodeWithSelector(HolographedERC721.afterApprovalAll.selector, msg.sender, to, approved))
                                                  );
                                                }
                                              }
                                              /**
                                               * @dev Allows for source smart contract to burn a token.
                                               *  Note: this is put in place to make sure that custom logic could be implemented for merging, gamification, etc.
                                               *  Note: token cannot be burned if it's locked by bridge.
                                               */
                                              function sourceBurn(uint256 tokenId) external onlySource {
                                                address wallet = _tokenOwner[tokenId];
                                                _burn(wallet, tokenId);
                                              }
                                              /**
                                               * @dev Allows for source smart contract to mint a token.
                                               */
                                              function sourceMint(address to, uint224 tokenId) external onlySource {
                                                // uint32 is reserved for chain id to be used
                                                // we need to get current chain id, and prepend it to tokenId
                                                // this will prevent possible tokenId overlap if minting simultaneously on multiple chains is possible
                                                uint256 token = uint256(bytes32(abi.encodePacked(_chain(), tokenId)));
                                                require(!_burnedTokens[token], "ERC721: can't mint burned token");
                                                _mint(to, token);
                                              }
                                              /**
                                               * @dev Allows source to get the prepend for their tokenIds.
                                               */
                                              function sourceGetChainPrepend() external view onlySource returns (uint256) {
                                                return uint256(bytes32(abi.encodePacked(_chain(), uint224(0))));
                                              }
                                              /**
                                               * @dev Allows for source smart contract to mint a batch of tokens.
                                               */
                                              function sourceMintBatch(address to, uint224[] calldata tokenIds) external onlySource {
                                                require(tokenIds.length < 1000, "ERC721: max batch size is 1000");
                                                uint32 chain = _chain();
                                                uint256 token;
                                                for (uint256 i = 0; i < tokenIds.length; i++) {
                                                  require(!_burnedTokens[token], "ERC721: can't mint burned token");
                                                  token = uint256(bytes32(abi.encodePacked(chain, tokenIds[i])));
                                                  require(!_burnedTokens[token], "ERC721: can't mint burned token");
                                                  _mint(to, token);
                                                }
                                              }
                                              /**
                                               * @dev Allows for source smart contract to mint a batch of tokens.
                                               */
                                              function sourceMintBatch(address[] calldata wallets, uint224[] calldata tokenIds) external onlySource {
                                                require(wallets.length == tokenIds.length, "ERC721: array length missmatch");
                                                require(tokenIds.length < 1000, "ERC721: max batch size is 1000");
                                                uint32 chain = _chain();
                                                uint256 token;
                                                for (uint256 i = 0; i < tokenIds.length; i++) {
                                                  token = uint256(bytes32(abi.encodePacked(chain, tokenIds[i])));
                                                  require(!_burnedTokens[token], "ERC721: can't mint burned token");
                                                  _mint(wallets[i], token);
                                                }
                                              }
                                              /**
                                               * @dev Allows for source smart contract to mint a batch of tokens.
                                               */
                                              function sourceMintBatchIncremental(address to, uint224 startingTokenId, uint256 length) external onlySource {
                                                uint256 token = uint256(bytes32(abi.encodePacked(_chain(), startingTokenId)));
                                                for (uint256 i = 0; i < length; i++) {
                                                  require(!_burnedTokens[token], "ERC721: can't mint burned token");
                                                  _mint(to, token);
                                                  token++;
                                                }
                                              }
                                              /**
                                               * @dev Allows for source smart contract to transfer a token.
                                               *  Note: this is put in place to make sure that custom logic could be implemented for merging, gamification, etc.
                                               *  Note: token cannot be transfered if it's locked by bridge.
                                               */
                                              function sourceTransfer(address to, uint256 tokenId) external onlySource {
                                                require(!_burnedTokens[tokenId], "ERC721: token has been burned");
                                                address wallet = _tokenOwner[tokenId];
                                                _transferFrom(wallet, to, tokenId);
                                              }
                                              /**
                                               * @notice Transfers `tokenId` token from `msg.sender` to `to`.
                                               * @dev WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
                                               * @param to cannot be the zero address.
                                               * @param tokenId token must be owned by `from`.
                                               */
                                              function transfer(address to, uint256 tokenId) external payable {
                                                transferFrom(msg.sender, to, tokenId, "");
                                              }
                                              /**
                                               * @notice Transfers `tokenId` token from `from` to `to`.
                                               * @dev WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
                                               * @param from  cannot be the zero address.
                                               * @param to cannot be the zero address.
                                               * @param tokenId token must be owned by `from`.
                                               */
                                              function transferFrom(address from, address to, uint256 tokenId) public payable {
                                                transferFrom(from, to, tokenId, "");
                                              }
                                              /**
                                               * @notice Transfers `tokenId` token from `from` to `to`.
                                               * @dev WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
                                               * @dev Since it's not being used, the _data variable is commented out to avoid compiler warnings.
                                               * @param from  cannot be the zero address.
                                               * @param to cannot be the zero address.
                                               * @param tokenId token must be owned by `from`.
                                               * @param data additional data to pass.
                                               */
                                              function transferFrom(address from, address to, uint256 tokenId, bytes memory data) public payable {
                                                require(_isApproved(msg.sender, tokenId), "ERC721: not approved sender");
                                                if (_isEventRegistered(HolographERC721Event.beforeTransfer)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.beforeTransfer.selector, from, to, tokenId, data)));
                                                }
                                                _transferFrom(from, to, tokenId);
                                                if (_isEventRegistered(HolographERC721Event.afterTransfer)) {
                                                  require(_sourceCall(abi.encodeWithSelector(HolographedERC721.afterTransfer.selector, from, to, tokenId, data)));
                                                }
                                              }
                                              /**
                                               * @notice Get total number of tokens owned by wallet.
                                               * @dev Used to see total amount of tokens owned by a specific wallet.
                                               * @param wallet Address for which to get token balance.
                                               * @return uint256 Returns an integer, representing total amount of tokens held by address.
                                               */
                                              function balanceOf(address wallet) public view returns (uint256) {
                                                require(wallet != address(0), "ERC721: zero address");
                                                return _ownedTokensCount[wallet];
                                              }
                                              function burned(uint256 tokenId) public view returns (bool) {
                                                return _burnedTokens[tokenId];
                                              }
                                              /**
                                               * @notice Decimal places to have for totalSupply.
                                               * @dev Since ERC721s are single, we use 0 as the decimal places to make sure a round number for totalSupply.
                                               * @return uint256 Returns the number of decimal places to have for totalSupply.
                                               */
                                              function decimals() external pure returns (uint256) {
                                                return 0;
                                              }
                                              function exists(uint256 tokenId) public view returns (bool) {
                                                return _tokenOwner[tokenId] != address(0);
                                              }
                                              /**
                                               * @notice Gets the approved address for the token.
                                               * @dev Single operator set for a specific token. Usually used for one-time very specific authorisations.
                                               * @param tokenId Token id to get approved operator for.
                                               * @return address Approved address for token.
                                               */
                                              function getApproved(uint256 tokenId) external view returns (address) {
                                                return _tokenApprovals[tokenId];
                                              }
                                              /**
                                               * @notice Checks if the address is approved.
                                               * @dev Includes references to OpenSea and Rarible marketplace proxies.
                                               * @param wallet Address of the wallet.
                                               * @param operator Address of the marketplace operator.
                                               * @return bool True if approved.
                                               */
                                              function isApprovedForAll(address wallet, address operator) external view returns (bool) {
                                                return (_operatorApprovals[wallet][operator] || _sourceApproved(wallet, operator));
                                              }
                                              /**
                                               * @notice Checks who the owner of a token is.
                                               * @dev The token must exist.
                                               * @param tokenId The token to look up.
                                               * @return address Owner of the token.
                                               */
                                              function ownerOf(uint256 tokenId) external view returns (address) {
                                                address tokenOwner = _tokenOwner[tokenId];
                                                require(tokenOwner != address(0), "ERC721: token does not exist");
                                                return tokenOwner;
                                              }
                                              /**
                                               * @notice Get token by index.
                                               * @dev Used in conjunction with totalSupply function to iterate over all tokens in collection.
                                               * @param index Index of token in array.
                                               * @return uint256 Returns the token id of token located at that index.
                                               */
                                              function tokenByIndex(uint256 index) external view returns (uint256) {
                                                require(index < _allTokens.length, "ERC721: index out of bounds");
                                                return _allTokens[index];
                                              }
                                              /**
                                               * @notice Get set length list, starting from index, for all tokens.
                                               * @param index The index to start enumeration from.
                                               * @param length The length of returned results.
                                               * @return tokenIds uint256[] Returns a set length array of token ids minted.
                                               */
                                              function tokens(uint256 index, uint256 length) external view returns (uint256[] memory tokenIds) {
                                                uint256 supply = _allTokens.length;
                                                if (index + length > supply) {
                                                  length = supply - index;
                                                }
                                                tokenIds = new uint256[](length);
                                                for (uint256 i = 0; i < length; i++) {
                                                  tokenIds[i] = _allTokens[index + i];
                                                }
                                              }
                                              /**
                                               * @notice Get token from wallet by index instead of token id.
                                               * @dev Helpful for wallet token enumeration where token id info is not yet available. Use in conjunction with balanceOf function.
                                               * @param wallet Specific address for which to get token for.
                                               * @param index Index of token in array.
                                               * @return uint256 Returns the token id of token located at that index in specified wallet.
                                               */
                                              function tokenOfOwnerByIndex(address wallet, uint256 index) external view returns (uint256) {
                                                require(index < balanceOf(wallet), "ERC721: index out of bounds");
                                                return _ownedTokens[wallet][index];
                                              }
                                              /**
                                               * @notice Total amount of tokens in the collection.
                                               * @dev Ignores burned tokens.
                                               * @return uint256 Returns the total number of active (not burned) tokens.
                                               */
                                              function totalSupply() external view returns (uint256) {
                                                return _allTokens.length;
                                              }
                                              /**
                                               * @notice Empty function that is triggered by external contract on NFT transfer.
                                               * @dev We have this blank function in place to make sure that external contract sending in NFTs don't error out.
                                               * @dev Since it's not being used, the _operator variable is commented out to avoid compiler warnings.
                                               * @dev Since it's not being used, the _from variable is commented out to avoid compiler warnings.
                                               * @dev Since it's not being used, the _tokenId variable is commented out to avoid compiler warnings.
                                               * @dev Since it's not being used, the _data variable is commented out to avoid compiler warnings.
                                               * @return bytes4 Returns the interfaceId of onERC721Received.
                                               */
                                              function onERC721Received(
                                                address _operator,
                                                address _from,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bytes4) {
                                                require(_isContract(_operator), "ERC721: operator not contract");
                                                if (_isEventRegistered(HolographERC721Event.beforeOnERC721Received)) {
                                                  require(
                                                    _sourceCall(
                                                      abi.encodeWithSelector(
                                                        HolographedERC721.beforeOnERC721Received.selector,
                                                        _operator,
                                                        _from,
                                                        address(this),
                                                        _tokenId,
                                                        _data
                                                      )
                                                    )
                                                  );
                                                }
                                                try HolographERC721Interface(_operator).ownerOf(_tokenId) returns (address tokenOwner) {
                                                  require(tokenOwner == address(this), "ERC721: contract not token owner");
                                                } catch {
                                                  revert("ERC721: token does not exist");
                                                }
                                                if (_isEventRegistered(HolographERC721Event.afterOnERC721Received)) {
                                                  require(
                                                    _sourceCall(
                                                      abi.encodeWithSelector(
                                                        HolographedERC721.afterOnERC721Received.selector,
                                                        _operator,
                                                        _from,
                                                        address(this),
                                                        _tokenId,
                                                        _data
                                                      )
                                                    )
                                                  );
                                                }
                                                return ERC721TokenReceiver.onERC721Received.selector;
                                              }
                                              /**
                                               * @dev Add a newly minted token into managed list of tokens.
                                               * @param to Address of token owner for which to add the token.
                                               * @param tokenId Id of token to add.
                                               */
                                              function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
                                                _ownedTokensIndex[tokenId] = _ownedTokensCount[to];
                                                _ownedTokensCount[to]++;
                                                _ownedTokens[to].push(tokenId);
                                                _allTokensIndex[tokenId] = _allTokens.length;
                                                _allTokens.push(tokenId);
                                              }
                                              /**
                                               * @notice Burns the token.
                                               * @dev All validation needs to be done before calling this function.
                                               * @param wallet Address of current token owner.
                                               * @param tokenId The token to burn.
                                               */
                                              function _burn(address wallet, uint256 tokenId) private {
                                                _clearApproval(tokenId);
                                                _tokenOwner[tokenId] = address(0);
                                                _registryTransfer(wallet, address(0), tokenId);
                                                _removeTokenFromOwnerEnumeration(wallet, tokenId);
                                                _burnedTokens[tokenId] = true;
                                              }
                                              /**
                                               * @notice Deletes a token from the approval list.
                                               * @dev Removes from count.
                                               * @param tokenId T.
                                               */
                                              function _clearApproval(uint256 tokenId) private {
                                                delete _tokenApprovals[tokenId];
                                              }
                                              /**
                                               * @notice Mints an NFT.
                                               * @dev Can to mint the token to the zero address and the token cannot already exist.
                                               * @param to Address to mint to.
                                               * @param tokenId The new token.
                                               */
                                              function _mint(address to, uint256 tokenId) private {
                                                require(tokenId > 0, "ERC721: token id cannot be zero");
                                                require(to != address(0), "ERC721: minting to burn address");
                                                require(!_exists(tokenId), "ERC721: token already exists");
                                                require(!_burnedTokens[tokenId], "ERC721: token has been burned");
                                                _tokenOwner[tokenId] = to;
                                                _registryTransfer(address(0), to, tokenId);
                                                _addTokenToOwnerEnumeration(to, tokenId);
                                              }
                                              function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
                                                uint256 lastTokenIndex = _allTokens.length - 1;
                                                uint256 tokenIndex = _allTokensIndex[tokenId];
                                                uint256 lastTokenId = _allTokens[lastTokenIndex];
                                                _allTokens[tokenIndex] = lastTokenId;
                                                _allTokensIndex[lastTokenId] = tokenIndex;
                                                delete _allTokensIndex[tokenId];
                                                delete _allTokens[lastTokenIndex];
                                                _allTokens.pop();
                                              }
                                              /**
                                               * @dev Remove a token from managed list of tokens.
                                               * @param from Address of token owner for which to remove the token.
                                               * @param tokenId Id of token to remove.
                                               */
                                              function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
                                                _removeTokenFromAllTokensEnumeration(tokenId);
                                                _ownedTokensCount[from]--;
                                                uint256 lastTokenIndex = _ownedTokensCount[from];
                                                uint256 tokenIndex = _ownedTokensIndex[tokenId];
                                                if (tokenIndex != lastTokenIndex) {
                                                  uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
                                                  _ownedTokens[from][tokenIndex] = lastTokenId;
                                                  _ownedTokensIndex[lastTokenId] = tokenIndex;
                                                }
                                                if (lastTokenIndex == 0) {
                                                  delete _ownedTokens[from];
                                                } else {
                                                  delete _ownedTokens[from][lastTokenIndex];
                                                  _ownedTokens[from].pop();
                                                }
                                              }
                                              /**
                                               * @dev Primary private function that handles the transfer/mint/burn functionality.
                                               * @param from Address from where token is being transferred. Zero address means it is being minted.
                                               * @param to Address to whom the token is being transferred. Zero address means it is being burned.
                                               * @param tokenId Id of token that is being transferred/minted/burned.
                                               */
                                              function _transferFrom(address from, address to, uint256 tokenId) private {
                                                require(_tokenOwner[tokenId] == from, "ERC721: token not owned");
                                                require(to != address(0), "ERC721: use burn instead");
                                                _clearApproval(tokenId);
                                                _tokenOwner[tokenId] = to;
                                                _registryTransfer(from, to, tokenId);
                                                _removeTokenFromOwnerEnumeration(from, tokenId);
                                                _addTokenToOwnerEnumeration(to, tokenId);
                                              }
                                              function _chain() private view returns (uint32) {
                                                uint32 currentChain = HolographInterface(HolographerInterface(payable(address(this))).getHolograph())
                                                  .getHolographChainId();
                                                if (currentChain != HolographerInterface(payable(address(this))).getOriginChain()) {
                                                  return currentChain;
                                                }
                                                return uint32(0);
                                              }
                                              /**
                                               * @notice Checks if the token owner exists.
                                               * @dev If the address is the zero address no owner exists.
                                               * @param tokenId The affected token.
                                               * @return bool True if it exists.
                                               */
                                              function _exists(uint256 tokenId) private view returns (bool) {
                                                address tokenOwner = _tokenOwner[tokenId];
                                                return tokenOwner != address(0);
                                              }
                                              function _sourceApproved(address _tokenWallet, address _tokenSpender) internal view returns (bool approved) {
                                                if (_isEventRegistered(HolographERC721Event.onIsApprovedForAll)) {
                                                  HolographedERC721 sourceContract;
                                                  assembly {
                                                    sourceContract := sload(_sourceContractSlot)
                                                  }
                                                  if (sourceContract.onIsApprovedForAll(_tokenWallet, _tokenSpender)) {
                                                    approved = true;
                                                  }
                                                }
                                              }
                                              /**
                                               * @notice Checks if the address is an approved one.
                                               * @dev Uses inlined checks for different usecases of approval.
                                               * @param spender Address of the spender.
                                               * @param tokenId The affected token.
                                               * @return bool True if approved.
                                               */
                                              function _isApproved(address spender, uint256 tokenId) private view returns (bool) {
                                                require(_exists(tokenId), "ERC721: token does not exist");
                                                address tokenOwner = _tokenOwner[tokenId];
                                                return (spender == tokenOwner ||
                                                  _tokenApprovals[tokenId] == spender ||
                                                  _operatorApprovals[tokenOwner][spender] ||
                                                  _sourceApproved(tokenOwner, spender));
                                              }
                                              function _isApprovedStrict(address spender, uint256 tokenId) private view returns (bool) {
                                                require(_exists(tokenId), "ERC721: token does not exist");
                                                address tokenOwner = _tokenOwner[tokenId];
                                                return (spender == tokenOwner || _operatorApprovals[tokenOwner][spender] || _sourceApproved(tokenOwner, spender));
                                              }
                                              function _isContract(address contractAddress) private view returns (bool) {
                                                bytes32 codehash;
                                                assembly {
                                                  codehash := extcodehash(contractAddress)
                                                }
                                                return (codehash != 0x0 && codehash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470);
                                              }
                                              /**
                                               * @dev Get the interfaces contract address.
                                               */
                                              function _interfaces() private view returns (address) {
                                                return _holograph().getInterfaces();
                                              }
                                              function owner() public view override returns (address) {
                                                assembly {
                                                  calldatacopy(0, 0, calldatasize())
                                                  mstore(calldatasize(), caller())
                                                  let result := staticcall(gas(), sload(_sourceContractSlot), 0, add(calldatasize(), 0x20), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                              function _holograph() private view returns (HolographInterface holograph) {
                                                assembly {
                                                  holograph := sload(_holographSlot)
                                                }
                                              }
                                              /**
                                               * @dev Get the bridge contract address.
                                               */
                                              function _royalties() private view returns (address) {
                                                return
                                                  HolographRegistryInterface(_holograph().getRegistry()).getContractTypeAddress(0x0000000000000000000000000000486f6c6f6772617068526f79616c74696573);
                                              }
                                              function _registryTransfer(address _from, address _to, uint256 _tokenId) private {
                                                emit Transfer(_from, _to, _tokenId);
                                                HolographRegistryInterface(_holograph().getRegistry()).holographableEvent(
                                                  abi.encode(
                                                    // keccak256("TransferERC721(address,address,uint256)")
                                                    bytes32(0x351b8d13789e4d8d2717631559251955685881a31494dd0b8b19b4ef8530bb6d),
                                                    _from,
                                                    _to,
                                                    _tokenId
                                                  )
                                                );
                                              }
                                              /**
                                               * @dev Purposefully left empty, to prevent running out of gas errors when receiving native token payments.
                                               */
                                              event FundsReceived(address indexed source, uint256 amount);
                                              receive() external payable {
                                                emit FundsReceived(msg.sender, msg.value);
                                              }
                                              /**
                                               * @notice Fallback to the source contract.
                                               * @dev Any function call that is not covered here, will automatically be sent over to the source contract.
                                               */
                                              fallback() external payable {
                                                // Check if royalties support the function, send there, otherwise revert to source
                                                address _target;
                                                if (HolographInterfacesInterface(_interfaces()).supportsInterface(InterfaceType.ROYALTIES, msg.sig)) {
                                                  _target = _royalties();
                                                  assembly {
                                                    calldatacopy(0, 0, calldatasize())
                                                    let result := delegatecall(gas(), _target, 0, calldatasize(), 0, 0)
                                                    returndatacopy(0, 0, returndatasize())
                                                    switch result
                                                    case 0 {
                                                      revert(0, returndatasize())
                                                    }
                                                    default {
                                                      return(0, returndatasize())
                                                    }
                                                  }
                                                } else {
                                                  assembly {
                                                    calldatacopy(0, 0, calldatasize())
                                                    mstore(calldatasize(), caller())
                                                    let result := call(gas(), sload(_sourceContractSlot), callvalue(), 0, add(calldatasize(), 0x20), 0, 0)
                                                    returndatacopy(0, 0, returndatasize())
                                                    switch result
                                                    case 0 {
                                                      revert(0, returndatasize())
                                                    }
                                                    default {
                                                      return(0, returndatasize())
                                                    }
                                                  }
                                                }
                                              }
                                              /*
                                               * @dev all calls to source contract go through this function in order to inject original msg.sender in calldata
                                               */
                                              function _sourceCall(bytes memory payload) private returns (bool output) {
                                                assembly {
                                                  mstore(add(payload, add(mload(payload), 0x20)), caller())
                                                  // offset memory position by 32 bytes to skip the 32 bytes where bytes length is stored
                                                  // add 32 bytes to bytes length to include the appended msg.sender to calldata
                                                  let result := call(
                                                    gas(),
                                                    sload(_sourceContractSlot),
                                                    callvalue(),
                                                    add(payload, 0x20),
                                                    add(mload(payload), 0x20),
                                                    0,
                                                    0
                                                  )
                                                  let pos := mload(0x40)
                                                  // reserve memory space for return data
                                                  mstore(0x40, add(pos, returndatasize()))
                                                  returndatacopy(pos, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(pos, returndatasize())
                                                  }
                                                  output := mload(pos)
                                                }
                                              }
                                              function _isEventRegistered(HolographERC721Event _eventName) private view returns (bool) {
                                                return ((_eventConfig >> uint256(_eventName)) & uint256(1) == 1 ? true : false);
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum ChainIdType {
                                              UNDEFINED, //  0
                                              EVM, //        1
                                              HOLOGRAPH, //  2
                                              LAYERZERO, //  3
                                              HYPERLANE //   4
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum HolographERC721Event {
                                              UNDEFINED, // 0
                                              bridgeIn, //  1
                                              bridgeOut, //  2
                                              afterApprove, //  3
                                              beforeApprove, //  4
                                              afterApprovalAll, //  5
                                              beforeApprovalAll, //  6
                                              afterBurn, //  7
                                              beforeBurn, //  8
                                              afterMint, //  9
                                              beforeMint, // 10
                                              afterSafeTransfer, // 11
                                              beforeSafeTransfer, // 12
                                              afterTransfer, // 13
                                              beforeTransfer, // 14
                                              beforeOnERC721Received, // 15
                                              afterOnERC721Received, // 16
                                              onIsApprovedForAll, // 17
                                              customContractURI // 18
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum InterfaceType {
                                              UNDEFINED, // 0
                                              ERC20, //     1
                                              ERC721, //    2
                                              ERC1155, //   3
                                              ROYALTIES, // 4
                                              GENERIC //    5
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum TokenUriType {
                                              UNDEFINED, //   0
                                              IPFS, //        1
                                              HTTPS, //       2
                                              ARWEAVE //      3
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface CollectionURI {
                                              function contractURI() external view returns (string memory);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            interface ERC165 {
                                              /// @notice Query if a contract implements an interface
                                              /// @param interfaceID The interface identifier, as specified in ERC-165
                                              /// @dev Interface identification is specified in ERC-165. This function
                                              ///  uses less than 30,000 gas.
                                              /// @return `true` if the contract implements `interfaceID` and
                                              ///  `interfaceID` is not 0xffffffff, `false` otherwise
                                              function supportsInterface(bytes4 interfaceID) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x80ac58cd.
                                            /* is ERC165 */
                                            interface ERC721 {
                                              /// @dev This emits when ownership of any NFT changes by any mechanism.
                                              ///  This event emits when NFTs are created (`from` == 0) and destroyed
                                              ///  (`to` == 0). Exception: during contract creation, any number of NFTs
                                              ///  may be created and assigned without emitting Transfer. At the time of
                                              ///  any transfer, the approved address for that NFT (if any) is reset to none.
                                              event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
                                              /// @dev This emits when the approved address for an NFT is changed or
                                              ///  reaffirmed. The zero address indicates there is no approved address.
                                              ///  When a Transfer event emits, this also indicates that the approved
                                              ///  address for that NFT (if any) is reset to none.
                                              event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
                                              /// @dev This emits when an operator is enabled or disabled for an owner.
                                              ///  The operator can manage all NFTs of the owner.
                                              event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
                                              /// @notice Count all NFTs assigned to an owner
                                              /// @dev NFTs assigned to the zero address are considered invalid, and this
                                              ///  function throws for queries about the zero address.
                                              /// @param _owner An address for whom to query the balance
                                              /// @return The number of NFTs owned by `_owner`, possibly zero
                                              function balanceOf(address _owner) external view returns (uint256);
                                              /// @notice Find the owner of an NFT
                                              /// @dev NFTs assigned to zero address are considered invalid, and queries
                                              ///  about them do throw.
                                              /// @param _tokenId The identifier for an NFT
                                              /// @return The address of the owner of the NFT
                                              function ownerOf(uint256 _tokenId) external view returns (address);
                                              /// @notice Transfers the ownership of an NFT from one address to another address
                                              /// @dev Throws unless `msg.sender` is the current owner, an authorized
                                              ///  operator, or the approved address for this NFT. Throws if `_from` is
                                              ///  not the current owner. Throws if `_to` is the zero address. Throws if
                                              ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
                                              ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
                                              ///  `onERC721Received` on `_to` and throws if the return value is not
                                              ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              /// @param data Additional data with no specified format, sent in call to `_to`
                                              function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;
                                              /// @notice Transfers the ownership of an NFT from one address to another address
                                              /// @dev This works identically to the other function with an extra data parameter,
                                              ///  except this function just sets data to "".
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
                                              /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
                                              ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
                                              ///  THEY MAY BE PERMANENTLY LOST
                                              /// @dev Throws unless `msg.sender` is the current owner, an authorized
                                              ///  operator, or the approved address for this NFT. Throws if `_from` is
                                              ///  not the current owner. Throws if `_to` is the zero address. Throws if
                                              ///  `_tokenId` is not a valid NFT.
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
                                              /// @notice Change or reaffirm the approved address for an NFT
                                              /// @dev The zero address indicates there is no approved address.
                                              ///  Throws unless `msg.sender` is the current NFT owner, or an authorized
                                              ///  operator of the current owner.
                                              /// @param _approved The new approved NFT controller
                                              /// @param _tokenId The NFT to approve
                                              function approve(address _approved, uint256 _tokenId) external payable;
                                              /// @notice Enable or disable approval for a third party ("operator") to manage
                                              ///  all of `msg.sender`'s assets
                                              /// @dev Emits the ApprovalForAll event. The contract MUST allow
                                              ///  multiple operators per owner.
                                              /// @param _operator Address to add to the set of authorized operators
                                              /// @param _approved True if the operator is approved, false to revoke approval
                                              function setApprovalForAll(address _operator, bool _approved) external;
                                              /// @notice Get the approved address for a single NFT
                                              /// @dev Throws if `_tokenId` is not a valid NFT.
                                              /// @param _tokenId The NFT to find the approved address for
                                              /// @return The approved address for this NFT, or the zero address if there is none
                                              function getApproved(uint256 _tokenId) external view returns (address);
                                              /// @notice Query if an address is an authorized operator for another address
                                              /// @param _owner The address that owns the NFTs
                                              /// @param _operator The address that acts on behalf of the owner
                                              /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
                                              function isApprovedForAll(address _owner, address _operator) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x780e9d63.
                                            /* is ERC721 */
                                            interface ERC721Enumerable {
                                              /// @notice Count NFTs tracked by this contract
                                              /// @return A count of valid NFTs tracked by this contract, where each one of
                                              ///  them has an assigned and queryable owner not equal to the zero address
                                              function totalSupply() external view returns (uint256);
                                              /// @notice Enumerate valid NFTs
                                              /// @dev Throws if `_index` >= `totalSupply()`.
                                              /// @param _index A counter less than `totalSupply()`
                                              /// @return The token identifier for the `_index`th NFT,
                                              ///  (sort order not specified)
                                              function tokenByIndex(uint256 _index) external view returns (uint256);
                                              /// @notice Enumerate NFTs assigned to an owner
                                              /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
                                              ///  `_owner` is the zero address, representing invalid NFTs.
                                              /// @param _owner An address where we are interested in NFTs owned by them
                                              /// @param _index A counter less than `balanceOf(_owner)`
                                              /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
                                              ///   (sort order not specified)
                                              function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x5b5e139f.
                                            /* is ERC721 */
                                            interface ERC721Metadata {
                                              /// @notice A descriptive name for a collection of NFTs in this contract
                                              function name() external view returns (string memory _name);
                                              /// @notice An abbreviated name for NFTs in this contract
                                              function symbol() external view returns (string memory _symbol);
                                              /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
                                              /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
                                              ///  3986. The URI may point to a JSON file that conforms to the "ERC721
                                              ///  Metadata JSON Schema".
                                              function tokenURI(uint256 _tokenId) external view returns (string memory);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
                                            interface ERC721TokenReceiver {
                                              /// @notice Handle the receipt of an NFT
                                              /// @dev The ERC721 smart contract calls this function on the recipient
                                              ///  after a `transfer`. This function MAY throw to revert and reject the
                                              ///  transfer. Return of other than the magic value MUST result in the
                                              ///  transaction being reverted.
                                              ///  Note: the contract address is always the message sender.
                                              /// @param _operator The address which called `safeTransferFrom` function
                                              /// @param _from The address which previously owned the token
                                              /// @param _tokenId The NFT identifier which is being transferred
                                              /// @param _data Additional data with no specified format
                                              /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
                                              ///  unless throwing
                                              function onERC721Received(
                                                address _operator,
                                                address _from,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bytes4);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface Holographable {
                                              function bridgeIn(uint32 fromChain, bytes calldata payload) external returns (bytes4);
                                              function bridgeOut(
                                                uint32 toChain,
                                                address sender,
                                                bytes calldata payload
                                              ) external returns (bytes4 selector, bytes memory data);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /// @title Holograph ERC-721 Non-Fungible Token Standard
                                            /// @dev See https://holograph.network/standard/ERC-721
                                            ///  Note: the ERC-165 identifier for this interface is 0xFFFFFFFF.
                                            interface HolographedERC721 {
                                              // event id = 1
                                              function bridgeIn(
                                                uint32 _chainId,
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 2
                                              function bridgeOut(
                                                uint32 _chainId,
                                                address _from,
                                                address _to,
                                                uint256 _tokenId
                                              ) external returns (bytes memory _data);
                                              // event id = 3
                                              function afterApprove(address _owner, address _to, uint256 _tokenId) external returns (bool success);
                                              // event id = 4
                                              function beforeApprove(address _owner, address _to, uint256 _tokenId) external returns (bool success);
                                              // event id = 5
                                              function afterApprovalAll(address _sender, address _to, bool _approved) external returns (bool success);
                                              // event id = 6
                                              function beforeApprovalAll(address _sender, address _to, bool _approved) external returns (bool success);
                                              // event id = 7
                                              function afterBurn(address _owner, uint256 _tokenId) external returns (bool success);
                                              // event id = 8
                                              function beforeBurn(address _owner, uint256 _tokenId) external returns (bool success);
                                              // event id = 9
                                              function afterMint(address _owner, uint256 _tokenId) external returns (bool success);
                                              // event id = 10
                                              function beforeMint(address _owner, uint256 _tokenId) external returns (bool success);
                                              // event id = 11
                                              function afterSafeTransfer(
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 12
                                              function beforeSafeTransfer(
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 13
                                              function afterTransfer(
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 14
                                              function beforeTransfer(
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 15
                                              function afterOnERC721Received(
                                                address _operator,
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 16
                                              function beforeOnERC721Received(
                                                address _operator,
                                                address _from,
                                                address _to,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bool success);
                                              // event id = 17
                                              function onIsApprovedForAll(address _wallet, address _operator) external view returns (bool approved);
                                              // event id = 18
                                              function contractURI() external view returns (string memory contractJSON);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./CollectionURI.sol";
                                            import "./ERC165.sol";
                                            import "./ERC721.sol";
                                            import "./ERC721Enumerable.sol";
                                            import "./ERC721Metadata.sol";
                                            import "./ERC721TokenReceiver.sol";
                                            import "./Holographable.sol";
                                            interface HolographERC721Interface is
                                              ERC165,
                                              ERC721,
                                              ERC721Enumerable,
                                              ERC721Metadata,
                                              ERC721TokenReceiver,
                                              CollectionURI,
                                              Holographable
                                            {
                                              function approve(address to, uint256 tokenId) external payable;
                                              function burn(uint256 tokenId) external;
                                              function safeTransferFrom(address from, address to, uint256 tokenId) external payable;
                                              function setApprovalForAll(address to, bool approved) external;
                                              function sourceBurn(uint256 tokenId) external;
                                              function sourceMint(address to, uint224 tokenId) external;
                                              function sourceGetChainPrepend() external view returns (uint256);
                                              function sourceTransfer(address to, uint256 tokenId) external;
                                              function transfer(address to, uint256 tokenId) external payable;
                                              function contractURI() external view returns (string memory);
                                              function getApproved(uint256 tokenId) external view returns (address);
                                              function isApprovedForAll(address wallet, address operator) external view returns (bool);
                                              function name() external view returns (string memory);
                                              function burned(uint256 tokenId) external view returns (bool);
                                              function decimals() external pure returns (uint256);
                                              function exists(uint256 tokenId) external view returns (bool);
                                              function ownerOf(uint256 tokenId) external view returns (address);
                                              function supportsInterface(bytes4 interfaceId) external view returns (bool);
                                              function symbol() external view returns (string memory);
                                              function tokenByIndex(uint256 index) external view returns (uint256);
                                              function tokenOfOwnerByIndex(address wallet, uint256 index) external view returns (uint256);
                                              function tokensOfOwner(address wallet) external view returns (uint256[] memory);
                                              function tokenURI(uint256 tokenId) external view returns (string memory);
                                              function totalSupply() external view returns (uint256);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographerInterface {
                                              function getContractType() external view returns (bytes32 contractType);
                                              function getDeploymentBlock() external view returns (uint256 deploymentBlock);
                                              function getHolograph() external view returns (address holograph);
                                              function getHolographEnforcer() external view returns (address);
                                              function getOriginChain() external view returns (uint32 originChain);
                                              function getSourceContract() external view returns (address sourceContract);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            interface HolographInterface {
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge);
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external;
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId);
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory);
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external;
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId);
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces);
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external;
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator);
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external;
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry);
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external;
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury);
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external;
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken);
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../enum/ChainIdType.sol";
                                            import "../enum/InterfaceType.sol";
                                            import "../enum/TokenUriType.sol";
                                            interface HolographInterfacesInterface {
                                              function contractURI(
                                                string calldata name,
                                                string calldata imageURL,
                                                string calldata externalLink,
                                                uint16 bps,
                                                address contractAddress
                                              ) external pure returns (string memory);
                                              function getUriPrepend(TokenUriType uriType) external view returns (string memory prepend);
                                              function updateUriPrepend(TokenUriType uriType, string calldata prepend) external;
                                              function updateUriPrepends(TokenUriType[] calldata uriTypes, string[] calldata prepends) external;
                                              function getChainId(
                                                ChainIdType fromChainType,
                                                uint256 fromChainId,
                                                ChainIdType toChainType
                                              ) external view returns (uint256 toChainId);
                                              function updateChainIdMap(
                                                ChainIdType fromChainType,
                                                uint256 fromChainId,
                                                ChainIdType toChainType,
                                                uint256 toChainId
                                              ) external;
                                              function updateChainIdMaps(
                                                ChainIdType[] calldata fromChainType,
                                                uint256[] calldata fromChainId,
                                                ChainIdType[] calldata toChainType,
                                                uint256[] calldata toChainId
                                              ) external;
                                              function supportsInterface(InterfaceType interfaceType, bytes4 interfaceId) external view returns (bool);
                                              function updateInterface(InterfaceType interfaceType, bytes4 interfaceId, bool supported) external;
                                              function updateInterfaces(InterfaceType interfaceType, bytes4[] calldata interfaceIds, bool supported) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographRegistryInterface {
                                              event HolographableContractEvent(address indexed _holographableContract, bytes _payload);
                                              function isHolographedContract(address smartContract) external view returns (bool);
                                              function isHolographedHashDeployed(bytes32 hash) external view returns (bool);
                                              function referenceContractTypeAddress(address contractAddress) external returns (bytes32);
                                              function getContractTypeAddress(bytes32 contractType) external view returns (address);
                                              function setContractTypeAddress(bytes32 contractType, address contractAddress) external;
                                              function getHolograph() external view returns (address holograph);
                                              function setHolograph(address holograph) external;
                                              function getHolographableContracts(uint256 index, uint256 length) external view returns (address[] memory contracts);
                                              function getHolographableContractsLength() external view returns (uint256);
                                              function getHolographedHashAddress(bytes32 hash) external view returns (address);
                                              function setHolographedHashAddress(bytes32 hash, address contractAddress) external;
                                              function getHToken(uint32 chainId) external view returns (address);
                                              function setHToken(uint32 chainId, address hToken) external;
                                              function getReservedContractTypeAddress(bytes32 contractType) external view returns (address contractTypeAddress);
                                              function setReservedContractTypeAddress(bytes32 hash, bool reserved) external;
                                              function setReservedContractTypeAddresses(bytes32[] calldata hashes, bool[] calldata reserved) external;
                                              function getUtilityToken() external view returns (address utilityToken);
                                              function setUtilityToken(address utilityToken) external;
                                              function holographableEvent(bytes calldata payload) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../struct/ZoraBidShares.sol";
                                            interface HolographRoyaltiesInterface {
                                              function initHolographRoyalties(bytes memory data) external returns (bytes4);
                                              function configurePayouts(address payable[] memory addresses, uint256[] memory bps) external;
                                              function getPayoutInfo() external view returns (address payable[] memory addresses, uint256[] memory bps);
                                              function getEthPayout() external;
                                              function getTokenPayout(address tokenAddress) external;
                                              function getTokensPayout(address[] memory tokenAddresses) external;
                                              function supportsInterface(bytes4 interfaceId) external pure returns (bool);
                                              function setRoyalties(uint256 tokenId, address payable receiver, uint256 bp) external;
                                              function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);
                                              function getFeeBps(uint256 tokenId) external view returns (uint256[] memory);
                                              function getFeeRecipients(uint256 tokenId) external view returns (address payable[] memory);
                                              function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
                                              function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
                                              function tokenCreator(address /* contractAddress*/, uint256 tokenId) external view returns (address);
                                              function calculateRoyaltyFee(
                                                address /* contractAddress */,
                                                uint256 tokenId,
                                                uint256 amount
                                              ) external view returns (uint256);
                                              function marketContract() external view returns (address);
                                              function tokenCreators(uint256 tokenId) external view returns (address);
                                              function bidSharesForToken(uint256 tokenId) external view returns (HolographBidShares memory bidShares);
                                              function getStorageSlot(string calldata slot) external pure returns (bytes32);
                                              function getTokenAddress(string memory tokenName) external view returns (address);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface Ownable {
                                              event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                                              function owner() external view returns (address);
                                              function transferOwnership(address _newOwner) external;
                                              function isOwner() external view returns (bool);
                                              function isOwner(address wallet) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./ZoraDecimal.sol";
                                            struct HolographBidShares {
                                              // % of sale value that goes to the _previous_ owner of the nft
                                              HolographDecimal prevOwner;
                                              // % of sale value that goes to the original creator of the nft
                                              HolographDecimal creator;
                                              // % of sale value that goes to the seller (current owner) of the nft
                                              HolographDecimal owner;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            struct HolographDecimal {
                                              uint256 value;
                                            }
                                            

                                            File 7 of 14: HolographInterfaces
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./abstract/Admin.sol";
                                            import "./abstract/Initializable.sol";
                                            import "./enum/ChainIdType.sol";
                                            import "./enum/InterfaceType.sol";
                                            import "./enum/TokenUriType.sol";
                                            import "./interface/InitializableInterface.sol";
                                            import "./library/Base64.sol";
                                            import "./library/Strings.sol";
                                            /**
                                             * @title Holograph Interfaces
                                             * @author https://github.com/holographxyz
                                             * @notice Get universal Holograph Protocol variables
                                             * @dev The contract stores a reference of all supported: chains, interfaces, functions, etc.
                                             */
                                            contract HolographInterfaces is Admin, Initializable {
                                              /**
                                               * @dev Internal mapping of all InterfaceType interfaces
                                               */
                                              mapping(InterfaceType => mapping(bytes4 => bool)) private _supportedInterfaces;
                                              /**
                                               * @dev Internal mapping of all ChainIdType conversions
                                               */
                                              mapping(ChainIdType => mapping(uint256 => mapping(ChainIdType => uint256))) private _chainIdMap;
                                              /**
                                               * @dev Internal mapping of all TokenUriType prepends
                                               */
                                              mapping(TokenUriType => string) private _prependURI;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                address contractAdmin = abi.decode(initPayload, (address));
                                                assembly {
                                                  sstore(_adminSlot, contractAdmin)
                                                }
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              /**
                                               * @notice Get a base64 encoded contract URI JSON string
                                               * @dev Used to dynamically generate contract JSON payload
                                               * @param name the name of the smart contract
                                               * @param imageURL string pointing to the primary contract image, can be: https, ipfs, or ar (arweave)
                                               * @param externalLink url to website/page related to smart contract
                                               * @param bps basis points used for specifying royalties percentage
                                               * @param contractAddress address of the smart contract
                                               * @return a base64 encoded json string representing the smart contract
                                               */
                                              function contractURI(
                                                string calldata name,
                                                string calldata imageURL,
                                                string calldata externalLink,
                                                uint16 bps,
                                                address contractAddress
                                              ) external pure returns (string memory) {
                                                return
                                                  string(
                                                    abi.encodePacked(
                                                      "data:application/json;base64,",
                                                      Base64.encode(
                                                        abi.encodePacked(
                                                          '{"name":"',
                                                          name,
                                                          '","description":"',
                                                          name,
                                                          '","image":"',
                                                          imageURL,
                                                          '","external_link":"',
                                                          externalLink,
                                                          '","seller_fee_basis_points":',
                                                          Strings.uint2str(bps),
                                                          ',"fee_recipient":"0x',
                                                          Strings.toAsciiString(contractAddress),
                                                          '"}'
                                                        )
                                                      )
                                                    )
                                                  );
                                              }
                                              /**
                                               * @notice Get the prepend to use for tokenURI
                                               * @dev Provides the prepend to use with TokenUriType URI
                                               */
                                              function getUriPrepend(TokenUriType uriType) external view returns (string memory prepend) {
                                                prepend = _prependURI[uriType];
                                              }
                                              /**
                                               * @notice Update the tokenURI prepend
                                               * @param uriType specify which TokenUriType to set for
                                               * @param prepend the string to use for the prepend
                                               */
                                              function updateUriPrepend(TokenUriType uriType, string calldata prepend) external onlyAdmin {
                                                _prependURI[uriType] = prepend;
                                              }
                                              /**
                                               * @notice Update the tokenURI prepends
                                               * @param uriTypes specify array of TokenUriTypes to set for
                                               * @param prepends array string to use for the prepends
                                               */
                                              function updateUriPrepends(TokenUriType[] calldata uriTypes, string[] calldata prepends) external onlyAdmin {
                                                for (uint256 i = 0; i < uriTypes.length; i++) {
                                                  _prependURI[uriTypes[i]] = prepends[i];
                                                }
                                              }
                                              function getChainId(
                                                ChainIdType fromChainType,
                                                uint256 fromChainId,
                                                ChainIdType toChainType
                                              ) external view returns (uint256 toChainId) {
                                                return _chainIdMap[fromChainType][fromChainId][toChainType];
                                              }
                                              function updateChainIdMap(
                                                ChainIdType fromChainType,
                                                uint256 fromChainId,
                                                ChainIdType toChainType,
                                                uint256 toChainId
                                              ) external onlyAdmin {
                                                _chainIdMap[fromChainType][fromChainId][toChainType] = toChainId;
                                              }
                                              function updateChainIdMaps(
                                                ChainIdType[] calldata fromChainType,
                                                uint256[] calldata fromChainId,
                                                ChainIdType[] calldata toChainType,
                                                uint256[] calldata toChainId
                                              ) external onlyAdmin {
                                                uint256 length = fromChainType.length;
                                                for (uint256 i = 0; i < length; i++) {
                                                  _chainIdMap[fromChainType[i]][fromChainId[i]][toChainType[i]] = toChainId[i];
                                                }
                                              }
                                              function supportsInterface(InterfaceType interfaceType, bytes4 interfaceId) external view returns (bool) {
                                                return _supportedInterfaces[interfaceType][interfaceId];
                                              }
                                              function updateInterface(
                                                InterfaceType interfaceType,
                                                bytes4 interfaceId,
                                                bool supported
                                              ) external onlyAdmin {
                                                _supportedInterfaces[interfaceType][interfaceId] = supported;
                                              }
                                              function updateInterfaces(
                                                InterfaceType interfaceType,
                                                bytes4[] calldata interfaceIds,
                                                bool supported
                                              ) external onlyAdmin {
                                                for (uint256 i = 0; i < interfaceIds.length; i++) {
                                                  _supportedInterfaces[interfaceType][interfaceIds[i]] = supported;
                                                }
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent having any type of ether transfered into the contract
                                               */
                                              receive() external payable {
                                                revert();
                                              }
                                              /**
                                               * @dev Purposefully reverts to prevent any calls to undefined functions
                                               */
                                              fallback() external payable {
                                                revert();
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum ChainIdType {
                                              UNDEFINED, //  0
                                              EVM, //        1
                                              HOLOGRAPH, //  2
                                              LAYERZERO, //  3
                                              HYPERLANE //   4
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum TokenUriType {
                                              UNDEFINED, //   0
                                              IPFS, //        1
                                              HTTPS, //       2
                                              ARWEAVE //      3
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            enum InterfaceType {
                                              UNDEFINED, // 0
                                              ERC20, //     1
                                              ERC721, //    2
                                              ERC1155, //   3
                                              ROYALTIES, // 4
                                              GENERIC //    5
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            library Base64 {
                                              bytes private constant base64stdchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
                                              bytes private constant base64urlchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
                                              function encode(string memory _str) internal pure returns (string memory) {
                                                bytes memory _bs = bytes(_str);
                                                return encode(_bs);
                                              }
                                              function encode(bytes memory _bs) internal pure returns (string memory) {
                                                uint256 rem = _bs.length % 3;
                                                uint256 res_length = ((_bs.length + 2) / 3) * 4 - ((3 - rem) % 3);
                                                bytes memory res = new bytes(res_length);
                                                uint256 i = 0;
                                                uint256 j = 0;
                                                for (; i + 3 <= _bs.length; i += 3) {
                                                  (res[j], res[j + 1], res[j + 2], res[j + 3]) = encode3(uint8(_bs[i]), uint8(_bs[i + 1]), uint8(_bs[i + 2]));
                                                  j += 4;
                                                }
                                                if (rem != 0) {
                                                  uint8 la0 = uint8(_bs[_bs.length - rem]);
                                                  uint8 la1 = 0;
                                                  if (rem == 2) {
                                                    la1 = uint8(_bs[_bs.length - 1]);
                                                  }
                                                  (
                                                    bytes1 b0,
                                                    bytes1 b1,
                                                    bytes1 b2, /* bytes1 b3*/
                                                  ) = encode3(la0, la1, 0);
                                                  res[j] = b0;
                                                  res[j + 1] = b1;
                                                  if (rem == 2) {
                                                    res[j + 2] = b2;
                                                  }
                                                }
                                                return string(res);
                                              }
                                              function encode3(
                                                uint256 a0,
                                                uint256 a1,
                                                uint256 a2
                                              )
                                                private
                                                pure
                                                returns (
                                                  bytes1 b0,
                                                  bytes1 b1,
                                                  bytes1 b2,
                                                  bytes1 b3
                                                )
                                              {
                                                uint256 n = (a0 << 16) | (a1 << 8) | a2;
                                                uint256 c0 = (n >> 18) & 63;
                                                uint256 c1 = (n >> 12) & 63;
                                                uint256 c2 = (n >> 6) & 63;
                                                uint256 c3 = (n) & 63;
                                                b0 = base64urlchars[c0];
                                                b1 = base64urlchars[c1];
                                                b2 = base64urlchars[c2];
                                                b3 = base64urlchars[c3];
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            library Strings {
                                              function toHexString(address account) internal pure returns (string memory) {
                                                return toHexString(uint256(uint160(account)));
                                              }
                                              function toHexString(uint256 value) internal pure returns (string memory) {
                                                if (value == 0) {
                                                  return "0x00";
                                                }
                                                uint256 temp = value;
                                                uint256 length = 0;
                                                while (temp != 0) {
                                                  length++;
                                                  temp >>= 8;
                                                }
                                                return toHexString(value, length);
                                              }
                                              function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
                                                bytes memory buffer = new bytes(2 * length + 2);
                                                buffer[0] = "0";
                                                buffer[1] = "x";
                                                for (uint256 i = 2 * length + 1; i > 1; --i) {
                                                  buffer[i] = bytes16("0123456789abcdef")[value & 0xf];
                                                  value >>= 4;
                                                }
                                                require(value == 0, "Strings: hex length insufficient");
                                                return string(buffer);
                                              }
                                              function toAsciiString(address x) internal pure returns (string memory) {
                                                bytes memory s = new bytes(40);
                                                for (uint256 i = 0; i < 20; i++) {
                                                  bytes1 b = bytes1(uint8(uint256(uint160(x)) / (2**(8 * (19 - i)))));
                                                  bytes1 hi = bytes1(uint8(b) / 16);
                                                  bytes1 lo = bytes1(uint8(b) - 16 * uint8(hi));
                                                  s[2 * i] = char(hi);
                                                  s[2 * i + 1] = char(lo);
                                                }
                                                return string(s);
                                              }
                                              function char(bytes1 b) internal pure returns (bytes1 c) {
                                                if (uint8(b) < 10) {
                                                  return bytes1(uint8(b) + 0x30);
                                                } else {
                                                  return bytes1(uint8(b) + 0x57);
                                                }
                                              }
                                              function uint2str(uint256 _i) internal pure returns (string memory _uint256AsString) {
                                                if (_i == 0) {
                                                  return "0";
                                                }
                                                uint256 j = _i;
                                                uint256 len;
                                                while (j != 0) {
                                                  len++;
                                                  j /= 10;
                                                }
                                                bytes memory bstr = new bytes(len);
                                                uint256 k = len;
                                                while (_i != 0) {
                                                  k = k - 1;
                                                  uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
                                                  bytes1 b1 = bytes1(temp);
                                                  bstr[k] = b1;
                                                  _i /= 10;
                                                }
                                                return string(bstr);
                                              }
                                              function toString(uint256 value) internal pure returns (string memory) {
                                                if (value == 0) {
                                                  return "0";
                                                }
                                                uint256 temp = value;
                                                uint256 digits;
                                                while (temp != 0) {
                                                  digits++;
                                                  temp /= 10;
                                                }
                                                bytes memory buffer = new bytes(digits);
                                                while (value != 0) {
                                                  digits -= 1;
                                                  buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
                                                  value /= 10;
                                                }
                                                return string(buffer);
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 8 of 14: HolographDropERC721
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../abstract/Initializable.sol";
                                            abstract contract ERC721H is Initializable {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.holographer')) - 1)
                                               */
                                              bytes32 constant _holographerSlot = 0xe9fcff60011c1a99f7b7244d1f2d9da93d79ea8ef3654ce590d775575255b2bd;
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.owner')) - 1)
                                               */
                                              bytes32 constant _ownerSlot = 0xb56711ba6bd3ded7639fc335ee7524fe668a79d7558c85992e3f8494cf772777;
                                              modifier onlyHolographer() {
                                                require(msg.sender == holographer(), "ERC721: holographer only");
                                                _;
                                              }
                                              modifier onlyOwner() {
                                                require(msgSender() == _getOwner(), "ERC721: owner only function");
                                                _;
                                              }
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual override returns (bytes4) {
                                                return _init(initPayload);
                                              }
                                              function _init(bytes memory /* initPayload*/) internal returns (bytes4) {
                                                require(!_isInitialized(), "ERC721: already initialized");
                                                address _holographer = msg.sender;
                                                address currentOwner;
                                                assembly {
                                                  sstore(_holographerSlot, _holographer)
                                                  currentOwner := sload(_ownerSlot)
                                                }
                                                require(currentOwner != address(0), "HOLOGRAPH: owner not set");
                                                _setInitialized();
                                                return InitializableInterface.init.selector;
                                              }
                                              /**
                                               * @dev The Holographer passes original msg.sender via calldata. This function extracts it.
                                               */
                                              function msgSender() internal view returns (address sender) {
                                                assembly {
                                                  switch eq(caller(), sload(_holographerSlot))
                                                  case 0 {
                                                    sender := caller()
                                                  }
                                                  default {
                                                    sender := calldataload(sub(calldatasize(), 0x20))
                                                  }
                                                }
                                              }
                                              /**
                                               * @dev Address of Holograph ERC721 standards enforcer smart contract.
                                               */
                                              function holographer() internal view returns (address _holographer) {
                                                assembly {
                                                  _holographer := sload(_holographerSlot)
                                                }
                                              }
                                              function supportsInterface(bytes4) external pure virtual returns (bool) {
                                                return false;
                                              }
                                              /**
                                               * @dev Address of initial creator/owner of the collection.
                                               */
                                              function owner() external view virtual returns (address) {
                                                return _getOwner();
                                              }
                                              function isOwner() external view returns (bool) {
                                                return (msgSender() == _getOwner());
                                              }
                                              function isOwner(address wallet) external view returns (bool) {
                                                return wallet == _getOwner();
                                              }
                                              function _getOwner() internal view returns (address ownerAddress) {
                                                assembly {
                                                  ownerAddress := sload(_ownerSlot)
                                                }
                                              }
                                              function _setOwner(address ownerAddress) internal {
                                                assembly {
                                                  sstore(_ownerSlot, ownerAddress)
                                                }
                                              }
                                              function withdraw() external virtual onlyOwner {
                                                payable(_getOwner()).transfer(address(this).balance);
                                              }
                                              event FundsReceived(address indexed source, uint256 amount);
                                              /**
                                               * @dev This function emits an event to indicate native gas token receipt. Do not rely on this to work.
                                               *      Please use custom payable functions for accepting native value.
                                               */
                                              receive() external payable virtual {
                                                emit FundsReceived(msgSender(), msg.value);
                                              }
                                              /**
                                               * @dev Return true for any un-implemented event hooks
                                               */
                                              fallback() external payable virtual {
                                                assembly {
                                                  switch eq(sload(_holographerSlot), caller())
                                                  case 1 {
                                                    mstore(0x80, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                    return(0x80, 0x20)
                                                  }
                                                  default {
                                                    revert(0x00, 0x00)
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract NonReentrant {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.reentrant')) - 1)
                                               */
                                              bytes32 constant _reentrantSlot = 0x04b524dd539523930d3901481aa9455d7752b49add99e1647adb8b09a3137279;
                                              modifier nonReentrant() {
                                                require(getStatus() != 2, "HOLOGRAPH: reentrant call");
                                                setStatus(2);
                                                _;
                                                setStatus(1);
                                              }
                                              constructor() {}
                                              function getStatus() internal view returns (uint256 status) {
                                                assembly {
                                                  status := sload(_reentrantSlot)
                                                }
                                              }
                                              function setStatus(uint256 status) internal {
                                                assembly {
                                                  sstore(_reentrantSlot, status)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            interface IDropsPriceOracle {
                                              function convertUsdToWei(uint256 usdAmount) external view returns (uint256 weiAmount);
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            import {IMetadataRenderer} from "./IMetadataRenderer.sol";
                                            import {AddressMintDetails} from "../struct/AddressMintDetails.sol";
                                            import {SaleDetails} from "../struct/SaleDetails.sol";
                                            /// @notice Interface for HOLOGRAPH Drops contract
                                            interface IHolographDropERC721 {
                                              // Access errors
                                              /// @notice Only admin can access this function
                                              error Access_OnlyAdmin();
                                              /// @notice Missing the given role or admin access
                                              error Access_MissingRoleOrAdmin(bytes32 role);
                                              /// @notice Withdraw is not allowed by this user
                                              error Access_WithdrawNotAllowed();
                                              /// @notice Cannot withdraw funds due to ETH send failure.
                                              error Withdraw_FundsSendFailure();
                                              /// @notice Mint fee send failure
                                              error MintFee_FundsSendFailure();
                                              /// @notice Call to external metadata renderer failed.
                                              error ExternalMetadataRenderer_CallFailed();
                                              /// @notice Thrown when the operator for the contract is not allowed
                                              /// @dev Used when strict enforcement of marketplaces for creator royalties is desired.
                                              error OperatorNotAllowed(address operator);
                                              /// @notice Thrown when there is no active market filter DAO address supported for the current chain
                                              /// @dev Used for enabling and disabling filter for the given chain.
                                              error MarketFilterDAOAddressNotSupportedForChain();
                                              /// @notice Used when the operator filter registry external call fails
                                              /// @dev Used for bubbling error up to clients.
                                              error RemoteOperatorFilterRegistryCallFailed();
                                              // Sale/Purchase errors
                                              /// @notice Sale is inactive
                                              error Sale_Inactive();
                                              /// @notice Presale is inactive
                                              error Presale_Inactive();
                                              /// @notice Presale merkle root is invalid
                                              error Presale_MerkleNotApproved();
                                              /// @notice Wrong price for purchase
                                              error Purchase_WrongPrice(uint256 correctPrice);
                                              /// @notice NFT sold out
                                              error Mint_SoldOut();
                                              /// @notice Too many purchase for address
                                              error Purchase_TooManyForAddress();
                                              /// @notice Too many presale for address
                                              error Presale_TooManyForAddress();
                                              // Admin errors
                                              /// @notice Royalty percentage too high
                                              error Setup_RoyaltyPercentageTooHigh(uint16 maxRoyaltyBPS);
                                              /// @notice Invalid admin upgrade address
                                              error Admin_InvalidUpgradeAddress(address proposedAddress);
                                              /// @notice Unable to finalize an edition not marked as open (size set to uint64_max_value)
                                              error Admin_UnableToFinalizeNotOpenEdition();
                                              /// @notice Event emitted for mint fee payout
                                              /// @param mintFeeAmount amount of the mint fee
                                              /// @param mintFeeRecipient recipient of the mint fee
                                              /// @param success if the payout succeeded
                                              event MintFeePayout(uint256 mintFeeAmount, address mintFeeRecipient, bool success);
                                              /// @notice Event emitted for each sale
                                              /// @param to address sale was made to
                                              /// @param quantity quantity of the minted nfts
                                              /// @param pricePerToken price for each token
                                              /// @param firstPurchasedTokenId first purchased token ID (to get range add to quantity for max)
                                              event Sale(
                                                address indexed to,
                                                uint256 indexed quantity,
                                                uint256 indexed pricePerToken,
                                                uint256 firstPurchasedTokenId
                                              );
                                              /// @notice Sales configuration has been changed
                                              /// @dev To access new sales configuration, use getter function.
                                              /// @param changedBy Changed by user
                                              event SalesConfigChanged(address indexed changedBy);
                                              /// @notice Event emitted when the funds recipient is changed
                                              /// @param newAddress new address for the funds recipient
                                              /// @param changedBy address that the recipient is changed by
                                              event FundsRecipientChanged(address indexed newAddress, address indexed changedBy);
                                              /// @notice Event emitted when the funds are withdrawn from the minting contract
                                              /// @param withdrawnBy address that issued the withdraw
                                              /// @param withdrawnTo address that the funds were withdrawn to
                                              /// @param amount amount that was withdrawn
                                              /// @param feeRecipient user getting withdraw fee (if any)
                                              /// @param feeAmount amount of the fee getting sent (if any)
                                              event FundsWithdrawn(
                                                address indexed withdrawnBy,
                                                address indexed withdrawnTo,
                                                uint256 amount,
                                                address feeRecipient,
                                                uint256 feeAmount
                                              );
                                              /// @notice Event emitted when an open mint is finalized and further minting is closed forever on the contract.
                                              /// @param sender address sending close mint
                                              /// @param numberOfMints number of mints the contract is finalized at
                                              event OpenMintFinalized(address indexed sender, uint256 numberOfMints);
                                              /// @notice Event emitted when metadata renderer is updated.
                                              /// @param sender address of the updater
                                              /// @param renderer new metadata renderer address
                                              event UpdatedMetadataRenderer(address sender, IMetadataRenderer renderer);
                                              /// @notice Admin function to update the sales configuration settings
                                              /// @param publicSalePrice public sale price in ether
                                              /// @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed
                                              /// @param publicSaleStart unix timestamp when the public sale starts
                                              /// @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable)
                                              /// @param presaleStart unix timestamp when the presale starts
                                              /// @param presaleEnd unix timestamp when the presale ends
                                              /// @param presaleMerkleRoot merkle root for the presale information
                                              function setSaleConfiguration(
                                                uint104 publicSalePrice,
                                                uint32 maxSalePurchasePerAddress,
                                                uint64 publicSaleStart,
                                                uint64 publicSaleEnd,
                                                uint64 presaleStart,
                                                uint64 presaleEnd,
                                                bytes32 presaleMerkleRoot
                                              ) external;
                                              /// @notice External purchase function (payable in eth)
                                              /// @param quantity to purchase
                                              /// @return first minted token ID
                                              function purchase(uint256 quantity) external payable returns (uint256);
                                              /// @notice External purchase presale function (takes a merkle proof and matches to root) (payable in eth)
                                              /// @param quantity to purchase
                                              /// @param maxQuantity can purchase (verified by merkle root)
                                              /// @param pricePerToken price per token allowed (verified by merkle root)
                                              /// @param merkleProof input for merkle proof leaf verified by merkle root
                                              /// @return first minted token ID
                                              function purchasePresale(
                                                uint256 quantity,
                                                uint256 maxQuantity,
                                                uint256 pricePerToken,
                                                bytes32[] memory merkleProof
                                              ) external payable returns (uint256);
                                              /// @notice Function to return the global sales details for the given drop
                                              function saleDetails() external view returns (SaleDetails memory);
                                              /// @notice Function to return the specific sales details for a given address
                                              /// @param minter address for minter to return mint information for
                                              function mintedPerAddress(address minter) external view returns (AddressMintDetails memory);
                                              /// @notice This is the opensea/public owner setting that can be set by the contract admin
                                              function owner() external view returns (address);
                                              /// @notice Update the metadata renderer
                                              /// @param newRenderer new address for renderer
                                              /// @param setupRenderer data to call to bootstrap data for the new renderer (optional)
                                              function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external;
                                              /// @notice This is an admin mint function to mint a quantity to a specific address
                                              /// @param to address to mint to
                                              /// @param quantity quantity to mint
                                              /// @return the id of the first minted NFT
                                              function adminMint(address to, uint256 quantity) external returns (uint256);
                                              /// @notice This is an admin mint function to mint a single nft each to a list of addresses
                                              /// @param to list of addresses to mint an NFT each to
                                              /// @return the id of the first minted NFT
                                              function adminMintAirdrop(address[] memory to) external returns (uint256);
                                              /// @dev Getter for admin role associated with the contract to handle metadata
                                              /// @return boolean if address is admin
                                              function isAdmin(address user) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            interface IMetadataRenderer {
                                              function tokenURI(uint256) external view returns (string memory);
                                              function contractURI() external view returns (string memory);
                                              function initializeWithData(bytes memory initData) external;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            interface IOperatorFilterRegistry {
                                              function isOperatorAllowed(address registrant, address operator) external view returns (bool);
                                              function register(address registrant) external;
                                              function registerAndSubscribe(address registrant, address subscription) external;
                                              function registerAndCopyEntries(address registrant, address registrantToCopy) external;
                                              function updateOperator(address registrant, address operator, bool filtered) external;
                                              function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
                                              function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
                                              function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
                                              function subscribe(address registrant, address registrantToSubscribe) external;
                                              function unsubscribe(address registrant, bool copyExistingEntries) external;
                                              function subscriptionOf(address addr) external returns (address registrant);
                                              function subscribers(address registrant) external returns (address[] memory);
                                              function subscriberAt(address registrant, uint256 index) external returns (address);
                                              function copyEntriesOf(address registrant, address registrantToCopy) external;
                                              function isOperatorFiltered(address registrant, address operator) external returns (bool);
                                              function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
                                              function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
                                              function filteredOperators(address addr) external returns (address[] memory);
                                              function filteredCodeHashes(address addr) external returns (bytes32[] memory);
                                              function filteredOperatorAt(address registrant, uint256 index) external returns (address);
                                              function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
                                              function isRegistered(address addr) external returns (bool);
                                              function codeHashOf(address addr) external returns (bytes32);
                                              function unregister(address registrant) external;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            library Address {
                                              function isContract(address account) internal view returns (bool) {
                                                // This method relies on extcodesize/address.code.length, which returns 0
                                                // for contracts in construction, since the code is only stored at the end
                                                // of the constructor execution.
                                                return account.code.length > 0;
                                              }
                                              /**
                                               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
                                               * but performing a delegate call.
                                               *
                                               * _Available since v3.4._
                                               */
                                              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                                                return functionDelegateCall(target, data, "Address: low-level delegate call failed");
                                              }
                                              /**
                                               * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
                                               * but performing a delegate call.
                                               *
                                               * _Available since v3.4._
                                               */
                                              function functionDelegateCall(
                                                address target,
                                                bytes memory data,
                                                string memory errorMessage
                                              ) internal returns (bytes memory) {
                                                (bool success, bytes memory returndata) = target.delegatecall(data);
                                                return verifyCallResultFromTarget(target, success, returndata, errorMessage);
                                              }
                                              /**
                                               * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
                                               * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
                                               *
                                               * _Available since v4.8._
                                               */
                                              function verifyCallResultFromTarget(
                                                address target,
                                                bool success,
                                                bytes memory returndata,
                                                string memory errorMessage
                                              ) internal view returns (bytes memory) {
                                                if (success) {
                                                  if (returndata.length == 0) {
                                                    // only check isContract if the call was successful and the return data is empty
                                                    // otherwise we already know that it was a contract
                                                    require(isContract(target), "Address: call to non-contract");
                                                  }
                                                  return returndata;
                                                } else {
                                                  _revert(returndata, errorMessage);
                                                }
                                              }
                                              function _revert(bytes memory returndata, string memory errorMessage) private pure {
                                                // Look for revert reason and bubble it up if present
                                                if (returndata.length > 0) {
                                                  // The easiest way to bubble the revert reason is using memory via assembly
                                                  /// @solidity memory-safe-assembly
                                                  assembly {
                                                    let returndata_size := mload(returndata)
                                                    revert(add(32, returndata), returndata_size)
                                                  }
                                                } else {
                                                  revert(errorMessage);
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            library MerkleProof {
                                              /**
                                               * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
                                               * defined by `root`. For this, a `proof` must be provided, containing
                                               * sibling hashes on the branch from the leaf to the root of the tree. Each
                                               * pair of leaves and each pair of pre-images are assumed to be sorted.
                                               */
                                              function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
                                                return processProof(proof, leaf) == root;
                                              }
                                              /**
                                               * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
                                               * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
                                               * hash matches the root of the tree. When processing the proof, the pairs
                                               * of leafs & pre-images are assumed to be sorted.
                                               *
                                               * _Available since v4.4._
                                               */
                                              function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
                                                bytes32 computedHash = leaf;
                                                for (uint256 i = 0; i < proof.length; i++) {
                                                  bytes32 proofElement = proof[i];
                                                  if (computedHash <= proofElement) {
                                                    // Hash(current computed hash + current element of the proof)
                                                    computedHash = _efficientHash(computedHash, proofElement);
                                                  } else {
                                                    // Hash(current element of the proof + current computed hash)
                                                    computedHash = _efficientHash(proofElement, computedHash);
                                                  }
                                                }
                                                return computedHash;
                                              }
                                              function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
                                                assembly {
                                                  mstore(0x00, a)
                                                  mstore(0x20, b)
                                                  value := keccak256(0x00, 0x40)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            /// @notice Return type of specific mint counts and details per address
                                            struct AddressMintDetails {
                                              /// Number of total mints from the given address
                                              uint256 totalMints;
                                              /// Number of presale mints from the given address
                                              uint256 presaleMints;
                                              /// Number of public mints from the given address
                                              uint256 publicMints;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            import {IMetadataRenderer} from "../interface/IMetadataRenderer.sol";
                                            /// @notice General configuration for NFT Minting and bookkeeping
                                            struct Configuration {
                                              /// @dev Metadata renderer (uint160)
                                              IMetadataRenderer metadataRenderer;
                                              /// @dev Total size of edition that can be minted (uint160+64 = 224)
                                              uint64 editionSize;
                                              /// @dev Royalty amount in bps (uint224+16 = 240)
                                              uint16 royaltyBPS;
                                              /// @dev Funds recipient for sale (new slot, uint160)
                                              address payable fundsRecipient;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            import {SalesConfiguration} from "./SalesConfiguration.sol";
                                            /// @param erc721TransferHelper Transfer helper contract
                                            /// @param marketFilterAddress Market filter address - Manage subscription to the for marketplace filtering based off royalty payouts.
                                            /// @param initialOwner User that owns and can mint the edition, gets royalty and sales payouts and can update the base url if needed.
                                            /// @param fundsRecipient Wallet/user that receives funds from sale
                                            /// @param editionSize Number of editions that can be minted in total. If type(uint64).max, unlimited editions can be minted as an open edition.
                                            /// @param royaltyBPS BPS of the royalty set on the contract. Can be 0 for no royalty.
                                            /// @param salesConfiguration The initial SalesConfiguration
                                            /// @param metadataRenderer Renderer contract to use
                                            /// @param metadataRendererInit Renderer data initial contract
                                            struct DropsInitializer {
                                              address erc721TransferHelper;
                                              address marketFilterAddress;
                                              address initialOwner;
                                              address payable fundsRecipient;
                                              uint64 editionSize;
                                              uint16 royaltyBPS;
                                              bool enableOpenSeaRoyaltyRegistry;
                                              SalesConfiguration salesConfiguration;
                                              address metadataRenderer;
                                              bytes metadataRendererInit;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            /// @notice Return value for sales details to use with front-ends
                                            struct SaleDetails {
                                              // Synthesized status variables for sale and presale
                                              bool publicSaleActive;
                                              bool presaleActive;
                                              // Price for public sale
                                              uint256 publicSalePrice;
                                              // Timed sale actions for public sale
                                              uint64 publicSaleStart;
                                              uint64 publicSaleEnd;
                                              // Timed sale actions for presale
                                              uint64 presaleStart;
                                              uint64 presaleEnd;
                                              // Merkle root (includes address, quantity, and price data for each entry)
                                              bytes32 presaleMerkleRoot;
                                              // Limit public sale to a specific number of mints per wallet
                                              uint256 maxSalePurchasePerAddress;
                                              // Information about the rest of the supply
                                              // Total that have been minted
                                              uint256 totalMinted;
                                              // The total supply available
                                              uint256 maxSupply;
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            /// @notice Sales states and configuration
                                            /// @dev Uses 3 storage slots
                                            struct SalesConfiguration {
                                              /// @dev Public sale price (max ether value > 1000 ether with this value)
                                              uint104 publicSalePrice;
                                              /// @notice Purchase mint limit per address (if set to 0 === unlimited mints)
                                              /// @dev Max purchase number per txn (90+32 = 122)
                                              uint32 maxSalePurchasePerAddress;
                                              /// @dev uint64 type allows for dates into 292 billion years
                                              /// @notice Public sale start timestamp (136+64 = 186)
                                              uint64 publicSaleStart;
                                              /// @notice Public sale end timestamp (186+64 = 250)
                                              uint64 publicSaleEnd;
                                              /// @notice Presale start timestamp
                                              /// @dev new storage slot
                                              uint64 presaleStart;
                                              /// @notice Presale end timestamp
                                              uint64 presaleEnd;
                                              /// @notice Presale merkle root
                                              bytes32 presaleMerkleRoot;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import {ERC721H} from "../../abstract/ERC721H.sol";
                                            import {NonReentrant} from "../../abstract/NonReentrant.sol";
                                            import {HolographERC721Interface} from "../../interface/HolographERC721Interface.sol";
                                            import {HolographerInterface} from "../../interface/HolographerInterface.sol";
                                            import {HolographInterface} from "../../interface/HolographInterface.sol";
                                            import {AddressMintDetails} from "../struct/AddressMintDetails.sol";
                                            import {Configuration} from "../struct/Configuration.sol";
                                            import {DropsInitializer} from "../struct/DropsInitializer.sol";
                                            import {SaleDetails} from "../struct/SaleDetails.sol";
                                            import {SalesConfiguration} from "../struct/SalesConfiguration.sol";
                                            import {Address} from "../library/Address.sol";
                                            import {MerkleProof} from "../library/MerkleProof.sol";
                                            import {IMetadataRenderer} from "../interface/IMetadataRenderer.sol";
                                            import {IOperatorFilterRegistry} from "../interface/IOperatorFilterRegistry.sol";
                                            import {IHolographDropERC721} from "../interface/IHolographDropERC721.sol";
                                            import {IDropsPriceOracle} from "../interface/IDropsPriceOracle.sol";
                                            /**
                                             * @dev This contract subscribes to the following HolographERC721 events:
                                             *       - beforeSafeTransfer
                                             *       - beforeTransfer
                                             *       - onIsApprovedForAll
                                             *       - customContractURI
                                             *
                                             *       Do not enable or subscribe to any other events unless you modified your source code for them.
                                             */
                                            contract HolographDropERC721 is NonReentrant, ERC721H, IHolographDropERC721 {
                                              /**
                                               * CONTRACT VARIABLES
                                               * all variables, without custom storage slots, are defined here
                                               */
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.osRegistryEnabled')) - 1)
                                               */
                                              bytes32 constant _osRegistryEnabledSlot = 0x5c835f3b6bd322d9a084ffdeac746df2b96cce308e7f0612f4ff4f9c490734cc;
                                              /**
                                               * @dev Address of the operator filter registry
                                               */
                                              IOperatorFilterRegistry public constant openseaOperatorFilterRegistry =
                                                IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);
                                              /**
                                               * @dev Address of the price oracle proxy
                                               */
                                              IDropsPriceOracle public constant dropsPriceOracle = IDropsPriceOracle(0xA3Db09EEC42BAfF7A50fb8F9aF90A0e035Ef3302);
                                              /**
                                               * @dev Internal reference used for minting incremental token ids.
                                               */
                                              uint224 private _currentTokenId;
                                              /**
                                               * @dev HOLOGRAPH transfer helper address for auto-approval
                                               */
                                              address public erc721TransferHelper;
                                              /**
                                               * @dev Address of the market filter registry
                                               */
                                              address public marketFilterAddress;
                                              /**
                                               * @notice Configuration for NFT minting contract storage
                                               */
                                              Configuration public config;
                                              /**
                                               * @notice Sales configuration
                                               */
                                              SalesConfiguration public salesConfig;
                                              /**
                                               * @dev Mapping for presale mint counts by address to allow public mint limit
                                               */
                                              mapping(address => uint256) public presaleMintsByAddress;
                                              /**
                                               * @dev Mapping for presale mint counts by address to allow public mint limit
                                               */
                                              mapping(address => uint256) public totalMintsByAddress;
                                              /**
                                               * CUSTOM ERRORS
                                               */
                                              /**
                                               * @notice Thrown when there is no active market filter address supported for the current chain
                                               * @dev Used for enabling and disabling filter for the given chain.
                                               */
                                              error MarketFilterAddressNotSupportedForChain();
                                              /**
                                               * MODIFIERS
                                               */
                                              /**
                                               * @notice Allows user to mint tokens at a quantity
                                               */
                                              modifier canMintTokens(uint256 quantity) {
                                                if (config.editionSize != 0 && quantity + _currentTokenId > config.editionSize) {
                                                  revert Mint_SoldOut();
                                                }
                                                _;
                                              }
                                              /**
                                               * @notice Presale active
                                               */
                                              modifier onlyPresaleActive() {
                                                if (!_presaleActive()) {
                                                  revert Presale_Inactive();
                                                }
                                                _;
                                              }
                                              /**
                                               * @notice Public sale active
                                               */
                                              modifier onlyPublicSaleActive() {
                                                if (!_publicSaleActive()) {
                                                  revert Sale_Inactive();
                                                }
                                                _;
                                              }
                                              /**
                                               * CONTRACT INITIALIZERS
                                               * init function is used instead of constructor
                                               */
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                DropsInitializer memory initializer = abi.decode(initPayload, (DropsInitializer));
                                                erc721TransferHelper = initializer.erc721TransferHelper;
                                                if (initializer.marketFilterAddress != address(0)) {
                                                  marketFilterAddress = initializer.marketFilterAddress;
                                                }
                                                // Setup the owner role
                                                _setOwner(initializer.initialOwner);
                                                // Setup config variables
                                                config = Configuration({
                                                  metadataRenderer: IMetadataRenderer(initializer.metadataRenderer),
                                                  editionSize: initializer.editionSize,
                                                  royaltyBPS: initializer.royaltyBPS,
                                                  fundsRecipient: initializer.fundsRecipient
                                                });
                                                salesConfig = initializer.salesConfiguration;
                                                // TODO: Need to make sure to initialize the metadata renderer
                                                if (initializer.metadataRenderer != address(0)) {
                                                  IMetadataRenderer(initializer.metadataRenderer).initializeWithData(initializer.metadataRendererInit);
                                                }
                                                if (initializer.enableOpenSeaRoyaltyRegistry && Address.isContract(address(openseaOperatorFilterRegistry))) {
                                                  if (marketFilterAddress == address(0)) {
                                                    // this is a default filter that can be used for OS royalty filtering
                                                    // marketFilterAddress = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;
                                                    // we just register to OS royalties and let OS handle it for us with their default filter contract
                                                    openseaOperatorFilterRegistry.register(address(this));
                                                  } else {
                                                    // allow user to specify custom filtering contract address
                                                    openseaOperatorFilterRegistry.registerAndSubscribe(address(this), marketFilterAddress);
                                                  }
                                                  assembly {
                                                    sstore(_osRegistryEnabledSlot, true)
                                                  }
                                                }
                                                setStatus(1);
                                                return _init(initPayload);
                                              }
                                              /**
                                               * PUBLIC NON STATE CHANGING FUNCTIONS
                                               * static
                                               */
                                              /**
                                               * @notice Returns the version of the contract
                                               * @dev Used for contract versioning and validation
                                               * @return version string representing the version of the contract
                                               */
                                              function version() external pure returns (string memory) {
                                                return "1.0.0";
                                              }
                                              function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
                                                return interfaceId == type(IHolographDropERC721).interfaceId;
                                              }
                                              /**
                                               * PUBLIC NON STATE CHANGING FUNCTIONS
                                               * dynamic
                                               */
                                              function owner() external view override(ERC721H, IHolographDropERC721) returns (address) {
                                                return _getOwner();
                                              }
                                              function isAdmin(address user) external view returns (bool) {
                                                return (_getOwner() == user);
                                              }
                                              function beforeSafeTransfer(
                                                address _from,
                                                address /* _to*/,
                                                uint256 /* _tokenId*/,
                                                bytes calldata /* _data*/
                                              ) external view returns (bool) {
                                                if (
                                                  _from != address(0) && // skip on mints
                                                  _from != msgSender() // skip on transfers from sender
                                                ) {
                                                  bool osRegistryEnabled;
                                                  assembly {
                                                    osRegistryEnabled := sload(_osRegistryEnabledSlot)
                                                  }
                                                  if (osRegistryEnabled) {
                                                    try openseaOperatorFilterRegistry.isOperatorAllowed(address(this), msgSender()) returns (bool allowed) {
                                                      return allowed;
                                                    } catch {
                                                      revert OperatorNotAllowed(msgSender());
                                                    }
                                                  }
                                                }
                                                return true;
                                              }
                                              function beforeTransfer(
                                                address _from,
                                                address /* _to*/,
                                                uint256 /* _tokenId*/,
                                                bytes calldata /* _data*/
                                              ) external view returns (bool) {
                                                if (
                                                  _from != address(0) && // skip on mints
                                                  _from != msgSender() // skip on transfers from sender
                                                ) {
                                                  bool osRegistryEnabled;
                                                  assembly {
                                                    osRegistryEnabled := sload(_osRegistryEnabledSlot)
                                                  }
                                                  if (osRegistryEnabled) {
                                                    try openseaOperatorFilterRegistry.isOperatorAllowed(address(this), msgSender()) returns (bool allowed) {
                                                      return allowed;
                                                    } catch {
                                                      revert OperatorNotAllowed(msgSender());
                                                    }
                                                  }
                                                }
                                                return true;
                                              }
                                              function onIsApprovedForAll(address /* _wallet*/, address _operator) external view returns (bool approved) {
                                                approved = (erc721TransferHelper != address(0) && _operator == erc721TransferHelper);
                                              }
                                              /**
                                               * @notice Sale details
                                               * @return SaleDetails sale information details
                                               */
                                              function saleDetails() external view returns (SaleDetails memory) {
                                                return
                                                  SaleDetails({
                                                    publicSaleActive: _publicSaleActive(),
                                                    presaleActive: _presaleActive(),
                                                    publicSalePrice: salesConfig.publicSalePrice,
                                                    publicSaleStart: salesConfig.publicSaleStart,
                                                    publicSaleEnd: salesConfig.publicSaleEnd,
                                                    presaleStart: salesConfig.presaleStart,
                                                    presaleEnd: salesConfig.presaleEnd,
                                                    presaleMerkleRoot: salesConfig.presaleMerkleRoot,
                                                    totalMinted: _currentTokenId,
                                                    maxSupply: config.editionSize,
                                                    maxSalePurchasePerAddress: salesConfig.maxSalePurchasePerAddress
                                                  });
                                              }
                                              /**
                                               * @dev Number of NFTs the user has minted per address
                                               * @param minter to get counts for
                                               */
                                              function mintedPerAddress(address minter) external view returns (AddressMintDetails memory) {
                                                return
                                                  AddressMintDetails({
                                                    presaleMints: presaleMintsByAddress[minter],
                                                    publicMints: totalMintsByAddress[minter] - presaleMintsByAddress[minter],
                                                    totalMints: totalMintsByAddress[minter]
                                                  });
                                              }
                                              /**
                                               * @notice Contract URI Getter, proxies to metadataRenderer
                                               * @return Contract URI
                                               */
                                              function contractURI() external view returns (string memory) {
                                                return config.metadataRenderer.contractURI();
                                              }
                                              /**
                                               * @notice Getter for metadataRenderer contract
                                               */
                                              function metadataRenderer() external view returns (IMetadataRenderer) {
                                                return IMetadataRenderer(config.metadataRenderer);
                                              }
                                              /**
                                               * @notice Convert USD price to current price in native Ether
                                               */
                                              function getNativePrice() external view returns (uint256) {
                                                return _usdToWei(salesConfig.publicSalePrice);
                                              }
                                              /**
                                               * @notice Returns the name of the token through the holographer entrypoint
                                               */
                                              function name() external view returns (string memory) {
                                                return HolographERC721Interface(holographer()).name();
                                              }
                                              /**
                                               * @notice Token URI Getter, proxies to metadataRenderer
                                               * @param tokenId id of token to get URI for
                                               * @return Token URI
                                               */
                                              function tokenURI(uint256 tokenId) external view returns (string memory) {
                                                HolographERC721Interface H721 = HolographERC721Interface(holographer());
                                                require(H721.exists(tokenId), "ERC721: token does not exist");
                                                return config.metadataRenderer.tokenURI(tokenId);
                                              }
                                              /**
                                               * PUBLIC STATE CHANGING FUNCTIONS
                                               * available to all
                                               */
                                              function multicall(bytes[] memory data) public returns (bytes[] memory results) {
                                                results = new bytes[](data.length);
                                                for (uint256 i = 0; i < data.length; i++) {
                                                  results[i] = Address.functionDelegateCall(address(this), abi.encodePacked(data[i], msgSender()));
                                                }
                                              }
                                              /**
                                               * @dev This allows the user to purchase/mint a edition at the given price in the contract.
                                               */
                                              function purchase(
                                                uint256 quantity
                                              ) external payable nonReentrant canMintTokens(quantity) onlyPublicSaleActive returns (uint256) {
                                                uint256 salePrice = _usdToWei(salesConfig.publicSalePrice);
                                                if (msg.value < salePrice * quantity) {
                                                  revert Purchase_WrongPrice(salesConfig.publicSalePrice * quantity);
                                                }
                                                uint256 remainder = msg.value - (salePrice * quantity);
                                                // If max purchase per address == 0 there is no limit.
                                                // Any other number, the per address mint limit is that.
                                                if (
                                                  salesConfig.maxSalePurchasePerAddress != 0 &&
                                                  totalMintsByAddress[msgSender()] + quantity - presaleMintsByAddress[msgSender()] >
                                                  salesConfig.maxSalePurchasePerAddress
                                                ) {
                                                  revert Purchase_TooManyForAddress();
                                                }
                                                _mintNFTs(msgSender(), quantity);
                                                HolographERC721Interface H721 = HolographERC721Interface(holographer());
                                                uint256 chainPrepend = H721.sourceGetChainPrepend();
                                                uint256 firstMintedTokenId = (chainPrepend + uint256(_currentTokenId - quantity)) + 1;
                                                emit Sale({
                                                  to: msgSender(),
                                                  quantity: quantity,
                                                  pricePerToken: salePrice,
                                                  firstPurchasedTokenId: firstMintedTokenId
                                                });
                                                if (remainder > 0) {
                                                  msgSender().call{value: remainder, gas: gasleft() > 210_000 ? 210_000 : gasleft()}("");
                                                }
                                                return firstMintedTokenId;
                                              }
                                              /**
                                               * @notice Merkle-tree based presale purchase function
                                               * @param quantity quantity to purchase
                                               * @param maxQuantity max quantity that can be purchased via merkle proof #
                                               * @param pricePerToken price that each token is purchased at
                                               * @param merkleProof proof for presale mint
                                               */
                                              function purchasePresale(
                                                uint256 quantity,
                                                uint256 maxQuantity,
                                                uint256 pricePerToken,
                                                bytes32[] calldata merkleProof
                                              ) external payable nonReentrant canMintTokens(quantity) onlyPresaleActive returns (uint256) {
                                                if (
                                                  !MerkleProof.verify(
                                                    merkleProof,
                                                    salesConfig.presaleMerkleRoot,
                                                    keccak256(
                                                      // address, uint256, uint256
                                                      abi.encode(msgSender(), maxQuantity, pricePerToken)
                                                    )
                                                  )
                                                ) {
                                                  revert Presale_MerkleNotApproved();
                                                }
                                                uint256 weiPricePerToken = _usdToWei(pricePerToken);
                                                if (msg.value < weiPricePerToken * quantity) {
                                                  revert Purchase_WrongPrice(pricePerToken * quantity);
                                                }
                                                uint256 remainder = msg.value - (weiPricePerToken * quantity);
                                                presaleMintsByAddress[msgSender()] += quantity;
                                                if (presaleMintsByAddress[msgSender()] > maxQuantity) {
                                                  revert Presale_TooManyForAddress();
                                                }
                                                _mintNFTs(msgSender(), quantity);
                                                HolographERC721Interface H721 = HolographERC721Interface(holographer());
                                                uint256 chainPrepend = H721.sourceGetChainPrepend();
                                                uint256 firstMintedTokenId = (chainPrepend + uint256(_currentTokenId - quantity)) + 1;
                                                emit Sale({
                                                  to: msgSender(),
                                                  quantity: quantity,
                                                  pricePerToken: weiPricePerToken,
                                                  firstPurchasedTokenId: firstMintedTokenId
                                                });
                                                if (remainder > 0) {
                                                  msgSender().call{value: remainder, gas: gasleft() > 210_000 ? 210_000 : gasleft()}("");
                                                }
                                                return firstMintedTokenId;
                                              }
                                              /**
                                               * PUBLIC STATE CHANGING FUNCTIONS
                                               * admin only
                                               */
                                              /**
                                               * @notice Proxy to update market filter settings in the main registry contracts
                                               * @notice Requires admin permissions
                                               * @param args Calldata args to pass to the registry
                                               */
                                              function updateMarketFilterSettings(bytes calldata args) external onlyOwner returns (bytes memory) {
                                                (bool success, bytes memory ret) = address(openseaOperatorFilterRegistry).call(args);
                                                if (!success) {
                                                  revert RemoteOperatorFilterRegistryCallFailed();
                                                }
                                                bool osRegistryEnabled = openseaOperatorFilterRegistry.isRegistered(address(this));
                                                assembly {
                                                  sstore(_osRegistryEnabledSlot, osRegistryEnabled)
                                                }
                                                return ret;
                                              }
                                              /**
                                               * @notice Manage subscription for marketplace filtering based off royalty payouts.
                                               * @param enable Enable filtering to non-royalty payout marketplaces
                                               */
                                              function manageMarketFilterSubscription(bool enable) external onlyOwner {
                                                address self = address(this);
                                                if (marketFilterAddress == address(0)) {
                                                  revert MarketFilterAddressNotSupportedForChain();
                                                }
                                                if (!openseaOperatorFilterRegistry.isRegistered(self) && enable) {
                                                  openseaOperatorFilterRegistry.registerAndSubscribe(self, marketFilterAddress);
                                                } else if (enable) {
                                                  openseaOperatorFilterRegistry.subscribe(self, marketFilterAddress);
                                                } else {
                                                  openseaOperatorFilterRegistry.unsubscribe(self, false);
                                                  openseaOperatorFilterRegistry.unregister(self);
                                                }
                                                bool osRegistryEnabled = openseaOperatorFilterRegistry.isRegistered(address(this));
                                                assembly {
                                                  sstore(_osRegistryEnabledSlot, osRegistryEnabled)
                                                }
                                              }
                                              function modifyMarketFilterAddress(address newMarketFilterAddress) external onlyOwner {
                                                marketFilterAddress = newMarketFilterAddress;
                                              }
                                              /**
                                               * @notice Admin mint tokens to a recipient for free
                                               * @param recipient recipient to mint to
                                               * @param quantity quantity to mint
                                               */
                                              function adminMint(address recipient, uint256 quantity) external onlyOwner canMintTokens(quantity) returns (uint256) {
                                                _mintNFTs(recipient, quantity);
                                                return _currentTokenId;
                                              }
                                              /**
                                               * @dev Mints multiple editions to the given list of addresses.
                                               * @param recipients list of addresses to send the newly minted editions to
                                               */
                                              function adminMintAirdrop(
                                                address[] calldata recipients
                                              ) external onlyOwner canMintTokens(recipients.length) returns (uint256) {
                                                unchecked {
                                                  for (uint256 i = 0; i < recipients.length; i++) {
                                                    _mintNFTs(recipients[i], 1);
                                                  }
                                                }
                                                return _currentTokenId;
                                              }
                                              /**
                                               * @notice Set a new metadata renderer
                                               * @param newRenderer new renderer address to use
                                               * @param setupRenderer data to setup new renderer with
                                               */
                                              function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external onlyOwner {
                                                config.metadataRenderer = newRenderer;
                                                if (setupRenderer.length > 0) {
                                                  newRenderer.initializeWithData(setupRenderer);
                                                }
                                                emit UpdatedMetadataRenderer({sender: msgSender(), renderer: newRenderer});
                                              }
                                              /**
                                               * @dev This sets the sales configuration
                                               * @param publicSalePrice New public sale price
                                               * @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed
                                               * @param publicSaleStart unix timestamp when the public sale starts
                                               * @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable)
                                               * @param presaleStart unix timestamp when the presale starts
                                               * @param presaleEnd unix timestamp when the presale ends
                                               * @param presaleMerkleRoot merkle root for the presale information
                                               */
                                              function setSaleConfiguration(
                                                uint104 publicSalePrice,
                                                uint32 maxSalePurchasePerAddress,
                                                uint64 publicSaleStart,
                                                uint64 publicSaleEnd,
                                                uint64 presaleStart,
                                                uint64 presaleEnd,
                                                bytes32 presaleMerkleRoot
                                              ) external onlyOwner {
                                                salesConfig.publicSalePrice = publicSalePrice;
                                                salesConfig.maxSalePurchasePerAddress = maxSalePurchasePerAddress;
                                                salesConfig.publicSaleStart = publicSaleStart;
                                                salesConfig.publicSaleEnd = publicSaleEnd;
                                                salesConfig.presaleStart = presaleStart;
                                                salesConfig.presaleEnd = presaleEnd;
                                                salesConfig.presaleMerkleRoot = presaleMerkleRoot;
                                                emit SalesConfigChanged(msgSender());
                                              }
                                              /**
                                               * @notice Set a different funds recipient
                                               * @param newRecipientAddress new funds recipient address
                                               */
                                              function setFundsRecipient(address payable newRecipientAddress) external onlyOwner {
                                                if (newRecipientAddress == address(0)) {
                                                  revert("Funds Recipient cannot be 0 address");
                                                }
                                                config.fundsRecipient = newRecipientAddress;
                                                emit FundsRecipientChanged(newRecipientAddress, msgSender());
                                              }
                                              /**
                                               * @notice This withdraws ETH from the contract to the contract owner.
                                               */
                                              function withdraw() external override nonReentrant {
                                                if (config.fundsRecipient == address(0)) {
                                                  revert("Funds Recipient address not set");
                                                }
                                                address sender = msgSender();
                                                // Get fee amount
                                                uint256 funds = address(this).balance;
                                                address payable feeRecipient = payable(
                                                  HolographInterface(HolographerInterface(holographer()).getHolograph()).getTreasury()
                                                );
                                                // for now set it to 0 since there is no fee
                                                uint256 holographFee = 0;
                                                // Check if withdraw is allowed for sender
                                                if (sender != config.fundsRecipient && sender != _getOwner() && sender != feeRecipient) {
                                                  revert Access_WithdrawNotAllowed();
                                                }
                                                // Payout HOLOGRAPH fee
                                                if (holographFee > 0) {
                                                  (bool successFee, ) = feeRecipient.call{value: holographFee, gas: 210_000}("");
                                                  if (!successFee) {
                                                    revert Withdraw_FundsSendFailure();
                                                  }
                                                  funds -= holographFee;
                                                }
                                                // Payout recipient
                                                (bool successFunds, ) = config.fundsRecipient.call{value: funds, gas: 210_000}("");
                                                if (!successFunds) {
                                                  revert Withdraw_FundsSendFailure();
                                                }
                                                // Emit event for indexing
                                                emit FundsWithdrawn(sender, config.fundsRecipient, funds, feeRecipient, holographFee);
                                              }
                                              /**
                                               * @notice Admin function to finalize and open edition sale
                                               */
                                              function finalizeOpenEdition() external onlyOwner {
                                                if (config.editionSize != type(uint64).max) {
                                                  revert Admin_UnableToFinalizeNotOpenEdition();
                                                }
                                                config.editionSize = uint64(_currentTokenId);
                                                emit OpenMintFinalized(msgSender(), config.editionSize);
                                              }
                                              /**
                                               * INTERNAL FUNCTIONS
                                               * non state changing
                                               */
                                              function _presaleActive() internal view returns (bool) {
                                                return salesConfig.presaleStart <= block.timestamp && salesConfig.presaleEnd > block.timestamp;
                                              }
                                              function _publicSaleActive() internal view returns (bool) {
                                                return salesConfig.publicSaleStart <= block.timestamp && salesConfig.publicSaleEnd > block.timestamp;
                                              }
                                              function _usdToWei(uint256 amount) internal view returns (uint256 weiAmount) {
                                                if (amount == 0) {
                                                  return 0;
                                                }
                                                weiAmount = dropsPriceOracle.convertUsdToWei(amount);
                                              }
                                              /**
                                               * INTERNAL FUNCTIONS
                                               * state changing
                                               */
                                              function _mintNFTs(address recipient, uint256 quantity) internal {
                                                HolographERC721Interface H721 = HolographERC721Interface(holographer());
                                                uint256 chainPrepend = H721.sourceGetChainPrepend();
                                                uint224 tokenId = 0;
                                                for (uint256 i = 0; i < quantity; i++) {
                                                  _currentTokenId += 1;
                                                  while (
                                                    H721.exists(chainPrepend + uint256(_currentTokenId)) || H721.burned(chainPrepend + uint256(_currentTokenId))
                                                  ) {
                                                    _currentTokenId += 1;
                                                  }
                                                  tokenId = _currentTokenId;
                                                  H721.sourceMint(recipient, tokenId);
                                                  // uint256 id = chainPrepend + uint256(tokenId);
                                                }
                                              }
                                              fallback() external payable override {
                                                assembly {
                                                  // Allocate memory for the error message
                                                  let errorMsg := mload(0x40)
                                                  // Error message: "Function not found", properly padded with zeroes
                                                  mstore(errorMsg, 0x46756e6374696f6e206e6f7420666f756e640000000000000000000000000000)
                                                  // Revert with the error message
                                                  revert(errorMsg, 20) // 20 is the length of the error message in bytes
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface CollectionURI {
                                              function contractURI() external view returns (string memory);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            interface ERC165 {
                                              /// @notice Query if a contract implements an interface
                                              /// @param interfaceID The interface identifier, as specified in ERC-165
                                              /// @dev Interface identification is specified in ERC-165. This function
                                              ///  uses less than 30,000 gas.
                                              /// @return `true` if the contract implements `interfaceID` and
                                              ///  `interfaceID` is not 0xffffffff, `false` otherwise
                                              function supportsInterface(bytes4 interfaceID) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x80ac58cd.
                                            /* is ERC165 */
                                            interface ERC721 {
                                              /// @dev This emits when ownership of any NFT changes by any mechanism.
                                              ///  This event emits when NFTs are created (`from` == 0) and destroyed
                                              ///  (`to` == 0). Exception: during contract creation, any number of NFTs
                                              ///  may be created and assigned without emitting Transfer. At the time of
                                              ///  any transfer, the approved address for that NFT (if any) is reset to none.
                                              event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
                                              /// @dev This emits when the approved address for an NFT is changed or
                                              ///  reaffirmed. The zero address indicates there is no approved address.
                                              ///  When a Transfer event emits, this also indicates that the approved
                                              ///  address for that NFT (if any) is reset to none.
                                              event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
                                              /// @dev This emits when an operator is enabled or disabled for an owner.
                                              ///  The operator can manage all NFTs of the owner.
                                              event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
                                              /// @notice Count all NFTs assigned to an owner
                                              /// @dev NFTs assigned to the zero address are considered invalid, and this
                                              ///  function throws for queries about the zero address.
                                              /// @param _owner An address for whom to query the balance
                                              /// @return The number of NFTs owned by `_owner`, possibly zero
                                              function balanceOf(address _owner) external view returns (uint256);
                                              /// @notice Find the owner of an NFT
                                              /// @dev NFTs assigned to zero address are considered invalid, and queries
                                              ///  about them do throw.
                                              /// @param _tokenId The identifier for an NFT
                                              /// @return The address of the owner of the NFT
                                              function ownerOf(uint256 _tokenId) external view returns (address);
                                              /// @notice Transfers the ownership of an NFT from one address to another address
                                              /// @dev Throws unless `msg.sender` is the current owner, an authorized
                                              ///  operator, or the approved address for this NFT. Throws if `_from` is
                                              ///  not the current owner. Throws if `_to` is the zero address. Throws if
                                              ///  `_tokenId` is not a valid NFT. When transfer is complete, this function
                                              ///  checks if `_to` is a smart contract (code size > 0). If so, it calls
                                              ///  `onERC721Received` on `_to` and throws if the return value is not
                                              ///  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              /// @param data Additional data with no specified format, sent in call to `_to`
                                              function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;
                                              /// @notice Transfers the ownership of an NFT from one address to another address
                                              /// @dev This works identically to the other function with an extra data parameter,
                                              ///  except this function just sets data to "".
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
                                              /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
                                              ///  TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
                                              ///  THEY MAY BE PERMANENTLY LOST
                                              /// @dev Throws unless `msg.sender` is the current owner, an authorized
                                              ///  operator, or the approved address for this NFT. Throws if `_from` is
                                              ///  not the current owner. Throws if `_to` is the zero address. Throws if
                                              ///  `_tokenId` is not a valid NFT.
                                              /// @param _from The current owner of the NFT
                                              /// @param _to The new owner
                                              /// @param _tokenId The NFT to transfer
                                              function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
                                              /// @notice Change or reaffirm the approved address for an NFT
                                              /// @dev The zero address indicates there is no approved address.
                                              ///  Throws unless `msg.sender` is the current NFT owner, or an authorized
                                              ///  operator of the current owner.
                                              /// @param _approved The new approved NFT controller
                                              /// @param _tokenId The NFT to approve
                                              function approve(address _approved, uint256 _tokenId) external payable;
                                              /// @notice Enable or disable approval for a third party ("operator") to manage
                                              ///  all of `msg.sender`'s assets
                                              /// @dev Emits the ApprovalForAll event. The contract MUST allow
                                              ///  multiple operators per owner.
                                              /// @param _operator Address to add to the set of authorized operators
                                              /// @param _approved True if the operator is approved, false to revoke approval
                                              function setApprovalForAll(address _operator, bool _approved) external;
                                              /// @notice Get the approved address for a single NFT
                                              /// @dev Throws if `_tokenId` is not a valid NFT.
                                              /// @param _tokenId The NFT to find the approved address for
                                              /// @return The approved address for this NFT, or the zero address if there is none
                                              function getApproved(uint256 _tokenId) external view returns (address);
                                              /// @notice Query if an address is an authorized operator for another address
                                              /// @param _owner The address that owns the NFTs
                                              /// @param _operator The address that acts on behalf of the owner
                                              /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
                                              function isApprovedForAll(address _owner, address _operator) external view returns (bool);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x780e9d63.
                                            /* is ERC721 */
                                            interface ERC721Enumerable {
                                              /// @notice Count NFTs tracked by this contract
                                              /// @return A count of valid NFTs tracked by this contract, where each one of
                                              ///  them has an assigned and queryable owner not equal to the zero address
                                              function totalSupply() external view returns (uint256);
                                              /// @notice Enumerate valid NFTs
                                              /// @dev Throws if `_index` >= `totalSupply()`.
                                              /// @param _index A counter less than `totalSupply()`
                                              /// @return The token identifier for the `_index`th NFT,
                                              ///  (sort order not specified)
                                              function tokenByIndex(uint256 _index) external view returns (uint256);
                                              /// @notice Enumerate NFTs assigned to an owner
                                              /// @dev Throws if `_index` >= `balanceOf(_owner)` or if
                                              ///  `_owner` is the zero address, representing invalid NFTs.
                                              /// @param _owner An address where we are interested in NFTs owned by them
                                              /// @param _index A counter less than `balanceOf(_owner)`
                                              /// @return The token identifier for the `_index`th NFT assigned to `_owner`,
                                              ///   (sort order not specified)
                                              function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            pragma solidity 0.8.13;
                                            /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
                                            /// @dev See https://eips.ethereum.org/EIPS/eip-721
                                            ///  Note: the ERC-165 identifier for this interface is 0x5b5e139f.
                                            /* is ERC721 */
                                            interface ERC721Metadata {
                                              /// @notice A descriptive name for a collection of NFTs in this contract
                                              function name() external view returns (string memory _name);
                                              /// @notice An abbreviated name for NFTs in this contract
                                              function symbol() external view returns (string memory _symbol);
                                              /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
                                              /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
                                              ///  3986. The URI may point to a JSON file that conforms to the "ERC721
                                              ///  Metadata JSON Schema".
                                              function tokenURI(uint256 _tokenId) external view returns (string memory);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.
                                            interface ERC721TokenReceiver {
                                              /// @notice Handle the receipt of an NFT
                                              /// @dev The ERC721 smart contract calls this function on the recipient
                                              ///  after a `transfer`. This function MAY throw to revert and reject the
                                              ///  transfer. Return of other than the magic value MUST result in the
                                              ///  transaction being reverted.
                                              ///  Note: the contract address is always the message sender.
                                              /// @param _operator The address which called `safeTransferFrom` function
                                              /// @param _from The address which previously owned the token
                                              /// @param _tokenId The NFT identifier which is being transferred
                                              /// @param _data Additional data with no specified format
                                              /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
                                              ///  unless throwing
                                              function onERC721Received(
                                                address _operator,
                                                address _from,
                                                uint256 _tokenId,
                                                bytes calldata _data
                                              ) external returns (bytes4);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface Holographable {
                                              function bridgeIn(uint32 fromChain, bytes calldata payload) external returns (bytes4);
                                              function bridgeOut(
                                                uint32 toChain,
                                                address sender,
                                                bytes calldata payload
                                              ) external returns (bytes4 selector, bytes memory data);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "./CollectionURI.sol";
                                            import "./ERC165.sol";
                                            import "./ERC721.sol";
                                            import "./ERC721Enumerable.sol";
                                            import "./ERC721Metadata.sol";
                                            import "./ERC721TokenReceiver.sol";
                                            import "./Holographable.sol";
                                            interface HolographERC721Interface is
                                              ERC165,
                                              ERC721,
                                              ERC721Enumerable,
                                              ERC721Metadata,
                                              ERC721TokenReceiver,
                                              CollectionURI,
                                              Holographable
                                            {
                                              function approve(address to, uint256 tokenId) external payable;
                                              function burn(uint256 tokenId) external;
                                              function safeTransferFrom(address from, address to, uint256 tokenId) external payable;
                                              function setApprovalForAll(address to, bool approved) external;
                                              function sourceBurn(uint256 tokenId) external;
                                              function sourceMint(address to, uint224 tokenId) external;
                                              function sourceGetChainPrepend() external view returns (uint256);
                                              function sourceTransfer(address to, uint256 tokenId) external;
                                              function transfer(address to, uint256 tokenId) external payable;
                                              function contractURI() external view returns (string memory);
                                              function getApproved(uint256 tokenId) external view returns (address);
                                              function isApprovedForAll(address wallet, address operator) external view returns (bool);
                                              function name() external view returns (string memory);
                                              function burned(uint256 tokenId) external view returns (bool);
                                              function decimals() external pure returns (uint256);
                                              function exists(uint256 tokenId) external view returns (bool);
                                              function ownerOf(uint256 tokenId) external view returns (address);
                                              function supportsInterface(bytes4 interfaceId) external view returns (bool);
                                              function symbol() external view returns (string memory);
                                              function tokenByIndex(uint256 index) external view returns (uint256);
                                              function tokenOfOwnerByIndex(address wallet, uint256 index) external view returns (uint256);
                                              function tokensOfOwner(address wallet) external view returns (uint256[] memory);
                                              function tokenURI(uint256 tokenId) external view returns (string memory);
                                              function totalSupply() external view returns (uint256);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            interface HolographerInterface {
                                              function getContractType() external view returns (bytes32 contractType);
                                              function getDeploymentBlock() external view returns (uint256 deploymentBlock);
                                              function getHolograph() external view returns (address holograph);
                                              function getHolographEnforcer() external view returns (address);
                                              function getOriginChain() external view returns (uint32 originChain);
                                              function getSourceContract() external view returns (address sourceContract);
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Holograph Protocol
                                             * @author https://github.com/holographxyz
                                             * @notice This is the primary Holograph Protocol smart contract
                                             * @dev This contract stores a reference to all the primary modules and variables of the protocol
                                             */
                                            interface HolographInterface {
                                              /**
                                               * @notice Get the address of the Holograph Bridge module
                                               * @dev Used for beaming holographable assets cross-chain
                                               */
                                              function getBridge() external view returns (address bridge);
                                              /**
                                               * @notice Update the Holograph Bridge module address
                                               * @param bridge address of the Holograph Bridge smart contract to use
                                               */
                                              function setBridge(address bridge) external;
                                              /**
                                               * @notice Get the chain ID that the Protocol was deployed on
                                               * @dev Useful for checking if/when a hard fork occurs
                                               */
                                              function getChainId() external view returns (uint256 chainId);
                                              /**
                                               * @notice Update the chain ID
                                               * @dev Useful for updating once a hard fork has been mitigated
                                               * @param chainId EVM chain ID to use
                                               */
                                              function setChainId(uint256 chainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Factory module
                                               * @dev Used for deploying holographable smart contracts
                                               */
                                              function getFactory() external view returns (address factory);
                                              /**
                                               * @notice Update the Holograph Factory module address
                                               * @param factory address of the Holograph Factory smart contract to use
                                               */
                                              function setFactory(address factory) external;
                                              /**
                                               * @notice Get the Holograph chain Id
                                               * @dev Holograph uses an internal chain id mapping
                                               */
                                              function getHolographChainId() external view returns (uint32 holographChainId);
                                              /**
                                               * @notice Update the Holograph chain ID
                                               * @dev Useful for updating once a hard fork was mitigated
                                               * @param holographChainId Holograph chain ID to use
                                               */
                                              function setHolographChainId(uint32 holographChainId) external;
                                              /**
                                               * @notice Get the address of the Holograph Interfaces module
                                               * @dev Holograph uses this contract to store data that needs to be accessed by a large portion of the modules
                                               */
                                              function getInterfaces() external view returns (address interfaces);
                                              /**
                                               * @notice Update the Holograph Interfaces module address
                                               * @param interfaces address of the Holograph Interfaces smart contract to use
                                               */
                                              function setInterfaces(address interfaces) external;
                                              /**
                                               * @notice Get the address of the Holograph Operator module
                                               * @dev All cross-chain Holograph Bridge beams are handled by the Holograph Operator module
                                               */
                                              function getOperator() external view returns (address operator);
                                              /**
                                               * @notice Update the Holograph Operator module address
                                               * @param operator address of the Holograph Operator smart contract to use
                                               */
                                              function setOperator(address operator) external;
                                              /**
                                               * @notice Get the Holograph Registry module
                                               * @dev This module stores a reference for all deployed holographable smart contracts
                                               */
                                              function getRegistry() external view returns (address registry);
                                              /**
                                               * @notice Update the Holograph Registry module address
                                               * @param registry address of the Holograph Registry smart contract to use
                                               */
                                              function setRegistry(address registry) external;
                                              /**
                                               * @notice Get the Holograph Treasury module
                                               * @dev All of the Holograph Protocol assets are stored and managed by this module
                                               */
                                              function getTreasury() external view returns (address treasury);
                                              /**
                                               * @notice Update the Holograph Treasury module address
                                               * @param treasury address of the Holograph Treasury smart contract to use
                                               */
                                              function setTreasury(address treasury) external;
                                              /**
                                               * @notice Get the Holograph Utility Token address
                                               * @dev This is the official utility token of the Holograph Protocol
                                               */
                                              function getUtilityToken() external view returns (address utilityToken);
                                              /**
                                               * @notice Update the Holograph Utility Token address
                                               * @param utilityToken address of the Holograph Utility Token smart contract to use
                                               */
                                              function setUtilityToken(address utilityToken) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 9 of 14: DropsPriceOracleProxy
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../../abstract/Admin.sol";
                                            import "../../abstract/Initializable.sol";
                                            contract DropsPriceOracleProxy is Admin, Initializable {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.dropsPriceOracle')) - 1)
                                               */
                                              bytes32 constant _dropsPriceOracleSlot = 0x26600f0171e5a2b86874be26285c66444b2a6fa5f62114757214d5e732aded36;
                                              constructor() {}
                                              function init(bytes memory data) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                (address dropsPriceOracle, bytes memory initCode) = abi.decode(data, (address, bytes));
                                                assembly {
                                                  sstore(_adminSlot, origin())
                                                  sstore(_dropsPriceOracleSlot, dropsPriceOracle)
                                                }
                                                (bool success, bytes memory returnData) = dropsPriceOracle.delegatecall(
                                                  abi.encodeWithSignature("init(bytes)", initCode)
                                                );
                                                bytes4 selector = abi.decode(returnData, (bytes4));
                                                require(success && selector == Initializable.init.selector, "initialization failed");
                                                _setInitialized();
                                                return Initializable.init.selector;
                                              }
                                              function getDropsPriceOracle() external view returns (address dropsPriceOracle) {
                                                assembly {
                                                  dropsPriceOracle := sload(_dropsPriceOracleSlot)
                                                }
                                              }
                                              function setDropsPriceOracle(address dropsPriceOracle) external onlyAdmin {
                                                assembly {
                                                  sstore(_dropsPriceOracleSlot, dropsPriceOracle)
                                                }
                                              }
                                              receive() external payable {}
                                              fallback() external payable {
                                                assembly {
                                                  let dropsPriceOracle := sload(_dropsPriceOracleSlot)
                                                  calldatacopy(0, 0, calldatasize())
                                                  let result := delegatecall(gas(), dropsPriceOracle, 0, calldatasize(), 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 10 of 14: DropsPriceOracleEthereum
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            abstract contract Admin {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.admin')) - 1)
                                               */
                                              bytes32 constant _adminSlot = 0x3f106594dc74eeef980dae234cde8324dc2497b13d27a0c59e55bd2ca10a07c9;
                                              modifier onlyAdmin() {
                                                require(msg.sender == getAdmin(), "HOLOGRAPH: admin only function");
                                                _;
                                              }
                                              constructor() {}
                                              function admin() public view returns (address) {
                                                return getAdmin();
                                              }
                                              function getAdmin() public view returns (address adminAddress) {
                                                assembly {
                                                  adminAddress := sload(_adminSlot)
                                                }
                                              }
                                              function setAdmin(address adminAddress) public onlyAdmin {
                                                assembly {
                                                  sstore(_adminSlot, adminAddress)
                                                }
                                              }
                                              function adminCall(address target, bytes calldata data) external payable onlyAdmin {
                                                assembly {
                                                  calldatacopy(0, data.offset, data.length)
                                                  let result := call(gas(), target, callvalue(), 0, data.length, 0, 0)
                                                  returndatacopy(0, 0, returndatasize())
                                                  switch result
                                                  case 0 {
                                                    revert(0, returndatasize())
                                                  }
                                                  default {
                                                    return(0, returndatasize())
                                                  }
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            import "../interface/InitializableInterface.sol";
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need for a constructor
                                             */
                                            abstract contract Initializable is InitializableInterface {
                                              /**
                                               * @dev bytes32(uint256(keccak256('eip1967.Holograph.initialized')) - 1)
                                               */
                                              bytes32 constant _initializedSlot = 0x4e5f991bca30eca2d4643aaefa807e88f96a4a97398933d572a3c0d973004a01;
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external virtual returns (bytes4);
                                              function _isInitialized() internal view returns (bool initialized) {
                                                assembly {
                                                  initialized := sload(_initializedSlot)
                                                }
                                              }
                                              function _setInitialized() internal {
                                                assembly {
                                                  sstore(_initializedSlot, 0x0000000000000000000000000000000000000000000000000000000000000001)
                                                }
                                              }
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            interface IDropsPriceOracle {
                                              function convertUsdToWei(uint256 usdAmount) external view returns (uint256 weiAmount);
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            import {Admin} from "../../abstract/Admin.sol";
                                            import {Initializable} from "../../abstract/Initializable.sol";
                                            import {IDropsPriceOracle} from "../interface/IDropsPriceOracle.sol";
                                            import {IUniswapV2Pair} from "./interface/IUniswapV2Pair.sol";
                                            contract DropsPriceOracleEthereum is Admin, Initializable, IDropsPriceOracle {
                                              address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // 18 decimals
                                              address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; // 6 decimals
                                              address constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; // 6 decimals
                                              IUniswapV2Pair constant SushiV2UsdcPool = IUniswapV2Pair(0x397FF1542f962076d0BFE58eA045FfA2d347ACa0);
                                              IUniswapV2Pair constant SushiV2UsdtPool = IUniswapV2Pair(0x06da0fd433C1A5d7a4faa01111c044910A184553);
                                              IUniswapV2Pair constant UniV2UsdcPool = IUniswapV2Pair(0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc);
                                              IUniswapV2Pair constant UniV2UsdtPool = IUniswapV2Pair(0x0d4a11d5EEaaC28EC3F61d100daF4d40471f1852);
                                              /**
                                               * @dev Constructor is left empty and init is used instead
                                               */
                                              constructor() {}
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               */
                                              function init(bytes memory) external override returns (bytes4) {
                                                require(!_isInitialized(), "HOLOGRAPH: already initialized");
                                                assembly {
                                                  sstore(_adminSlot, origin())
                                                }
                                                _setInitialized();
                                                return Initializable.init.selector;
                                              }
                                              /**
                                               * @notice Convert USD value to native gas token value
                                               * @dev It is important to note that different USD stablecoins use different decimal places.
                                               * @param usdAmount a 6 decimal places USD amount
                                               */
                                              function convertUsdToWei(uint256 usdAmount) external view returns (uint256 weiAmount) {
                                                weiAmount =
                                                  (_getSushiUSDC(usdAmount) + _getSushiUSDT(usdAmount) + _getUniUSDC(usdAmount) + _getUniUSDT(usdAmount)) /
                                                  4;
                                              }
                                              function _getSushiUSDC(uint256 usdAmount) internal view returns (uint256 weiAmount) {
                                                // add decimal places for amount IF decimals are above 6!
                                                // usdAmount = usdAmount * (10**(18 - 6));
                                                (uint112 _reserve0, uint112 _reserve1, ) = SushiV2UsdcPool.getReserves();
                                                // x is always native token / WETH
                                                uint256 x = _reserve1;
                                                // y is always USD token / USDC
                                                uint256 y = _reserve0;
                                                uint256 numerator = (x * usdAmount) * 1000;
                                                uint256 denominator = (y - usdAmount) * 997;
                                                weiAmount = (numerator / denominator) + 1;
                                              }
                                              function _getSushiUSDT(uint256 usdAmount) internal view returns (uint256 weiAmount) {
                                                // add decimal places for amount IF decimals are above 6!
                                                // usdAmount = usdAmount * (10**(18 - 6));
                                                (uint112 _reserve0, uint112 _reserve1, ) = SushiV2UsdtPool.getReserves();
                                                // x is always native token / WETH
                                                uint256 x = _reserve0;
                                                // y is always USD token / USDT
                                                uint256 y = _reserve1;
                                                uint256 numerator = (x * usdAmount) * 1000;
                                                uint256 denominator = (y - usdAmount) * 997;
                                                weiAmount = (numerator / denominator) + 1;
                                              }
                                              function _getUniUSDC(uint256 usdAmount) internal view returns (uint256 weiAmount) {
                                                // add decimal places for amount IF decimals are above 6!
                                                // usdAmount = usdAmount * (10**(18 - 6));
                                                (uint112 _reserve0, uint112 _reserve1, ) = UniV2UsdcPool.getReserves();
                                                // x is always native token / WETH
                                                uint256 x = _reserve1;
                                                // y is always USD token / USDC
                                                uint256 y = _reserve0;
                                                uint256 numerator = (x * usdAmount) * 1000;
                                                uint256 denominator = (y - usdAmount) * 997;
                                                weiAmount = (numerator / denominator) + 1;
                                              }
                                              function _getUniUSDT(uint256 usdAmount) internal view returns (uint256 weiAmount) {
                                                // add decimal places for amount IF decimals are above 6!
                                                // usdAmount = usdAmount * (10**(18 - 6));
                                                (uint112 _reserve0, uint112 _reserve1, ) = UniV2UsdtPool.getReserves();
                                                // x is always native token / WETH
                                                uint256 x = _reserve0;
                                                // y is always USD token / USDT
                                                uint256 y = _reserve1;
                                                uint256 numerator = (x * usdAmount) * 1000;
                                                uint256 denominator = (y - usdAmount) * 997;
                                                weiAmount = (numerator / denominator) + 1;
                                              }
                                            }
                                            // SPDX-License-Identifier: MIT
                                            pragma solidity 0.8.13;
                                            interface IUniswapV2Pair {
                                              event Approval(address indexed owner, address indexed spender, uint256 value);
                                              event Transfer(address indexed from, address indexed to, uint256 value);
                                              function name() external pure returns (string memory);
                                              function symbol() external pure returns (string memory);
                                              function decimals() external pure returns (uint8);
                                              function totalSupply() external view returns (uint256);
                                              function balanceOf(address owner) external view returns (uint256);
                                              function allowance(address owner, address spender) external view returns (uint256);
                                              function approve(address spender, uint256 value) external returns (bool);
                                              function transfer(address to, uint256 value) external returns (bool);
                                              function transferFrom(address from, address to, uint256 value) external returns (bool);
                                              function DOMAIN_SEPARATOR() external view returns (bytes32);
                                              function PERMIT_TYPEHASH() external pure returns (bytes32);
                                              function nonces(address owner) external view returns (uint256);
                                              function permit(
                                                address owner,
                                                address spender,
                                                uint256 value,
                                                uint256 deadline,
                                                uint8 v,
                                                bytes32 r,
                                                bytes32 s
                                              ) external;
                                              event Mint(address indexed sender, uint256 amount0, uint256 amount1);
                                              event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
                                              event Swap(
                                                address indexed sender,
                                                uint256 amount0In,
                                                uint256 amount1In,
                                                uint256 amount0Out,
                                                uint256 amount1Out,
                                                address indexed to
                                              );
                                              event Sync(uint112 reserve0, uint112 reserve1);
                                              function MINIMUM_LIQUIDITY() external pure returns (uint256);
                                              function factory() external view returns (address);
                                              function token0() external view returns (address);
                                              function token1() external view returns (address);
                                              function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
                                              function price0CumulativeLast() external view returns (uint256);
                                              function price1CumulativeLast() external view returns (uint256);
                                              function kLast() external view returns (uint256);
                                              function mint(address to) external returns (uint256 liquidity);
                                              function burn(address to) external returns (uint256 amount0, uint256 amount1);
                                              function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
                                              function skim(address to) external;
                                              function sync() external;
                                              function initialize(address, address) external;
                                            }
                                            // SPDX-License-Identifier: UNLICENSED
                                            /*
                                                                     ┌───────────┐
                                                                     │ HOLOGRAPH │
                                                                     └───────────┘
                                            ╔═════════════════════════════════════════════════════════════╗
                                            ║                                                             ║
                                            ║                            / ^ \\                            ║
                                            ║                            ~~*~~            ¸               ║
                                            ║                         [ '<>:<>' ]         │░░░            ║
                                            ║               ╔╗           _/"\\_           ╔╣               ║
                                            ║             ┌─╬╬─┐          """          ┌─╬╬─┐             ║
                                            ║          ┌─┬┘ ╠╣ └┬─┐       \\_/       ┌─┬┘ ╠╣ └┬─┐          ║
                                            ║       ┌─┬┘ │  ╠╣  │ └┬─┐           ┌─┬┘ │  ╠╣  │ └┬─┐       ║
                                            ║    ┌─┬┘ │  │  ╠╣  │  │ └┬─┐     ┌─┬┘ │  │  ╠╣  │  │ └┬─┐    ║
                                            ║ ┌─┬┘ │  │  │  ╠╣  │  │  │ └┬┐ ┌┬┘ │  │  │  ╠╣  │  │  │ └┬─┐ ║
                                            ╠┬┘ │  │  │  │  ╠╣  │  │  │  │└¤┘│  │  │  │  ╠╣  │  │  │  │ └┬╣
                                            ║│  │  │  │  │  ╠╣  │  │  │  │   │  │  │  │  ╠╣  │  │  │  │  │║
                                            ╠╩══╩══╩══╩══╩══╬╬══╩══╩══╩══╩═══╩══╩══╩══╩══╬╬══╩══╩══╩══╩══╩╣
                                            ╠┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╬╬┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴╣
                                            ║               ╠╣                           ╠╣               ║
                                            ║               ╠╣                           ╠╣               ║
                                            ║    ,          ╠╣     ,        ,'      *    ╠╣               ║
                                            ║~~~~~^~~~~~~~~┌╬╬┐~~~^~~~~~~~~^^~~~~~~~~^~~┌╬╬┐~~~~~~~^~~~~~~║
                                            ╚══════════════╩╩╩╩═════════════════════════╩╩╩╩══════════════╝
                                                 - one protocol, one bridge = infinite possibilities -
                                             ***************************************************************
                                             DISCLAIMER: U.S Patent Pending
                                             LICENSE: Holograph Limited Public License (H-LPL)
                                             https://holograph.xyz/licenses/h-lpl/1.0.0
                                             This license governs use of the accompanying software. If you
                                             use the software, you accept this license. If you do not accept
                                             the license, you are not permitted to use the software.
                                             1. Definitions
                                             The terms "reproduce," "reproduction," "derivative works," and
                                             "distribution" have the same meaning here as under U.S.
                                             copyright law. A "contribution" is the original software, or
                                             any additions or changes to the software. A "contributor" is
                                             any person that distributes its contribution under this
                                             license. "Licensed patents" are a contributor’s patent claims
                                             that read directly on its contribution.
                                             2. Grant of Rights
                                             A) Copyright Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in sections 3
                                             and 4, each contributor grants you a non-exclusive, worldwide,
                                             royalty-free copyright license to reproduce its contribution,
                                             prepare derivative works of its contribution, and distribute
                                             its contribution or any derivative works that you create.
                                             B) Patent Grant- Subject to the terms of this license,
                                             including the license conditions and limitations in section 3,
                                             each contributor grants you a non-exclusive, worldwide,
                                             royalty-free license under its licensed patents to make, have
                                             made, use, sell, offer for sale, import, and/or otherwise
                                             dispose of its contribution in the software or derivative works
                                             of the contribution in the software.
                                             3. Conditions and Limitations
                                             A) No Trademark License- This license does not grant you rights
                                             to use any contributors’ name, logo, or trademarks.
                                             B) If you bring a patent claim against any contributor over
                                             patents that you claim are infringed by the software, your
                                             patent license from such contributor is terminated with
                                             immediate effect.
                                             C) If you distribute any portion of the software, you must
                                             retain all copyright, patent, trademark, and attribution
                                             notices that are present in the software.
                                             D) If you distribute any portion of the software in source code
                                             form, you may do so only under this license by including a
                                             complete copy of this license with your distribution. If you
                                             distribute any portion of the software in compiled or object
                                             code form, you may only do so under a license that complies
                                             with this license.
                                             E) The software is licensed “as-is.” You bear all risks of
                                             using it. The contributors give no express warranties,
                                             guarantees, or conditions. You may have additional consumer
                                             rights under your local laws which this license cannot change.
                                             To the extent permitted under your local laws, the contributors
                                             exclude all implied warranties, including those of
                                             merchantability, fitness for a particular purpose and
                                             non-infringement.
                                             4. (F) Platform Limitation- The licenses granted in sections
                                             2.A & 2.B extend only to the software or derivative works that
                                             you create that run on a Holograph system product.
                                             ***************************************************************
                                            */
                                            pragma solidity 0.8.13;
                                            /**
                                             * @title Initializable
                                             * @author https://github.com/holographxyz
                                             * @notice Use init instead of constructor
                                             * @dev This allows for use of init function to make one time initializations without the need of a constructor
                                             */
                                            interface InitializableInterface {
                                              /**
                                               * @notice Used internally to initialize the contract instead of through a constructor
                                               * @dev This function is called by the deployer/factory when creating a contract
                                               * @param initPayload abi encoded payload to use for contract initilaization
                                               */
                                              function init(bytes memory initPayload) external returns (bytes4);
                                            }
                                            

                                            File 11 of 14: UniswapV2Pair
                                            // File: contracts/interfaces/IUniswapV2Pair.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Pair {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external pure returns (string memory);
                                                function symbol() external pure returns (string memory);
                                                function decimals() external pure returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            
                                                function DOMAIN_SEPARATOR() external view returns (bytes32);
                                                function PERMIT_TYPEHASH() external pure returns (bytes32);
                                                function nonces(address owner) external view returns (uint);
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                function MINIMUM_LIQUIDITY() external pure returns (uint);
                                                function factory() external view returns (address);
                                                function token0() external view returns (address);
                                                function token1() external view returns (address);
                                                function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
                                                function price0CumulativeLast() external view returns (uint);
                                                function price1CumulativeLast() external view returns (uint);
                                                function kLast() external view returns (uint);
                                            
                                                function mint(address to) external returns (uint liquidity);
                                                function burn(address to) external returns (uint amount0, uint amount1);
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
                                                function skim(address to) external;
                                                function sync() external;
                                            
                                                function initialize(address, address) external;
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2ERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2ERC20 {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external pure returns (string memory);
                                                function symbol() external pure returns (string memory);
                                                function decimals() external pure returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            
                                                function DOMAIN_SEPARATOR() external view returns (bytes32);
                                                function PERMIT_TYPEHASH() external pure returns (bytes32);
                                                function nonces(address owner) external view returns (uint);
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
                                            }
                                            
                                            // File: contracts/libraries/SafeMath.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
                                            
                                            library SafeMath {
                                                function add(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x + y) >= x, 'ds-math-add-overflow');
                                                }
                                            
                                                function sub(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x - y) <= x, 'ds-math-sub-underflow');
                                                }
                                            
                                                function mul(uint x, uint y) internal pure returns (uint z) {
                                                    require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
                                                }
                                            }
                                            
                                            // File: contracts/UniswapV2ERC20.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            
                                            
                                            contract UniswapV2ERC20 is IUniswapV2ERC20 {
                                                using SafeMath for uint;
                                            
                                                string public constant name = 'Uniswap V2';
                                                string public constant symbol = 'UNI-V2';
                                                uint8 public constant decimals = 18;
                                                uint  public totalSupply;
                                                mapping(address => uint) public balanceOf;
                                                mapping(address => mapping(address => uint)) public allowance;
                                            
                                                bytes32 public DOMAIN_SEPARATOR;
                                                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                                                bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
                                                mapping(address => uint) public nonces;
                                            
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                constructor() public {
                                                    uint chainId;
                                                    assembly {
                                                        chainId := chainid
                                                    }
                                                    DOMAIN_SEPARATOR = keccak256(
                                                        abi.encode(
                                                            keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                                                            keccak256(bytes(name)),
                                                            keccak256(bytes('1')),
                                                            chainId,
                                                            address(this)
                                                        )
                                                    );
                                                }
                                            
                                                function _mint(address to, uint value) internal {
                                                    totalSupply = totalSupply.add(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(address(0), to, value);
                                                }
                                            
                                                function _burn(address from, uint value) internal {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    totalSupply = totalSupply.sub(value);
                                                    emit Transfer(from, address(0), value);
                                                }
                                            
                                                function _approve(address owner, address spender, uint value) private {
                                                    allowance[owner][spender] = value;
                                                    emit Approval(owner, spender, value);
                                                }
                                            
                                                function _transfer(address from, address to, uint value) private {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(from, to, value);
                                                }
                                            
                                                function approve(address spender, uint value) external returns (bool) {
                                                    _approve(msg.sender, spender, value);
                                                    return true;
                                                }
                                            
                                                function transfer(address to, uint value) external returns (bool) {
                                                    _transfer(msg.sender, to, value);
                                                    return true;
                                                }
                                            
                                                function transferFrom(address from, address to, uint value) external returns (bool) {
                                                    if (allowance[from][msg.sender] != uint(-1)) {
                                                        allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
                                                    }
                                                    _transfer(from, to, value);
                                                    return true;
                                                }
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
                                                    require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
                                                    bytes32 digest = keccak256(
                                                        abi.encodePacked(
                                                            '\x19\x01',
                                                            DOMAIN_SEPARATOR,
                                                            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                                                        )
                                                    );
                                                    address recoveredAddress = ecrecover(digest, v, r, s);
                                                    require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
                                                    _approve(owner, spender, value);
                                                }
                                            }
                                            
                                            // File: contracts/libraries/Math.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for performing various math operations
                                            
                                            library Math {
                                                function min(uint x, uint y) internal pure returns (uint z) {
                                                    z = x < y ? x : y;
                                                }
                                            
                                                // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
                                                function sqrt(uint y) internal pure returns (uint z) {
                                                    if (y > 3) {
                                                        z = y;
                                                        uint x = y / 2 + 1;
                                                        while (x < z) {
                                                            z = x;
                                                            x = (y / x + x) / 2;
                                                        }
                                                    } else if (y != 0) {
                                                        z = 1;
                                                    }
                                                }
                                            }
                                            
                                            // File: contracts/libraries/UQ112x112.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
                                            
                                            // range: [0, 2**112 - 1]
                                            // resolution: 1 / 2**112
                                            
                                            library UQ112x112 {
                                                uint224 constant Q112 = 2**112;
                                            
                                                // encode a uint112 as a UQ112x112
                                                function encode(uint112 y) internal pure returns (uint224 z) {
                                                    z = uint224(y) * Q112; // never overflows
                                                }
                                            
                                                // divide a UQ112x112 by a uint112, returning a UQ112x112
                                                function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
                                                    z = x / uint224(y);
                                                }
                                            }
                                            
                                            // File: contracts/interfaces/IERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IERC20 {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external view returns (string memory);
                                                function symbol() external view returns (string memory);
                                                function decimals() external view returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2Factory.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Factory {
                                                event PairCreated(address indexed token0, address indexed token1, address pair, uint);
                                            
                                                function feeTo() external view returns (address);
                                                function feeToSetter() external view returns (address);
                                            
                                                function getPair(address tokenA, address tokenB) external view returns (address pair);
                                                function allPairs(uint) external view returns (address pair);
                                                function allPairsLength() external view returns (uint);
                                            
                                                function createPair(address tokenA, address tokenB) external returns (address pair);
                                            
                                                function setFeeTo(address) external;
                                                function setFeeToSetter(address) external;
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2Callee.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Callee {
                                                function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
                                            }
                                            
                                            // File: contracts/UniswapV2Pair.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
                                                using SafeMath  for uint;
                                                using UQ112x112 for uint224;
                                            
                                                uint public constant MINIMUM_LIQUIDITY = 10**3;
                                                bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
                                            
                                                address public factory;
                                                address public token0;
                                                address public token1;
                                            
                                                uint112 private reserve0;           // uses single storage slot, accessible via getReserves
                                                uint112 private reserve1;           // uses single storage slot, accessible via getReserves
                                                uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves
                                            
                                                uint public price0CumulativeLast;
                                                uint public price1CumulativeLast;
                                                uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
                                            
                                                uint private unlocked = 1;
                                                modifier lock() {
                                                    require(unlocked == 1, 'UniswapV2: LOCKED');
                                                    unlocked = 0;
                                                    _;
                                                    unlocked = 1;
                                                }
                                            
                                                function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
                                                    _reserve0 = reserve0;
                                                    _reserve1 = reserve1;
                                                    _blockTimestampLast = blockTimestampLast;
                                                }
                                            
                                                function _safeTransfer(address token, address to, uint value) private {
                                                    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
                                                    require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
                                                }
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                constructor() public {
                                                    factory = msg.sender;
                                                }
                                            
                                                // called once by the factory at time of deployment
                                                function initialize(address _token0, address _token1) external {
                                                    require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
                                                    token0 = _token0;
                                                    token1 = _token1;
                                                }
                                            
                                                // update reserves and, on the first call per block, price accumulators
                                                function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
                                                    require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW');
                                                    uint32 blockTimestamp = uint32(block.timestamp % 2**32);
                                                    uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
                                                    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
                                                        // * never overflows, and + overflow is desired
                                                        price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
                                                        price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
                                                    }
                                                    reserve0 = uint112(balance0);
                                                    reserve1 = uint112(balance1);
                                                    blockTimestampLast = blockTimestamp;
                                                    emit Sync(reserve0, reserve1);
                                                }
                                            
                                                // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
                                                function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
                                                    address feeTo = IUniswapV2Factory(factory).feeTo();
                                                    feeOn = feeTo != address(0);
                                                    uint _kLast = kLast; // gas savings
                                                    if (feeOn) {
                                                        if (_kLast != 0) {
                                                            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                                                            uint rootKLast = Math.sqrt(_kLast);
                                                            if (rootK > rootKLast) {
                                                                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                                                                uint denominator = rootK.mul(5).add(rootKLast);
                                                                uint liquidity = numerator / denominator;
                                                                if (liquidity > 0) _mint(feeTo, liquidity);
                                                            }
                                                        }
                                                    } else if (_kLast != 0) {
                                                        kLast = 0;
                                                    }
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function mint(address to) external lock returns (uint liquidity) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    uint balance0 = IERC20(token0).balanceOf(address(this));
                                                    uint balance1 = IERC20(token1).balanceOf(address(this));
                                                    uint amount0 = balance0.sub(_reserve0);
                                                    uint amount1 = balance1.sub(_reserve1);
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    if (_totalSupply == 0) {
                                                        liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
                                                       _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
                                                    } else {
                                                        liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
                                                    }
                                                    require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
                                                    _mint(to, liquidity);
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Mint(msg.sender, amount0, amount1);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function burn(address to) external lock returns (uint amount0, uint amount1) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    address _token0 = token0;                                // gas savings
                                                    address _token1 = token1;                                // gas savings
                                                    uint balance0 = IERC20(_token0).balanceOf(address(this));
                                                    uint balance1 = IERC20(_token1).balanceOf(address(this));
                                                    uint liquidity = balanceOf[address(this)];
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
                                                    amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
                                                    require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED');
                                                    _burn(address(this), liquidity);
                                                    _safeTransfer(_token0, to, amount0);
                                                    _safeTransfer(_token1, to, amount1);
                                                    balance0 = IERC20(_token0).balanceOf(address(this));
                                                    balance1 = IERC20(_token1).balanceOf(address(this));
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Burn(msg.sender, amount0, amount1, to);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
                                                    require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');
                                            
                                                    uint balance0;
                                                    uint balance1;
                                                    { // scope for _token{0,1}, avoids stack too deep errors
                                                    address _token0 = token0;
                                                    address _token1 = token1;
                                                    require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
                                                    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
                                                    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
                                                    if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
                                                    balance0 = IERC20(_token0).balanceOf(address(this));
                                                    balance1 = IERC20(_token1).balanceOf(address(this));
                                                    }
                                                    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
                                                    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
                                                    require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
                                                    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
                                                    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
                                                    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
                                                    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
                                                    }
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
                                                }
                                            
                                                // force balances to match reserves
                                                function skim(address to) external lock {
                                                    address _token0 = token0; // gas savings
                                                    address _token1 = token1; // gas savings
                                                    _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
                                                    _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
                                                }
                                            
                                                // force reserves to match balances
                                                function sync() external lock {
                                                    _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
                                                }
                                            }

                                            File 12 of 14: UniswapV2Pair
                                            // File: contracts/interfaces/IUniswapV2Pair.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Pair {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external pure returns (string memory);
                                                function symbol() external pure returns (string memory);
                                                function decimals() external pure returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            
                                                function DOMAIN_SEPARATOR() external view returns (bytes32);
                                                function PERMIT_TYPEHASH() external pure returns (bytes32);
                                                function nonces(address owner) external view returns (uint);
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                function MINIMUM_LIQUIDITY() external pure returns (uint);
                                                function factory() external view returns (address);
                                                function token0() external view returns (address);
                                                function token1() external view returns (address);
                                                function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
                                                function price0CumulativeLast() external view returns (uint);
                                                function price1CumulativeLast() external view returns (uint);
                                                function kLast() external view returns (uint);
                                            
                                                function mint(address to) external returns (uint liquidity);
                                                function burn(address to) external returns (uint amount0, uint amount1);
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
                                                function skim(address to) external;
                                                function sync() external;
                                            
                                                function initialize(address, address) external;
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2ERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2ERC20 {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external pure returns (string memory);
                                                function symbol() external pure returns (string memory);
                                                function decimals() external pure returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            
                                                function DOMAIN_SEPARATOR() external view returns (bytes32);
                                                function PERMIT_TYPEHASH() external pure returns (bytes32);
                                                function nonces(address owner) external view returns (uint);
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
                                            }
                                            
                                            // File: contracts/libraries/SafeMath.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
                                            
                                            library SafeMath {
                                                function add(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x + y) >= x, 'ds-math-add-overflow');
                                                }
                                            
                                                function sub(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x - y) <= x, 'ds-math-sub-underflow');
                                                }
                                            
                                                function mul(uint x, uint y) internal pure returns (uint z) {
                                                    require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
                                                }
                                            }
                                            
                                            // File: contracts/UniswapV2ERC20.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            
                                            
                                            contract UniswapV2ERC20 is IUniswapV2ERC20 {
                                                using SafeMath for uint;
                                            
                                                string public constant name = 'Uniswap V2';
                                                string public constant symbol = 'UNI-V2';
                                                uint8 public constant decimals = 18;
                                                uint  public totalSupply;
                                                mapping(address => uint) public balanceOf;
                                                mapping(address => mapping(address => uint)) public allowance;
                                            
                                                bytes32 public DOMAIN_SEPARATOR;
                                                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                                                bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
                                                mapping(address => uint) public nonces;
                                            
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                constructor() public {
                                                    uint chainId;
                                                    assembly {
                                                        chainId := chainid
                                                    }
                                                    DOMAIN_SEPARATOR = keccak256(
                                                        abi.encode(
                                                            keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                                                            keccak256(bytes(name)),
                                                            keccak256(bytes('1')),
                                                            chainId,
                                                            address(this)
                                                        )
                                                    );
                                                }
                                            
                                                function _mint(address to, uint value) internal {
                                                    totalSupply = totalSupply.add(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(address(0), to, value);
                                                }
                                            
                                                function _burn(address from, uint value) internal {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    totalSupply = totalSupply.sub(value);
                                                    emit Transfer(from, address(0), value);
                                                }
                                            
                                                function _approve(address owner, address spender, uint value) private {
                                                    allowance[owner][spender] = value;
                                                    emit Approval(owner, spender, value);
                                                }
                                            
                                                function _transfer(address from, address to, uint value) private {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(from, to, value);
                                                }
                                            
                                                function approve(address spender, uint value) external returns (bool) {
                                                    _approve(msg.sender, spender, value);
                                                    return true;
                                                }
                                            
                                                function transfer(address to, uint value) external returns (bool) {
                                                    _transfer(msg.sender, to, value);
                                                    return true;
                                                }
                                            
                                                function transferFrom(address from, address to, uint value) external returns (bool) {
                                                    if (allowance[from][msg.sender] != uint(-1)) {
                                                        allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
                                                    }
                                                    _transfer(from, to, value);
                                                    return true;
                                                }
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
                                                    require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
                                                    bytes32 digest = keccak256(
                                                        abi.encodePacked(
                                                            '\x19\x01',
                                                            DOMAIN_SEPARATOR,
                                                            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                                                        )
                                                    );
                                                    address recoveredAddress = ecrecover(digest, v, r, s);
                                                    require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
                                                    _approve(owner, spender, value);
                                                }
                                            }
                                            
                                            // File: contracts/libraries/Math.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for performing various math operations
                                            
                                            library Math {
                                                function min(uint x, uint y) internal pure returns (uint z) {
                                                    z = x < y ? x : y;
                                                }
                                            
                                                // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
                                                function sqrt(uint y) internal pure returns (uint z) {
                                                    if (y > 3) {
                                                        z = y;
                                                        uint x = y / 2 + 1;
                                                        while (x < z) {
                                                            z = x;
                                                            x = (y / x + x) / 2;
                                                        }
                                                    } else if (y != 0) {
                                                        z = 1;
                                                    }
                                                }
                                            }
                                            
                                            // File: contracts/libraries/UQ112x112.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
                                            
                                            // range: [0, 2**112 - 1]
                                            // resolution: 1 / 2**112
                                            
                                            library UQ112x112 {
                                                uint224 constant Q112 = 2**112;
                                            
                                                // encode a uint112 as a UQ112x112
                                                function encode(uint112 y) internal pure returns (uint224 z) {
                                                    z = uint224(y) * Q112; // never overflows
                                                }
                                            
                                                // divide a UQ112x112 by a uint112, returning a UQ112x112
                                                function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
                                                    z = x / uint224(y);
                                                }
                                            }
                                            
                                            // File: contracts/interfaces/IERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IERC20 {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external view returns (string memory);
                                                function symbol() external view returns (string memory);
                                                function decimals() external view returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2Factory.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Factory {
                                                event PairCreated(address indexed token0, address indexed token1, address pair, uint);
                                            
                                                function feeTo() external view returns (address);
                                                function feeToSetter() external view returns (address);
                                            
                                                function getPair(address tokenA, address tokenB) external view returns (address pair);
                                                function allPairs(uint) external view returns (address pair);
                                                function allPairsLength() external view returns (uint);
                                            
                                                function createPair(address tokenA, address tokenB) external returns (address pair);
                                            
                                                function setFeeTo(address) external;
                                                function setFeeToSetter(address) external;
                                            }
                                            
                                            // File: contracts/interfaces/IUniswapV2Callee.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Callee {
                                                function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
                                            }
                                            
                                            // File: contracts/UniswapV2Pair.sol
                                            
                                            pragma solidity =0.5.16;
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
                                                using SafeMath  for uint;
                                                using UQ112x112 for uint224;
                                            
                                                uint public constant MINIMUM_LIQUIDITY = 10**3;
                                                bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
                                            
                                                address public factory;
                                                address public token0;
                                                address public token1;
                                            
                                                uint112 private reserve0;           // uses single storage slot, accessible via getReserves
                                                uint112 private reserve1;           // uses single storage slot, accessible via getReserves
                                                uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves
                                            
                                                uint public price0CumulativeLast;
                                                uint public price1CumulativeLast;
                                                uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
                                            
                                                uint private unlocked = 1;
                                                modifier lock() {
                                                    require(unlocked == 1, 'UniswapV2: LOCKED');
                                                    unlocked = 0;
                                                    _;
                                                    unlocked = 1;
                                                }
                                            
                                                function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
                                                    _reserve0 = reserve0;
                                                    _reserve1 = reserve1;
                                                    _blockTimestampLast = blockTimestampLast;
                                                }
                                            
                                                function _safeTransfer(address token, address to, uint value) private {
                                                    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
                                                    require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
                                                }
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                constructor() public {
                                                    factory = msg.sender;
                                                }
                                            
                                                // called once by the factory at time of deployment
                                                function initialize(address _token0, address _token1) external {
                                                    require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
                                                    token0 = _token0;
                                                    token1 = _token1;
                                                }
                                            
                                                // update reserves and, on the first call per block, price accumulators
                                                function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
                                                    require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW');
                                                    uint32 blockTimestamp = uint32(block.timestamp % 2**32);
                                                    uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
                                                    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
                                                        // * never overflows, and + overflow is desired
                                                        price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
                                                        price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
                                                    }
                                                    reserve0 = uint112(balance0);
                                                    reserve1 = uint112(balance1);
                                                    blockTimestampLast = blockTimestamp;
                                                    emit Sync(reserve0, reserve1);
                                                }
                                            
                                                // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
                                                function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
                                                    address feeTo = IUniswapV2Factory(factory).feeTo();
                                                    feeOn = feeTo != address(0);
                                                    uint _kLast = kLast; // gas savings
                                                    if (feeOn) {
                                                        if (_kLast != 0) {
                                                            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                                                            uint rootKLast = Math.sqrt(_kLast);
                                                            if (rootK > rootKLast) {
                                                                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                                                                uint denominator = rootK.mul(5).add(rootKLast);
                                                                uint liquidity = numerator / denominator;
                                                                if (liquidity > 0) _mint(feeTo, liquidity);
                                                            }
                                                        }
                                                    } else if (_kLast != 0) {
                                                        kLast = 0;
                                                    }
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function mint(address to) external lock returns (uint liquidity) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    uint balance0 = IERC20(token0).balanceOf(address(this));
                                                    uint balance1 = IERC20(token1).balanceOf(address(this));
                                                    uint amount0 = balance0.sub(_reserve0);
                                                    uint amount1 = balance1.sub(_reserve1);
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    if (_totalSupply == 0) {
                                                        liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
                                                       _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
                                                    } else {
                                                        liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
                                                    }
                                                    require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
                                                    _mint(to, liquidity);
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Mint(msg.sender, amount0, amount1);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function burn(address to) external lock returns (uint amount0, uint amount1) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    address _token0 = token0;                                // gas savings
                                                    address _token1 = token1;                                // gas savings
                                                    uint balance0 = IERC20(_token0).balanceOf(address(this));
                                                    uint balance1 = IERC20(_token1).balanceOf(address(this));
                                                    uint liquidity = balanceOf[address(this)];
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
                                                    amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
                                                    require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED');
                                                    _burn(address(this), liquidity);
                                                    _safeTransfer(_token0, to, amount0);
                                                    _safeTransfer(_token1, to, amount1);
                                                    balance0 = IERC20(_token0).balanceOf(address(this));
                                                    balance1 = IERC20(_token1).balanceOf(address(this));
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Burn(msg.sender, amount0, amount1, to);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
                                                    require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');
                                            
                                                    uint balance0;
                                                    uint balance1;
                                                    { // scope for _token{0,1}, avoids stack too deep errors
                                                    address _token0 = token0;
                                                    address _token1 = token1;
                                                    require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
                                                    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
                                                    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
                                                    if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
                                                    balance0 = IERC20(_token0).balanceOf(address(this));
                                                    balance1 = IERC20(_token1).balanceOf(address(this));
                                                    }
                                                    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
                                                    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
                                                    require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
                                                    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
                                                    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
                                                    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
                                                    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
                                                    }
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
                                                }
                                            
                                                // force balances to match reserves
                                                function skim(address to) external lock {
                                                    address _token0 = token0; // gas savings
                                                    address _token1 = token1; // gas savings
                                                    _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
                                                    _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
                                                }
                                            
                                                // force reserves to match balances
                                                function sync() external lock {
                                                    _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
                                                }
                                            }

                                            File 13 of 14: UniswapV2Pair
                                            // File: contracts/uniswapv2/interfaces/IUniswapV2Factory.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Factory {
                                                event PairCreated(address indexed token0, address indexed token1, address pair, uint);
                                            
                                                function feeTo() external view returns (address);
                                                function feeToSetter() external view returns (address);
                                                function migrator() external view returns (address);
                                            
                                                function getPair(address tokenA, address tokenB) external view returns (address pair);
                                                function allPairs(uint) external view returns (address pair);
                                                function allPairsLength() external view returns (uint);
                                            
                                                function createPair(address tokenA, address tokenB) external returns (address pair);
                                            
                                                function setFeeTo(address) external;
                                                function setFeeToSetter(address) external;
                                                function setMigrator(address) external;
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/SafeMath.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
                                            
                                            library SafeMathUniswap {
                                                function add(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x + y) >= x, 'ds-math-add-overflow');
                                                }
                                            
                                                function sub(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x - y) <= x, 'ds-math-sub-underflow');
                                                }
                                            
                                                function mul(uint x, uint y) internal pure returns (uint z) {
                                                    require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/UniswapV2ERC20.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            
                                            contract UniswapV2ERC20 {
                                                using SafeMathUniswap for uint;
                                            
                                                string public constant name = 'SushiSwap LP Token';
                                                string public constant symbol = 'SLP';
                                                uint8 public constant decimals = 18;
                                                uint  public totalSupply;
                                                mapping(address => uint) public balanceOf;
                                                mapping(address => mapping(address => uint)) public allowance;
                                            
                                                bytes32 public DOMAIN_SEPARATOR;
                                                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                                                bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
                                                mapping(address => uint) public nonces;
                                            
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                constructor() public {
                                                    uint chainId;
                                                    assembly {
                                                        chainId := chainid()
                                                    }
                                                    DOMAIN_SEPARATOR = keccak256(
                                                        abi.encode(
                                                            keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                                                            keccak256(bytes(name)),
                                                            keccak256(bytes('1')),
                                                            chainId,
                                                            address(this)
                                                        )
                                                    );
                                                }
                                            
                                                function _mint(address to, uint value) internal {
                                                    totalSupply = totalSupply.add(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(address(0), to, value);
                                                }
                                            
                                                function _burn(address from, uint value) internal {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    totalSupply = totalSupply.sub(value);
                                                    emit Transfer(from, address(0), value);
                                                }
                                            
                                                function _approve(address owner, address spender, uint value) private {
                                                    allowance[owner][spender] = value;
                                                    emit Approval(owner, spender, value);
                                                }
                                            
                                                function _transfer(address from, address to, uint value) private {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(from, to, value);
                                                }
                                            
                                                function approve(address spender, uint value) external returns (bool) {
                                                    _approve(msg.sender, spender, value);
                                                    return true;
                                                }
                                            
                                                function transfer(address to, uint value) external returns (bool) {
                                                    _transfer(msg.sender, to, value);
                                                    return true;
                                                }
                                            
                                                function transferFrom(address from, address to, uint value) external returns (bool) {
                                                    if (allowance[from][msg.sender] != uint(-1)) {
                                                        allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
                                                    }
                                                    _transfer(from, to, value);
                                                    return true;
                                                }
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
                                                    require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
                                                    bytes32 digest = keccak256(
                                                        abi.encodePacked(
                                                            '\x19\x01',
                                                            DOMAIN_SEPARATOR,
                                                            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                                                        )
                                                    );
                                                    address recoveredAddress = ecrecover(digest, v, r, s);
                                                    require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
                                                    _approve(owner, spender, value);
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/Math.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for performing various math operations
                                            
                                            library Math {
                                                function min(uint x, uint y) internal pure returns (uint z) {
                                                    z = x < y ? x : y;
                                                }
                                            
                                                // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
                                                function sqrt(uint y) internal pure returns (uint z) {
                                                    if (y > 3) {
                                                        z = y;
                                                        uint x = y / 2 + 1;
                                                        while (x < z) {
                                                            z = x;
                                                            x = (y / x + x) / 2;
                                                        }
                                                    } else if (y != 0) {
                                                        z = 1;
                                                    }
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/UQ112x112.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
                                            
                                            // range: [0, 2**112 - 1]
                                            // resolution: 1 / 2**112
                                            
                                            library UQ112x112 {
                                                uint224 constant Q112 = 2**112;
                                            
                                                // encode a uint112 as a UQ112x112
                                                function encode(uint112 y) internal pure returns (uint224 z) {
                                                    z = uint224(y) * Q112; // never overflows
                                                }
                                            
                                                // divide a UQ112x112 by a uint112, returning a UQ112x112
                                                function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
                                                    z = x / uint224(y);
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/interfaces/IERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IERC20Uniswap {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external view returns (string memory);
                                                function symbol() external view returns (string memory);
                                                function decimals() external view returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            }
                                            
                                            // File: contracts/uniswapv2/interfaces/IUniswapV2Callee.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Callee {
                                                function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
                                            }
                                            
                                            // File: contracts/uniswapv2/UniswapV2Pair.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            interface IMigrator {
                                                // Return the desired amount of liquidity token that the migrator wants.
                                                function desiredLiquidity() external view returns (uint256);
                                            }
                                            
                                            contract UniswapV2Pair is UniswapV2ERC20 {
                                                using SafeMathUniswap  for uint;
                                                using UQ112x112 for uint224;
                                            
                                                uint public constant MINIMUM_LIQUIDITY = 10**3;
                                                bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
                                            
                                                address public factory;
                                                address public token0;
                                                address public token1;
                                            
                                                uint112 private reserve0;           // uses single storage slot, accessible via getReserves
                                                uint112 private reserve1;           // uses single storage slot, accessible via getReserves
                                                uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves
                                            
                                                uint public price0CumulativeLast;
                                                uint public price1CumulativeLast;
                                                uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
                                            
                                                uint private unlocked = 1;
                                                modifier lock() {
                                                    require(unlocked == 1, 'UniswapV2: LOCKED');
                                                    unlocked = 0;
                                                    _;
                                                    unlocked = 1;
                                                }
                                            
                                                function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
                                                    _reserve0 = reserve0;
                                                    _reserve1 = reserve1;
                                                    _blockTimestampLast = blockTimestampLast;
                                                }
                                            
                                                function _safeTransfer(address token, address to, uint value) private {
                                                    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
                                                    require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
                                                }
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                constructor() public {
                                                    factory = msg.sender;
                                                }
                                            
                                                // called once by the factory at time of deployment
                                                function initialize(address _token0, address _token1) external {
                                                    require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
                                                    token0 = _token0;
                                                    token1 = _token1;
                                                }
                                            
                                                // update reserves and, on the first call per block, price accumulators
                                                function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
                                                    require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW');
                                                    uint32 blockTimestamp = uint32(block.timestamp % 2**32);
                                                    uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
                                                    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
                                                        // * never overflows, and + overflow is desired
                                                        price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
                                                        price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
                                                    }
                                                    reserve0 = uint112(balance0);
                                                    reserve1 = uint112(balance1);
                                                    blockTimestampLast = blockTimestamp;
                                                    emit Sync(reserve0, reserve1);
                                                }
                                            
                                                // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
                                                function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
                                                    address feeTo = IUniswapV2Factory(factory).feeTo();
                                                    feeOn = feeTo != address(0);
                                                    uint _kLast = kLast; // gas savings
                                                    if (feeOn) {
                                                        if (_kLast != 0) {
                                                            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                                                            uint rootKLast = Math.sqrt(_kLast);
                                                            if (rootK > rootKLast) {
                                                                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                                                                uint denominator = rootK.mul(5).add(rootKLast);
                                                                uint liquidity = numerator / denominator;
                                                                if (liquidity > 0) _mint(feeTo, liquidity);
                                                            }
                                                        }
                                                    } else if (_kLast != 0) {
                                                        kLast = 0;
                                                    }
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function mint(address to) external lock returns (uint liquidity) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    uint balance0 = IERC20Uniswap(token0).balanceOf(address(this));
                                                    uint balance1 = IERC20Uniswap(token1).balanceOf(address(this));
                                                    uint amount0 = balance0.sub(_reserve0);
                                                    uint amount1 = balance1.sub(_reserve1);
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    if (_totalSupply == 0) {
                                                        address migrator = IUniswapV2Factory(factory).migrator();
                                                        if (msg.sender == migrator) {
                                                            liquidity = IMigrator(migrator).desiredLiquidity();
                                                            require(liquidity > 0 && liquidity != uint256(-1), "Bad desired liquidity");
                                                        } else {
                                                            require(migrator == address(0), "Must not have migrator");
                                                            liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
                                                            _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
                                                        }
                                                    } else {
                                                        liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
                                                    }
                                                    require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
                                                    _mint(to, liquidity);
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Mint(msg.sender, amount0, amount1);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function burn(address to) external lock returns (uint amount0, uint amount1) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    address _token0 = token0;                                // gas savings
                                                    address _token1 = token1;                                // gas savings
                                                    uint balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    uint balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                                    uint liquidity = balanceOf[address(this)];
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
                                                    amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
                                                    require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED');
                                                    _burn(address(this), liquidity);
                                                    _safeTransfer(_token0, to, amount0);
                                                    _safeTransfer(_token1, to, amount1);
                                                    balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Burn(msg.sender, amount0, amount1, to);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
                                                    require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');
                                            
                                                    uint balance0;
                                                    uint balance1;
                                                    { // scope for _token{0,1}, avoids stack too deep errors
                                                    address _token0 = token0;
                                                    address _token1 = token1;
                                                    require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
                                                    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
                                                    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
                                                    if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
                                                    balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                                    }
                                                    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
                                                    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
                                                    require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
                                                    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
                                                    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
                                                    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
                                                    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
                                                    }
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
                                                }
                                            
                                                // force balances to match reserves
                                                function skim(address to) external lock {
                                                    address _token0 = token0; // gas savings
                                                    address _token1 = token1; // gas savings
                                                    _safeTransfer(_token0, to, IERC20Uniswap(_token0).balanceOf(address(this)).sub(reserve0));
                                                    _safeTransfer(_token1, to, IERC20Uniswap(_token1).balanceOf(address(this)).sub(reserve1));
                                                }
                                            
                                                // force reserves to match balances
                                                function sync() external lock {
                                                    _update(IERC20Uniswap(token0).balanceOf(address(this)), IERC20Uniswap(token1).balanceOf(address(this)), reserve0, reserve1);
                                                }
                                            }

                                            File 14 of 14: UniswapV2Pair
                                            // File: contracts/uniswapv2/interfaces/IUniswapV2Factory.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Factory {
                                                event PairCreated(address indexed token0, address indexed token1, address pair, uint);
                                            
                                                function feeTo() external view returns (address);
                                                function feeToSetter() external view returns (address);
                                                function migrator() external view returns (address);
                                            
                                                function getPair(address tokenA, address tokenB) external view returns (address pair);
                                                function allPairs(uint) external view returns (address pair);
                                                function allPairsLength() external view returns (uint);
                                            
                                                function createPair(address tokenA, address tokenB) external returns (address pair);
                                            
                                                function setFeeTo(address) external;
                                                function setFeeToSetter(address) external;
                                                function setMigrator(address) external;
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/SafeMath.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
                                            
                                            library SafeMathUniswap {
                                                function add(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x + y) >= x, 'ds-math-add-overflow');
                                                }
                                            
                                                function sub(uint x, uint y) internal pure returns (uint z) {
                                                    require((z = x - y) <= x, 'ds-math-sub-underflow');
                                                }
                                            
                                                function mul(uint x, uint y) internal pure returns (uint z) {
                                                    require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/UniswapV2ERC20.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            
                                            contract UniswapV2ERC20 {
                                                using SafeMathUniswap for uint;
                                            
                                                string public constant name = 'SushiSwap LP Token';
                                                string public constant symbol = 'SLP';
                                                uint8 public constant decimals = 18;
                                                uint  public totalSupply;
                                                mapping(address => uint) public balanceOf;
                                                mapping(address => mapping(address => uint)) public allowance;
                                            
                                                bytes32 public DOMAIN_SEPARATOR;
                                                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                                                bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
                                                mapping(address => uint) public nonces;
                                            
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                constructor() public {
                                                    uint chainId;
                                                    assembly {
                                                        chainId := chainid()
                                                    }
                                                    DOMAIN_SEPARATOR = keccak256(
                                                        abi.encode(
                                                            keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
                                                            keccak256(bytes(name)),
                                                            keccak256(bytes('1')),
                                                            chainId,
                                                            address(this)
                                                        )
                                                    );
                                                }
                                            
                                                function _mint(address to, uint value) internal {
                                                    totalSupply = totalSupply.add(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(address(0), to, value);
                                                }
                                            
                                                function _burn(address from, uint value) internal {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    totalSupply = totalSupply.sub(value);
                                                    emit Transfer(from, address(0), value);
                                                }
                                            
                                                function _approve(address owner, address spender, uint value) private {
                                                    allowance[owner][spender] = value;
                                                    emit Approval(owner, spender, value);
                                                }
                                            
                                                function _transfer(address from, address to, uint value) private {
                                                    balanceOf[from] = balanceOf[from].sub(value);
                                                    balanceOf[to] = balanceOf[to].add(value);
                                                    emit Transfer(from, to, value);
                                                }
                                            
                                                function approve(address spender, uint value) external returns (bool) {
                                                    _approve(msg.sender, spender, value);
                                                    return true;
                                                }
                                            
                                                function transfer(address to, uint value) external returns (bool) {
                                                    _transfer(msg.sender, to, value);
                                                    return true;
                                                }
                                            
                                                function transferFrom(address from, address to, uint value) external returns (bool) {
                                                    if (allowance[from][msg.sender] != uint(-1)) {
                                                        allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
                                                    }
                                                    _transfer(from, to, value);
                                                    return true;
                                                }
                                            
                                                function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
                                                    require(deadline >= block.timestamp, 'UniswapV2: EXPIRED');
                                                    bytes32 digest = keccak256(
                                                        abi.encodePacked(
                                                            '\x19\x01',
                                                            DOMAIN_SEPARATOR,
                                                            keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                                                        )
                                                    );
                                                    address recoveredAddress = ecrecover(digest, v, r, s);
                                                    require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE');
                                                    _approve(owner, spender, value);
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/Math.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for performing various math operations
                                            
                                            library Math {
                                                function min(uint x, uint y) internal pure returns (uint z) {
                                                    z = x < y ? x : y;
                                                }
                                            
                                                // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
                                                function sqrt(uint y) internal pure returns (uint z) {
                                                    if (y > 3) {
                                                        z = y;
                                                        uint x = y / 2 + 1;
                                                        while (x < z) {
                                                            z = x;
                                                            x = (y / x + x) / 2;
                                                        }
                                                    } else if (y != 0) {
                                                        z = 1;
                                                    }
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/libraries/UQ112x112.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
                                            
                                            // range: [0, 2**112 - 1]
                                            // resolution: 1 / 2**112
                                            
                                            library UQ112x112 {
                                                uint224 constant Q112 = 2**112;
                                            
                                                // encode a uint112 as a UQ112x112
                                                function encode(uint112 y) internal pure returns (uint224 z) {
                                                    z = uint224(y) * Q112; // never overflows
                                                }
                                            
                                                // divide a UQ112x112 by a uint112, returning a UQ112x112
                                                function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
                                                    z = x / uint224(y);
                                                }
                                            }
                                            
                                            // File: contracts/uniswapv2/interfaces/IERC20.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IERC20Uniswap {
                                                event Approval(address indexed owner, address indexed spender, uint value);
                                                event Transfer(address indexed from, address indexed to, uint value);
                                            
                                                function name() external view returns (string memory);
                                                function symbol() external view returns (string memory);
                                                function decimals() external view returns (uint8);
                                                function totalSupply() external view returns (uint);
                                                function balanceOf(address owner) external view returns (uint);
                                                function allowance(address owner, address spender) external view returns (uint);
                                            
                                                function approve(address spender, uint value) external returns (bool);
                                                function transfer(address to, uint value) external returns (bool);
                                                function transferFrom(address from, address to, uint value) external returns (bool);
                                            }
                                            
                                            // File: contracts/uniswapv2/interfaces/IUniswapV2Callee.sol
                                            
                                            pragma solidity >=0.5.0;
                                            
                                            interface IUniswapV2Callee {
                                                function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
                                            }
                                            
                                            // File: contracts/uniswapv2/UniswapV2Pair.sol
                                            
                                            pragma solidity =0.6.12;
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            
                                            interface IMigrator {
                                                // Return the desired amount of liquidity token that the migrator wants.
                                                function desiredLiquidity() external view returns (uint256);
                                            }
                                            
                                            contract UniswapV2Pair is UniswapV2ERC20 {
                                                using SafeMathUniswap  for uint;
                                                using UQ112x112 for uint224;
                                            
                                                uint public constant MINIMUM_LIQUIDITY = 10**3;
                                                bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
                                            
                                                address public factory;
                                                address public token0;
                                                address public token1;
                                            
                                                uint112 private reserve0;           // uses single storage slot, accessible via getReserves
                                                uint112 private reserve1;           // uses single storage slot, accessible via getReserves
                                                uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves
                                            
                                                uint public price0CumulativeLast;
                                                uint public price1CumulativeLast;
                                                uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
                                            
                                                uint private unlocked = 1;
                                                modifier lock() {
                                                    require(unlocked == 1, 'UniswapV2: LOCKED');
                                                    unlocked = 0;
                                                    _;
                                                    unlocked = 1;
                                                }
                                            
                                                function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
                                                    _reserve0 = reserve0;
                                                    _reserve1 = reserve1;
                                                    _blockTimestampLast = blockTimestampLast;
                                                }
                                            
                                                function _safeTransfer(address token, address to, uint value) private {
                                                    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
                                                    require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
                                                }
                                            
                                                event Mint(address indexed sender, uint amount0, uint amount1);
                                                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                                                event Swap(
                                                    address indexed sender,
                                                    uint amount0In,
                                                    uint amount1In,
                                                    uint amount0Out,
                                                    uint amount1Out,
                                                    address indexed to
                                                );
                                                event Sync(uint112 reserve0, uint112 reserve1);
                                            
                                                constructor() public {
                                                    factory = msg.sender;
                                                }
                                            
                                                // called once by the factory at time of deployment
                                                function initialize(address _token0, address _token1) external {
                                                    require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
                                                    token0 = _token0;
                                                    token1 = _token1;
                                                }
                                            
                                                // update reserves and, on the first call per block, price accumulators
                                                function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
                                                    require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW');
                                                    uint32 blockTimestamp = uint32(block.timestamp % 2**32);
                                                    uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
                                                    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
                                                        // * never overflows, and + overflow is desired
                                                        price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
                                                        price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
                                                    }
                                                    reserve0 = uint112(balance0);
                                                    reserve1 = uint112(balance1);
                                                    blockTimestampLast = blockTimestamp;
                                                    emit Sync(reserve0, reserve1);
                                                }
                                            
                                                // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
                                                function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
                                                    address feeTo = IUniswapV2Factory(factory).feeTo();
                                                    feeOn = feeTo != address(0);
                                                    uint _kLast = kLast; // gas savings
                                                    if (feeOn) {
                                                        if (_kLast != 0) {
                                                            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                                                            uint rootKLast = Math.sqrt(_kLast);
                                                            if (rootK > rootKLast) {
                                                                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                                                                uint denominator = rootK.mul(5).add(rootKLast);
                                                                uint liquidity = numerator / denominator;
                                                                if (liquidity > 0) _mint(feeTo, liquidity);
                                                            }
                                                        }
                                                    } else if (_kLast != 0) {
                                                        kLast = 0;
                                                    }
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function mint(address to) external lock returns (uint liquidity) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    uint balance0 = IERC20Uniswap(token0).balanceOf(address(this));
                                                    uint balance1 = IERC20Uniswap(token1).balanceOf(address(this));
                                                    uint amount0 = balance0.sub(_reserve0);
                                                    uint amount1 = balance1.sub(_reserve1);
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    if (_totalSupply == 0) {
                                                        address migrator = IUniswapV2Factory(factory).migrator();
                                                        if (msg.sender == migrator) {
                                                            liquidity = IMigrator(migrator).desiredLiquidity();
                                                            require(liquidity > 0 && liquidity != uint256(-1), "Bad desired liquidity");
                                                        } else {
                                                            require(migrator == address(0), "Must not have migrator");
                                                            liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
                                                            _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
                                                        }
                                                    } else {
                                                        liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
                                                    }
                                                    require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
                                                    _mint(to, liquidity);
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Mint(msg.sender, amount0, amount1);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function burn(address to) external lock returns (uint amount0, uint amount1) {
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    address _token0 = token0;                                // gas savings
                                                    address _token1 = token1;                                // gas savings
                                                    uint balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    uint balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                                    uint liquidity = balanceOf[address(this)];
                                            
                                                    bool feeOn = _mintFee(_reserve0, _reserve1);
                                                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                                                    amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
                                                    amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
                                                    require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED');
                                                    _burn(address(this), liquidity);
                                                    _safeTransfer(_token0, to, amount0);
                                                    _safeTransfer(_token1, to, amount1);
                                                    balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                                                    emit Burn(msg.sender, amount0, amount1, to);
                                                }
                                            
                                                // this low-level function should be called from a contract which performs important safety checks
                                                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
                                                    require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT');
                                                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                                                    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');
                                            
                                                    uint balance0;
                                                    uint balance1;
                                                    { // scope for _token{0,1}, avoids stack too deep errors
                                                    address _token0 = token0;
                                                    address _token1 = token1;
                                                    require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO');
                                                    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
                                                    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
                                                    if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data);
                                                    balance0 = IERC20Uniswap(_token0).balanceOf(address(this));
                                                    balance1 = IERC20Uniswap(_token1).balanceOf(address(this));
                                                    }
                                                    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
                                                    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
                                                    require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');
                                                    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
                                                    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
                                                    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
                                                    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K');
                                                    }
                                            
                                                    _update(balance0, balance1, _reserve0, _reserve1);
                                                    emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
                                                }
                                            
                                                // force balances to match reserves
                                                function skim(address to) external lock {
                                                    address _token0 = token0; // gas savings
                                                    address _token1 = token1; // gas savings
                                                    _safeTransfer(_token0, to, IERC20Uniswap(_token0).balanceOf(address(this)).sub(reserve0));
                                                    _safeTransfer(_token1, to, IERC20Uniswap(_token1).balanceOf(address(this)).sub(reserve1));
                                                }
                                            
                                                // force reserves to match balances
                                                function sync() external lock {
                                                    _update(IERC20Uniswap(token0).balanceOf(address(this)), IERC20Uniswap(token1).balanceOf(address(this)), reserve0, reserve1);
                                                }
                                            }