@superfluid-finance/ethereum-contracts 1.2.3-dev.f94fdbb.0 → 1.3.1-dev.ad4bf1f.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/build/contracts/AccessControl.json +3 -3
  2. package/build/contracts/AccessControlEnumerable.json +3 -3
  3. package/build/contracts/Address.json +5 -5
  4. package/build/contracts/AgreementBase.json +13 -13
  5. package/build/contracts/AgreementLibrary.json +7 -7
  6. package/build/contracts/BaseRelayRecipient.json +5 -5
  7. package/build/contracts/BatchLiquidator.json +179 -179
  8. package/build/contracts/BatchOperation.json +5 -5
  9. package/build/contracts/CFAv1Library.json +5 -5
  10. package/build/contracts/CallUtils.json +7 -7
  11. package/build/contracts/ClosingOnUpdateFlowTestApp.json +2107 -1917
  12. package/build/contracts/ConstantFlowAgreementV1.json +8 -8
  13. package/build/contracts/Context.json +3 -3
  14. package/build/contracts/ContextDefinitions.json +5 -5
  15. package/build/contracts/Create2.json +5 -5
  16. package/build/contracts/CustomSuperTokenBase.json +3 -3
  17. package/build/contracts/ERC165.json +3 -3
  18. package/build/contracts/ERC1820Implementer.json +5 -5
  19. package/build/contracts/ERC1820RegistryCompiled.json +7 -7
  20. package/build/contracts/ERC20.json +5 -5
  21. package/build/contracts/ERC20Burnable.json +3 -3
  22. package/build/contracts/ERC20Pausable.json +3 -3
  23. package/build/contracts/ERC20PresetMinterPauser.json +5 -5
  24. package/build/contracts/ERC20WithTokenInfo.json +3 -3
  25. package/build/contracts/ERC777Helper.json +7 -7
  26. package/build/contracts/ERC777RecipientDrainingGas.json +839 -839
  27. package/build/contracts/ERC777RecipientReverting.json +839 -839
  28. package/build/contracts/EnumerableSet.json +5 -5
  29. package/build/contracts/EventsEmitter.json +47 -47
  30. package/build/contracts/ExclusiveInflowTestApp.json +2107 -1917
  31. package/build/contracts/FixedSizeData.json +213 -213
  32. package/build/contracts/FlowExchangeTestApp.json +2107 -1917
  33. package/build/contracts/FlowOperatorDefinitions.json +5 -5
  34. package/build/contracts/FullUpgradableSuperTokenProxy.json +226 -312
  35. package/build/contracts/IAccessControl.json +3 -3
  36. package/build/contracts/IAccessControlEnumerable.json +3 -3
  37. package/build/contracts/IConstantFlowAgreementV1.json +451 -444
  38. package/build/contracts/IDAv1Library.json +5 -5
  39. package/build/contracts/IERC165.json +3 -3
  40. package/build/contracts/IERC1820Implementer.json +3 -3
  41. package/build/contracts/IERC1820Registry.json +3 -3
  42. package/build/contracts/IERC20.json +3 -3
  43. package/build/contracts/IERC20Metadata.json +3 -3
  44. package/build/contracts/IERC777.json +3 -3
  45. package/build/contracts/IERC777Recipient.json +3 -3
  46. package/build/contracts/IERC777Sender.json +3 -3
  47. package/build/contracts/IInstantDistributionAgreementV1.json +570 -559
  48. package/build/contracts/IMaticBridgedNativeSuperToken.json +71 -32
  49. package/build/contracts/IMaticBridgedNativeSuperTokenCustom.json +3 -3
  50. package/build/contracts/IMultiSigWallet.json +3 -3
  51. package/build/contracts/IPureSuperToken.json +71 -32
  52. package/build/contracts/IPureSuperTokenCustom.json +3 -3
  53. package/build/contracts/IRelayRecipient.json +3 -3
  54. package/build/contracts/IResolver.json +3 -3
  55. package/build/contracts/ISETH.json +71 -32
  56. package/build/contracts/ISETHCustom.json +3 -3
  57. package/build/contracts/ISuperAgreement.json +3 -3
  58. package/build/contracts/ISuperApp.json +179 -173
  59. package/build/contracts/ISuperToken.json +522 -483
  60. package/build/contracts/ISuperTokenFactory.json +3 -3
  61. package/build/contracts/ISuperfluid.json +633 -628
  62. package/build/contracts/ISuperfluidGovernance.json +134 -133
  63. package/build/contracts/ISuperfluidToken.json +403 -394
  64. package/build/contracts/ITOGAv1.json +1211 -1211
  65. package/build/contracts/ITOGAv2.json +1211 -1211
  66. package/build/contracts/Initializable.json +3 -3
  67. package/build/contracts/InstantDistributionAgreementV1.json +10 -10
  68. package/build/contracts/MaticBridgedNativeSuperTokenProxy.json +194 -194
  69. package/build/contracts/NonClosableOutflowTestApp.json +2107 -1917
  70. package/build/contracts/Ownable.json +3 -3
  71. package/build/contracts/Pausable.json +3 -3
  72. package/build/contracts/Proxy.json +3 -3
  73. package/build/contracts/PureSuperToken.json +91 -91
  74. package/build/contracts/Resolver.json +96 -96
  75. package/build/contracts/SETHProxy.json +199 -199
  76. package/build/contracts/SafeCast.json +5 -5
  77. package/build/contracts/SafeERC20.json +5 -5
  78. package/build/contracts/SafeMath.json +5 -5
  79. package/build/contracts/SelfDeletingFlowTestApp.json +2107 -1917
  80. package/build/contracts/SlotsBitmapLibrary.json +7 -7
  81. package/build/contracts/Strings.json +5 -5
  82. package/build/contracts/SuperAppBase.json +3 -3
  83. package/build/contracts/SuperAppDefinitions.json +5 -5
  84. package/build/contracts/SuperToken.json +2262 -2262
  85. package/build/contracts/SuperTokenFactory.json +582 -582
  86. package/build/contracts/SuperTokenFactoryBase.json +576 -576
  87. package/build/contracts/SuperTokenFactoryHelper.json +578 -578
  88. package/build/contracts/SuperUpgrader.json +687 -687
  89. package/build/contracts/Superfluid.json +6648 -6678
  90. package/build/contracts/SuperfluidFrameworkDeployer.json +526 -526
  91. package/build/contracts/SuperfluidGovernanceBase.json +13 -13
  92. package/build/contracts/SuperfluidGovernanceConfigs.json +5 -5
  93. package/build/contracts/SuperfluidGovernanceII.json +21 -21
  94. package/build/contracts/SuperfluidGovernanceIIProxy.json +20 -20
  95. package/build/contracts/SuperfluidLoader.json +147 -147
  96. package/build/contracts/SuperfluidToken.json +1269 -1269
  97. package/build/contracts/TOGA.json +1221 -1221
  98. package/build/contracts/TestGovernance.json +315 -315
  99. package/build/contracts/TestToken.json +475 -561
  100. package/build/contracts/TokenCustodian.json +220 -220
  101. package/build/contracts/TokenInfo.json +3 -3
  102. package/build/contracts/UUPSProxiable.json +136 -136
  103. package/build/contracts/UUPSProxy.json +87 -87
  104. package/build/contracts/UUPSUtils.json +43 -43
  105. package/build/contracts-sizes.txt +3 -3
  106. package/contracts/agreements/AgreementBase.sol +1 -1
  107. package/contracts/agreements/AgreementLibrary.sol +1 -1
  108. package/contracts/agreements/ConstantFlowAgreementV1.sol +1 -1
  109. package/contracts/agreements/InstantDistributionAgreementV1.sol +1 -1
  110. package/contracts/gov/SuperfluidGovernanceBase.sol +1 -1
  111. package/contracts/gov/SuperfluidGovernanceII.sol +1 -1
  112. package/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol +7 -10
  113. package/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol +11 -18
  114. package/contracts/interfaces/superfluid/ISuperApp.sol +7 -9
  115. package/contracts/interfaces/superfluid/ISuperToken.sol +36 -44
  116. package/contracts/interfaces/superfluid/ISuperfluid.sol +17 -21
  117. package/contracts/interfaces/superfluid/ISuperfluidGovernance.sol +1 -1
  118. package/contracts/interfaces/superfluid/ISuperfluidToken.sol +13 -14
  119. package/contracts/libs/BaseRelayRecipient.sol +1 -1
  120. package/contracts/libs/CallUtils.sol +1 -1
  121. package/contracts/libs/ERC1820RegistryCompiled.sol +1 -1
  122. package/contracts/libs/ERC777Helper.sol +1 -1
  123. package/contracts/libs/EventsEmitter.sol +2 -2
  124. package/contracts/libs/FixedSizeData.sol +2 -2
  125. package/contracts/libs/SlotsBitmapLibrary.sol +1 -1
  126. package/contracts/mocks/AgreementMock.sol +1 -1
  127. package/contracts/mocks/CFAAppMocks.sol +6 -6
  128. package/contracts/mocks/CFALibraryMock.sol +2 -2
  129. package/contracts/mocks/CallUtilsMock.sol +1 -1
  130. package/contracts/mocks/CallUtilsTester.sol +1 -1
  131. package/contracts/mocks/CustomSuperTokenMock.sol +1 -1
  132. package/contracts/mocks/ERC777SenderRecipientMock.sol +1 -1
  133. package/contracts/mocks/FakeSuperfluidMock.sol +1 -1
  134. package/contracts/mocks/ForwarderMock.sol +1 -1
  135. package/contracts/mocks/IDASuperAppTester.sol +2 -2
  136. package/contracts/mocks/IDAv1LibraryMock.sol +3 -3
  137. package/contracts/mocks/MockSmartWallet.sol +1 -1
  138. package/contracts/mocks/MultiFlowTesterApp.sol +2 -2
  139. package/contracts/mocks/SuperAppMocks.sol +15 -12
  140. package/contracts/mocks/SuperTokenFactoryMock.sol +1 -1
  141. package/contracts/mocks/SuperTokenMock.sol +1 -1
  142. package/contracts/mocks/SuperfluidDestructorMock.sol +1 -1
  143. package/contracts/mocks/SuperfluidGovernanceIIMock.sol +1 -1
  144. package/contracts/mocks/SuperfluidMock.sol +2 -2
  145. package/contracts/mocks/UUPSProxiableMock.sol +1 -1
  146. package/contracts/superfluid/FullUpgradableSuperTokenProxy.sol +2 -2
  147. package/contracts/superfluid/SuperToken.sol +1 -1
  148. package/contracts/superfluid/SuperTokenFactory.sol +1 -1
  149. package/contracts/superfluid/Superfluid.sol +4 -4
  150. package/contracts/superfluid/SuperfluidToken.sol +1 -1
  151. package/contracts/tokens/MaticBridgedNativeSuperToken.sol +1 -1
  152. package/contracts/tokens/PureSuperToken.sol +1 -1
  153. package/contracts/tokens/SETH.sol +1 -1
  154. package/contracts/upgradability/UUPSProxiable.sol +1 -1
  155. package/contracts/upgradability/UUPSProxy.sol +1 -1
  156. package/contracts/upgradability/UUPSUtils.sol +1 -1
  157. package/contracts/utils/BatchLiquidator.sol +1 -1
  158. package/contracts/utils/Resolver.sol +1 -1
  159. package/contracts/utils/SuperUpgrader.sol +6 -6
  160. package/contracts/utils/SuperfluidLoader.sol +1 -1
  161. package/contracts/utils/TOGA.sol +1 -1
  162. package/contracts/utils/TestGovernance.sol +2 -2
  163. package/contracts/utils/TestToken.sol +2 -2
  164. package/contracts/utils/TokenCustodian.sol +1 -1
  165. package/package.json +5 -3
  166. package/scripts/deploy-framework.js +5 -5
  167. package/scripts/deploy-super-token.js +13 -4
  168. package/scripts/gov-create-new-app-registration-key.js +2 -1
  169. package/scripts/gov-create-new-factory-registration.js +1 -1
  170. package/scripts/libs/getConfig.js +21 -3
  171. package/scripts/resolver-list-super-token.js +1 -0
@@ -898,9 +898,9 @@
898
898
  "type": "function"
899
899
  }
900
900
  ],
901
- "metadata": "{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ISuperfluid\",\"name\":\"host\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uuid\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"codeAddress\",\"type\":\"address\"}],\"name\":\"CodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"name\":\"FlowOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"totalSenderFlowRate\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"totalReceiverFlowRate\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"}],\"name\":\"FlowUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"name\":\"FlowUpdatedExtension\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_MINIMUM_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_FLOW_RATE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"agreementType\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"authorizeFlowOperatorWithFullControl\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"createFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"createFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"deleteFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"deleteFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountFlowInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCodeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"codeAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"name\":\"getDepositRequiredForFlowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"getFlow\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"flowId\",\"type\":\"bytes32\"}],\"name\":\"getFlowByID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"}],\"name\":\"getFlowOperatorData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"flowOperatorId\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"flowOperatorId\",\"type\":\"bytes32\"}],\"name\":\"getFlowOperatorDataByID\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"name\":\"getMaximumFlowRateFromDeposit\",\"outputs\":[{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNetFlow\",\"outputs\":[{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"isPatricianPeriod\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPatricianPeriodNow\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isCurrentlyPatricianPeriod\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"}],\"name\":\"realtimeBalanceOf\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"dynamicBalance\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"revokeFlowOperatorWithFullControl\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"}],\"name\":\"updateCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlowOperatorPermissions\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Superfluid\",\"details\":\"Please read IConstantFlowAgreementV1 for implementation notes.For more technical notes, please visit protocol-monorepo wiki area.\",\"kind\":\"dev\",\"methods\":{\"agreementType()\":{\"details\":\"ISuperAgreement.agreementType implementation\"},\"authorizeFlowOperatorWithFullControl(address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.authorizeFlowOperatorWithFullControl implementation\"},\"createFlow(address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.createFlow implementation\"},\"createFlowByOperator(address,address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.createFlowByOperator implementation\"},\"deleteFlow(address,address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.deleteFlow implementation\"},\"deleteFlowByOperator(address,address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.deleteFlowByOperator implementation\"},\"getAccountFlowInfo(address,address)\":{\"details\":\"IConstantFlowAgreementV1.getAccountFlowInfo implementation\"},\"getCodeAddress()\":{\"details\":\"Get current implementation code address.\"},\"getDepositRequiredForFlowRate(address,int96)\":{\"details\":\"IConstantFlowAgreementV1.getDepositRequiredForFlowRate implementation\"},\"getFlow(address,address,address)\":{\"details\":\"IConstantFlowAgreementV1.getFlow implementation\"},\"getFlowByID(address,bytes32)\":{\"details\":\"IConstantFlowAgreementV1.getFlow implementation\"},\"getFlowOperatorData(address,address,address)\":{\"details\":\"IConstantFlowAgreementV1.getFlowOperatorData implementation\"},\"getFlowOperatorDataByID(address,bytes32)\":{\"details\":\"IConstantFlowAgreementV1.getFlowOperatorDataByID implementation\"},\"getMaximumFlowRateFromDeposit(address,uint256)\":{\"details\":\"IConstantFlowAgreementV1.getMaximumFlowRateFromDeposit implementation\"},\"getNetFlow(address,address)\":{\"details\":\"IConstantFlowAgreementV1.getNetFlow implementation\"},\"isPatricianPeriod(address,address,uint256)\":{\"details\":\"Returns whether it is the patrician period based on timestamp\",\"params\":{\"account\":\"The account we are interested in\",\"timestamp\":\"The timestamp we are interested in observing the result of isPatricianPeriod\"},\"returns\":{\"_0\":\"bool Whether it is currently the patrician period dictated by governance\"}},\"isPatricianPeriodNow(address,address)\":{\"details\":\"Returns whether it is the patrician period based on host.getNow()\",\"params\":{\"account\":\"The account we are interested in\"},\"returns\":{\"isCurrentlyPatricianPeriod\":\"Whether it is currently the patrician period dictated by governance\",\"timestamp\":\"The value of host.getNow()\"}},\"proxiableUUID()\":{\"details\":\"Proxiable UUID marker function, this would help to avoid wrong logic contract to be used for upgrading. NOTE: The semantics of the UUID deviates from the actual UUPS standard, where it is equivalent of _IMPLEMENTATION_SLOT.\"},\"realtimeBalanceOf(address,address,uint256)\":{\"details\":\"ISuperAgreement.realtimeBalanceOf implementation\"},\"revokeFlowOperatorWithFullControl(address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.revokeFlowOperatorWithFullControl implementation\"},\"updateFlow(address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlow implementation\"},\"updateFlowByOperator(address,address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlowByOperator implementation\"},\"updateFlowOperatorPermissions(address,address,uint8,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlowOperatorPermissions implementation\"}},\"stateVariables\":{\"DEFAULT_MINIMUM_DEPOSIT\":{\"details\":\"Default minimum deposit value NOTE: - It may come as a surprise that it is not 0, this is the minimum friction we have in the system for the imperfect blockchain system we live in. - It is related to deposit clipping, and it is always rounded-up when clipping.\"},\"MAXIMUM_DEPOSIT\":{\"details\":\"Maximum deposit value\"},\"MAXIMUM_FLOW_RATE\":{\"details\":\"Maximum flow rate\"}},\"title\":\"ConstantFlowAgreementV1 contract\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"project:/contracts/agreements/ConstantFlowAgreementV1.sol\":\"ConstantFlowAgreementV1\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x4823752b07b8ea4ca971b217e39457930e7cb103c2c91e2a29729e5ca907e4f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f319af26a9ade3e6cf3698bf1b84aa6213bdd7a76606ea9ba56ced163593934\",\"dweb:/ipfs/QmZ2u9zen5Htan4dSP1RZCY2XqB9HUwqkNCMzdn7aV2jWc\"]},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://87a7a5d2f6f63f84598af02b8c50ca2df2631cb8ba2453e8d95fcb17e4be9824\",\"dweb:/ipfs/QmR76hqtAcRqoFj33tmNjcWTLrgNsAaakYwnKZ8zoJtKei\"]},\"@openzeppelin/contracts/token/ERC777/IERC777.sol\":{\"keccak256\":\"0xe4e0b7e3f0265ffaa565d26acd2d45f2633f19127ed625e5a05a9f201a87a667\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1762b5bc15a009b5f092ccf547b81e0827c8705884f18e0623e497658514a7ed\",\"dweb:/ipfs/QmTtmVQYuynan3j2uVjdjjRJS1mr7LPRgxSZNnfqC7oxkz\"]},\"@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3a57d0854b2fdce6ebff933a48dca2445643d1eccfc27f00292e937f26c6a58\",\"dweb:/ipfs/QmW45rZooS9TqR4YXUbjRbtf2Bpb5ouSarBvfW1LdGprvV\"]},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x5c6caab697d302ad7eb59c234a4d2dbc965c1bae87709bd2850060b7695b28c7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb62abcee612c175f1b9bc70e5dfe5bd23473c99987ade6e80e291f68dc60ff1\",\"dweb:/ipfs/QmZCMajhG7FtRYNDwBchXN89mXR6HLPVzr9732qfUdNf9E\"]},\"project:/contracts/agreements/AgreementBase.sol\":{\"keccak256\":\"0xe59fc8bbe728c574773b5d3a3e9cfb4e8f323e9a3c3267a82d36fb79921b9997\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://0e21d969b3b996ab211eff83fa5bb7041614c0ac597c7479012c0fe625f4e15f\",\"dweb:/ipfs/QmWThBae9FCDgCAcco2bZicvsPq8vz5K1XW66hz3LXSK2V\"]},\"project:/contracts/agreements/AgreementLibrary.sol\":{\"keccak256\":\"0x107ee59e59b54e9ee85997d135a9bfc97979eda1143c7b1b61b63959777bff91\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://1a235f5a0fc7a04143662a69279d513d2434eeb7d60afdcc57911dcfeef712e5\",\"dweb:/ipfs/QmbUDhcf9mizwLxyCttibMxEM9NUun4guT3Sc9vdEaSxAv\"]},\"project:/contracts/agreements/ConstantFlowAgreementV1.sol\":{\"keccak256\":\"0xf601772532bdd09c6b98a0dfe3eba5fd6309161f9275ca3d103459b9bd1fd983\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://8839421289ec98fa3e5f7a13c7bba89b04f3e21579d1fcd86697cd9a172f17b2\",\"dweb:/ipfs/QmaetJch2QxW6HjWAXrXAguA7g6DyvegpBA2vspx3a7G6N\"]},\"project:/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol\":{\"keccak256\":\"0xb96bb6cb0fe88ddf5b890b6826f7f7585cf6e94223c76d8e2fb269779afe4445\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://b864597ae952222f0f43c66943492966013021c4171d5ef4f7357c047dfd737c\",\"dweb:/ipfs/Qmcr7xicfmPDD343B34ETP3XrdU9Vi1z3zxJSgqLipfQmY\"]},\"project:/contracts/interfaces/superfluid/Definitions.sol\":{\"keccak256\":\"0x199095781e4221b6015d859558da09977f79199f38d342ab4899c2cecdf8cec1\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://9fd3a5a8b16d8517e2af10e20390a9af5adbfa4e783e3a7dd89eb4588db98385\",\"dweb:/ipfs/QmPDtGR43DeMMVsHjUh7FYzMGsFKPpGriRkaahFpN5T5d3\"]},\"project:/contracts/interfaces/superfluid/ISuperAgreement.sol\":{\"keccak256\":\"0xc3a6a907245116bcecc70fe4b207454012e8ce4fa190228fb8bbe39e0b1bc5cf\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://83c116bdae48685d20e5a27c942111e685ec1ef6334e7ff6f6d9af66edbd8025\",\"dweb:/ipfs/QmTnVuNTaRFiDmkAmDk7NFYdfQTW1kqgBZiY2exC6k8jDx\"]},\"project:/contracts/interfaces/superfluid/ISuperApp.sol\":{\"keccak256\":\"0x57f4203168992c940eb6b8c7cc75f854cb36a1f9323b3f39ddc5e4fbe819c043\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://888941dfa3e5004f678f215b98a85d1bf54e412317928a78e0a1cff090773d4c\",\"dweb:/ipfs/QmVe838upcAyqpy1d3oQNHJrbRyWCKHL51zWrMKruvLxFG\"]},\"project:/contracts/interfaces/superfluid/ISuperToken.sol\":{\"keccak256\":\"0x3cb0b7216007b942f7611d7b3d983c0df9408fdd4fd6b799c33fc9033e0abf8b\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://17901a1fd3635f441671e14ece8ecc6806af20c5eb80cca3b7c6e53a51fef7b6\",\"dweb:/ipfs/QmUXXMfU6nmsyEnufyGEwyZ5M7pzpXNTr6vw32e3JjjoZp\"]},\"project:/contracts/interfaces/superfluid/ISuperTokenFactory.sol\":{\"keccak256\":\"0x68a466c978557e47bd7385b1d7d78f1c8fb07462a870efc5a791008e33a4f535\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://d109879bdb7f022560a792af2ff481df729bf1b4b8e1831b8022f4d12892d41d\",\"dweb:/ipfs/QmRSWqHq8CP5XWgyV4mJpPxMg33s312s2K5ndHRHVqqZ8n\"]},\"project:/contracts/interfaces/superfluid/ISuperfluid.sol\":{\"keccak256\":\"0x2d9b845469a35b66f1166406149ac85e933dbe9156f57e4a4078948e6a6e71a4\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://48e5cb11d4b90e42af521e23b33d57e12187c989d8d56be332b1649308168d45\",\"dweb:/ipfs/QmdaTW4HfpFfHjkHiJ3CmZUmCfLJyFCPTnCygwhiNhx3Tu\"]},\"project:/contracts/interfaces/superfluid/ISuperfluidGovernance.sol\":{\"keccak256\":\"0x2166f766b7f61f9bb1376b0948efa0d0c0046b93dc301e51ce495203b145189b\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://929630e6a15f523b142b2897783b2f7a54532ac5ae578bd17a0b7f25a6ca2bd8\",\"dweb:/ipfs/QmTu9ffH9qbQncJGEc24bmnoCGjifQ7BG47AYR8AzMLfXR\"]},\"project:/contracts/interfaces/superfluid/ISuperfluidToken.sol\":{\"keccak256\":\"0x518b869178aafffde40c654a1e24b3b1a2b5e42e5e8f17562556f404db8b9434\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://458ce84666b418fa3a7569c0e109db4d920fb6d1cb67ebc4c497c9c71107d93b\",\"dweb:/ipfs/QmV9nqhRF7MDGkV6UW3WWcqeXov2vmqHuRcvbqaaV8yP6u\"]},\"project:/contracts/interfaces/tokens/ERC20WithTokenInfo.sol\":{\"keccak256\":\"0x66708dae3fcd06e6fc0a46f2959fc2d1e6b9361f28598337339d26af8eb8c0f9\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://77b80718cec21b81ef190c19fb9fbe73913a95c71f7e6715f671bbe8a224dafc\",\"dweb:/ipfs/QmUdsc6DF2Bgih5VZm7sfaECjhGmwE7tAx8pMkzGQgVKQw\"]},\"project:/contracts/interfaces/tokens/TokenInfo.sol\":{\"keccak256\":\"0x70e573644a0ff271c0ccef526809e9d9ab4950ec58755ca84e833cde3b8f3df0\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://aea3709687cc37ba625f4cc882fbdb149a7bf5be5afe2b030203c8719641a77b\",\"dweb:/ipfs/QmVpvfR6ZheE5wNUK9CobaVBgVvEnEPkvjWF9cfwyZr7eQ\"]},\"project:/contracts/upgradability/UUPSProxiable.sol\":{\"keccak256\":\"0x5f50cec21a585dab7b59545aeb51735f36e3222e4b0768370be8d46373d0ef05\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://acdd57d81b5b2d346da335636baf1e37da3d31cf2eef58af493e43bc65a27414\",\"dweb:/ipfs/QmTepRBNAfRBXVDBM37ME1jpw1YgcseVehC17sWpEYeFDc\"]},\"project:/contracts/upgradability/UUPSUtils.sol\":{\"keccak256\":\"0xffec084e77ce3c0b595f0612687242f3d8b7a84cab15e5650c17428ee48d0b5b\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://be0183816467872b053562d9a737042ac3a91ea67e3c74e03de5db7226f3e73b\",\"dweb:/ipfs/QmUyi4YXh1T7MExbrLwZ6rAdXTPChF8q27YpZxxniR6CHM\"]}},\"version\":1}",
902
- "bytecode": "0x60a06040523480156200001157600080fd5b506040516200538b3803806200538b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516152f762000094600039600061077701526152f76000f3fe608060405234801561001057600080fd5b50600436106101a85760003560e01c806350d75d25116100f957806394229ecb11610097578063aabd266811610071578063aabd26681461042e578063b4b333c614610441578063e6a1e88814610454578063e8e7e2d11461046757600080fd5b806394229ecb146103ed5780639b2e48bc146104005780639cb28b72146102aa57600080fd5b806362fc305e116100d357806362fc305e1461038e5780637730599e146103a1578063811b3d40146103c75780638d997f6e146103da57600080fd5b806350d75d251461035357806352d1902d1461037357806354b770e31461037b57600080fd5b806326b0f536116101665780634b839e0b116101405780634b839e0b146102e05780634c8b181f146103035780634fe9c2911461031657806350209a621461034057600080fd5b806326b0f536146102aa578063354b9590146102b857806346951954146102cb57600080fd5b8062422bbe146101ad57806304aafa49146101e55780630602f7db146101ff578063062e56ec1461022557806309d256ef146102455780630f1ac49514610274575b600080fd5b6101c06101bb366004614493565b61047a565b6040805193845260ff9092166020840152600b0b908201526060015b60405180910390f35b6101f164010000000081565b6040519081526020016101dc565b61021261020d3660046144de565b6104b0565b604051600b9190910b81526020016101dc565b61023861023336600461454c565b6104d1565b6040516101dc919061460d565b6102586102533660046144de565b6104eb565b6040805160ff9093168352600b9190910b6020830152016101dc565b610287610282366004614620565b61050f565b60408051948552600b9390930b60208501529183015260608201526080016101dc565b6101f160016001605f1b0381565b6102386102c636600461466b565b610545565b6102de6102d93660046146f7565b61076c565b005b6102f36102ee366004614714565b6107f0565b60405190151581526020016101dc565b610238610311366004614755565b6108c7565b610329610324366004614620565b6109e1565b6040805192151583526020830191909152016101dc565b61023861034e3660046147d1565b610ac3565b61035b610b96565b6040516001600160a01b0390911681526020016101dc565b6101f1610bc5565b61023861038936600461454c565b610c29565b61023861039c3660046147d1565b610c41565b7fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd36101f1565b6102386103d5366004614821565b610cf4565b6101f16103e8366004614865565b610f7e565b6102386103fb36600461466b565b611199565b61041361040e366004614714565b611379565b604080519384526020840192909252908201526060016101dc565b61028761043c3660046144de565b6113d3565b61023861044f366004614755565b6113e5565b610287610462366004614493565b611479565b610212610475366004614620565b6114b4565b600080600061048985856114ce565b925060006104978785611539565b8051602090910151959990985094965093945050505050565b6000806104bc846115fe565b5090506104c98184611779565b949350505050565b60606104e285856000808787610cf4565b95945050505050565b60008060006104fa8585611539565b80516020909101519097909650945050505050565b600080600080600061052187876117e8565b805160208201516040830151606090930151919b909a509198509650945050505050565b606060006105898885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036105f55760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f55504441544500000000000000000060448201526064015b60405180910390fd5b60008061060b8a6106068b8b611a65565b611a8d565b9150915060008060006106238d8d886060015161047a565b925092509250610634826001611ad4565b6106805760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f5550444154455f464c4f570000000000000060448201526064016105ec565b6000600b82900b60016001605f1b0314806106a557508a600b0b8560200151600b0b12155b6106c75760208501516106b8908c6148b0565b6106c290836148b0565b6106c9565b815b9050600081600b0b12156106ef5760405162461bcd60e51b81526004016105ec90614900565b6106fb8e858584611b2f565b5050505061072960408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808c1682528a8116602083015289166040820152600b88900b606082015261075d8183858a8a89611bb8565b9b9a5050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107e45760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920686f73742063616e2075706461746520636f64650000000000000060448201526064016105ec565b6107ed81611d3d565b50565b604051633acd4df360e21b81526001600160a01b03838116600483015260248201839052600091829186169063eb3537cc90604401606060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190614941565b505090506000811261087c5760019150506108c0565b600080610888876115fe565b91509150600061089888886117e8565b91505060006108aa8260400151611f4b565b90506108b885828686611fb9565b955050505050505b9392505050565b6060600061090b8785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061091e8888846060015161047a565b50915050600061092f826002611ad4565b90508061097e5760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f44454c4554455f464c4f570000000000000060448201526064016105ec565b6040805160808101825260008082526020820181905291810182905260608101919091525b6001600160a01b03808b168252898116602083015288166040820152600060608201526109d38183898988611ff6565b9a9950505050505050505050565b6000806000846001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a48919061497a565b9050806001600160a01b031663bbe4fd506040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190614997565b9150610ab98585846107f0565b9250509250929050565b60606000610b078785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610b3360408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808916825260608084015182166020840181905291891660408401819052600b89900b91840191909152600091610b7191611a65565b9050600080610b84846000015184611a8d565b9150915061075d8482848b8b8a611bb8565b6000610bc07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000306001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190614997565b60606104e28585600760016001605f1b038787610cf4565b60606000610c858785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610cb160408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b038089168252606080840151821660208401529088166040830152600b87900b90820152610ce88186868561278d565b98975050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3b925087915061292d9050565b610d875760405162461bcd60e51b815260206004820152601860248201527f4346413a20556e636c65616e207065726d697373696f6e73000000000000000060448201526064016105ec565b6000610dc98885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b031603610e305760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f53454e4445525f464c4f575f4f50455241544f52000060448201526064016105ec565b600085600b0b1215610e845760405162461bcd60e51b815260206004820152601c60248201527f4346413a20455f4e4f5f4e454741544956455f414c4c4f57414e43450000000060448201526064016105ec565b6040805180820190915260ff87168152600b86900b60208201526060820151600090610eb0908a6114ce565b9050896001600160a01b031663a1b2bf8b82610ecb85612934565b6040518363ffffffff1660e01b8152600401610ee89291906149eb565b600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505060608401516040805160ff8c168152600b8b900b60208201526001600160a01b03808e169450928316928e16917fc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8910160405180910390a45050509695505050505050565b600080836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe3919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611049919061497a565b90506000816001600160a01b03166380f70cba84887feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc46040518463ffffffff1660e01b815260040161109d93929190614a04565b602060405180830381865afa1580156110ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110de9190614997565b90506000826001600160a01b03166380f70cba85897fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161113293929190614a04565b602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190614997565b9050602081901c63ffffffff1661118b8382896129aa565b955050505050505b92915050565b606060006111dd8885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036112445760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f43524541544500000000000000000060448201526064016105ec565b60008060006112588b8b866060015161047a565b925092509250611269826000611ad4565b6112b55760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f4f50455241544f525f4352454154455f464c4f57000060448201526064016105ec565b6000600b82900b60016001605f1b03146112d8576112d389836148b0565b6112da565b815b9050600081600b0b12156113005760405162461bcd60e51b81526004016105ec90614900565b61130c8c858584611b2f565b5050505061133a60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808a168252888116602083015287166040820152600b86900b606082015261136c8186868561278d565b9998505050505050505050565b600080600080600061138b88886117e8565b9150915081156113c8578060200151600b0b8160000151876113ad9190614a28565b6113b79190614a67565b945080604001519350806060015192505b505093509350939050565b60008060008060006105218787611a8d565b606060006114298785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061143c8888846060015161047a565b50915050600061144d826002611ad4565b90506109a360408051608081018252600080825260208201819052918101829052606081019190915290565b600080600080600061148f886106068989611a65565b805160208201516040830151606090930151919c909b50919950975095505050505050565b6000806114c184846117e8565b6020015195945050505050565b6000828260405160200161151b9291906060808252600c908201526b333637bba7b832b930ba37b960a11b60808201526001600160a01b0392831660208201529116604082015260a00190565b60405160208183030381529060405280519060200120905092915050565b6040805180820182526000808252602082018190529151636c2d9f2f60e01b8152306004820152602481018490526001604482015282906001600160a01b03861690636c2d9f2f90606401600060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115c99190810190614b5d565b90506115f1816000815181106115e1576115e1614bf7565b602002602001015160001c612a7f565b92509250505b9250929050565b6000806000836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb919061497a565b90506000816001600160a01b03166380f70cba84887fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161171f93929190614a04565b602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117609190614997565b63ffffffff602082901c81169891169650945050505050565b600060016001605f1b038211156117d25760405162461bcd60e51b815260206004820152601b60248201527f4346413a206465706f736974206e756d62657220746f6f20626967000000000060448201526064016105ec565b63ffffffff198216915060006104c98484614c23565b60006117f26143cc565b604051634b61cc3360e01b81523060048201526001600160a01b038481166024830152600060448301819052600160648401529190861690634b61cc33906084015b600060405180830381865afa158015611851573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118799190810190614b5d565b90506115f18160008151811061189157611891614bf7565b602002602001015160001c612abf565b6118a96143f7565b336001600160a01b0316836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611915919061497a565b6001600160a01b03161461195f5760405162461bcd60e51b81526020600482015260116024820152701d5b985d5d1a1bdc9a5e9959081a1bdcdd607a1b60448201526064016105ec565b604051632fd0a1cd60e21b8152339063bf4287349061198290859060040161460d565b602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614c47565b6119fd5760405162461bcd60e51b815260206004820152600b60248201526a0d2dcecc2d8d2c840c6e8f60ab1b60448201526064016105ec565b604051631fb6491d60e11b81523390633f6c923a90611a2090859060040161460d565b600060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614ce9565b604080516001600160a01b03808516602083015283169181019190915260009060600161151b565b6000611a976143cc565b604051636c2d9f2f60e01b815230600482015260248101849052600160448201526000906001600160a01b03861690636c2d9f2f90606401611834565b600080826002811115611ae957611ae9614df0565b03611afa5750600182811614611193565b6001826002811115611b0e57611b0e614df0565b03611b215750600182811c811614611193565b505060021c60019081161490565b6040805180820190915260ff83168152600b82900b60208201526001600160a01b03851663a1b2bf8b85611b6284612934565b6040518363ffffffff1660e01b8152600401611b7f9291906149eb565b600060405180830381600087803b158015611b9957600080fd5b505af1158015611bad573d6000803e3d6000fd5b505050505050505050565b60606000611bc68884612b1f565b91505085611c115760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614c47565b15611cdb57611cd488604001518960000151838a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925060019150612c929050565b9150611d26565b611d238860000151828988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506133af915050565b91505b8751611d329084613487565b509695505050505050565b6000611d677f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031603611dbd5760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c6500000060448201526064016105ec565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614997565b611e27610bc5565b14611e805760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b60648201526084016105ec565b6001600160a01b0381163003611ed85760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f700000000000000060448201526064016105ec565b611f00817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc611f29610bc5565b604080519182526001600160a01b03841660208301520160405180910390a150565b60006001600160ff1b03821115611fb55760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016105ec565b5090565b600080611fc68587614e06565b90506000611fd48587614e47565b9050611fe08486614e75565b611fea8284614e47565b13979650505050505050565b6040805160c0810182526000808252602082018190529181018290526060818101839052608082019290925260a0810182905260208701516001600160a01b03166120795760405162461bcd60e51b81526020600482015260136024820152724346413a2073656e646572206973207a65726f60681b60448201526064016105ec565b60408701516001600160a01b03166120cb5760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b6120dd87602001518860400151611a65565b8082526020808901516001600160a01b03908116918401919091526040808a01518216908401526060808601519091169083015260006080830181905260a0808601519084015288519091829161213391611a8d565b915091508161217f5760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b885160208a01516040808801519051633acd4df360e21b81526000936001600160a01b03169263eb3537cc926121cb926004016001600160a01b03929092168252602082015260400190565b606060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190614941565b5050905089602001516001600160a01b031686606001516001600160a01b031614158015612254575089604001516001600160a01b031686606001516001600160a01b031614155b801561225e575088155b156123aa5760208a0151604051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa1580156122ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d19190614c47565b158015612349575060408a8101519051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190614c47565b155b156123aa57600081126123aa5760405162461bcd60e51b815260206004820152602360248201527f4346413a2073656e646572206163636f756e74206973206e6f7420637269746960448201526218d85b60ea1b60648201526084016105ec565b60008112156123c8576123c88a600001518286858a6060015161359e565b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208b015160608801519196506001600160a01b039081169116036124be5760408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248b9190614c47565b156124af576124a88a604001518b600001518685898b6002612c92565b9450612780565b89516124a8908584888a6133af565b89604001516001600160a01b031686606001516001600160a01b0316036125f25760208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d9190614c47565b1561256a576124a88a602001518b600001518685898b6002612c92565b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156125b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d89190614c47565b156124af576124a860008b600001518685898b6002612c92565b60208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190614c47565b801561266c5750600081125b156126e65760208a0151604051635b92108f60e11b8152339163b724211e9161269c918991600b90600401614e8c565b6000604051808303816000875af11580156126bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126e39190810190614eba565b94505b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614c47565b15612771576124a88a604001518b600001518685898b6002612c92565b89516109d3908584888a6133af565b5050505095945050505050565b606060008061279c8785612b1f565b915091506000806127b1896000015185611a8d565b9150915081156128035760405162461bcd60e51b815260206004820152601760248201527f4346413a20666c6f7720616c726561647920657869737400000000000000000060448201526064016105ec565b6040898101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614c47565b156128ca576128c389604001518a6000015185848c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508f93509150612c929050565b9450612915565b612912896000015184838b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92506133af915050565b94505b88516129219087613487565b50505050949350505050565b60f8161590565b606060008260200151600b0b121561294e5761294e614eef565b60408051600180825281830190925290602080830190803683370190505090508160200151600b0b6080836000015160ff16901b1760001b8160008151811061299957612999614bf7565b602002602001018181525050919050565b60008082600b0b13612a0a5760405162461bcd60e51b815260206004820152602360248201527f4346413a206e6f7420666f72206e6f6e2d706f73697469766520666c6f77207260448201526261746560e81b60648201526084016105ec565b60016001605f1b03612a2084600b85900b614f05565b1115612a675760405162461bcd60e51b81526020600482015260166024820152754346413a20666c6f77207261746520746f6f2062696760501b60448201526064016105ec565b6000612a7383856137aa565b90506104e285826137ee565b6040805180820190915260008082526020820152811580159190612aba5760016001605f1b038316600b0b6020820152608083901c60ff1681525b915091565b6000612ac96143cc565b821580159250612aba5760e083901c8152608083901c6bffffffffffffffffffffffff16600b0b6020808301919091526bffffffffffffffff0000000084821c811660408401529084901b166060820152915091565b6040805160c08101825260008082526020820181905291810182905260608082018390526080820183905260a082015260408401516001600160a01b0316612ba15760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b612bb384602001518560400151611a65565b8082526020808601516001600160a01b0390811691840182905260408088015182169085018190526060808801519092168286015290870151600b0b608085015260a0808701519085015291935003612c425760405162461bcd60e51b81526020600482015260116024820152704346413a206e6f2073656c6620666c6f7760781b60448201526064016105ec565b60008160800151600b0b136115f75760405162461bcd60e51b81526020600482015260166024820152754346413a20696e76616c696420666c6f77207261746560501b60448201526064016105ec565b82612c9b614452565b6001600160a01b03891615612e84576000612d30898b8a600001518b602001518c60400151604051602001612ce69291906001600160a01b0392831681529116602082015260400190565b60408051601f1981840301815260e08301825260006080840181905260a0840181905260c08401526001600160a01b03958616835293909416602082015292830152606082015290565b90506000846002811115612d4657612d46614df0565b03612d5b5764010000000060c0820152612d90565b6001846002811115612d6f57612d6f614df0565b03612d845764040000000060c0820152612d90565b64100000000060c08201525b612d9a8187613804565b82526040850151610140860151612db491908b8b8b6139bb565b506080830152508451612dc8906001614f24565b60ff168160800151612dda9190614f05565b60808201526060870151612ded90611f4b565b60a08201526000846002811115612e0657612e06614df0565b03612e1b5764020000000060c0820152612e50565b6001846002811115612e2f57612e2f614df0565b03612e445764080000000060c0820152612e50565b64200000000060c08201525b612e5f81836000015185613d9f565b60408401919091528851909350612e77908a90611a8d565b602084015250612ea29050565b612e9a84604001518561014001518a8a8a6139bb565b602084015250505b6000816040015161010001511315612ee157612ed6612ed1612ecc83604001516101000151614008565b61405a565b611f4b565b604082015161010001525b6000612ef08760600151611f4b565b82604001516101000151612f049190614a28565b9050612f2a81612f1b846020015160400151611f4b565b612f259190614e06565b614008565b82602001516040018181525050612f4c81612f1b846020015160600151611f4b565b60208301805160600191909152885190516001600160a01b038b169163a1b2bf8b91612f779061408e565b6040518363ffffffff1660e01b8152600401612f949291906149eb565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50505050612fde89896020015160008460008a604001516140ff565b50612ff6898960400151600080858a604001516140ff565b506101408501516001600160a01b031615806130285750886001600160a01b03168561014001516001600160a01b0316145b156130a657602082015160409081015190516303c9790560e11b81523391630792f20a9161305c9187918690600401614f49565b6000604051808303816000875af115801561307b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130a39190810190614eba565b92505b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156130f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131149190614c47565b156133a257604088810151868201519151633acd4df360e21b81526001600160a01b0391821660048201526024810192909252600091908b169063eb3537cc90604401606060405180830381865afa158015613174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131989190614941565b509091505060008112156133a05760028560028111156131ba576131ba614df0565b03613345576040808a01519051635b92108f60e11b8152339163b724211e916131ea918891600c90600401614e8c565b6000604051808303816000875af1158015613209573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132319190810190614eba565b9350600061325961324183614f6e565b613254600061324f87614f6e565b61426b565b61427a565b90508a6001600160a01b031663cf97256d8b602001518361327990614f6e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b5050505060408a810151905163cf97256d60e01b81526001600160a01b03918216600482015260248101839052908c169063cf97256d90604401600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b50505050506133a0565b60405162461bcd60e51b815260206004820152602a60248201527f4346413a204150505f52554c455f4e4f5f435249544943414c5f524543454956604482015269115497d050d0d3d5539560b21b60648201526084016105ec565b505b5050979650505050505050565b606083810151156133c2576133c2614eef565b60006133cc6143cc565b6133e284604001518561014001518a8a8a6139bb565b6101408701519294509250506001600160a01b03808a169116036134785760408082015190516303c9790560e11b81523391630792f20a9161342a9189918790600401614f49565b6000604051808303816000875af1158015613449573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134719190810190614eba565b925061347c565b8492505b505095945050505050565b602081015160ff1660031415806134b55750816001600160a01b03168161014001516001600160a01b031614155b1561359a5760608101516040808301519051633acd4df360e21b81526001600160a01b039283166004820152602481019190915260009184169063eb3537cc90604401606060405180830381865afa158015613515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135399190614941565b5050905060008112156135985760405162461bcd60e51b815260206004820152602160248201527f4346413a206e6f7420656e6f75676820617661696c61626c652062616c616e636044820152606560f81b60648201526084016105ec565b505b5050565b60006135ae8685602001516117e8565b91505060006135c08460400151611f4b565b905060006135d18360400151611f4b565b905060606000806135e2848b614e06565b90506000806135f08d6115fe565b915091506136008c878484611fb9565b93505050600081126136eb576000846136198388614a67565b6136239190614e47565b9050600183613633576001613636565b60005b6040805160ff9384166020820152929091169082015260600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b878f6020015161368588614008565b61369189600019614a67565b6040518863ffffffff1660e01b81526004016136b39796959493929190614f8a565b600060405180830381600087803b1580156136cd57600080fd5b505af11580156136e1573d6000803e3d6000fd5b505050505061379d565b6040805160016020820152600291810191909152859060600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b60008f6020015161373b88614008565b6137478a600019614a67565b6040518863ffffffff1660e01b81526004016137699796959493929190614f8a565b600060405180830381600087803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b50505050505b5050505050505050505050565b600082600b0b6000036137bf57506000611193565b60016001605f1b038211156137d6576137d6614eef565b6137e08284614fd7565b600b0b90506108c08161405a565b60008183116137fd57816108c0565b5090919050565b6020820151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613858573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061387c9190615071565b9194509250905082801561388e575081155b156139b257600061389f868861428f565b90508660c0015182166000036139a45760006138be8860c0015161430d565b88516040808b015160608c0151825160008152602081019093526138ea939230929190604481016150ad565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918a015160c08b01519251633a020f0160e11b815291935033926374041e029261395992918691641000000000919091149088906004016150f2565b6000604051808303816000875af1158015613978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526139a09190810190614eba565b9550505b6139af8660006143a4565b50505b50505092915050565b6000806139c66143cc565b60008060006139d4896115fe565b5090506000336001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3b919061497a565b60405163407b865d60e11b81529091506001600160a01b038216906380f70cba90613a8e9033908e907feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc490600401614a04565b602060405180830381865afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614997565b9250613adf8960800151836137aa565b95505050613af08660600151611f4b565b613afd8760400151611f4b565b613b0686611f4b565b613b109190614a28565b613b1a9190614e06565b9450613b2d85612f1b8860400151611f4b565b91508082108015613b45575060008760800151600b0b135b15613b8757613b578660600151611f4b565b613b648760400151611f4b565b613b6d83611f4b565b613b779190614a28565b613b819190614e06565b94508091505b6001600160a01b03891615801590613bb15750876001600160a01b0316896001600160a01b031614155b15613bbb57600093505b604051806080016040528060008960800151600b0b13613bdc576000613bde565b8b5b81526020018860800151600b0b815260200183815260200187606001518152509250876001600160a01b031663a1b2bf8b8860000151613c1d8661408e565b6040518363ffffffff1660e01b8152600401613c3a9291906149eb565b600060405180830381600087803b158015613c5457600080fd5b505af1158015613c68573d6000803e3d6000fd5b505060408051808201909152600080825260208201529250613c88915050565b613cae88886020015189608001518960200151613ca591906148b0565b8860008f6140ff565b600b0b8152604087015160208701516080890151613cdd928b929091613cd491906148b0565b6000808f6140ff565b600b0b60208083018290526040808a0151918a015160808b0151855160a08d015193516001600160a01b0395861696938616958f16947f57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e94613d4394939290919061513b565b60405180910390a486606001516001600160a01b03167f71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f7483604051613d8a91815260200190565b60405180910390a25050955095509592505050565b613da76143f7565b6020840151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1f9190615071565b88965091945092509050828015613e34575081155b15613ffd57613e43848961428f565b93508760c001518116600003613feb576000613e628960c0015161430d565b89516040808c015160608d015182516000815260208101909352613e909392309291908e9060448101615173565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918b015160c08c0151925163079b42a160e21b81529193503392631e6d0a8492613eff9291869164200000000091909114908b906004016150f2565b6000604051808303816000875af1158015613f1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f469190810190614eba565b604051631fb6491d60e11b81529095503390633f6c923a90613f6c90889060040161460d565b600060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613fb19190810190614ce9565b9550613fe3600061324f613fc88c60800151611f4b565b613254613fd88b60e00151611f4b565b8b610100015161426b565b610100870152505b613ffa868661010001516143a4565b93505b505050935093915050565b600080821215611fb55760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f73697469766560448201526064016105ec565b60008063ffffffff831661406f576000614072565b60015b60ff16905060206140858285831c6151cc565b901b9392505050565b6040805160018082528183019092526060916020808301908036833701905050905060208260600151901c604060208460400151901c901b608084602001516bffffffffffffffffffffffff16901b60e08560000151901b17171760001b8160008151811061299957612999614bf7565b60008061410c88886117e8565b91505060008160200151600b0b61412c836000015186612ed19190614e75565b6141369190614a67565b905080156141a15760405163cf97256d60e01b81526001600160a01b038981166004830152602482018390528a169063cf97256d90604401600060405180830381600087803b15801561418857600080fd5b505af115801561419c573d6000803e3d6000fd5b505050505b8682602001516141b191906151e4565b600b0b602083015283825260408201516141d0908790612f1b90611f4b565b604083015260608201516141e9908690612f1b90611f4b565b60608301526001600160a01b03891663090c415e8960006142098661408e565b6040518463ffffffff1660e01b815260040161422793929190615233565b600060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b5050506020909201519998505050505050505050565b60008183136137fd57816108c0565b600081831361428957826108c0565b50919050565b6020810151608082015160a08301518351604051630768fabb60e41b8152606094339463768fabb0946142c6948a9460040161525a565b6000604051808303816000875af11580156142e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614eba565b6000640100000000820361432957506330d9c91560e01b919050565b64040000000082036143435750630221347d60e61b919050565b641000000000820361435d5750635f9e7d7760e01b919050565b6402000000008203614377575063d86ed3e560e01b919050565b6408000000008203614391575063230dbd2960e01b919050565b506353c11f9960e01b919050565b919050565b604051634c4d861f60e11b8152606090339063989b0c3e906142c6908690869060040161529f565b6040518060800160405280600081526020016000600b0b815260200160008152602001600081525090565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60405180606001604052806060815260200161446c6143cc565b81526020016144796143f7565b905290565b6001600160a01b03811681146107ed57600080fd5b6000806000606084860312156144a857600080fd5b83356144b38161447e565b925060208401356144c38161447e565b915060408401356144d38161447e565b809150509250925092565b600080604083850312156144f157600080fd5b82356144fc8161447e565b946020939093013593505050565b60008083601f84011261451c57600080fd5b50813567ffffffffffffffff81111561453457600080fd5b6020830191508360208285010111156115f757600080fd5b6000806000806060858703121561456257600080fd5b843561456d8161447e565b9350602085013561457d8161447e565b9250604085013567ffffffffffffffff81111561459957600080fd5b6145a58782880161450a565b95989497509550505050565b60005b838110156145cc5781810151838201526020016145b4565b838111156145db576000848401525b50505050565b600081518084526145f98160208601602086016145b1565b601f01601f19169290920160200192915050565b6020815260006108c060208301846145e1565b6000806040838503121561463357600080fd5b823561463e8161447e565b9150602083013561464e8161447e565b809150509250929050565b8035600b81900b811461439f57600080fd5b60008060008060008060a0878903121561468457600080fd5b863561468f8161447e565b9550602087013561469f8161447e565b945060408701356146af8161447e565b93506146bd60608801614659565b9250608087013567ffffffffffffffff8111156146d957600080fd5b6146e589828a0161450a565b979a9699509497509295939492505050565b60006020828403121561470957600080fd5b81356108c08161447e565b60008060006060848603121561472957600080fd5b83356147348161447e565b925060208401356147448161447e565b929592945050506040919091013590565b60008060008060006080868803121561476d57600080fd5b85356147788161447e565b945060208601356147888161447e565b935060408601356147988161447e565b9250606086013567ffffffffffffffff8111156147b457600080fd5b6147c08882890161450a565b969995985093965092949392505050565b6000806000806000608086880312156147e957600080fd5b85356147f48161447e565b945060208601356148048161447e565b935061479860408701614659565b60ff811681146107ed57600080fd5b60008060008060008060a0878903121561483a57600080fd5b86356148458161447e565b955060208701356148558161447e565b945060408701356146af81614812565b6000806040838503121561487857600080fd5b82356148838161447e565b915061489160208401614659565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b600081600b0b83600b0b600081128160016001605f1b0319018312811516156148db576148db61489a565b8160016001605f1b030183138116156148f6576148f661489a565b5090039392505050565b60208082526021908201527f4346413a20455f4558434545445f464c4f575f524154455f414c4c4f57414e436040820152604560f81b606082015260800190565b60008060006060848603121561495657600080fd5b8351925060208401519150604084015190509250925092565b805161439f8161447e565b60006020828403121561498c57600080fd5b81516108c08161447e565b6000602082840312156149a957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156149e0578151875295820195908201906001016149c4565b509495945050505050565b8281526040602082015260006104c960408301846149b0565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008083128015600160ff1b850184121615614a4657614a4661489a565b6001600160ff1b0384018313811615614a6157614a6161489a565b50500390565b60006001600160ff1b0381841382841380821686840486111615614a8d57614a8d61489a565b600160ff1b6000871282811687830589121615614aac57614aac61489a565b60008712925087820587128484161615614ac857614ac861489a565b87850587128184161615614ade57614ade61489a565b505050929093029392505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614b2657614b26614aec565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b5557614b55614aec565b604052919050565b60006020808385031215614b7057600080fd5b825167ffffffffffffffff80821115614b8857600080fd5b818501915085601f830112614b9c57600080fd5b815181811115614bae57614bae614aec565b8060051b9150614bbf848301614b2c565b8181529183018401918481019088841115614bd957600080fd5b938501935b83851015610ce857845182529385019390850190614bde565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614c3257614c32614c0d565b500490565b8051801515811461439f57600080fd5b600060208284031215614c5957600080fd5b6108c082614c37565b805161439f81614812565b80516001600160e01b03198116811461439f57600080fd5b600082601f830112614c9657600080fd5b815167ffffffffffffffff811115614cb057614cb0614aec565b614cc3601f8201601f1916602001614b2c565b818152846020838601011115614cd857600080fd5b6104c98260208301602087016145b1565b600060208284031215614cfb57600080fd5b815167ffffffffffffffff80821115614d1357600080fd5b908301906101608286031215614d2857600080fd5b614d30614b02565b614d3983614c62565b8152614d4760208401614c62565b602082015260408301516040820152614d626060840161496f565b6060820152614d7360808401614c6d565b608082015260a083015182811115614d8a57600080fd5b614d9687828601614c85565b60a08301525060c083015160c082015260e083015160e0820152610100915081830151828201526101209150614dcd82840161496f565b828201526101409150614de182840161496f565b91810191909152949350505050565b634e487b7160e01b600052602160045260246000fd5b600080821280156001600160ff1b0384900385131615614e2857614e2861489a565b600160ff1b8390038412811615614e4157614e4161489a565b50500190565b600082614e5657614e56614c0d565b600160ff1b821460001984141615614e7057614e7061489a565b500590565b600082821015614e8757614e8761489a565b500390565b606081526000614e9f60608301866145e1565b6001600160a01b039490941660208301525060400152919050565b600060208284031215614ecc57600080fd5b815167ffffffffffffffff811115614ee357600080fd5b6104c984828501614c85565b634e487b7160e01b600052600160045260246000fd5b6000816000190483118215151615614f1f57614f1f61489a565b500290565b600060ff821660ff84168060ff03821115614f4157614f4161489a565b019392505050565b606081526000614f5c60608301866145e1565b60208301949094525060400152919050565b6000600160ff1b8201614f8357614f8361489a565b5060000390565b87815260e060208201526000614fa360e08301896145e1565b6001600160a01b03978816604084015295151560608301525092909416608083015260a082015260c0019190915292915050565b600081600b0b83600b0b60016001605f1b036000821360008413838304851182821616156150075761500761489a565b6b7fffffffffffffffffffffff19600085128281168783058712161561502f5761502f61489a565b6000871292508582058712848416161561504b5761504b61489a565b858505871281841616156150615761506161489a565b5050509290910295945050505050565b60008060006060848603121561508657600080fd5b61508f84614c37565b925061509d60208501614c37565b9150604084015190509250925092565b6001600160a01b038681168252851660208201526040810184905260a0606082018190526000906150e0908301856145e1565b8281036080840152610ce881856145e1565b6001600160a01b0385168152608060208201819052600090615116908301866145e1565b8415156040840152828103606084015261513081856145e1565b979650505050505050565b84600b0b815283600b0b602082015282600b0b604082015260806060820152600061516960808301846145e1565b9695505050505050565b6001600160a01b038781168252861660208201526040810185905260c0606082018190526000906151a6908301866145e1565b82810360808401526151b881866145e1565b905082810360a084015261136c81856145e1565b600082198211156151df576151df61489a565b500190565b600081600b0b83600b0b600082128260016001605f1b030382138115161561520e5761520e61489a565b8260016001605f1b031903821281161561522a5761522a61489a565b50019392505050565b60018060a01b03841681528260208201526060604082015260006104e260608301846149b0565b60a08152600061526d60a08301886145e1565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b6040815260006152b260408301856145e1565b9050826020830152939250505056fea26469706673582212207948a69b198b07616fc08e079b66297a42497f1cb2066e1921d3c65c084c001164736f6c634300080d0033",
903
- "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a85760003560e01c806350d75d25116100f957806394229ecb11610097578063aabd266811610071578063aabd26681461042e578063b4b333c614610441578063e6a1e88814610454578063e8e7e2d11461046757600080fd5b806394229ecb146103ed5780639b2e48bc146104005780639cb28b72146102aa57600080fd5b806362fc305e116100d357806362fc305e1461038e5780637730599e146103a1578063811b3d40146103c75780638d997f6e146103da57600080fd5b806350d75d251461035357806352d1902d1461037357806354b770e31461037b57600080fd5b806326b0f536116101665780634b839e0b116101405780634b839e0b146102e05780634c8b181f146103035780634fe9c2911461031657806350209a621461034057600080fd5b806326b0f536146102aa578063354b9590146102b857806346951954146102cb57600080fd5b8062422bbe146101ad57806304aafa49146101e55780630602f7db146101ff578063062e56ec1461022557806309d256ef146102455780630f1ac49514610274575b600080fd5b6101c06101bb366004614493565b61047a565b6040805193845260ff9092166020840152600b0b908201526060015b60405180910390f35b6101f164010000000081565b6040519081526020016101dc565b61021261020d3660046144de565b6104b0565b604051600b9190910b81526020016101dc565b61023861023336600461454c565b6104d1565b6040516101dc919061460d565b6102586102533660046144de565b6104eb565b6040805160ff9093168352600b9190910b6020830152016101dc565b610287610282366004614620565b61050f565b60408051948552600b9390930b60208501529183015260608201526080016101dc565b6101f160016001605f1b0381565b6102386102c636600461466b565b610545565b6102de6102d93660046146f7565b61076c565b005b6102f36102ee366004614714565b6107f0565b60405190151581526020016101dc565b610238610311366004614755565b6108c7565b610329610324366004614620565b6109e1565b6040805192151583526020830191909152016101dc565b61023861034e3660046147d1565b610ac3565b61035b610b96565b6040516001600160a01b0390911681526020016101dc565b6101f1610bc5565b61023861038936600461454c565b610c29565b61023861039c3660046147d1565b610c41565b7fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd36101f1565b6102386103d5366004614821565b610cf4565b6101f16103e8366004614865565b610f7e565b6102386103fb36600461466b565b611199565b61041361040e366004614714565b611379565b604080519384526020840192909252908201526060016101dc565b61028761043c3660046144de565b6113d3565b61023861044f366004614755565b6113e5565b610287610462366004614493565b611479565b610212610475366004614620565b6114b4565b600080600061048985856114ce565b925060006104978785611539565b8051602090910151959990985094965093945050505050565b6000806104bc846115fe565b5090506104c98184611779565b949350505050565b60606104e285856000808787610cf4565b95945050505050565b60008060006104fa8585611539565b80516020909101519097909650945050505050565b600080600080600061052187876117e8565b805160208201516040830151606090930151919b909a509198509650945050505050565b606060006105898885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036105f55760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f55504441544500000000000000000060448201526064015b60405180910390fd5b60008061060b8a6106068b8b611a65565b611a8d565b9150915060008060006106238d8d886060015161047a565b925092509250610634826001611ad4565b6106805760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f5550444154455f464c4f570000000000000060448201526064016105ec565b6000600b82900b60016001605f1b0314806106a557508a600b0b8560200151600b0b12155b6106c75760208501516106b8908c6148b0565b6106c290836148b0565b6106c9565b815b9050600081600b0b12156106ef5760405162461bcd60e51b81526004016105ec90614900565b6106fb8e858584611b2f565b5050505061072960408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808c1682528a8116602083015289166040820152600b88900b606082015261075d8183858a8a89611bb8565b9b9a5050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107e45760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920686f73742063616e2075706461746520636f64650000000000000060448201526064016105ec565b6107ed81611d3d565b50565b604051633acd4df360e21b81526001600160a01b03838116600483015260248201839052600091829186169063eb3537cc90604401606060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190614941565b505090506000811261087c5760019150506108c0565b600080610888876115fe565b91509150600061089888886117e8565b91505060006108aa8260400151611f4b565b90506108b885828686611fb9565b955050505050505b9392505050565b6060600061090b8785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061091e8888846060015161047a565b50915050600061092f826002611ad4565b90508061097e5760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f44454c4554455f464c4f570000000000000060448201526064016105ec565b6040805160808101825260008082526020820181905291810182905260608101919091525b6001600160a01b03808b168252898116602083015288166040820152600060608201526109d38183898988611ff6565b9a9950505050505050505050565b6000806000846001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a48919061497a565b9050806001600160a01b031663bbe4fd506040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190614997565b9150610ab98585846107f0565b9250509250929050565b60606000610b078785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610b3360408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808916825260608084015182166020840181905291891660408401819052600b89900b91840191909152600091610b7191611a65565b9050600080610b84846000015184611a8d565b9150915061075d8482848b8b8a611bb8565b6000610bc07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000306001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190614997565b60606104e28585600760016001605f1b038787610cf4565b60606000610c858785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610cb160408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b038089168252606080840151821660208401529088166040830152600b87900b90820152610ce88186868561278d565b98975050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3b925087915061292d9050565b610d875760405162461bcd60e51b815260206004820152601860248201527f4346413a20556e636c65616e207065726d697373696f6e73000000000000000060448201526064016105ec565b6000610dc98885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b031603610e305760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f53454e4445525f464c4f575f4f50455241544f52000060448201526064016105ec565b600085600b0b1215610e845760405162461bcd60e51b815260206004820152601c60248201527f4346413a20455f4e4f5f4e454741544956455f414c4c4f57414e43450000000060448201526064016105ec565b6040805180820190915260ff87168152600b86900b60208201526060820151600090610eb0908a6114ce565b9050896001600160a01b031663a1b2bf8b82610ecb85612934565b6040518363ffffffff1660e01b8152600401610ee89291906149eb565b600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505060608401516040805160ff8c168152600b8b900b60208201526001600160a01b03808e169450928316928e16917fc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8910160405180910390a45050509695505050505050565b600080836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe3919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611049919061497a565b90506000816001600160a01b03166380f70cba84887feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc46040518463ffffffff1660e01b815260040161109d93929190614a04565b602060405180830381865afa1580156110ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110de9190614997565b90506000826001600160a01b03166380f70cba85897fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161113293929190614a04565b602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190614997565b9050602081901c63ffffffff1661118b8382896129aa565b955050505050505b92915050565b606060006111dd8885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036112445760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f43524541544500000000000000000060448201526064016105ec565b60008060006112588b8b866060015161047a565b925092509250611269826000611ad4565b6112b55760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f4f50455241544f525f4352454154455f464c4f57000060448201526064016105ec565b6000600b82900b60016001605f1b03146112d8576112d389836148b0565b6112da565b815b9050600081600b0b12156113005760405162461bcd60e51b81526004016105ec90614900565b61130c8c858584611b2f565b5050505061133a60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808a168252888116602083015287166040820152600b86900b606082015261136c8186868561278d565b9998505050505050505050565b600080600080600061138b88886117e8565b9150915081156113c8578060200151600b0b8160000151876113ad9190614a28565b6113b79190614a67565b945080604001519350806060015192505b505093509350939050565b60008060008060006105218787611a8d565b606060006114298785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061143c8888846060015161047a565b50915050600061144d826002611ad4565b90506109a360408051608081018252600080825260208201819052918101829052606081019190915290565b600080600080600061148f886106068989611a65565b805160208201516040830151606090930151919c909b50919950975095505050505050565b6000806114c184846117e8565b6020015195945050505050565b6000828260405160200161151b9291906060808252600c908201526b333637bba7b832b930ba37b960a11b60808201526001600160a01b0392831660208201529116604082015260a00190565b60405160208183030381529060405280519060200120905092915050565b6040805180820182526000808252602082018190529151636c2d9f2f60e01b8152306004820152602481018490526001604482015282906001600160a01b03861690636c2d9f2f90606401600060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115c99190810190614b5d565b90506115f1816000815181106115e1576115e1614bf7565b602002602001015160001c612a7f565b92509250505b9250929050565b6000806000836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb919061497a565b90506000816001600160a01b03166380f70cba84887fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161171f93929190614a04565b602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117609190614997565b63ffffffff602082901c81169891169650945050505050565b600060016001605f1b038211156117d25760405162461bcd60e51b815260206004820152601b60248201527f4346413a206465706f736974206e756d62657220746f6f20626967000000000060448201526064016105ec565b63ffffffff198216915060006104c98484614c23565b60006117f26143cc565b604051634b61cc3360e01b81523060048201526001600160a01b038481166024830152600060448301819052600160648401529190861690634b61cc33906084015b600060405180830381865afa158015611851573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118799190810190614b5d565b90506115f18160008151811061189157611891614bf7565b602002602001015160001c612abf565b6118a96143f7565b336001600160a01b0316836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611915919061497a565b6001600160a01b03161461195f5760405162461bcd60e51b81526020600482015260116024820152701d5b985d5d1a1bdc9a5e9959081a1bdcdd607a1b60448201526064016105ec565b604051632fd0a1cd60e21b8152339063bf4287349061198290859060040161460d565b602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614c47565b6119fd5760405162461bcd60e51b815260206004820152600b60248201526a0d2dcecc2d8d2c840c6e8f60ab1b60448201526064016105ec565b604051631fb6491d60e11b81523390633f6c923a90611a2090859060040161460d565b600060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614ce9565b604080516001600160a01b03808516602083015283169181019190915260009060600161151b565b6000611a976143cc565b604051636c2d9f2f60e01b815230600482015260248101849052600160448201526000906001600160a01b03861690636c2d9f2f90606401611834565b600080826002811115611ae957611ae9614df0565b03611afa5750600182811614611193565b6001826002811115611b0e57611b0e614df0565b03611b215750600182811c811614611193565b505060021c60019081161490565b6040805180820190915260ff83168152600b82900b60208201526001600160a01b03851663a1b2bf8b85611b6284612934565b6040518363ffffffff1660e01b8152600401611b7f9291906149eb565b600060405180830381600087803b158015611b9957600080fd5b505af1158015611bad573d6000803e3d6000fd5b505050505050505050565b60606000611bc68884612b1f565b91505085611c115760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614c47565b15611cdb57611cd488604001518960000151838a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925060019150612c929050565b9150611d26565b611d238860000151828988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506133af915050565b91505b8751611d329084613487565b509695505050505050565b6000611d677f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031603611dbd5760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c6500000060448201526064016105ec565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614997565b611e27610bc5565b14611e805760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b60648201526084016105ec565b6001600160a01b0381163003611ed85760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f700000000000000060448201526064016105ec565b611f00817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc611f29610bc5565b604080519182526001600160a01b03841660208301520160405180910390a150565b60006001600160ff1b03821115611fb55760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016105ec565b5090565b600080611fc68587614e06565b90506000611fd48587614e47565b9050611fe08486614e75565b611fea8284614e47565b13979650505050505050565b6040805160c0810182526000808252602082018190529181018290526060818101839052608082019290925260a0810182905260208701516001600160a01b03166120795760405162461bcd60e51b81526020600482015260136024820152724346413a2073656e646572206973207a65726f60681b60448201526064016105ec565b60408701516001600160a01b03166120cb5760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b6120dd87602001518860400151611a65565b8082526020808901516001600160a01b03908116918401919091526040808a01518216908401526060808601519091169083015260006080830181905260a0808601519084015288519091829161213391611a8d565b915091508161217f5760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b885160208a01516040808801519051633acd4df360e21b81526000936001600160a01b03169263eb3537cc926121cb926004016001600160a01b03929092168252602082015260400190565b606060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190614941565b5050905089602001516001600160a01b031686606001516001600160a01b031614158015612254575089604001516001600160a01b031686606001516001600160a01b031614155b801561225e575088155b156123aa5760208a0151604051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa1580156122ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d19190614c47565b158015612349575060408a8101519051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190614c47565b155b156123aa57600081126123aa5760405162461bcd60e51b815260206004820152602360248201527f4346413a2073656e646572206163636f756e74206973206e6f7420637269746960448201526218d85b60ea1b60648201526084016105ec565b60008112156123c8576123c88a600001518286858a6060015161359e565b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208b015160608801519196506001600160a01b039081169116036124be5760408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248b9190614c47565b156124af576124a88a604001518b600001518685898b6002612c92565b9450612780565b89516124a8908584888a6133af565b89604001516001600160a01b031686606001516001600160a01b0316036125f25760208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d9190614c47565b1561256a576124a88a602001518b600001518685898b6002612c92565b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156125b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d89190614c47565b156124af576124a860008b600001518685898b6002612c92565b60208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190614c47565b801561266c5750600081125b156126e65760208a0151604051635b92108f60e11b8152339163b724211e9161269c918991600b90600401614e8c565b6000604051808303816000875af11580156126bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126e39190810190614eba565b94505b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614c47565b15612771576124a88a604001518b600001518685898b6002612c92565b89516109d3908584888a6133af565b5050505095945050505050565b606060008061279c8785612b1f565b915091506000806127b1896000015185611a8d565b9150915081156128035760405162461bcd60e51b815260206004820152601760248201527f4346413a20666c6f7720616c726561647920657869737400000000000000000060448201526064016105ec565b6040898101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614c47565b156128ca576128c389604001518a6000015185848c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508f93509150612c929050565b9450612915565b612912896000015184838b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92506133af915050565b94505b88516129219087613487565b50505050949350505050565b60f8161590565b606060008260200151600b0b121561294e5761294e614eef565b60408051600180825281830190925290602080830190803683370190505090508160200151600b0b6080836000015160ff16901b1760001b8160008151811061299957612999614bf7565b602002602001018181525050919050565b60008082600b0b13612a0a5760405162461bcd60e51b815260206004820152602360248201527f4346413a206e6f7420666f72206e6f6e2d706f73697469766520666c6f77207260448201526261746560e81b60648201526084016105ec565b60016001605f1b03612a2084600b85900b614f05565b1115612a675760405162461bcd60e51b81526020600482015260166024820152754346413a20666c6f77207261746520746f6f2062696760501b60448201526064016105ec565b6000612a7383856137aa565b90506104e285826137ee565b6040805180820190915260008082526020820152811580159190612aba5760016001605f1b038316600b0b6020820152608083901c60ff1681525b915091565b6000612ac96143cc565b821580159250612aba5760e083901c8152608083901c6bffffffffffffffffffffffff16600b0b6020808301919091526bffffffffffffffff0000000084821c811660408401529084901b166060820152915091565b6040805160c08101825260008082526020820181905291810182905260608082018390526080820183905260a082015260408401516001600160a01b0316612ba15760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b612bb384602001518560400151611a65565b8082526020808601516001600160a01b0390811691840182905260408088015182169085018190526060808801519092168286015290870151600b0b608085015260a0808701519085015291935003612c425760405162461bcd60e51b81526020600482015260116024820152704346413a206e6f2073656c6620666c6f7760781b60448201526064016105ec565b60008160800151600b0b136115f75760405162461bcd60e51b81526020600482015260166024820152754346413a20696e76616c696420666c6f77207261746560501b60448201526064016105ec565b82612c9b614452565b6001600160a01b03891615612e84576000612d30898b8a600001518b602001518c60400151604051602001612ce69291906001600160a01b0392831681529116602082015260400190565b60408051601f1981840301815260e08301825260006080840181905260a0840181905260c08401526001600160a01b03958616835293909416602082015292830152606082015290565b90506000846002811115612d4657612d46614df0565b03612d5b5764010000000060c0820152612d90565b6001846002811115612d6f57612d6f614df0565b03612d845764040000000060c0820152612d90565b64100000000060c08201525b612d9a8187613804565b82526040850151610140860151612db491908b8b8b6139bb565b506080830152508451612dc8906001614f24565b60ff168160800151612dda9190614f05565b60808201526060870151612ded90611f4b565b60a08201526000846002811115612e0657612e06614df0565b03612e1b5764020000000060c0820152612e50565b6001846002811115612e2f57612e2f614df0565b03612e445764080000000060c0820152612e50565b64200000000060c08201525b612e5f81836000015185613d9f565b60408401919091528851909350612e77908a90611a8d565b602084015250612ea29050565b612e9a84604001518561014001518a8a8a6139bb565b602084015250505b6000816040015161010001511315612ee157612ed6612ed1612ecc83604001516101000151614008565b61405a565b611f4b565b604082015161010001525b6000612ef08760600151611f4b565b82604001516101000151612f049190614a28565b9050612f2a81612f1b846020015160400151611f4b565b612f259190614e06565b614008565b82602001516040018181525050612f4c81612f1b846020015160600151611f4b565b60208301805160600191909152885190516001600160a01b038b169163a1b2bf8b91612f779061408e565b6040518363ffffffff1660e01b8152600401612f949291906149eb565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50505050612fde89896020015160008460008a604001516140ff565b50612ff6898960400151600080858a604001516140ff565b506101408501516001600160a01b031615806130285750886001600160a01b03168561014001516001600160a01b0316145b156130a657602082015160409081015190516303c9790560e11b81523391630792f20a9161305c9187918690600401614f49565b6000604051808303816000875af115801561307b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130a39190810190614eba565b92505b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156130f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131149190614c47565b156133a257604088810151868201519151633acd4df360e21b81526001600160a01b0391821660048201526024810192909252600091908b169063eb3537cc90604401606060405180830381865afa158015613174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131989190614941565b509091505060008112156133a05760028560028111156131ba576131ba614df0565b03613345576040808a01519051635b92108f60e11b8152339163b724211e916131ea918891600c90600401614e8c565b6000604051808303816000875af1158015613209573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132319190810190614eba565b9350600061325961324183614f6e565b613254600061324f87614f6e565b61426b565b61427a565b90508a6001600160a01b031663cf97256d8b602001518361327990614f6e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b5050505060408a810151905163cf97256d60e01b81526001600160a01b03918216600482015260248101839052908c169063cf97256d90604401600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b50505050506133a0565b60405162461bcd60e51b815260206004820152602a60248201527f4346413a204150505f52554c455f4e4f5f435249544943414c5f524543454956604482015269115497d050d0d3d5539560b21b60648201526084016105ec565b505b5050979650505050505050565b606083810151156133c2576133c2614eef565b60006133cc6143cc565b6133e284604001518561014001518a8a8a6139bb565b6101408701519294509250506001600160a01b03808a169116036134785760408082015190516303c9790560e11b81523391630792f20a9161342a9189918790600401614f49565b6000604051808303816000875af1158015613449573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134719190810190614eba565b925061347c565b8492505b505095945050505050565b602081015160ff1660031415806134b55750816001600160a01b03168161014001516001600160a01b031614155b1561359a5760608101516040808301519051633acd4df360e21b81526001600160a01b039283166004820152602481019190915260009184169063eb3537cc90604401606060405180830381865afa158015613515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135399190614941565b5050905060008112156135985760405162461bcd60e51b815260206004820152602160248201527f4346413a206e6f7420656e6f75676820617661696c61626c652062616c616e636044820152606560f81b60648201526084016105ec565b505b5050565b60006135ae8685602001516117e8565b91505060006135c08460400151611f4b565b905060006135d18360400151611f4b565b905060606000806135e2848b614e06565b90506000806135f08d6115fe565b915091506136008c878484611fb9565b93505050600081126136eb576000846136198388614a67565b6136239190614e47565b9050600183613633576001613636565b60005b6040805160ff9384166020820152929091169082015260600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b878f6020015161368588614008565b61369189600019614a67565b6040518863ffffffff1660e01b81526004016136b39796959493929190614f8a565b600060405180830381600087803b1580156136cd57600080fd5b505af11580156136e1573d6000803e3d6000fd5b505050505061379d565b6040805160016020820152600291810191909152859060600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b60008f6020015161373b88614008565b6137478a600019614a67565b6040518863ffffffff1660e01b81526004016137699796959493929190614f8a565b600060405180830381600087803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b50505050505b5050505050505050505050565b600082600b0b6000036137bf57506000611193565b60016001605f1b038211156137d6576137d6614eef565b6137e08284614fd7565b600b0b90506108c08161405a565b60008183116137fd57816108c0565b5090919050565b6020820151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613858573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061387c9190615071565b9194509250905082801561388e575081155b156139b257600061389f868861428f565b90508660c0015182166000036139a45760006138be8860c0015161430d565b88516040808b015160608c0151825160008152602081019093526138ea939230929190604481016150ad565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918a015160c08b01519251633a020f0160e11b815291935033926374041e029261395992918691641000000000919091149088906004016150f2565b6000604051808303816000875af1158015613978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526139a09190810190614eba565b9550505b6139af8660006143a4565b50505b50505092915050565b6000806139c66143cc565b60008060006139d4896115fe565b5090506000336001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3b919061497a565b60405163407b865d60e11b81529091506001600160a01b038216906380f70cba90613a8e9033908e907feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc490600401614a04565b602060405180830381865afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614997565b9250613adf8960800151836137aa565b95505050613af08660600151611f4b565b613afd8760400151611f4b565b613b0686611f4b565b613b109190614a28565b613b1a9190614e06565b9450613b2d85612f1b8860400151611f4b565b91508082108015613b45575060008760800151600b0b135b15613b8757613b578660600151611f4b565b613b648760400151611f4b565b613b6d83611f4b565b613b779190614a28565b613b819190614e06565b94508091505b6001600160a01b03891615801590613bb15750876001600160a01b0316896001600160a01b031614155b15613bbb57600093505b604051806080016040528060008960800151600b0b13613bdc576000613bde565b8b5b81526020018860800151600b0b815260200183815260200187606001518152509250876001600160a01b031663a1b2bf8b8860000151613c1d8661408e565b6040518363ffffffff1660e01b8152600401613c3a9291906149eb565b600060405180830381600087803b158015613c5457600080fd5b505af1158015613c68573d6000803e3d6000fd5b505060408051808201909152600080825260208201529250613c88915050565b613cae88886020015189608001518960200151613ca591906148b0565b8860008f6140ff565b600b0b8152604087015160208701516080890151613cdd928b929091613cd491906148b0565b6000808f6140ff565b600b0b60208083018290526040808a0151918a015160808b0151855160a08d015193516001600160a01b0395861696938616958f16947f57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e94613d4394939290919061513b565b60405180910390a486606001516001600160a01b03167f71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f7483604051613d8a91815260200190565b60405180910390a25050955095509592505050565b613da76143f7565b6020840151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1f9190615071565b88965091945092509050828015613e34575081155b15613ffd57613e43848961428f565b93508760c001518116600003613feb576000613e628960c0015161430d565b89516040808c015160608d015182516000815260208101909352613e909392309291908e9060448101615173565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918b015160c08c0151925163079b42a160e21b81529193503392631e6d0a8492613eff9291869164200000000091909114908b906004016150f2565b6000604051808303816000875af1158015613f1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f469190810190614eba565b604051631fb6491d60e11b81529095503390633f6c923a90613f6c90889060040161460d565b600060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613fb19190810190614ce9565b9550613fe3600061324f613fc88c60800151611f4b565b613254613fd88b60e00151611f4b565b8b610100015161426b565b610100870152505b613ffa868661010001516143a4565b93505b505050935093915050565b600080821215611fb55760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f73697469766560448201526064016105ec565b60008063ffffffff831661406f576000614072565b60015b60ff16905060206140858285831c6151cc565b901b9392505050565b6040805160018082528183019092526060916020808301908036833701905050905060208260600151901c604060208460400151901c901b608084602001516bffffffffffffffffffffffff16901b60e08560000151901b17171760001b8160008151811061299957612999614bf7565b60008061410c88886117e8565b91505060008160200151600b0b61412c836000015186612ed19190614e75565b6141369190614a67565b905080156141a15760405163cf97256d60e01b81526001600160a01b038981166004830152602482018390528a169063cf97256d90604401600060405180830381600087803b15801561418857600080fd5b505af115801561419c573d6000803e3d6000fd5b505050505b8682602001516141b191906151e4565b600b0b602083015283825260408201516141d0908790612f1b90611f4b565b604083015260608201516141e9908690612f1b90611f4b565b60608301526001600160a01b03891663090c415e8960006142098661408e565b6040518463ffffffff1660e01b815260040161422793929190615233565b600060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b5050506020909201519998505050505050505050565b60008183136137fd57816108c0565b600081831361428957826108c0565b50919050565b6020810151608082015160a08301518351604051630768fabb60e41b8152606094339463768fabb0946142c6948a9460040161525a565b6000604051808303816000875af11580156142e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614eba565b6000640100000000820361432957506330d9c91560e01b919050565b64040000000082036143435750630221347d60e61b919050565b641000000000820361435d5750635f9e7d7760e01b919050565b6402000000008203614377575063d86ed3e560e01b919050565b6408000000008203614391575063230dbd2960e01b919050565b506353c11f9960e01b919050565b919050565b604051634c4d861f60e11b8152606090339063989b0c3e906142c6908690869060040161529f565b6040518060800160405280600081526020016000600b0b815260200160008152602001600081525090565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60405180606001604052806060815260200161446c6143cc565b81526020016144796143f7565b905290565b6001600160a01b03811681146107ed57600080fd5b6000806000606084860312156144a857600080fd5b83356144b38161447e565b925060208401356144c38161447e565b915060408401356144d38161447e565b809150509250925092565b600080604083850312156144f157600080fd5b82356144fc8161447e565b946020939093013593505050565b60008083601f84011261451c57600080fd5b50813567ffffffffffffffff81111561453457600080fd5b6020830191508360208285010111156115f757600080fd5b6000806000806060858703121561456257600080fd5b843561456d8161447e565b9350602085013561457d8161447e565b9250604085013567ffffffffffffffff81111561459957600080fd5b6145a58782880161450a565b95989497509550505050565b60005b838110156145cc5781810151838201526020016145b4565b838111156145db576000848401525b50505050565b600081518084526145f98160208601602086016145b1565b601f01601f19169290920160200192915050565b6020815260006108c060208301846145e1565b6000806040838503121561463357600080fd5b823561463e8161447e565b9150602083013561464e8161447e565b809150509250929050565b8035600b81900b811461439f57600080fd5b60008060008060008060a0878903121561468457600080fd5b863561468f8161447e565b9550602087013561469f8161447e565b945060408701356146af8161447e565b93506146bd60608801614659565b9250608087013567ffffffffffffffff8111156146d957600080fd5b6146e589828a0161450a565b979a9699509497509295939492505050565b60006020828403121561470957600080fd5b81356108c08161447e565b60008060006060848603121561472957600080fd5b83356147348161447e565b925060208401356147448161447e565b929592945050506040919091013590565b60008060008060006080868803121561476d57600080fd5b85356147788161447e565b945060208601356147888161447e565b935060408601356147988161447e565b9250606086013567ffffffffffffffff8111156147b457600080fd5b6147c08882890161450a565b969995985093965092949392505050565b6000806000806000608086880312156147e957600080fd5b85356147f48161447e565b945060208601356148048161447e565b935061479860408701614659565b60ff811681146107ed57600080fd5b60008060008060008060a0878903121561483a57600080fd5b86356148458161447e565b955060208701356148558161447e565b945060408701356146af81614812565b6000806040838503121561487857600080fd5b82356148838161447e565b915061489160208401614659565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b600081600b0b83600b0b600081128160016001605f1b0319018312811516156148db576148db61489a565b8160016001605f1b030183138116156148f6576148f661489a565b5090039392505050565b60208082526021908201527f4346413a20455f4558434545445f464c4f575f524154455f414c4c4f57414e436040820152604560f81b606082015260800190565b60008060006060848603121561495657600080fd5b8351925060208401519150604084015190509250925092565b805161439f8161447e565b60006020828403121561498c57600080fd5b81516108c08161447e565b6000602082840312156149a957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156149e0578151875295820195908201906001016149c4565b509495945050505050565b8281526040602082015260006104c960408301846149b0565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008083128015600160ff1b850184121615614a4657614a4661489a565b6001600160ff1b0384018313811615614a6157614a6161489a565b50500390565b60006001600160ff1b0381841382841380821686840486111615614a8d57614a8d61489a565b600160ff1b6000871282811687830589121615614aac57614aac61489a565b60008712925087820587128484161615614ac857614ac861489a565b87850587128184161615614ade57614ade61489a565b505050929093029392505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614b2657614b26614aec565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b5557614b55614aec565b604052919050565b60006020808385031215614b7057600080fd5b825167ffffffffffffffff80821115614b8857600080fd5b818501915085601f830112614b9c57600080fd5b815181811115614bae57614bae614aec565b8060051b9150614bbf848301614b2c565b8181529183018401918481019088841115614bd957600080fd5b938501935b83851015610ce857845182529385019390850190614bde565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614c3257614c32614c0d565b500490565b8051801515811461439f57600080fd5b600060208284031215614c5957600080fd5b6108c082614c37565b805161439f81614812565b80516001600160e01b03198116811461439f57600080fd5b600082601f830112614c9657600080fd5b815167ffffffffffffffff811115614cb057614cb0614aec565b614cc3601f8201601f1916602001614b2c565b818152846020838601011115614cd857600080fd5b6104c98260208301602087016145b1565b600060208284031215614cfb57600080fd5b815167ffffffffffffffff80821115614d1357600080fd5b908301906101608286031215614d2857600080fd5b614d30614b02565b614d3983614c62565b8152614d4760208401614c62565b602082015260408301516040820152614d626060840161496f565b6060820152614d7360808401614c6d565b608082015260a083015182811115614d8a57600080fd5b614d9687828601614c85565b60a08301525060c083015160c082015260e083015160e0820152610100915081830151828201526101209150614dcd82840161496f565b828201526101409150614de182840161496f565b91810191909152949350505050565b634e487b7160e01b600052602160045260246000fd5b600080821280156001600160ff1b0384900385131615614e2857614e2861489a565b600160ff1b8390038412811615614e4157614e4161489a565b50500190565b600082614e5657614e56614c0d565b600160ff1b821460001984141615614e7057614e7061489a565b500590565b600082821015614e8757614e8761489a565b500390565b606081526000614e9f60608301866145e1565b6001600160a01b039490941660208301525060400152919050565b600060208284031215614ecc57600080fd5b815167ffffffffffffffff811115614ee357600080fd5b6104c984828501614c85565b634e487b7160e01b600052600160045260246000fd5b6000816000190483118215151615614f1f57614f1f61489a565b500290565b600060ff821660ff84168060ff03821115614f4157614f4161489a565b019392505050565b606081526000614f5c60608301866145e1565b60208301949094525060400152919050565b6000600160ff1b8201614f8357614f8361489a565b5060000390565b87815260e060208201526000614fa360e08301896145e1565b6001600160a01b03978816604084015295151560608301525092909416608083015260a082015260c0019190915292915050565b600081600b0b83600b0b60016001605f1b036000821360008413838304851182821616156150075761500761489a565b6b7fffffffffffffffffffffff19600085128281168783058712161561502f5761502f61489a565b6000871292508582058712848416161561504b5761504b61489a565b858505871281841616156150615761506161489a565b5050509290910295945050505050565b60008060006060848603121561508657600080fd5b61508f84614c37565b925061509d60208501614c37565b9150604084015190509250925092565b6001600160a01b038681168252851660208201526040810184905260a0606082018190526000906150e0908301856145e1565b8281036080840152610ce881856145e1565b6001600160a01b0385168152608060208201819052600090615116908301866145e1565b8415156040840152828103606084015261513081856145e1565b979650505050505050565b84600b0b815283600b0b602082015282600b0b604082015260806060820152600061516960808301846145e1565b9695505050505050565b6001600160a01b038781168252861660208201526040810185905260c0606082018190526000906151a6908301866145e1565b82810360808401526151b881866145e1565b905082810360a084015261136c81856145e1565b600082198211156151df576151df61489a565b500190565b600081600b0b83600b0b600082128260016001605f1b030382138115161561520e5761520e61489a565b8260016001605f1b031903821281161561522a5761522a61489a565b50019392505050565b60018060a01b03841681528260208201526060604082015260006104e260608301846149b0565b60a08152600061526d60a08301886145e1565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b6040815260006152b260408301856145e1565b9050826020830152939250505056fea26469706673582212207948a69b198b07616fc08e079b66297a42497f1cb2066e1921d3c65c084c001164736f6c634300080d0033",
901
+ "metadata": "{\"compiler\":{\"version\":\"0.8.14+commit.80d49f37\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ISuperfluid\",\"name\":\"host\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"uuid\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"codeAddress\",\"type\":\"address\"}],\"name\":\"CodeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"name\":\"FlowOperatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"totalSenderFlowRate\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"totalReceiverFlowRate\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"userData\",\"type\":\"bytes\"}],\"name\":\"FlowUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"name\":\"FlowUpdatedExtension\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_MINIMUM_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAXIMUM_FLOW_RATE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"agreementType\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"authorizeFlowOperatorWithFullControl\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"createFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"createFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"deleteFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"deleteFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getAccountFlowInfo\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCodeAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"codeAddress\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"name\":\"getDepositRequiredForFlowRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"getFlow\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"flowId\",\"type\":\"bytes32\"}],\"name\":\"getFlowByID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"}],\"name\":\"getFlowOperatorData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"flowOperatorId\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"flowOperatorId\",\"type\":\"bytes32\"}],\"name\":\"getFlowOperatorDataByID\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"}],\"name\":\"getMaximumFlowRateFromDeposit\",\"outputs\":[{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getNetFlow\",\"outputs\":[{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"isPatricianPeriod\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isPatricianPeriodNow\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"isCurrentlyPatricianPeriod\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"time\",\"type\":\"uint256\"}],\"name\":\"realtimeBalanceOf\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"dynamicBalance\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"deposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"owedDeposit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"revokeFlowOperatorWithFullControl\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAddress\",\"type\":\"address\"}],\"name\":\"updateCode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlow\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"int96\",\"name\":\"flowRate\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlowByOperator\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISuperfluidToken\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"flowOperator\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"permissions\",\"type\":\"uint8\"},{\"internalType\":\"int96\",\"name\":\"flowRateAllowance\",\"type\":\"int96\"},{\"internalType\":\"bytes\",\"name\":\"ctx\",\"type\":\"bytes\"}],\"name\":\"updateFlowOperatorPermissions\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"newCtx\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Superfluid\",\"details\":\"Please read IConstantFlowAgreementV1 for implementation notes.For more technical notes, please visit protocol-monorepo wiki area.\",\"kind\":\"dev\",\"methods\":{\"agreementType()\":{\"details\":\"ISuperAgreement.agreementType implementation\"},\"authorizeFlowOperatorWithFullControl(address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.authorizeFlowOperatorWithFullControl implementation\"},\"createFlow(address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.createFlow implementation\"},\"createFlowByOperator(address,address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.createFlowByOperator implementation\"},\"deleteFlow(address,address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.deleteFlow implementation\"},\"deleteFlowByOperator(address,address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.deleteFlowByOperator implementation\"},\"getAccountFlowInfo(address,address)\":{\"details\":\"IConstantFlowAgreementV1.getAccountFlowInfo implementation\"},\"getCodeAddress()\":{\"details\":\"Get current implementation code address.\"},\"getDepositRequiredForFlowRate(address,int96)\":{\"details\":\"IConstantFlowAgreementV1.getDepositRequiredForFlowRate implementation\"},\"getFlow(address,address,address)\":{\"details\":\"IConstantFlowAgreementV1.getFlow implementation\"},\"getFlowByID(address,bytes32)\":{\"details\":\"IConstantFlowAgreementV1.getFlow implementation\"},\"getFlowOperatorData(address,address,address)\":{\"details\":\"IConstantFlowAgreementV1.getFlowOperatorData implementation\"},\"getFlowOperatorDataByID(address,bytes32)\":{\"details\":\"IConstantFlowAgreementV1.getFlowOperatorDataByID implementation\"},\"getMaximumFlowRateFromDeposit(address,uint256)\":{\"details\":\"IConstantFlowAgreementV1.getMaximumFlowRateFromDeposit implementation\"},\"getNetFlow(address,address)\":{\"details\":\"IConstantFlowAgreementV1.getNetFlow implementation\"},\"isPatricianPeriod(address,address,uint256)\":{\"details\":\"Returns whether it is the patrician period based on timestamp\",\"params\":{\"account\":\"The account we are interested in\",\"timestamp\":\"The timestamp we are interested in observing the result of isPatricianPeriod\"},\"returns\":{\"_0\":\"bool Whether it is currently the patrician period dictated by governance\"}},\"isPatricianPeriodNow(address,address)\":{\"details\":\"Returns whether it is the patrician period based on host.getNow()\",\"params\":{\"account\":\"The account we are interested in\"},\"returns\":{\"isCurrentlyPatricianPeriod\":\"Whether it is currently the patrician period dictated by governance\",\"timestamp\":\"The value of host.getNow()\"}},\"proxiableUUID()\":{\"details\":\"Proxiable UUID marker function, this would help to avoid wrong logic contract to be used for upgrading. NOTE: The semantics of the UUID deviates from the actual UUPS standard, where it is equivalent of _IMPLEMENTATION_SLOT.\"},\"realtimeBalanceOf(address,address,uint256)\":{\"details\":\"ISuperAgreement.realtimeBalanceOf implementation\"},\"revokeFlowOperatorWithFullControl(address,address,bytes)\":{\"details\":\"IConstantFlowAgreementV1.revokeFlowOperatorWithFullControl implementation\"},\"updateFlow(address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlow implementation\"},\"updateFlowByOperator(address,address,address,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlowByOperator implementation\"},\"updateFlowOperatorPermissions(address,address,uint8,int96,bytes)\":{\"details\":\"IConstantFlowAgreementV1.updateFlowOperatorPermissions implementation\"}},\"stateVariables\":{\"DEFAULT_MINIMUM_DEPOSIT\":{\"details\":\"Default minimum deposit value NOTE: - It may come as a surprise that it is not 0, this is the minimum friction we have in the system for the imperfect blockchain system we live in. - It is related to deposit clipping, and it is always rounded-up when clipping.\"},\"MAXIMUM_DEPOSIT\":{\"details\":\"Maximum deposit value\"},\"MAXIMUM_FLOW_RATE\":{\"details\":\"Maximum flow rate\"}},\"title\":\"ConstantFlowAgreementV1 contract\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"project:/contracts/agreements/ConstantFlowAgreementV1.sol\":\"ConstantFlowAgreementV1\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x4823752b07b8ea4ca971b217e39457930e7cb103c2c91e2a29729e5ca907e4f0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6f319af26a9ade3e6cf3698bf1b84aa6213bdd7a76606ea9ba56ced163593934\",\"dweb:/ipfs/QmZ2u9zen5Htan4dSP1RZCY2XqB9HUwqkNCMzdn7aV2jWc\"]},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://87a7a5d2f6f63f84598af02b8c50ca2df2631cb8ba2453e8d95fcb17e4be9824\",\"dweb:/ipfs/QmR76hqtAcRqoFj33tmNjcWTLrgNsAaakYwnKZ8zoJtKei\"]},\"@openzeppelin/contracts/token/ERC777/IERC777.sol\":{\"keccak256\":\"0xe4e0b7e3f0265ffaa565d26acd2d45f2633f19127ed625e5a05a9f201a87a667\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1762b5bc15a009b5f092ccf547b81e0827c8705884f18e0623e497658514a7ed\",\"dweb:/ipfs/QmTtmVQYuynan3j2uVjdjjRJS1mr7LPRgxSZNnfqC7oxkz\"]},\"@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b3a57d0854b2fdce6ebff933a48dca2445643d1eccfc27f00292e937f26c6a58\",\"dweb:/ipfs/QmW45rZooS9TqR4YXUbjRbtf2Bpb5ouSarBvfW1LdGprvV\"]},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"keccak256\":\"0x5c6caab697d302ad7eb59c234a4d2dbc965c1bae87709bd2850060b7695b28c7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fb62abcee612c175f1b9bc70e5dfe5bd23473c99987ade6e80e291f68dc60ff1\",\"dweb:/ipfs/QmZCMajhG7FtRYNDwBchXN89mXR6HLPVzr9732qfUdNf9E\"]},\"project:/contracts/agreements/AgreementBase.sol\":{\"keccak256\":\"0xa34a1b2dd83146a5ed280509f71a1c020ce1985e603da0fc3599eff71d234ab4\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://0c9e9eb4f857ddef830bd7bc9523151f7de82bf4ecfca1aeb9e8de1588e2e07d\",\"dweb:/ipfs/QmaFU7E1XGTYiHCQicCjLNSzYyBgEHdR5pcC64MzCCsNbC\"]},\"project:/contracts/agreements/AgreementLibrary.sol\":{\"keccak256\":\"0x4ad8252da82acdad4fe2b7a4fd1ebef8a7059b67c06f2af84ce86ded3ca531a4\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://2f1c14d9882316ab33e89329ca47449f2bb5a836df5a7abfb91a823fd428b546\",\"dweb:/ipfs/QmVJQxv5e4Ki19CzoVDHbqvuBrRM6XQa7igUmXTHBANcR4\"]},\"project:/contracts/agreements/ConstantFlowAgreementV1.sol\":{\"keccak256\":\"0xadae2b3519d14f50d79e6277f6305fa57557a63a223bc4e867730c499ea6b2a3\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://a4e30423c960d0e17fe8258b0904aa161751c5e99ded3f19f0aaa1dee6d3b278\",\"dweb:/ipfs/QmfGwPUCRsNENGF2EpsrqqEhkam3i6sz8D7HX54hersZBn\"]},\"project:/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol\":{\"keccak256\":\"0x5da735cab1cf7114564ec7d81ed35037a56b6f216a60569aef6e65f3aaca5dd8\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://27a2ad0243469f7364d5e5a483493b16e2b57b9b36c24c6de0ea0e2c13465c71\",\"dweb:/ipfs/QmSfHTC7ewk8LA27TrDqojqFjdkkafCoZmWE1V6HEuFqox\"]},\"project:/contracts/interfaces/superfluid/Definitions.sol\":{\"keccak256\":\"0x199095781e4221b6015d859558da09977f79199f38d342ab4899c2cecdf8cec1\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://9fd3a5a8b16d8517e2af10e20390a9af5adbfa4e783e3a7dd89eb4588db98385\",\"dweb:/ipfs/QmPDtGR43DeMMVsHjUh7FYzMGsFKPpGriRkaahFpN5T5d3\"]},\"project:/contracts/interfaces/superfluid/ISuperAgreement.sol\":{\"keccak256\":\"0xc3a6a907245116bcecc70fe4b207454012e8ce4fa190228fb8bbe39e0b1bc5cf\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://83c116bdae48685d20e5a27c942111e685ec1ef6334e7ff6f6d9af66edbd8025\",\"dweb:/ipfs/QmTnVuNTaRFiDmkAmDk7NFYdfQTW1kqgBZiY2exC6k8jDx\"]},\"project:/contracts/interfaces/superfluid/ISuperApp.sol\":{\"keccak256\":\"0x42b604992cf67321cc12e8bed16543df0db4eaf125b8c1c82c330ebbeb20c014\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://7c18b00caf7b8be7e11f75284fb96263ce48a3984d56f2a91ec44cae4413d2fc\",\"dweb:/ipfs/QmWVzdW9KnkwAVe9g5zRuMoqCf7N89AoBfzzRr8puw5d8a\"]},\"project:/contracts/interfaces/superfluid/ISuperToken.sol\":{\"keccak256\":\"0xcff22ed43df0f34a645e6cbe0d7c5fd08f204d769e9095bc59d7c2fe6d11b7d6\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://944b8c5a37839b40ec8ee1ccfecbaf007808a61ea16c7b1351a7184606772032\",\"dweb:/ipfs/QmbUKZqZtVfqZMKYnQUygE4svatKuN9kT2ibrnxMuWXR7n\"]},\"project:/contracts/interfaces/superfluid/ISuperTokenFactory.sol\":{\"keccak256\":\"0x68a466c978557e47bd7385b1d7d78f1c8fb07462a870efc5a791008e33a4f535\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://d109879bdb7f022560a792af2ff481df729bf1b4b8e1831b8022f4d12892d41d\",\"dweb:/ipfs/QmRSWqHq8CP5XWgyV4mJpPxMg33s312s2K5ndHRHVqqZ8n\"]},\"project:/contracts/interfaces/superfluid/ISuperfluid.sol\":{\"keccak256\":\"0xf16efd1ba72322e77e0d936b723c0e71eb14c23e11cf69efae8c7caa407012cf\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://ff4bb321b72dc3332984346e5b66ad131c6132101658fe6707d7a9d043f981ab\",\"dweb:/ipfs/QmXmVD2mZ3LRb7wQZ2VcrpYhtjm21zUe5hPDDDJA1WXbFz\"]},\"project:/contracts/interfaces/superfluid/ISuperfluidGovernance.sol\":{\"keccak256\":\"0xea33d20751ffea4f4446bc04f6c10194fb4da0803a988586d41d49cf4859731c\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://7716b1f5eec0a7ac8780d82de4f0274ecd7059be4eec46c82b0b7adce110f10b\",\"dweb:/ipfs/QmWRQafvdCBsyfDYnevXSav1AAz8uZRRBwh2be5Z3vSfVN\"]},\"project:/contracts/interfaces/superfluid/ISuperfluidToken.sol\":{\"keccak256\":\"0x3eec5a3bf337cd319c1918fd1b16f350cf5f6850ac71f6859066fbf86e734ff4\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://cda19a2f5ca18e79c1e2300c8efac84c718df76c4fb313f59f84264a4c6b398a\",\"dweb:/ipfs/QmfQiwgDH5Q64w5ufBnDzVaeWv6WCZ6fLTrYu1FSYfBGhq\"]},\"project:/contracts/interfaces/tokens/ERC20WithTokenInfo.sol\":{\"keccak256\":\"0x66708dae3fcd06e6fc0a46f2959fc2d1e6b9361f28598337339d26af8eb8c0f9\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://77b80718cec21b81ef190c19fb9fbe73913a95c71f7e6715f671bbe8a224dafc\",\"dweb:/ipfs/QmUdsc6DF2Bgih5VZm7sfaECjhGmwE7tAx8pMkzGQgVKQw\"]},\"project:/contracts/interfaces/tokens/TokenInfo.sol\":{\"keccak256\":\"0x70e573644a0ff271c0ccef526809e9d9ab4950ec58755ca84e833cde3b8f3df0\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://aea3709687cc37ba625f4cc882fbdb149a7bf5be5afe2b030203c8719641a77b\",\"dweb:/ipfs/QmVpvfR6ZheE5wNUK9CobaVBgVvEnEPkvjWF9cfwyZr7eQ\"]},\"project:/contracts/upgradability/UUPSProxiable.sol\":{\"keccak256\":\"0xabe3beb46dff1433d7ae61fe470fc347967d5a5b09d48fa45f35ddb2735d61f2\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://ad0fdb3210d3b0ed62886decdeef62b43bdbdd59bd55fc5ea3d636e97fbfb65d\",\"dweb:/ipfs/QmPjd6ehqgoiHkrf2g2h9AZRxKakqxsGx1GTiy5DSwfYJg\"]},\"project:/contracts/upgradability/UUPSUtils.sol\":{\"keccak256\":\"0xe624225773a60f62c7a0687afb0536ba19a17e4e5605ae71e8af77a0287aca59\",\"license\":\"AGPLv3\",\"urls\":[\"bzz-raw://4294e5eb5b194477bca3b8ca04ca92a6fe72dd6cf8da8f0d942a4a86c41c1c7f\",\"dweb:/ipfs/QmdfPXZxJPaBjKNfC8joTcvEhWammJHzRACB1S18sFYfd7\"]}},\"version\":1}",
902
+ "bytecode": "0x60a06040523480156200001157600080fd5b506040516200538b3803806200538b833981016040819052620000349162000046565b6001600160a01b031660805262000078565b6000602082840312156200005957600080fd5b81516001600160a01b03811681146200007157600080fd5b9392505050565b6080516152f762000094600039600061077701526152f76000f3fe608060405234801561001057600080fd5b50600436106101a85760003560e01c806350d75d25116100f957806394229ecb11610097578063aabd266811610071578063aabd26681461042e578063b4b333c614610441578063e6a1e88814610454578063e8e7e2d11461046757600080fd5b806394229ecb146103ed5780639b2e48bc146104005780639cb28b72146102aa57600080fd5b806362fc305e116100d357806362fc305e1461038e5780637730599e146103a1578063811b3d40146103c75780638d997f6e146103da57600080fd5b806350d75d251461035357806352d1902d1461037357806354b770e31461037b57600080fd5b806326b0f536116101665780634b839e0b116101405780634b839e0b146102e05780634c8b181f146103035780634fe9c2911461031657806350209a621461034057600080fd5b806326b0f536146102aa578063354b9590146102b857806346951954146102cb57600080fd5b8062422bbe146101ad57806304aafa49146101e55780630602f7db146101ff578063062e56ec1461022557806309d256ef146102455780630f1ac49514610274575b600080fd5b6101c06101bb366004614493565b61047a565b6040805193845260ff9092166020840152600b0b908201526060015b60405180910390f35b6101f164010000000081565b6040519081526020016101dc565b61021261020d3660046144de565b6104b0565b604051600b9190910b81526020016101dc565b61023861023336600461454c565b6104d1565b6040516101dc919061460d565b6102586102533660046144de565b6104eb565b6040805160ff9093168352600b9190910b6020830152016101dc565b610287610282366004614620565b61050f565b60408051948552600b9390930b60208501529183015260608201526080016101dc565b6101f160016001605f1b0381565b6102386102c636600461466b565b610545565b6102de6102d93660046146f7565b61076c565b005b6102f36102ee366004614714565b6107f0565b60405190151581526020016101dc565b610238610311366004614755565b6108c7565b610329610324366004614620565b6109e1565b6040805192151583526020830191909152016101dc565b61023861034e3660046147d1565b610ac3565b61035b610b96565b6040516001600160a01b0390911681526020016101dc565b6101f1610bc5565b61023861038936600461454c565b610c29565b61023861039c3660046147d1565b610c41565b7fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd36101f1565b6102386103d5366004614821565b610cf4565b6101f16103e8366004614865565b610f7e565b6102386103fb36600461466b565b611199565b61041361040e366004614714565b611379565b604080519384526020840192909252908201526060016101dc565b61028761043c3660046144de565b6113d3565b61023861044f366004614755565b6113e5565b610287610462366004614493565b611479565b610212610475366004614620565b6114b4565b600080600061048985856114ce565b925060006104978785611539565b8051602090910151959990985094965093945050505050565b6000806104bc846115fe565b5090506104c98184611779565b949350505050565b60606104e285856000808787610cf4565b95945050505050565b60008060006104fa8585611539565b80516020909101519097909650945050505050565b600080600080600061052187876117e8565b805160208201516040830151606090930151919b909a509198509650945050505050565b606060006105898885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036105f55760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f55504441544500000000000000000060448201526064015b60405180910390fd5b60008061060b8a6106068b8b611a65565b611a8d565b9150915060008060006106238d8d886060015161047a565b925092509250610634826001611ad4565b6106805760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f5550444154455f464c4f570000000000000060448201526064016105ec565b6000600b82900b60016001605f1b0314806106a557508a600b0b8560200151600b0b12155b6106c75760208501516106b8908c6148b0565b6106c290836148b0565b6106c9565b815b9050600081600b0b12156106ef5760405162461bcd60e51b81526004016105ec90614900565b6106fb8e858584611b2f565b5050505061072960408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808c1682528a8116602083015289166040820152600b88900b606082015261075d8183858a8a89611bb8565b9b9a5050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107e45760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920686f73742063616e2075706461746520636f64650000000000000060448201526064016105ec565b6107ed81611d3d565b50565b604051633acd4df360e21b81526001600160a01b03838116600483015260248201839052600091829186169063eb3537cc90604401606060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190614941565b505090506000811261087c5760019150506108c0565b600080610888876115fe565b91509150600061089888886117e8565b91505060006108aa8260400151611f4b565b90506108b885828686611fb9565b955050505050505b9392505050565b6060600061090b8785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061091e8888846060015161047a565b50915050600061092f826002611ad4565b90508061097e5760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f44454c4554455f464c4f570000000000000060448201526064016105ec565b6040805160808101825260008082526020820181905291810182905260608101919091525b6001600160a01b03808b168252898116602083015288166040820152600060608201526109d38183898988611ff6565b9a9950505050505050505050565b6000806000846001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a48919061497a565b9050806001600160a01b031663bbe4fd506040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190614997565b9150610ab98585846107f0565b9250509250929050565b60606000610b078785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610b3360408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808916825260608084015182166020840181905291891660408401819052600b89900b91840191909152600091610b7191611a65565b9050600080610b84846000015184611a8d565b9150915061075d8482848b8b8a611bb8565b6000610bc07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000306001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190614997565b60606104e28585600760016001605f1b038787610cf4565b60606000610c858785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610cb160408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b038089168252606080840151821660208401529088166040830152600b87900b90820152610ce88186868561278d565b98975050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3b925087915061292d9050565b610d875760405162461bcd60e51b815260206004820152601860248201527f4346413a20556e636c65616e207065726d697373696f6e73000000000000000060448201526064016105ec565b6000610dc98885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b031603610e305760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f53454e4445525f464c4f575f4f50455241544f52000060448201526064016105ec565b600085600b0b1215610e845760405162461bcd60e51b815260206004820152601c60248201527f4346413a20455f4e4f5f4e454741544956455f414c4c4f57414e43450000000060448201526064016105ec565b6040805180820190915260ff87168152600b86900b60208201526060820151600090610eb0908a6114ce565b9050896001600160a01b031663a1b2bf8b82610ecb85612934565b6040518363ffffffff1660e01b8152600401610ee89291906149eb565b600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505060608401516040805160ff8c168152600b8b900b60208201526001600160a01b03808e169450928316928e16917fc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8910160405180910390a45050509695505050505050565b600080836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe3919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611049919061497a565b90506000816001600160a01b03166380f70cba84887feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc46040518463ffffffff1660e01b815260040161109d93929190614a04565b602060405180830381865afa1580156110ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110de9190614997565b90506000826001600160a01b03166380f70cba85897fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161113293929190614a04565b602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190614997565b9050602081901c63ffffffff1661118b8382896129aa565b955050505050505b92915050565b606060006111dd8885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036112445760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f43524541544500000000000000000060448201526064016105ec565b60008060006112588b8b866060015161047a565b925092509250611269826000611ad4565b6112b55760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f4f50455241544f525f4352454154455f464c4f57000060448201526064016105ec565b6000600b82900b60016001605f1b03146112d8576112d389836148b0565b6112da565b815b9050600081600b0b12156113005760405162461bcd60e51b81526004016105ec90614900565b61130c8c858584611b2f565b5050505061133a60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808a168252888116602083015287166040820152600b86900b606082015261136c8186868561278d565b9998505050505050505050565b600080600080600061138b88886117e8565b9150915081156113c8578060200151600b0b8160000151876113ad9190614a28565b6113b79190614a67565b945080604001519350806060015192505b505093509350939050565b60008060008060006105218787611a8d565b606060006114298785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061143c8888846060015161047a565b50915050600061144d826002611ad4565b90506109a360408051608081018252600080825260208201819052918101829052606081019190915290565b600080600080600061148f886106068989611a65565b805160208201516040830151606090930151919c909b50919950975095505050505050565b6000806114c184846117e8565b6020015195945050505050565b6000828260405160200161151b9291906060808252600c908201526b333637bba7b832b930ba37b960a11b60808201526001600160a01b0392831660208201529116604082015260a00190565b60405160208183030381529060405280519060200120905092915050565b6040805180820182526000808252602082018190529151636c2d9f2f60e01b8152306004820152602481018490526001604482015282906001600160a01b03861690636c2d9f2f90606401600060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115c99190810190614b5d565b90506115f1816000815181106115e1576115e1614bf7565b602002602001015160001c612a7f565b92509250505b9250929050565b6000806000836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb919061497a565b90506000816001600160a01b03166380f70cba84887fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161171f93929190614a04565b602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117609190614997565b63ffffffff602082901c81169891169650945050505050565b600060016001605f1b038211156117d25760405162461bcd60e51b815260206004820152601b60248201527f4346413a206465706f736974206e756d62657220746f6f20626967000000000060448201526064016105ec565b63ffffffff198216915060006104c98484614c23565b60006117f26143cc565b604051634b61cc3360e01b81523060048201526001600160a01b038481166024830152600060448301819052600160648401529190861690634b61cc33906084015b600060405180830381865afa158015611851573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118799190810190614b5d565b90506115f18160008151811061189157611891614bf7565b602002602001015160001c612abf565b6118a96143f7565b336001600160a01b0316836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611915919061497a565b6001600160a01b03161461195f5760405162461bcd60e51b81526020600482015260116024820152701d5b985d5d1a1bdc9a5e9959081a1bdcdd607a1b60448201526064016105ec565b604051632fd0a1cd60e21b8152339063bf4287349061198290859060040161460d565b602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614c47565b6119fd5760405162461bcd60e51b815260206004820152600b60248201526a0d2dcecc2d8d2c840c6e8f60ab1b60448201526064016105ec565b604051631fb6491d60e11b81523390633f6c923a90611a2090859060040161460d565b600060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614ce9565b604080516001600160a01b03808516602083015283169181019190915260009060600161151b565b6000611a976143cc565b604051636c2d9f2f60e01b815230600482015260248101849052600160448201526000906001600160a01b03861690636c2d9f2f90606401611834565b600080826002811115611ae957611ae9614df0565b03611afa5750600182811614611193565b6001826002811115611b0e57611b0e614df0565b03611b215750600182811c811614611193565b505060021c60019081161490565b6040805180820190915260ff83168152600b82900b60208201526001600160a01b03851663a1b2bf8b85611b6284612934565b6040518363ffffffff1660e01b8152600401611b7f9291906149eb565b600060405180830381600087803b158015611b9957600080fd5b505af1158015611bad573d6000803e3d6000fd5b505050505050505050565b60606000611bc68884612b1f565b91505085611c115760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614c47565b15611cdb57611cd488604001518960000151838a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925060019150612c929050565b9150611d26565b611d238860000151828988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506133af915050565b91505b8751611d329084613487565b509695505050505050565b6000611d677f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031603611dbd5760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c6500000060448201526064016105ec565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614997565b611e27610bc5565b14611e805760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b60648201526084016105ec565b6001600160a01b0381163003611ed85760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f700000000000000060448201526064016105ec565b611f00817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc611f29610bc5565b604080519182526001600160a01b03841660208301520160405180910390a150565b60006001600160ff1b03821115611fb55760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016105ec565b5090565b600080611fc68587614e06565b90506000611fd48587614e47565b9050611fe08486614e75565b611fea8284614e47565b13979650505050505050565b6040805160c0810182526000808252602082018190529181018290526060818101839052608082019290925260a0810182905260208701516001600160a01b03166120795760405162461bcd60e51b81526020600482015260136024820152724346413a2073656e646572206973207a65726f60681b60448201526064016105ec565b60408701516001600160a01b03166120cb5760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b6120dd87602001518860400151611a65565b8082526020808901516001600160a01b03908116918401919091526040808a01518216908401526060808601519091169083015260006080830181905260a0808601519084015288519091829161213391611a8d565b915091508161217f5760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b885160208a01516040808801519051633acd4df360e21b81526000936001600160a01b03169263eb3537cc926121cb926004016001600160a01b03929092168252602082015260400190565b606060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190614941565b5050905089602001516001600160a01b031686606001516001600160a01b031614158015612254575089604001516001600160a01b031686606001516001600160a01b031614155b801561225e575088155b156123aa5760208a0151604051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa1580156122ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d19190614c47565b158015612349575060408a8101519051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190614c47565b155b156123aa57600081126123aa5760405162461bcd60e51b815260206004820152602360248201527f4346413a2073656e646572206163636f756e74206973206e6f7420637269746960448201526218d85b60ea1b60648201526084016105ec565b60008112156123c8576123c88a600001518286858a6060015161359e565b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208b015160608801519196506001600160a01b039081169116036124be5760408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248b9190614c47565b156124af576124a88a604001518b600001518685898b6002612c92565b9450612780565b89516124a8908584888a6133af565b89604001516001600160a01b031686606001516001600160a01b0316036125f25760208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d9190614c47565b1561256a576124a88a602001518b600001518685898b6002612c92565b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156125b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d89190614c47565b156124af576124a860008b600001518685898b6002612c92565b60208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190614c47565b801561266c5750600081125b156126e65760208a0151604051635b92108f60e11b8152339163b724211e9161269c918991600b90600401614e8c565b6000604051808303816000875af11580156126bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126e39190810190614eba565b94505b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614c47565b15612771576124a88a604001518b600001518685898b6002612c92565b89516109d3908584888a6133af565b5050505095945050505050565b606060008061279c8785612b1f565b915091506000806127b1896000015185611a8d565b9150915081156128035760405162461bcd60e51b815260206004820152601760248201527f4346413a20666c6f7720616c726561647920657869737400000000000000000060448201526064016105ec565b6040898101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614c47565b156128ca576128c389604001518a6000015185848c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508f93509150612c929050565b9450612915565b612912896000015184838b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92506133af915050565b94505b88516129219087613487565b50505050949350505050565b60f8161590565b606060008260200151600b0b121561294e5761294e614eef565b60408051600180825281830190925290602080830190803683370190505090508160200151600b0b6080836000015160ff16901b1760001b8160008151811061299957612999614bf7565b602002602001018181525050919050565b60008082600b0b13612a0a5760405162461bcd60e51b815260206004820152602360248201527f4346413a206e6f7420666f72206e6f6e2d706f73697469766520666c6f77207260448201526261746560e81b60648201526084016105ec565b60016001605f1b03612a2084600b85900b614f05565b1115612a675760405162461bcd60e51b81526020600482015260166024820152754346413a20666c6f77207261746520746f6f2062696760501b60448201526064016105ec565b6000612a7383856137aa565b90506104e285826137ee565b6040805180820190915260008082526020820152811580159190612aba5760016001605f1b038316600b0b6020820152608083901c60ff1681525b915091565b6000612ac96143cc565b821580159250612aba5760e083901c8152608083901c6bffffffffffffffffffffffff16600b0b6020808301919091526bffffffffffffffff0000000084821c811660408401529084901b166060820152915091565b6040805160c08101825260008082526020820181905291810182905260608082018390526080820183905260a082015260408401516001600160a01b0316612ba15760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b612bb384602001518560400151611a65565b8082526020808601516001600160a01b0390811691840182905260408088015182169085018190526060808801519092168286015290870151600b0b608085015260a0808701519085015291935003612c425760405162461bcd60e51b81526020600482015260116024820152704346413a206e6f2073656c6620666c6f7760781b60448201526064016105ec565b60008160800151600b0b136115f75760405162461bcd60e51b81526020600482015260166024820152754346413a20696e76616c696420666c6f77207261746560501b60448201526064016105ec565b82612c9b614452565b6001600160a01b03891615612e84576000612d30898b8a600001518b602001518c60400151604051602001612ce69291906001600160a01b0392831681529116602082015260400190565b60408051601f1981840301815260e08301825260006080840181905260a0840181905260c08401526001600160a01b03958616835293909416602082015292830152606082015290565b90506000846002811115612d4657612d46614df0565b03612d5b5764010000000060c0820152612d90565b6001846002811115612d6f57612d6f614df0565b03612d845764040000000060c0820152612d90565b64100000000060c08201525b612d9a8187613804565b82526040850151610140860151612db491908b8b8b6139bb565b506080830152508451612dc8906001614f24565b60ff168160800151612dda9190614f05565b60808201526060870151612ded90611f4b565b60a08201526000846002811115612e0657612e06614df0565b03612e1b5764020000000060c0820152612e50565b6001846002811115612e2f57612e2f614df0565b03612e445764080000000060c0820152612e50565b64200000000060c08201525b612e5f81836000015185613d9f565b60408401919091528851909350612e77908a90611a8d565b602084015250612ea29050565b612e9a84604001518561014001518a8a8a6139bb565b602084015250505b6000816040015161010001511315612ee157612ed6612ed1612ecc83604001516101000151614008565b61405a565b611f4b565b604082015161010001525b6000612ef08760600151611f4b565b82604001516101000151612f049190614a28565b9050612f2a81612f1b846020015160400151611f4b565b612f259190614e06565b614008565b82602001516040018181525050612f4c81612f1b846020015160600151611f4b565b60208301805160600191909152885190516001600160a01b038b169163a1b2bf8b91612f779061408e565b6040518363ffffffff1660e01b8152600401612f949291906149eb565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50505050612fde89896020015160008460008a604001516140ff565b50612ff6898960400151600080858a604001516140ff565b506101408501516001600160a01b031615806130285750886001600160a01b03168561014001516001600160a01b0316145b156130a657602082015160409081015190516303c9790560e11b81523391630792f20a9161305c9187918690600401614f49565b6000604051808303816000875af115801561307b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130a39190810190614eba565b92505b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156130f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131149190614c47565b156133a257604088810151868201519151633acd4df360e21b81526001600160a01b0391821660048201526024810192909252600091908b169063eb3537cc90604401606060405180830381865afa158015613174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131989190614941565b509091505060008112156133a05760028560028111156131ba576131ba614df0565b03613345576040808a01519051635b92108f60e11b8152339163b724211e916131ea918891600c90600401614e8c565b6000604051808303816000875af1158015613209573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132319190810190614eba565b9350600061325961324183614f6e565b613254600061324f87614f6e565b61426b565b61427a565b90508a6001600160a01b031663cf97256d8b602001518361327990614f6e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b5050505060408a810151905163cf97256d60e01b81526001600160a01b03918216600482015260248101839052908c169063cf97256d90604401600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b50505050506133a0565b60405162461bcd60e51b815260206004820152602a60248201527f4346413a204150505f52554c455f4e4f5f435249544943414c5f524543454956604482015269115497d050d0d3d5539560b21b60648201526084016105ec565b505b5050979650505050505050565b606083810151156133c2576133c2614eef565b60006133cc6143cc565b6133e284604001518561014001518a8a8a6139bb565b6101408701519294509250506001600160a01b03808a169116036134785760408082015190516303c9790560e11b81523391630792f20a9161342a9189918790600401614f49565b6000604051808303816000875af1158015613449573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134719190810190614eba565b925061347c565b8492505b505095945050505050565b602081015160ff1660031415806134b55750816001600160a01b03168161014001516001600160a01b031614155b1561359a5760608101516040808301519051633acd4df360e21b81526001600160a01b039283166004820152602481019190915260009184169063eb3537cc90604401606060405180830381865afa158015613515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135399190614941565b5050905060008112156135985760405162461bcd60e51b815260206004820152602160248201527f4346413a206e6f7420656e6f75676820617661696c61626c652062616c616e636044820152606560f81b60648201526084016105ec565b505b5050565b60006135ae8685602001516117e8565b91505060006135c08460400151611f4b565b905060006135d18360400151611f4b565b905060606000806135e2848b614e06565b90506000806135f08d6115fe565b915091506136008c878484611fb9565b93505050600081126136eb576000846136198388614a67565b6136239190614e47565b9050600183613633576001613636565b60005b6040805160ff9384166020820152929091169082015260600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b878f6020015161368588614008565b61369189600019614a67565b6040518863ffffffff1660e01b81526004016136b39796959493929190614f8a565b600060405180830381600087803b1580156136cd57600080fd5b505af11580156136e1573d6000803e3d6000fd5b505050505061379d565b6040805160016020820152600291810191909152859060600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b60008f6020015161373b88614008565b6137478a600019614a67565b6040518863ffffffff1660e01b81526004016137699796959493929190614f8a565b600060405180830381600087803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b50505050505b5050505050505050505050565b600082600b0b6000036137bf57506000611193565b60016001605f1b038211156137d6576137d6614eef565b6137e08284614fd7565b600b0b90506108c08161405a565b60008183116137fd57816108c0565b5090919050565b6020820151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613858573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061387c9190615071565b9194509250905082801561388e575081155b156139b257600061389f868861428f565b90508660c0015182166000036139a45760006138be8860c0015161430d565b88516040808b015160608c0151825160008152602081019093526138ea939230929190604481016150ad565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918a015160c08b01519251633a020f0160e11b815291935033926374041e029261395992918691641000000000919091149088906004016150f2565b6000604051808303816000875af1158015613978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526139a09190810190614eba565b9550505b6139af8660006143a4565b50505b50505092915050565b6000806139c66143cc565b60008060006139d4896115fe565b5090506000336001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3b919061497a565b60405163407b865d60e11b81529091506001600160a01b038216906380f70cba90613a8e9033908e907feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc490600401614a04565b602060405180830381865afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614997565b9250613adf8960800151836137aa565b95505050613af08660600151611f4b565b613afd8760400151611f4b565b613b0686611f4b565b613b109190614a28565b613b1a9190614e06565b9450613b2d85612f1b8860400151611f4b565b91508082108015613b45575060008760800151600b0b135b15613b8757613b578660600151611f4b565b613b648760400151611f4b565b613b6d83611f4b565b613b779190614a28565b613b819190614e06565b94508091505b6001600160a01b03891615801590613bb15750876001600160a01b0316896001600160a01b031614155b15613bbb57600093505b604051806080016040528060008960800151600b0b13613bdc576000613bde565b8b5b81526020018860800151600b0b815260200183815260200187606001518152509250876001600160a01b031663a1b2bf8b8860000151613c1d8661408e565b6040518363ffffffff1660e01b8152600401613c3a9291906149eb565b600060405180830381600087803b158015613c5457600080fd5b505af1158015613c68573d6000803e3d6000fd5b505060408051808201909152600080825260208201529250613c88915050565b613cae88886020015189608001518960200151613ca591906148b0565b8860008f6140ff565b600b0b8152604087015160208701516080890151613cdd928b929091613cd491906148b0565b6000808f6140ff565b600b0b60208083018290526040808a0151918a015160808b0151855160a08d015193516001600160a01b0395861696938616958f16947f57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e94613d4394939290919061513b565b60405180910390a486606001516001600160a01b03167f71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f7483604051613d8a91815260200190565b60405180910390a25050955095509592505050565b613da76143f7565b6020840151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1f9190615071565b88965091945092509050828015613e34575081155b15613ffd57613e43848961428f565b93508760c001518116600003613feb576000613e628960c0015161430d565b89516040808c015160608d015182516000815260208101909352613e909392309291908e9060448101615173565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918b015160c08c0151925163079b42a160e21b81529193503392631e6d0a8492613eff9291869164200000000091909114908b906004016150f2565b6000604051808303816000875af1158015613f1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f469190810190614eba565b604051631fb6491d60e11b81529095503390633f6c923a90613f6c90889060040161460d565b600060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613fb19190810190614ce9565b9550613fe3600061324f613fc88c60800151611f4b565b613254613fd88b60e00151611f4b565b8b610100015161426b565b610100870152505b613ffa868661010001516143a4565b93505b505050935093915050565b600080821215611fb55760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f73697469766560448201526064016105ec565b60008063ffffffff831661406f576000614072565b60015b60ff16905060206140858285831c6151cc565b901b9392505050565b6040805160018082528183019092526060916020808301908036833701905050905060208260600151901c604060208460400151901c901b608084602001516bffffffffffffffffffffffff16901b60e08560000151901b17171760001b8160008151811061299957612999614bf7565b60008061410c88886117e8565b91505060008160200151600b0b61412c836000015186612ed19190614e75565b6141369190614a67565b905080156141a15760405163cf97256d60e01b81526001600160a01b038981166004830152602482018390528a169063cf97256d90604401600060405180830381600087803b15801561418857600080fd5b505af115801561419c573d6000803e3d6000fd5b505050505b8682602001516141b191906151e4565b600b0b602083015283825260408201516141d0908790612f1b90611f4b565b604083015260608201516141e9908690612f1b90611f4b565b60608301526001600160a01b03891663090c415e8960006142098661408e565b6040518463ffffffff1660e01b815260040161422793929190615233565b600060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b5050506020909201519998505050505050505050565b60008183136137fd57816108c0565b600081831361428957826108c0565b50919050565b6020810151608082015160a08301518351604051630768fabb60e41b8152606094339463768fabb0946142c6948a9460040161525a565b6000604051808303816000875af11580156142e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614eba565b6000640100000000820361432957506330d9c91560e01b919050565b64040000000082036143435750630221347d60e61b919050565b641000000000820361435d5750635f9e7d7760e01b919050565b6402000000008203614377575063d86ed3e560e01b919050565b6408000000008203614391575063230dbd2960e01b919050565b506353c11f9960e01b919050565b919050565b604051634c4d861f60e11b8152606090339063989b0c3e906142c6908690869060040161529f565b6040518060800160405280600081526020016000600b0b815260200160008152602001600081525090565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60405180606001604052806060815260200161446c6143cc565b81526020016144796143f7565b905290565b6001600160a01b03811681146107ed57600080fd5b6000806000606084860312156144a857600080fd5b83356144b38161447e565b925060208401356144c38161447e565b915060408401356144d38161447e565b809150509250925092565b600080604083850312156144f157600080fd5b82356144fc8161447e565b946020939093013593505050565b60008083601f84011261451c57600080fd5b50813567ffffffffffffffff81111561453457600080fd5b6020830191508360208285010111156115f757600080fd5b6000806000806060858703121561456257600080fd5b843561456d8161447e565b9350602085013561457d8161447e565b9250604085013567ffffffffffffffff81111561459957600080fd5b6145a58782880161450a565b95989497509550505050565b60005b838110156145cc5781810151838201526020016145b4565b838111156145db576000848401525b50505050565b600081518084526145f98160208601602086016145b1565b601f01601f19169290920160200192915050565b6020815260006108c060208301846145e1565b6000806040838503121561463357600080fd5b823561463e8161447e565b9150602083013561464e8161447e565b809150509250929050565b8035600b81900b811461439f57600080fd5b60008060008060008060a0878903121561468457600080fd5b863561468f8161447e565b9550602087013561469f8161447e565b945060408701356146af8161447e565b93506146bd60608801614659565b9250608087013567ffffffffffffffff8111156146d957600080fd5b6146e589828a0161450a565b979a9699509497509295939492505050565b60006020828403121561470957600080fd5b81356108c08161447e565b60008060006060848603121561472957600080fd5b83356147348161447e565b925060208401356147448161447e565b929592945050506040919091013590565b60008060008060006080868803121561476d57600080fd5b85356147788161447e565b945060208601356147888161447e565b935060408601356147988161447e565b9250606086013567ffffffffffffffff8111156147b457600080fd5b6147c08882890161450a565b969995985093965092949392505050565b6000806000806000608086880312156147e957600080fd5b85356147f48161447e565b945060208601356148048161447e565b935061479860408701614659565b60ff811681146107ed57600080fd5b60008060008060008060a0878903121561483a57600080fd5b86356148458161447e565b955060208701356148558161447e565b945060408701356146af81614812565b6000806040838503121561487857600080fd5b82356148838161447e565b915061489160208401614659565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b600081600b0b83600b0b600081128160016001605f1b0319018312811516156148db576148db61489a565b8160016001605f1b030183138116156148f6576148f661489a565b5090039392505050565b60208082526021908201527f4346413a20455f4558434545445f464c4f575f524154455f414c4c4f57414e436040820152604560f81b606082015260800190565b60008060006060848603121561495657600080fd5b8351925060208401519150604084015190509250925092565b805161439f8161447e565b60006020828403121561498c57600080fd5b81516108c08161447e565b6000602082840312156149a957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156149e0578151875295820195908201906001016149c4565b509495945050505050565b8281526040602082015260006104c960408301846149b0565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008083128015600160ff1b850184121615614a4657614a4661489a565b6001600160ff1b0384018313811615614a6157614a6161489a565b50500390565b60006001600160ff1b0381841382841380821686840486111615614a8d57614a8d61489a565b600160ff1b6000871282811687830589121615614aac57614aac61489a565b60008712925087820587128484161615614ac857614ac861489a565b87850587128184161615614ade57614ade61489a565b505050929093029392505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614b2657614b26614aec565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b5557614b55614aec565b604052919050565b60006020808385031215614b7057600080fd5b825167ffffffffffffffff80821115614b8857600080fd5b818501915085601f830112614b9c57600080fd5b815181811115614bae57614bae614aec565b8060051b9150614bbf848301614b2c565b8181529183018401918481019088841115614bd957600080fd5b938501935b83851015610ce857845182529385019390850190614bde565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614c3257614c32614c0d565b500490565b8051801515811461439f57600080fd5b600060208284031215614c5957600080fd5b6108c082614c37565b805161439f81614812565b80516001600160e01b03198116811461439f57600080fd5b600082601f830112614c9657600080fd5b815167ffffffffffffffff811115614cb057614cb0614aec565b614cc3601f8201601f1916602001614b2c565b818152846020838601011115614cd857600080fd5b6104c98260208301602087016145b1565b600060208284031215614cfb57600080fd5b815167ffffffffffffffff80821115614d1357600080fd5b908301906101608286031215614d2857600080fd5b614d30614b02565b614d3983614c62565b8152614d4760208401614c62565b602082015260408301516040820152614d626060840161496f565b6060820152614d7360808401614c6d565b608082015260a083015182811115614d8a57600080fd5b614d9687828601614c85565b60a08301525060c083015160c082015260e083015160e0820152610100915081830151828201526101209150614dcd82840161496f565b828201526101409150614de182840161496f565b91810191909152949350505050565b634e487b7160e01b600052602160045260246000fd5b600080821280156001600160ff1b0384900385131615614e2857614e2861489a565b600160ff1b8390038412811615614e4157614e4161489a565b50500190565b600082614e5657614e56614c0d565b600160ff1b821460001984141615614e7057614e7061489a565b500590565b600082821015614e8757614e8761489a565b500390565b606081526000614e9f60608301866145e1565b6001600160a01b039490941660208301525060400152919050565b600060208284031215614ecc57600080fd5b815167ffffffffffffffff811115614ee357600080fd5b6104c984828501614c85565b634e487b7160e01b600052600160045260246000fd5b6000816000190483118215151615614f1f57614f1f61489a565b500290565b600060ff821660ff84168060ff03821115614f4157614f4161489a565b019392505050565b606081526000614f5c60608301866145e1565b60208301949094525060400152919050565b6000600160ff1b8201614f8357614f8361489a565b5060000390565b87815260e060208201526000614fa360e08301896145e1565b6001600160a01b03978816604084015295151560608301525092909416608083015260a082015260c0019190915292915050565b600081600b0b83600b0b60016001605f1b036000821360008413838304851182821616156150075761500761489a565b6b7fffffffffffffffffffffff19600085128281168783058712161561502f5761502f61489a565b6000871292508582058712848416161561504b5761504b61489a565b858505871281841616156150615761506161489a565b5050509290910295945050505050565b60008060006060848603121561508657600080fd5b61508f84614c37565b925061509d60208501614c37565b9150604084015190509250925092565b6001600160a01b038681168252851660208201526040810184905260a0606082018190526000906150e0908301856145e1565b8281036080840152610ce881856145e1565b6001600160a01b0385168152608060208201819052600090615116908301866145e1565b8415156040840152828103606084015261513081856145e1565b979650505050505050565b84600b0b815283600b0b602082015282600b0b604082015260806060820152600061516960808301846145e1565b9695505050505050565b6001600160a01b038781168252861660208201526040810185905260c0606082018190526000906151a6908301866145e1565b82810360808401526151b881866145e1565b905082810360a084015261136c81856145e1565b600082198211156151df576151df61489a565b500190565b600081600b0b83600b0b600082128260016001605f1b030382138115161561520e5761520e61489a565b8260016001605f1b031903821281161561522a5761522a61489a565b50019392505050565b60018060a01b03841681528260208201526060604082015260006104e260608301846149b0565b60a08152600061526d60a08301886145e1565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b6040815260006152b260408301856145e1565b9050826020830152939250505056fea264697066735822122076418c61ebec88bbc869733ccd3b7d51db9ab7eb6cf6426c327d897e84c12dbb64736f6c634300080e0033",
903
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a85760003560e01c806350d75d25116100f957806394229ecb11610097578063aabd266811610071578063aabd26681461042e578063b4b333c614610441578063e6a1e88814610454578063e8e7e2d11461046757600080fd5b806394229ecb146103ed5780639b2e48bc146104005780639cb28b72146102aa57600080fd5b806362fc305e116100d357806362fc305e1461038e5780637730599e146103a1578063811b3d40146103c75780638d997f6e146103da57600080fd5b806350d75d251461035357806352d1902d1461037357806354b770e31461037b57600080fd5b806326b0f536116101665780634b839e0b116101405780634b839e0b146102e05780634c8b181f146103035780634fe9c2911461031657806350209a621461034057600080fd5b806326b0f536146102aa578063354b9590146102b857806346951954146102cb57600080fd5b8062422bbe146101ad57806304aafa49146101e55780630602f7db146101ff578063062e56ec1461022557806309d256ef146102455780630f1ac49514610274575b600080fd5b6101c06101bb366004614493565b61047a565b6040805193845260ff9092166020840152600b0b908201526060015b60405180910390f35b6101f164010000000081565b6040519081526020016101dc565b61021261020d3660046144de565b6104b0565b604051600b9190910b81526020016101dc565b61023861023336600461454c565b6104d1565b6040516101dc919061460d565b6102586102533660046144de565b6104eb565b6040805160ff9093168352600b9190910b6020830152016101dc565b610287610282366004614620565b61050f565b60408051948552600b9390930b60208501529183015260608201526080016101dc565b6101f160016001605f1b0381565b6102386102c636600461466b565b610545565b6102de6102d93660046146f7565b61076c565b005b6102f36102ee366004614714565b6107f0565b60405190151581526020016101dc565b610238610311366004614755565b6108c7565b610329610324366004614620565b6109e1565b6040805192151583526020830191909152016101dc565b61023861034e3660046147d1565b610ac3565b61035b610b96565b6040516001600160a01b0390911681526020016101dc565b6101f1610bc5565b61023861038936600461454c565b610c29565b61023861039c3660046147d1565b610c41565b7fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd36101f1565b6102386103d5366004614821565b610cf4565b6101f16103e8366004614865565b610f7e565b6102386103fb36600461466b565b611199565b61041361040e366004614714565b611379565b604080519384526020840192909252908201526060016101dc565b61028761043c3660046144de565b6113d3565b61023861044f366004614755565b6113e5565b610287610462366004614493565b611479565b610212610475366004614620565b6114b4565b600080600061048985856114ce565b925060006104978785611539565b8051602090910151959990985094965093945050505050565b6000806104bc846115fe565b5090506104c98184611779565b949350505050565b60606104e285856000808787610cf4565b95945050505050565b60008060006104fa8585611539565b80516020909101519097909650945050505050565b600080600080600061052187876117e8565b805160208201516040830151606090930151919b909a509198509650945050505050565b606060006105898885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036105f55760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f55504441544500000000000000000060448201526064015b60405180910390fd5b60008061060b8a6106068b8b611a65565b611a8d565b9150915060008060006106238d8d886060015161047a565b925092509250610634826001611ad4565b6106805760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f5550444154455f464c4f570000000000000060448201526064016105ec565b6000600b82900b60016001605f1b0314806106a557508a600b0b8560200151600b0b12155b6106c75760208501516106b8908c6148b0565b6106c290836148b0565b6106c9565b815b9050600081600b0b12156106ef5760405162461bcd60e51b81526004016105ec90614900565b6106fb8e858584611b2f565b5050505061072960408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808c1682528a8116602083015289166040820152600b88900b606082015261075d8183858a8a89611bb8565b9b9a5050505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107e45760405162461bcd60e51b815260206004820152601960248201527f6f6e6c7920686f73742063616e2075706461746520636f64650000000000000060448201526064016105ec565b6107ed81611d3d565b50565b604051633acd4df360e21b81526001600160a01b03838116600483015260248201839052600091829186169063eb3537cc90604401606060405180830381865afa158015610842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108669190614941565b505090506000811261087c5760019150506108c0565b600080610888876115fe565b91509150600061089888886117e8565b91505060006108aa8260400151611f4b565b90506108b885828686611fb9565b955050505050505b9392505050565b6060600061090b8785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061091e8888846060015161047a565b50915050600061092f826002611ad4565b90508061097e5760405162461bcd60e51b815260206004820152601960248201527f455f4e4f5f4f50455241544f525f44454c4554455f464c4f570000000000000060448201526064016105ec565b6040805160808101825260008082526020820181905291810182905260608101919091525b6001600160a01b03808b168252898116602083015288166040820152600060608201526109d38183898988611ff6565b9a9950505050505050505050565b6000806000846001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a48919061497a565b9050806001600160a01b031663bbe4fd506040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aac9190614997565b9150610ab98585846107f0565b9250509250929050565b60606000610b078785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610b3360408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808916825260608084015182166020840181905291891660408401819052600b89900b91840191909152600091610b7191611a65565b9050600080610b84846000015184611a8d565b9150915061075d8482848b8b8a611bb8565b6000610bc07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000306001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc09190614997565b60606104e28585600760016001605f1b038787610cf4565b60606000610c858785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050610cb160408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b038089168252606080840151821660208401529088166040830152600b87900b90820152610ce88186868561278d565b98975050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3b925087915061292d9050565b610d875760405162461bcd60e51b815260206004820152601860248201527f4346413a20556e636c65616e207065726d697373696f6e73000000000000000060448201526064016105ec565b6000610dc98885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b031603610e305760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f53454e4445525f464c4f575f4f50455241544f52000060448201526064016105ec565b600085600b0b1215610e845760405162461bcd60e51b815260206004820152601c60248201527f4346413a20455f4e4f5f4e454741544956455f414c4c4f57414e43450000000060448201526064016105ec565b6040805180820190915260ff87168152600b86900b60208201526060820151600090610eb0908a6114ce565b9050896001600160a01b031663a1b2bf8b82610ecb85612934565b6040518363ffffffff1660e01b8152600401610ee89291906149eb565b600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505060608401516040805160ff8c168152600b8b900b60208201526001600160a01b03808e169450928316928e16917fc0d5d3a6ac18cc1769788c925e6e7fc89cd47e4270a42884736fa9b3ec09f3a8910160405180910390a45050509695505050505050565b600080836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015610fbf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe3919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611025573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611049919061497a565b90506000816001600160a01b03166380f70cba84887feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc46040518463ffffffff1660e01b815260040161109d93929190614a04565b602060405180830381865afa1580156110ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110de9190614997565b90506000826001600160a01b03166380f70cba85897fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161113293929190614a04565b602060405180830381865afa15801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111739190614997565b9050602081901c63ffffffff1661118b8382896129aa565b955050505050505b92915050565b606060006111dd8885858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050866001600160a01b031681606001516001600160a01b0316036112445760405162461bcd60e51b815260206004820152601760248201527f4346413a20455f4e4f5f53454e4445525f43524541544500000000000000000060448201526064016105ec565b60008060006112588b8b866060015161047a565b925092509250611269826000611ad4565b6112b55760405162461bcd60e51b815260206004820152601e60248201527f4346413a20455f4e4f5f4f50455241544f525f4352454154455f464c4f57000060448201526064016105ec565b6000600b82900b60016001605f1b03146112d8576112d389836148b0565b6112da565b815b9050600081600b0b12156113005760405162461bcd60e51b81526004016105ec90614900565b61130c8c858584611b2f565b5050505061133a60408051608081018252600080825260208201819052918101829052606081019190915290565b6001600160a01b03808a168252888116602083015287166040820152600b86900b606082015261136c8186868561278d565b9998505050505050505050565b600080600080600061138b88886117e8565b9150915081156113c8578060200151600b0b8160000151876113ad9190614a28565b6113b79190614a67565b945080604001519350806060015192505b505093509350939050565b60008060008060006105218787611a8d565b606060006114298785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506118a192505050565b9050600061143c8888846060015161047a565b50915050600061144d826002611ad4565b90506109a360408051608081018252600080825260208201819052918101829052606081019190915290565b600080600080600061148f886106068989611a65565b805160208201516040830151606090930151919c909b50919950975095505050505050565b6000806114c184846117e8565b6020015195945050505050565b6000828260405160200161151b9291906060808252600c908201526b333637bba7b832b930ba37b960a11b60808201526001600160a01b0392831660208201529116604082015260a00190565b60405160208183030381529060405280519060200120905092915050565b6040805180820182526000808252602082018190529151636c2d9f2f60e01b8152306004820152602481018490526001604482015282906001600160a01b03861690636c2d9f2f90606401600060405180830381865afa1580156115a1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526115c99190810190614b5d565b90506115f1816000815181106115e1576115e1614bf7565b602002602001015160001c612a7f565b92509250505b9250929050565b6000806000836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa158015611641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611665919061497a565b90506000816001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cb919061497a565b90506000816001600160a01b03166380f70cba84887fe420d96e81cb4a6b2abb2366c4f93312d4e2ae878a7d4b22e73472fdad891f786040518463ffffffff1660e01b815260040161171f93929190614a04565b602060405180830381865afa15801561173c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117609190614997565b63ffffffff602082901c81169891169650945050505050565b600060016001605f1b038211156117d25760405162461bcd60e51b815260206004820152601b60248201527f4346413a206465706f736974206e756d62657220746f6f20626967000000000060448201526064016105ec565b63ffffffff198216915060006104c98484614c23565b60006117f26143cc565b604051634b61cc3360e01b81523060048201526001600160a01b038481166024830152600060448301819052600160648401529190861690634b61cc33906084015b600060405180830381865afa158015611851573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118799190810190614b5d565b90506115f18160008151811061189157611891614bf7565b602002602001015160001c612abf565b6118a96143f7565b336001600160a01b0316836001600160a01b03166320bc44256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611915919061497a565b6001600160a01b03161461195f5760405162461bcd60e51b81526020600482015260116024820152701d5b985d5d1a1bdc9a5e9959081a1bdcdd607a1b60448201526064016105ec565b604051632fd0a1cd60e21b8152339063bf4287349061198290859060040161460d565b602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614c47565b6119fd5760405162461bcd60e51b815260206004820152600b60248201526a0d2dcecc2d8d2c840c6e8f60ab1b60448201526064016105ec565b604051631fb6491d60e11b81523390633f6c923a90611a2090859060040161460d565b600060405180830381865afa158015611a3d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614ce9565b604080516001600160a01b03808516602083015283169181019190915260009060600161151b565b6000611a976143cc565b604051636c2d9f2f60e01b815230600482015260248101849052600160448201526000906001600160a01b03861690636c2d9f2f90606401611834565b600080826002811115611ae957611ae9614df0565b03611afa5750600182811614611193565b6001826002811115611b0e57611b0e614df0565b03611b215750600182811c811614611193565b505060021c60019081161490565b6040805180820190915260ff83168152600b82900b60208201526001600160a01b03851663a1b2bf8b85611b6284612934565b6040518363ffffffff1660e01b8152600401611b7f9291906149eb565b600060405180830381600087803b158015611b9957600080fd5b505af1158015611bad573d6000803e3d6000fd5b505050505050505050565b60606000611bc68884612b1f565b91505085611c115760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015611c5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7f9190614c47565b15611cdb57611cd488604001518960000151838a89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925060019150612c929050565b9150611d26565b611d238860000151828988888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a92506133af915050565b91505b8751611d329084613487565b509695505050505050565b6000611d677f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b031603611dbd5760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c6500000060448201526064016105ec565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614997565b611e27610bc5565b14611e805760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b60648201526084016105ec565b6001600160a01b0381163003611ed85760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f700000000000000060448201526064016105ec565b611f00817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc611f29610bc5565b604080519182526001600160a01b03841660208301520160405180910390a150565b60006001600160ff1b03821115611fb55760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016105ec565b5090565b600080611fc68587614e06565b90506000611fd48587614e47565b9050611fe08486614e75565b611fea8284614e47565b13979650505050505050565b6040805160c0810182526000808252602082018190529181018290526060818101839052608082019290925260a0810182905260208701516001600160a01b03166120795760405162461bcd60e51b81526020600482015260136024820152724346413a2073656e646572206973207a65726f60681b60448201526064016105ec565b60408701516001600160a01b03166120cb5760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b6120dd87602001518860400151611a65565b8082526020808901516001600160a01b03908116918401919091526040808a01518216908401526060808601519091169083015260006080830181905260a0808601519084015288519091829161213391611a8d565b915091508161217f5760405162461bcd60e51b815260206004820152601860248201527710d1904e88199b1bddc8191bd95cc81b9bdd08195e1a5cdd60421b60448201526064016105ec565b885160208a01516040808801519051633acd4df360e21b81526000936001600160a01b03169263eb3537cc926121cb926004016001600160a01b03929092168252602082015260400190565b606060405180830381865afa1580156121e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220c9190614941565b5050905089602001516001600160a01b031686606001516001600160a01b031614158015612254575089604001516001600160a01b031686606001516001600160a01b031614155b801561225e575088155b156123aa5760208a0151604051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa1580156122ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d19190614c47565b158015612349575060408a8101519051636b4f333560e01b81526001600160a01b0390911660048201523390636b4f333590602401602060405180830381865afa158015612323573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123479190614c47565b155b156123aa57600081126123aa5760405162461bcd60e51b815260206004820152602360248201527f4346413a2073656e646572206163636f756e74206973206e6f7420637269746960448201526218d85b60ea1b60648201526084016105ec565b60008112156123c8576123c88a600001518286858a6060015161359e565b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050505060208b015160608801519196506001600160a01b039081169116036124be5760408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061248b9190614c47565b156124af576124a88a604001518b600001518685898b6002612c92565b9450612780565b89516124a8908584888a6133af565b89604001516001600160a01b031686606001516001600160a01b0316036125f25760208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061254d9190614c47565b1561256a576124a88a602001518b600001518685898b6002612c92565b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156125b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d89190614c47565b156124af576124a860008b600001518685898b6002612c92565b60208a0151604051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561263c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126609190614c47565b801561266c5750600081125b156126e65760208a0151604051635b92108f60e11b8152339163b724211e9161269c918991600b90600401614e8c565b6000604051808303816000875af11580156126bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126e39190810190614eba565b94505b60408a8101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa158015612730573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127549190614c47565b15612771576124a88a604001518b600001518685898b6002612c92565b89516109d3908584888a6133af565b5050505095945050505050565b606060008061279c8785612b1f565b915091506000806127b1896000015185611a8d565b9150915081156128035760405162461bcd60e51b815260206004820152601760248201527f4346413a20666c6f7720616c726561647920657869737400000000000000000060448201526064016105ec565b6040898101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614c47565b156128ca576128c389604001518a6000015185848c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508f93509150612c929050565b9450612915565b612912896000015184838b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508d92506133af915050565b94505b88516129219087613487565b50505050949350505050565b60f8161590565b606060008260200151600b0b121561294e5761294e614eef565b60408051600180825281830190925290602080830190803683370190505090508160200151600b0b6080836000015160ff16901b1760001b8160008151811061299957612999614bf7565b602002602001018181525050919050565b60008082600b0b13612a0a5760405162461bcd60e51b815260206004820152602360248201527f4346413a206e6f7420666f72206e6f6e2d706f73697469766520666c6f77207260448201526261746560e81b60648201526084016105ec565b60016001605f1b03612a2084600b85900b614f05565b1115612a675760405162461bcd60e51b81526020600482015260166024820152754346413a20666c6f77207261746520746f6f2062696760501b60448201526064016105ec565b6000612a7383856137aa565b90506104e285826137ee565b6040805180820190915260008082526020820152811580159190612aba5760016001605f1b038316600b0b6020820152608083901c60ff1681525b915091565b6000612ac96143cc565b821580159250612aba5760e083901c8152608083901c6bffffffffffffffffffffffff16600b0b6020808301919091526bffffffffffffffff0000000084821c811660408401529084901b166060820152915091565b6040805160c08101825260008082526020820181905291810182905260608082018390526080820183905260a082015260408401516001600160a01b0316612ba15760405162461bcd60e51b81526020600482015260156024820152744346413a207265636569766572206973207a65726f60581b60448201526064016105ec565b612bb384602001518560400151611a65565b8082526020808601516001600160a01b0390811691840182905260408088015182169085018190526060808801519092168286015290870151600b0b608085015260a0808701519085015291935003612c425760405162461bcd60e51b81526020600482015260116024820152704346413a206e6f2073656c6620666c6f7760781b60448201526064016105ec565b60008160800151600b0b136115f75760405162461bcd60e51b81526020600482015260166024820152754346413a20696e76616c696420666c6f77207261746560501b60448201526064016105ec565b82612c9b614452565b6001600160a01b03891615612e84576000612d30898b8a600001518b602001518c60400151604051602001612ce69291906001600160a01b0392831681529116602082015260400190565b60408051601f1981840301815260e08301825260006080840181905260a0840181905260c08401526001600160a01b03958616835293909416602082015292830152606082015290565b90506000846002811115612d4657612d46614df0565b03612d5b5764010000000060c0820152612d90565b6001846002811115612d6f57612d6f614df0565b03612d845764040000000060c0820152612d90565b64100000000060c08201525b612d9a8187613804565b82526040850151610140860151612db491908b8b8b6139bb565b506080830152508451612dc8906001614f24565b60ff168160800151612dda9190614f05565b60808201526060870151612ded90611f4b565b60a08201526000846002811115612e0657612e06614df0565b03612e1b5764020000000060c0820152612e50565b6001846002811115612e2f57612e2f614df0565b03612e445764080000000060c0820152612e50565b64200000000060c08201525b612e5f81836000015185613d9f565b60408401919091528851909350612e77908a90611a8d565b602084015250612ea29050565b612e9a84604001518561014001518a8a8a6139bb565b602084015250505b6000816040015161010001511315612ee157612ed6612ed1612ecc83604001516101000151614008565b61405a565b611f4b565b604082015161010001525b6000612ef08760600151611f4b565b82604001516101000151612f049190614a28565b9050612f2a81612f1b846020015160400151611f4b565b612f259190614e06565b614008565b82602001516040018181525050612f4c81612f1b846020015160600151611f4b565b60208301805160600191909152885190516001600160a01b038b169163a1b2bf8b91612f779061408e565b6040518363ffffffff1660e01b8152600401612f949291906149eb565b600060405180830381600087803b158015612fae57600080fd5b505af1158015612fc2573d6000803e3d6000fd5b50505050612fde89896020015160008460008a604001516140ff565b50612ff6898960400151600080858a604001516140ff565b506101408501516001600160a01b031615806130285750886001600160a01b03168561014001516001600160a01b0316145b156130a657602082015160409081015190516303c9790560e11b81523391630792f20a9161305c9187918690600401614f49565b6000604051808303816000875af115801561307b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526130a39190810190614eba565b92505b6040888101519051631e51d6a760e11b81526001600160a01b0390911660048201523390633ca3ad4e90602401602060405180830381865afa1580156130f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131149190614c47565b156133a257604088810151868201519151633acd4df360e21b81526001600160a01b0391821660048201526024810192909252600091908b169063eb3537cc90604401606060405180830381865afa158015613174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131989190614941565b509091505060008112156133a05760028560028111156131ba576131ba614df0565b03613345576040808a01519051635b92108f60e11b8152339163b724211e916131ea918891600c90600401614e8c565b6000604051808303816000875af1158015613209573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132319190810190614eba565b9350600061325961324183614f6e565b613254600061324f87614f6e565b61426b565b61427a565b90508a6001600160a01b031663cf97256d8b602001518361327990614f6e565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156132bf57600080fd5b505af11580156132d3573d6000803e3d6000fd5b5050505060408a810151905163cf97256d60e01b81526001600160a01b03918216600482015260248101839052908c169063cf97256d90604401600060405180830381600087803b15801561332757600080fd5b505af115801561333b573d6000803e3d6000fd5b50505050506133a0565b60405162461bcd60e51b815260206004820152602a60248201527f4346413a204150505f52554c455f4e4f5f435249544943414c5f524543454956604482015269115497d050d0d3d5539560b21b60648201526084016105ec565b505b5050979650505050505050565b606083810151156133c2576133c2614eef565b60006133cc6143cc565b6133e284604001518561014001518a8a8a6139bb565b6101408701519294509250506001600160a01b03808a169116036134785760408082015190516303c9790560e11b81523391630792f20a9161342a9189918790600401614f49565b6000604051808303816000875af1158015613449573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526134719190810190614eba565b925061347c565b8492505b505095945050505050565b602081015160ff1660031415806134b55750816001600160a01b03168161014001516001600160a01b031614155b1561359a5760608101516040808301519051633acd4df360e21b81526001600160a01b039283166004820152602481019190915260009184169063eb3537cc90604401606060405180830381865afa158015613515573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135399190614941565b5050905060008112156135985760405162461bcd60e51b815260206004820152602160248201527f4346413a206e6f7420656e6f75676820617661696c61626c652062616c616e636044820152606560f81b60648201526084016105ec565b505b5050565b60006135ae8685602001516117e8565b91505060006135c08460400151611f4b565b905060006135d18360400151611f4b565b905060606000806135e2848b614e06565b90506000806135f08d6115fe565b915091506136008c878484611fb9565b93505050600081126136eb576000846136198388614a67565b6136239190614e47565b9050600183613633576001613636565b60005b6040805160ff9384166020820152929091169082015260600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b878f6020015161368588614008565b61369189600019614a67565b6040518863ffffffff1660e01b81526004016136b39796959493929190614f8a565b600060405180830381600087803b1580156136cd57600080fd5b505af11580156136e1573d6000803e3d6000fd5b505050505061379d565b6040805160016020820152600291810191909152859060600160405160208183030381529060405293508b6001600160a01b0316631863e8098b60000151868b60008f6020015161373b88614008565b6137478a600019614a67565b6040518863ffffffff1660e01b81526004016137699796959493929190614f8a565b600060405180830381600087803b15801561378357600080fd5b505af1158015613797573d6000803e3d6000fd5b50505050505b5050505050505050505050565b600082600b0b6000036137bf57506000611193565b60016001605f1b038211156137d6576137d6614eef565b6137e08284614fd7565b600b0b90506108c08161405a565b60008183116137fd57816108c0565b5090919050565b6020820151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613858573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061387c9190615071565b9194509250905082801561388e575081155b156139b257600061389f868861428f565b90508660c0015182166000036139a45760006138be8860c0015161430d565b88516040808b015160608c0151825160008152602081019093526138ea939230929190604481016150ad565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918a015160c08b01519251633a020f0160e11b815291935033926374041e029261395992918691641000000000919091149088906004016150f2565b6000604051808303816000875af1158015613978573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526139a09190810190614eba565b9550505b6139af8660006143a4565b50505b50505092915050565b6000806139c66143cc565b60008060006139d4896115fe565b5090506000336001600160a01b031663289b3c0d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a3b919061497a565b60405163407b865d60e11b81529091506001600160a01b038216906380f70cba90613a8e9033908e907feae305fa863b373417e615b1044222e2806cefc7788d169ce6748a443c3f6cc490600401614a04565b602060405180830381865afa158015613aab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613acf9190614997565b9250613adf8960800151836137aa565b95505050613af08660600151611f4b565b613afd8760400151611f4b565b613b0686611f4b565b613b109190614a28565b613b1a9190614e06565b9450613b2d85612f1b8860400151611f4b565b91508082108015613b45575060008760800151600b0b135b15613b8757613b578660600151611f4b565b613b648760400151611f4b565b613b6d83611f4b565b613b779190614a28565b613b819190614e06565b94508091505b6001600160a01b03891615801590613bb15750876001600160a01b0316896001600160a01b031614155b15613bbb57600093505b604051806080016040528060008960800151600b0b13613bdc576000613bde565b8b5b81526020018860800151600b0b815260200183815260200187606001518152509250876001600160a01b031663a1b2bf8b8860000151613c1d8661408e565b6040518363ffffffff1660e01b8152600401613c3a9291906149eb565b600060405180830381600087803b158015613c5457600080fd5b505af1158015613c68573d6000803e3d6000fd5b505060408051808201909152600080825260208201529250613c88915050565b613cae88886020015189608001518960200151613ca591906148b0565b8860008f6140ff565b600b0b8152604087015160208701516080890151613cdd928b929091613cd491906148b0565b6000808f6140ff565b600b0b60208083018290526040808a0151918a015160808b0151855160a08d015193516001600160a01b0395861696938616958f16947f57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e94613d4394939290919061513b565b60405180910390a486606001516001600160a01b03167f71e0c98e270fc3084227b473f176924d5303ece8c639e679998a2d7dc8e70f7483604051613d8a91815260200190565b60405180910390a25050955095509592505050565b613da76143f7565b6020840151604051633e7d48bd60e21b81526001600160a01b03909116600482015260609060009081908190339063f9f522f490602401606060405180830381865afa158015613dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e1f9190615071565b88965091945092509050828015613e34575081155b15613ffd57613e43848961428f565b93508760c001518116600003613feb576000613e628960c0015161430d565b89516040808c015160608d015182516000815260208101909352613e909392309291908e9060448101615173565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b031990951694909417909352918b015160c08c0151925163079b42a160e21b81529193503392631e6d0a8492613eff9291869164200000000091909114908b906004016150f2565b6000604051808303816000875af1158015613f1e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613f469190810190614eba565b604051631fb6491d60e11b81529095503390633f6c923a90613f6c90889060040161460d565b600060405180830381865afa158015613f89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613fb19190810190614ce9565b9550613fe3600061324f613fc88c60800151611f4b565b613254613fd88b60e00151611f4b565b8b610100015161426b565b610100870152505b613ffa868661010001516143a4565b93505b505050935093915050565b600080821215611fb55760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f73697469766560448201526064016105ec565b60008063ffffffff831661406f576000614072565b60015b60ff16905060206140858285831c6151cc565b901b9392505050565b6040805160018082528183019092526060916020808301908036833701905050905060208260600151901c604060208460400151901c901b608084602001516bffffffffffffffffffffffff16901b60e08560000151901b17171760001b8160008151811061299957612999614bf7565b60008061410c88886117e8565b91505060008160200151600b0b61412c836000015186612ed19190614e75565b6141369190614a67565b905080156141a15760405163cf97256d60e01b81526001600160a01b038981166004830152602482018390528a169063cf97256d90604401600060405180830381600087803b15801561418857600080fd5b505af115801561419c573d6000803e3d6000fd5b505050505b8682602001516141b191906151e4565b600b0b602083015283825260408201516141d0908790612f1b90611f4b565b604083015260608201516141e9908690612f1b90611f4b565b60608301526001600160a01b03891663090c415e8960006142098661408e565b6040518463ffffffff1660e01b815260040161422793929190615233565b600060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b5050506020909201519998505050505050505050565b60008183136137fd57816108c0565b600081831361428957826108c0565b50919050565b6020810151608082015160a08301518351604051630768fabb60e41b8152606094339463768fabb0946142c6948a9460040161525a565b6000604051808303816000875af11580156142e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108c09190810190614eba565b6000640100000000820361432957506330d9c91560e01b919050565b64040000000082036143435750630221347d60e61b919050565b641000000000820361435d5750635f9e7d7760e01b919050565b6402000000008203614377575063d86ed3e560e01b919050565b6408000000008203614391575063230dbd2960e01b919050565b506353c11f9960e01b919050565b919050565b604051634c4d861f60e11b8152606090339063989b0c3e906142c6908690869060040161529f565b6040518060800160405280600081526020016000600b0b815260200160008152602001600081525090565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b60405180606001604052806060815260200161446c6143cc565b81526020016144796143f7565b905290565b6001600160a01b03811681146107ed57600080fd5b6000806000606084860312156144a857600080fd5b83356144b38161447e565b925060208401356144c38161447e565b915060408401356144d38161447e565b809150509250925092565b600080604083850312156144f157600080fd5b82356144fc8161447e565b946020939093013593505050565b60008083601f84011261451c57600080fd5b50813567ffffffffffffffff81111561453457600080fd5b6020830191508360208285010111156115f757600080fd5b6000806000806060858703121561456257600080fd5b843561456d8161447e565b9350602085013561457d8161447e565b9250604085013567ffffffffffffffff81111561459957600080fd5b6145a58782880161450a565b95989497509550505050565b60005b838110156145cc5781810151838201526020016145b4565b838111156145db576000848401525b50505050565b600081518084526145f98160208601602086016145b1565b601f01601f19169290920160200192915050565b6020815260006108c060208301846145e1565b6000806040838503121561463357600080fd5b823561463e8161447e565b9150602083013561464e8161447e565b809150509250929050565b8035600b81900b811461439f57600080fd5b60008060008060008060a0878903121561468457600080fd5b863561468f8161447e565b9550602087013561469f8161447e565b945060408701356146af8161447e565b93506146bd60608801614659565b9250608087013567ffffffffffffffff8111156146d957600080fd5b6146e589828a0161450a565b979a9699509497509295939492505050565b60006020828403121561470957600080fd5b81356108c08161447e565b60008060006060848603121561472957600080fd5b83356147348161447e565b925060208401356147448161447e565b929592945050506040919091013590565b60008060008060006080868803121561476d57600080fd5b85356147788161447e565b945060208601356147888161447e565b935060408601356147988161447e565b9250606086013567ffffffffffffffff8111156147b457600080fd5b6147c08882890161450a565b969995985093965092949392505050565b6000806000806000608086880312156147e957600080fd5b85356147f48161447e565b945060208601356148048161447e565b935061479860408701614659565b60ff811681146107ed57600080fd5b60008060008060008060a0878903121561483a57600080fd5b86356148458161447e565b955060208701356148558161447e565b945060408701356146af81614812565b6000806040838503121561487857600080fd5b82356148838161447e565b915061489160208401614659565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b600081600b0b83600b0b600081128160016001605f1b0319018312811516156148db576148db61489a565b8160016001605f1b030183138116156148f6576148f661489a565b5090039392505050565b60208082526021908201527f4346413a20455f4558434545445f464c4f575f524154455f414c4c4f57414e436040820152604560f81b606082015260800190565b60008060006060848603121561495657600080fd5b8351925060208401519150604084015190509250925092565b805161439f8161447e565b60006020828403121561498c57600080fd5b81516108c08161447e565b6000602082840312156149a957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156149e0578151875295820195908201906001016149c4565b509495945050505050565b8281526040602082015260006104c960408301846149b0565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60008083128015600160ff1b850184121615614a4657614a4661489a565b6001600160ff1b0384018313811615614a6157614a6161489a565b50500390565b60006001600160ff1b0381841382841380821686840486111615614a8d57614a8d61489a565b600160ff1b6000871282811687830589121615614aac57614aac61489a565b60008712925087820587128484161615614ac857614ac861489a565b87850587128184161615614ade57614ade61489a565b505050929093029392505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614b2657614b26614aec565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715614b5557614b55614aec565b604052919050565b60006020808385031215614b7057600080fd5b825167ffffffffffffffff80821115614b8857600080fd5b818501915085601f830112614b9c57600080fd5b815181811115614bae57614bae614aec565b8060051b9150614bbf848301614b2c565b8181529183018401918481019088841115614bd957600080fd5b938501935b83851015610ce857845182529385019390850190614bde565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601260045260246000fd5b600082614c3257614c32614c0d565b500490565b8051801515811461439f57600080fd5b600060208284031215614c5957600080fd5b6108c082614c37565b805161439f81614812565b80516001600160e01b03198116811461439f57600080fd5b600082601f830112614c9657600080fd5b815167ffffffffffffffff811115614cb057614cb0614aec565b614cc3601f8201601f1916602001614b2c565b818152846020838601011115614cd857600080fd5b6104c98260208301602087016145b1565b600060208284031215614cfb57600080fd5b815167ffffffffffffffff80821115614d1357600080fd5b908301906101608286031215614d2857600080fd5b614d30614b02565b614d3983614c62565b8152614d4760208401614c62565b602082015260408301516040820152614d626060840161496f565b6060820152614d7360808401614c6d565b608082015260a083015182811115614d8a57600080fd5b614d9687828601614c85565b60a08301525060c083015160c082015260e083015160e0820152610100915081830151828201526101209150614dcd82840161496f565b828201526101409150614de182840161496f565b91810191909152949350505050565b634e487b7160e01b600052602160045260246000fd5b600080821280156001600160ff1b0384900385131615614e2857614e2861489a565b600160ff1b8390038412811615614e4157614e4161489a565b50500190565b600082614e5657614e56614c0d565b600160ff1b821460001984141615614e7057614e7061489a565b500590565b600082821015614e8757614e8761489a565b500390565b606081526000614e9f60608301866145e1565b6001600160a01b039490941660208301525060400152919050565b600060208284031215614ecc57600080fd5b815167ffffffffffffffff811115614ee357600080fd5b6104c984828501614c85565b634e487b7160e01b600052600160045260246000fd5b6000816000190483118215151615614f1f57614f1f61489a565b500290565b600060ff821660ff84168060ff03821115614f4157614f4161489a565b019392505050565b606081526000614f5c60608301866145e1565b60208301949094525060400152919050565b6000600160ff1b8201614f8357614f8361489a565b5060000390565b87815260e060208201526000614fa360e08301896145e1565b6001600160a01b03978816604084015295151560608301525092909416608083015260a082015260c0019190915292915050565b600081600b0b83600b0b60016001605f1b036000821360008413838304851182821616156150075761500761489a565b6b7fffffffffffffffffffffff19600085128281168783058712161561502f5761502f61489a565b6000871292508582058712848416161561504b5761504b61489a565b858505871281841616156150615761506161489a565b5050509290910295945050505050565b60008060006060848603121561508657600080fd5b61508f84614c37565b925061509d60208501614c37565b9150604084015190509250925092565b6001600160a01b038681168252851660208201526040810184905260a0606082018190526000906150e0908301856145e1565b8281036080840152610ce881856145e1565b6001600160a01b0385168152608060208201819052600090615116908301866145e1565b8415156040840152828103606084015261513081856145e1565b979650505050505050565b84600b0b815283600b0b602082015282600b0b604082015260806060820152600061516960808301846145e1565b9695505050505050565b6001600160a01b038781168252861660208201526040810185905260c0606082018190526000906151a6908301866145e1565b82810360808401526151b881866145e1565b905082810360a084015261136c81856145e1565b600082198211156151df576151df61489a565b500190565b600081600b0b83600b0b600082128260016001605f1b030382138115161561520e5761520e61489a565b8260016001605f1b031903821281161561522a5761522a61489a565b50019392505050565b60018060a01b03841681528260208201526060604082015260006104e260608301846149b0565b60a08152600061526d60a08301886145e1565b6001600160a01b0396871660208401526040830195909552506060810192909252909216608090920191909152919050565b6040815260006152b260408301856145e1565b9050826020830152939250505056fea264697066735822122076418c61ebec88bbc869733ccd3b7d51db9ab7eb6cf6426c327d897e84c12dbb64736f6c634300080e0033",
904
904
  "immutableReferences": {
905
905
  "4332": [
906
906
  {
@@ -30250,7 +30250,7 @@
30250
30250
  ],
30251
30251
  "sourceMap": "824:56343:32:-:0;;;3209:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;456:12:30;;;824:56343:32;;14:311:105;105:6;158:2;146:9;137:7;133:23;129:32;126:52;;;174:1;171;164:12;126:52;200:16;;-1:-1:-1;;;;;245:31:105;;235:42;;225:70;;291:1;288;281:12;225:70;314:5;14:311;-1:-1:-1;;;14:311:105:o;:::-;824:56343:32;;;;;;;;;;;;",
30252
30252
  "deployedSourceMap": "824:56343:32:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28357:533;;;;;;:::i;:::-;;:::i;:::-;;;;976:25:105;;;1049:4;1037:17;;;1032:2;1017:18;;1010:45;1102:2;1091:22;1071:18;;;1064:50;964:2;949:18;28357:533:32;;;;;;;;1931:74;;1996:7;1931:74;;;;;1271:25:105;;;1259:2;1244:18;1931:74:32;1125:177:105;5536:326:32;;;;;;:::i;:::-;;:::i;:::-;;;1842:2:105;1831:22;;;;1813:41;;1801:2;1786:18;5536:326:32;1671:189:105;27944:334:32;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;28973:421::-;;;;;;:::i;:::-;;:::i;:::-;;;;4276:4:105;4264:17;;;4246:36;;4329:2;4318:22;;;;4313:2;4298:18;;4291:50;4219:18;28973:421:32;4080:267:105;11614:488:32;;;;;;:::i;:::-;;:::i;:::-;;;;5034:25:105;;;5106:2;5095:22;;;;5090:2;5075:18;;5068:50;5134:18;;;5127:34;5192:2;5177:18;;5170:34;5021:3;5006:19;11614:488:32;4807:403:105;2158:76:32;;-1:-1:-1;;;;;2158:76:32;;23083:1953;;;;;;:::i;:::-;;:::i;632:191:30:-;;;;;;:::i;:::-;;:::i;:::-;;7040:753:32;;;;;;:::i;:::-;;:::i;:::-;;;7322:14:105;;7315:22;7297:41;;7285:2;7270:18;7040:753:32;7157:187:105;25116:855:32;;;;;;:::i;:::-;;:::i;6662:372::-;;;;;;:::i;:::-;;:::i;:::-;;;;8454:14:105;;8447:22;8429:41;;8501:2;8486:18;;8479:34;;;;8402:18;6662:372:32;8261:258:105;8578:863:32;;;;;;:::i;:::-;;:::i;400:122:93:-;;;:::i;:::-;;;-1:-1:-1;;;;;9511:32:105;;;9493:51;;9481:2;9466:18;400:122:93;9347:203:105;481:145:30;;;:::i;27426:425:32:-;;;;;;:::i;:::-;;:::i;7863:645::-;;;;;;:::i;:::-;;:::i;405:161:39:-;488:71;405:161;;26060:1270:32;;;;;;:::i;:::-;;:::i;5953:703::-;;;;;;:::i;:::-;;:::i;21305:1698::-;;;;;;:::i;:::-;;:::i;3532:536::-;;;;;;:::i;:::-;;:::i;:::-;;;;11383:25:105;;;11439:2;11424:18;;11417:34;;;;11467:18;;;11460:34;11371:2;11356:18;3532:536:32;11183:317:105;11006:530:32;;;;;;:::i;:::-;;:::i;9511:791::-;;;;;;:::i;:::-;;:::i;10369:570::-;;;;;;:::i;:::-;;:::i;12172:263::-;;;;;;:::i;:::-;;:::i;28357:533::-;28523:22;28547:17;28566:23;28622:45;28646:6;28654:12;28622:23;:45::i;:::-;28605:62;;28680:40;28724:43;28745:5;28752:14;28724:20;:43::i;:::-;28791:28;;28849:34;;;;;28357:533;;28791:28;;-1:-1:-1;28849:34:32;;-1:-1:-1;28357:533:32;;-1:-1:-1;;;;;28357:533:32:o;5536:326::-;5685:14;5718:25;5749:21;5764:5;5749:14;:21::i;:::-;5717:53;;;5792:62;5827:17;5846:7;5792:34;:62::i;:::-;5781:73;5536:326;-1:-1:-1;;;;5536:326:32:o;27944:334::-;28125:19;28210:61;28240:5;28247:12;28261:1;28264;28267:3;;28210:29;:61::i;:::-;28201:70;27944:334;-1:-1:-1;;;;;27944:334:32:o;28973:421::-;29123:17;29142:23;29184:40;29228:43;29249:5;29256:14;29228:20;:43::i;:::-;29295:28;;29353:34;;;;;29295:28;;29353:34;;-1:-1:-1;28973:421:32;-1:-1:-1;;;;;28973:421:32:o;11614:488::-;11766:17;11797:14;11825:15;11854:19;11892:21;11917:36;11938:5;11945:7;11917:20;:36::i;:::-;11984:15;;12013:14;;;;12041:13;;;;12068:17;;;;;11984:15;;12013:14;;-1:-1:-1;12041:13:32;;-1:-1:-1;12068:17:32;-1:-1:-1;11614:488:32;-1:-1:-1;;;;;11614:488:32:o;23083:1953::-;23295:19;23330:41;23374:49;23412:5;23419:3;;23374:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23374:37:32;;-1:-1:-1;;;23374:49:32:i;:::-;23330:93;;23469:6;-1:-1:-1;;;;;23441:34:32;:14;:24;;;-1:-1:-1;;;;;23441:34:32;;23433:70;;;;-1:-1:-1;;;23433:70:32;;11707:2:105;23433:70:32;;;11689:21:105;11746:2;11726:18;;;11719:30;11785:25;11765:18;;;11758:53;11828:18;;23433:70:32;;;;;;;;;23547:10;23559:27;23590:59;23608:5;23615:33;23631:6;23639:8;23615:15;:33::i;:::-;23590:17;:59::i;:::-;23546:103;;;;23753:22;23793:17;23828:23;23868:60;23888:5;23895:6;23903:14;:24;;;23868:19;:60::i;:::-;23735:193;;;;;;23967:75;24002:11;24015:26;23967:34;:75::i;:::-;23942:159;;;;-1:-1:-1;;;23942:159:32;;12059:2:105;23942:159:32;;;12041:21:105;12098:2;12078:18;;;12071:30;12137:27;12117:18;;;12110:55;12182:18;;23942:159:32;11857:349:105;23942:159:32;24200:30;24233:36;;;;-1:-1:-1;;;;;24233:36:32;;:72;;;24297:8;24273:32;;:11;:20;;;:32;;;;24233:72;:180;;24392:20;;;;24381:31;;:8;:31;:::i;:::-;24360:53;;:17;:53;:::i;:::-;24233:180;;;24324:17;24233:180;24200:213;;24463:1;24435:24;:29;;;;24427:75;;;;-1:-1:-1;;;24427:75:32;;;;;;;:::i;:::-;24516:86;24541:5;24548:14;24564:11;24577:24;24516;:86::i;:::-;23660:953;;;;24637:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24637:45:32;-1:-1:-1;;;;;24696:22:32;;;;;24732:24;;;:15;;;:24;24770:28;;:17;;;:28;24812;;;;:17;;;:28;24863:156;24696:8;24918:11;24947:5;24970:3;;24991:14;24863:11;:156::i;:::-;24854:165;23083:1953;-1:-1:-1;;;;;;;;;;;23083:1953:32:o;632:191:30:-;720:10;-1:-1:-1;;;;;734:5:30;720:19;;712:57;;;;-1:-1:-1;;;712:57:30;;13333:2:105;712:57:30;;;13315:21:105;13372:2;13352:18;;;13345:30;13411:27;13391:18;;;13384:55;13456:18;;712:57:30;13131:349:105;712:57:30;786:30;805:10;786:18;:30::i;:::-;632:191;:::o;7040:753:32:-;7249:43;;-1:-1:-1;;;7249:43:32;;-1:-1:-1;;;;;13677:32:105;;;7249:43:32;;;13659:51:105;13726:18;;;13719:34;;;7198:4:32;;;;7249:23;;;;;13632:18:105;;7249:43:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7218:74;;;;7326:1;7306:16;:21;7302:63;;7350:4;7343:11;;;;;7302:63;7376:25;7403:23;7430:21;7445:5;7430:14;:21::i;:::-;7375:76;;;;7463:34;7501:36;7522:5;7529:7;7501:20;:36::i;:::-;7461:76;;;7547:28;7578:37;:18;:26;;;:35;:37::i;:::-;7547:68;;7633:153;7665:16;7695:21;7730:17;7761:15;7633:18;:153::i;:::-;7626:160;;;;;;;7040:753;;;;;;:::o;25116:855::-;25304:19;25339:41;25383:49;25421:5;25428:3;;25383:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25383:37:32;;-1:-1:-1;;;25383:49:32:i;:::-;25339:93;;25444:17;25466:60;25486:5;25493:6;25501:14;:24;;;25466:19;:60::i;:::-;25442:84;;;;25536:19;25558:75;25593:11;25606:26;25558:34;:75::i;:::-;25536:97;;25651:14;25643:52;;;;-1:-1:-1;;;25643:52:32;;14276:2:105;25643:52:32;;;14258:21:105;14315:2;14295:18;;;14288:30;14354:27;14334:18;;;14327:55;14399:18;;25643:52:32;14074:349:105;25643:52:32;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25706:45:32;-1:-1:-1;;;;;25761:22:32;;;;;25793:24;;;:15;;;:24;25827:28;;:17;;;:28;25761:14;25865:17;;;:21;25906:58;25761:8;25928:14;25944:3;;25949:14;25906:11;:58::i;:::-;25897:67;25116:855;-1:-1:-1;;;;;;;;;;25116:855:32:o;6662:372::-;6796:31;6829:17;6862:16;6893:5;-1:-1:-1;;;;;6893:13:32;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6862:47;;6931:4;-1:-1:-1;;;;;6931:11:32;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6919:25;;6983:44;7001:5;7008:7;7017:9;6983:17;:44::i;:::-;6954:73;;6852:182;6662:372;;;;;:::o;8578:863::-;8764:19;8799:41;8843:49;8881:5;8888:3;;8843:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8843:37:32;;-1:-1:-1;;;8843:49:32:i;:::-;8799:93;;8903:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8903:45:32;-1:-1:-1;;;;;8958:22:32;;;;;9008:24;;;;;8990:42;;:15;;;:42;;;9042:28;;;-1:-1:-1;9042:17:32;;:28;;;9080;;;;:17;;;:28;;;;8958:14;;9136:51;;:15;:51::i;:::-;9119:68;;9198:10;9210:27;9241:41;9259:8;:14;;;9275:6;9241:17;:41::i;:::-;9197:85;;;;9302:132;9327:8;9349:11;9374:5;9393:3;;9410:14;9302:11;:132::i;400:122:93:-;447:19;489:26;751:20:95;745:27;;618:170;489:26:93;482:33;;400:122;:::o;481:145:30:-;552:7;598:4;-1:-1:-1;;;;;582:35:30;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;27426:425:32:-;27610:19;27654:190;27697:5;27716:12;4923:96:42;-1:-1:-1;;;;;27831:3:32;;27654:29;:190::i;7863:645::-;8049:19;8084:41;8128:49;8166:5;8173:3;;8128:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8128:37:32;;-1:-1:-1;;;8128:49:32:i;:::-;8084:93;;8188:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8188:45:32;-1:-1:-1;;;;;8243:22:32;;;;;8293:24;;;;;8275:42;;:15;;;:42;8327:28;;;-1:-1:-1;8327:17:32;;:28;8365;;;;:17;;;:28;8413:88;8243:8;8460:3;;8293:14;8413:11;:88::i;:::-;8404:97;7863:645;-1:-1:-1;;;;;;;;7863:645:32:o;26060:1270::-;26297:19;26337:3;;26328:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26328:12:32;;-1:-1:-1;26358:55:32;;-1:-1:-1;26401:11:32;;-1:-1:-1;26358:42:32;;-1:-1:-1;26358:55:32:i;:::-;26350:92;;;;-1:-1:-1;;;26350:92:32;;15443:2:105;26350:92:32;;;15425:21:105;15482:2;15462:18;;;15455:30;15521:26;15501:18;;;15494:54;15565:18;;26350:92:32;15241:348:105;26350:92:32;26452:41;26496:49;26534:5;26541:3;;26496:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26496:37:32;;-1:-1:-1;;;26496:49:32:i;:::-;26452:93;;26731:12;-1:-1:-1;;;;;26703:40:32;:14;:24;;;-1:-1:-1;;;;;26703:40:32;;26695:83;;;;-1:-1:-1;;;26695:83:32;;15796:2:105;26695:83:32;;;15778:21:105;15835:2;15815:18;;;15808:30;15874:32;15854:18;;;15847:60;15924:18;;26695:83:32;15594:354:105;26695:83:32;26817:1;26796:17;:22;;;;26788:63;;;;-1:-1:-1;;;26788:63:32;;16155:2:105;26788:63:32;;;16137:21:105;16194:2;16174:18;;;16167:30;16233;16213:18;;;16206:58;16281:18;;26788:63:32;15953:352:105;26788:63:32;-1:-1:-1;;;;;;;;;26911:42:32;;;;;26963:54;;;;-1:-1:-1;;;26963:54:32;27076:24;;;;-1:-1:-1;;27052:63:32;;27102:12;27052:23;:63::i;:::-;27027:88;;27125:5;-1:-1:-1;;;;;27125:25:32;;27151:14;27167:41;27191:16;27167:23;:41::i;:::-;27125:84;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;27252:24:32;;;;27225:98;;;4276:4:105;4264:17;;4246:36;;4329:2;4318:22;;;4313:2;4298:18;;4291:50;-1:-1:-1;;;;;27225:98:32;;;;-1:-1:-1;27225:98:32;;;;;;;;;4219:18:105;27225:98:32;;;;;;;26318:1012;;;26060:1270;;;;;;;;:::o;5953:703::-;6101:15;6134:16;6165:5;-1:-1:-1;;;;;6165:13:32;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6134:47;;6192:25;6242:4;-1:-1:-1;;;;;6242:18:32;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6192:71;;6274:22;6299:3;-1:-1:-1;;;;;6299:22:32;;6322:4;6328:5;2458:71;6299:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6274:92;;6377:17;6397:3;-1:-1:-1;;;;;6397:22:32;;6420:4;6426:5;2297:88;6397:57;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6377:77;-1:-1:-1;8790:2:42;8777:15;;;8796:16;8776:36;6569:79:32;6604:14;8776:36:42;6639:8:32;6569:34;:79::i;:::-;6562:86;;;;;;;5953:703;;;;;:::o;21305:1698::-;21517:19;21552:41;21596:49;21634:5;21641:3;;21596:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21596:37:32;;-1:-1:-1;;;21596:49:32:i;:::-;21552:93;;21691:6;-1:-1:-1;;;;;21663:34:32;:14;:24;;;-1:-1:-1;;;;;21663:34:32;;21655:70;;;;-1:-1:-1;;;21655:70:32;;18021:2:105;21655:70:32;;;18003:21:105;18060:2;18040:18;;;18033:30;18099:25;18079:18;;;18072:53;18142:18;;21655:70:32;17819:347:105;21655:70:32;21829:22;21869:17;21904:23;21944:60;21964:5;21971:6;21979:14;:24;;;21944:19;:60::i;:::-;21811:193;;;;;;22043:75;22078:11;22091:26;22043:34;:75::i;:::-;22018:164;;;;-1:-1:-1;;;22018:164:32;;18373:2:105;22018:164:32;;;18355:21:105;18412:2;18392:18;;;18385:30;18451:32;18431:18;;;18424:60;18501:18;;22018:164:32;18171:354:105;22018:164:32;22281:30;22314:36;;;;-1:-1:-1;;;;;22314:36:32;:119;;22405:28;22425:8;22405:17;:28;:::i;:::-;22314:119;;;22369:17;22314:119;22281:152;;22483:1;22455:24;:29;;;;22447:75;;;;-1:-1:-1;;;22447:75:32;;;;;;;:::i;:::-;22536:86;22561:5;22568:14;22584:11;22597:24;22536;:86::i;:::-;21736:897;;;;22656:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22656:45:32;-1:-1:-1;;;;;22715:22:32;;;;;22751:24;;;:15;;;:24;22789:28;;:17;;;:28;22831;;;;:17;;;:28;22882:104;22715:8;22937:3;;22958:14;22882:11;:104::i;:::-;22873:113;21305:1698;-1:-1:-1;;;;;;;;;21305:1698:32:o;3532:536::-;3708:21;3731:15;3748:19;3784:10;3796:21;3821:36;3842:5;3849:7;3821:20;:36::i;:::-;3783:74;;;;3870:5;3867:195;;;3954:5;:14;;;3909:59;;3933:5;:15;;;3917:4;3910:40;;;;:::i;:::-;3909:59;;;;:::i;:::-;3891:78;;3993:5;:13;;;3983:23;;4034:5;:17;;;4020:31;;3867:195;3773:295;;3532:536;;;;;;;:::o;11006:530::-;11165:17;11196:14;11224:15;11253:19;11300:20;11324:66;11355:5;11374:6;11324:17;:66::i;9511:791::-;9697:19;9732:41;9776:49;9814:5;9821:3;;9776:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9776:37:32;;-1:-1:-1;;;9776:49:32:i;:::-;9732:93;;9837:17;9859:60;9879:5;9886:6;9894:14;:24;;;9859:19;:60::i;:::-;9835:84;;;;9929:19;9951:75;9986:11;9999:26;9951:34;:75::i;:::-;9929:97;;10037:45;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10369:570:32;10551:17;10582:14;10610:15;10639:19;10686:20;10710:84;10741:5;10760:33;10776:6;10784:8;10760:15;:33::i;10710:84::-;10825:14;;10853:13;;;;10880:12;;;;10906:16;;;;;10825:14;;10853:13;;-1:-1:-1;10880:12:32;;-1:-1:-1;10906:16:32;-1:-1:-1;10369:570:32;-1:-1:-1;;;;;;10369:570:32:o;12172:263::-;12303:14;12336:21;12361:36;12382:5;12389:7;12361:20;:36::i;:::-;12414:14;;;;12172:263;-1:-1:-1;;;;;12172:263:32:o;55016:187::-;55108:10;55174:6;55182:12;55147:48;;;;;;;;19618:2:105;19600:21;;;19657:2;19637:18;;;19630:30;-1:-1:-1;;;19691:3:105;19676:19;;19669:43;-1:-1:-1;;;;;19824:15:105;;;19817:4;19802:20;;19795:45;19876:15;;-1:-1:-1;19856:18:105;;19849:43;19744:3;19729:19;;19360:538;55147:48:32;;;;;;;;;;;;;55137:59;;;;;;55130:66;;55016:187;;;;:::o;30340:409::-;-1:-1:-1;;;;;;;;;;;;;;;;;;30628:56:32;;-1:-1:-1;;;30628:56:32;;30659:4;30628:56;;;20113:51:105;20180:18;;;20173:34;;;30682:1:32;20223:18:105;;;20216:34;-1:-1:-1;;;;;;;30628:22:32;;;;;20086:18:105;;30628:56:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;30628:56:32;;;;;;;;;;;;:::i;:::-;30604:80;;30701:41;30733:4;30738:1;30733:7;;;;;;;;:::i;:::-;;;;;;;30725:16;;30701:23;:41::i;:::-;30694:48;;;;;30340:409;;;;;;:::o;53778:491::-;53878:25;53905:23;53944:16;53975:5;-1:-1:-1;;;;;53975:13:32;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53944:47;;54001:25;54051:4;-1:-1:-1;;;;;54051:18:32;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54001:71;;54082:17;54102:3;-1:-1:-1;;;;;54102:22:32;;54125:4;54131:5;2297:88;54102:57;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8796:16:42;8790:2;8777:15;;;8776:36;;;8840:28;;;-1:-1:-1;8776:36:42;-1:-1:-1;;;;;53778:491:32:o;4278:581::-;4426:14;-1:-1:-1;;;;;4466:26:32;;;4458:66;;;;-1:-1:-1;;;4458:66:32;;22208:2:105;4458:66:32;;;22190:21:105;22247:2;22227:18;;;22220:30;22286:29;22266:18;;;22259:57;22333:18;;4458:66:32;22006:351:105;4458:66:32;-1:-1:-1;;50578:23:32;;4535:49;-1:-1:-1;4596:17:32;4616:27;4626:17;4535:49;4616:27;:::i;29688:342::-;29823:10;29835:15;;:::i;:::-;29890:83;;-1:-1:-1;;;29890:83:32;;29926:4;29890:83;;;22904:34:105;-1:-1:-1;;;;;22974:15:105;;;22954:18;;;22947:43;29866:21:32;23006:18:105;;;22999:34;;;29958:1:32;23049:18:105;;;23042:34;29866:21:32;29890:27;;;;;;22838:19:105;;29890:83:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;29890:83:32;;;;;;;;;;;;:::i;:::-;29866:107;;29990:33;30014:4;30019:1;30014:7;;;;;;;;:::i;:::-;;;;;;;30006:16;;29990:15;:33::i;1013:347:31:-;1124:26;;:::i;:::-;1193:10;-1:-1:-1;;;;;1174:29:31;:5;-1:-1:-1;;;;;1174:13:31;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1174:29:31;;1166:59;;;;-1:-1:-1;;;1166:59:31;;23289:2:105;1166:59:31;;;23271:21:105;23328:2;23308:18;;;23301:30;-1:-1:-1;;;23347:18:105;;;23340:47;23404:18;;1166:59:31;23087:341:105;1166:59:31;1243:39;;-1:-1:-1;;;1243:39:31;;1255:10;;1243:34;;:39;;1278:3;;1243:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1235:63;;;;-1:-1:-1;;;1235:63:31;;24011:2:105;1235:63:31;;;23993:21:105;24050:2;24030:18;;;24023:30;-1:-1:-1;;;24069:18:105;;;24062:41;24120:18;;1235:63:31;23809:335:105;1235:63:31;1315:38;;-1:-1:-1;;;1315:38:31;;1327:10;;1315:33;;:38;;1349:3;;1315:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1315:38:31;;;;;;;;;;;;:::i;51533:155:32:-;51652:28;;;-1:-1:-1;;;;;26548:15:105;;;51652:28:32;;;26530:34:105;26600:15;;26580:18;;;26573:43;;;;51613:10:32;;26465:18:105;;51652:28:32;26318:304:105;30036:298:32;30165:10;30177:15;;:::i;:::-;30232:45;;-1:-1:-1;;;30232:45:32;;30263:4;30232:45;;;20113:51:105;20180:18;;;20173:34;;;30275:1:32;20223:18:105;;;20216:34;30208:21:32;;-1:-1:-1;;;;;30232:22:32;;;;;20086:18:105;;30232:45:32;19903:353:105;56550:615:32;56710:26;;56756:14;:44;;;;;;;;:::i;:::-;;56752:407;;-1:-1:-1;56860:1:32;56840:22;;;:27;56752:407;;;56906:26;56888:14;:44;;;;;;;;:::i;:::-;;56884:275;;-1:-1:-1;56999:1:32;56973:16;;;56972:29;;:34;56884:275;;;-1:-1:-1;;57130:1:32;57115:16;57141:1;57114:29;;;:34;;56550:615::o;30755:486::-;-1:-1:-1;;;;;;;;;31019:50:32;;;;;31079:61;;;;-1:-1:-1;;;31079:61:32;-1:-1:-1;;;;;31150:25:32;;;31176:14;31192:41;-1:-1:-1;31192:23:32;:41::i;:::-;31150:84;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30959:282;30755:486;;;;:::o;14878:935::-;15129:19;15167:28;15199:50;15224:8;15234:14;15199:24;:50::i;:::-;15164:85;;;15268:5;15260:42;;;;-1:-1:-1;;;15260:42:32;;26961:2:105;15260:42:32;;;26943:21:105;27000:2;26980:18;;;26973:30;-1:-1:-1;;;27019:18:105;;;27012:54;27083:18;;15260:42:32;26759:348:105;15260:42:32;15357:17;;;;;15317:59;;-1:-1:-1;;;15317:59:32;;-1:-1:-1;;;;;9511:32:105;;;15317:59:32;;;9493:51:105;15329:10:32;;15317:29;;9466:18:105;;15317:59:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;15313:427;;;15401:174;15435:8;:17;;;15470:8;:14;;;15486:10;15498:11;15527:3;;15401:174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15532:14:32;;-1:-1:-1;15548:26:32;;-1:-1:-1;15401:16:32;;-1:-1:-1;15401:174:32:i;:::-;15392:183;;15313:427;;;15615:114;15652:8;:14;;;15668:10;15680:11;15709:3;;15615:114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15714:14:32;;-1:-1:-1;15615:19:32;;-1:-1:-1;;15615:114:32:i;:::-;15606:123;;15313:427;15775:14;;15750:56;;15791:14;15750:24;:56::i;:::-;15154:659;14878:935;;;;;;;;:::o;1099:576:93:-;1267:1;1229:26;751:20:95;745:27;;618:170;1229:26:93;-1:-1:-1;;;;;1229:40:93;;1221:82;;;;-1:-1:-1;;;1221:82:93;;27541:2:105;1221:82:93;;;27523:21:105;27580:2;27560:18;;;27553:30;27619:31;27599:18;;;27592:59;27668:18;;1221:82:93;27339:353:105;1221:82:93;1367:10;-1:-1:-1;;;;;1353:39:93;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1334:15;:13;:15::i;:::-;:60;1313:142;;;;-1:-1:-1;;;1313:142:93;;27899:2:105;1313:142:93;;;27881:21:105;27938:2;27918:18;;;27911:30;27977:34;27957:18;;;27950:62;-1:-1:-1;;;28028:18:105;;;28021:33;28071:19;;1313:142:93;27697:399:105;1313:142:93;-1:-1:-1;;;;;1486:27:93;;1494:4;1486:27;1465:99;;;;-1:-1:-1;;;1465:99:93;;28303:2:105;1465:99:93;;;28285:21:105;28342:2;28322:18;;;28315:30;28381:27;28361:18;;;28354:55;28426:18;;1465:99:93;28101:349:105;1465:99:93;1574:39;1602:10;988:20:95;964:87;839:228;1574:39:93;1628:40;1640:15;:13;:15::i;:::-;1628:40;;;28629:25:105;;;-1:-1:-1;;;;;28690:32:105;;28685:2;28670:18;;28663:60;28602:18;1628:40:93;;;;;;;1099:576;:::o;7518:297:27:-;7574:6;-1:-1:-1;;;;;7699:5:27;:34;;7691:87;;;;-1:-1:-1;;;7691:87:27;;28936:2:105;7691:87:27;;;28918:21:105;28975:2;28955:18;;;28948:30;29014:34;28994:18;;;28987:62;-1:-1:-1;;;29065:18:105;;;29058:38;29113:19;;7691:87:27;28734:404:105;7691:87:27;-1:-1:-1;7802:5:27;7518:297::o;54275:548:32:-;54487:4;;54532:40;54551:21;54532:16;:40;:::i;:::-;54507:65;-1:-1:-1;54582:26:32;54611:49;54642:17;54611:21;:49;:::i;:::-;54582:78;-1:-1:-1;54780:35:32;54800:15;54780:17;:35;:::i;:::-;54733:37;54751:19;54733:15;:37;:::i;:::-;:83;;54275:548;-1:-1:-1;;;;;;;54275:548:32:o;15819:5224::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;16042:19:32;-1:-1:-1;;;;;;;;;;;;;;;;;;;16123:15:32;;;;-1:-1:-1;;;;;16123:29:32;16115:61;;;;-1:-1:-1;;;16115:61:32;;29943:2:105;16115:61:32;;;29925:21:105;29982:2;29962:18;;;29955:30;-1:-1:-1;;;30001:18:105;;;29994:49;30060:18;;16115:61:32;29741:343:105;16115:61:32;16194:17;;;;-1:-1:-1;;;;;16194:31:32;16186:65;;;;-1:-1:-1;;;16186:65:32;;30291:2:105;16186:65:32;;;30273:21:105;30330:2;30310:18;;;30303:30;-1:-1:-1;;;30349:18:105;;;30342:51;30410:18;;16186:65:32;30089:345:105;16186:65:32;16281:51;16297:8;:15;;;16314:8;:17;;;16281:15;:51::i;:::-;16261:71;;;16362:15;;;;;-1:-1:-1;;;;;16342:35:32;;;:17;;;:35;;;;16409:17;;;;;16387:39;;:19;;;:39;16462:24;;;;;16436:50;;;:23;;;:50;16261:17;16496:19;;;:23;;;16551;;;;;16529:19;;;:45;16646:14;;16261:17;;;;16628:52;;:17;:52::i;:::-;16584:96;;;;16698:5;16690:42;;;;-1:-1:-1;;;16690:42:32;;26961:2:105;16690:42:32;;;26943:21:105;27000:2;26980:18;;;26973:30;-1:-1:-1;;;27019:18:105;;;27012:54;27083:18;;16690:42:32;26759:348:105;16690:42:32;16773:14;;16806:15;;;;16823:24;;;;;16773:75;;-1:-1:-1;;;16773:75:32;;16744:23;;-1:-1:-1;;;;;16773:32:32;;;;:75;;;;-1:-1:-1;;;;;13677:32:105;;;;13659:51;;13741:2;13726:18;;13719:34;13647:2;13632:18;;13485:274;16773:75:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16743:105;;;;17028:8;:15;;;-1:-1:-1;;;;;17000:43:32;:14;:24;;;-1:-1:-1;;;;;17000:43:32;;;:104;;;;;17087:8;:17;;;-1:-1:-1;;;;;17059:45:32;:14;:24;;;-1:-1:-1;;;;;17059:45:32;;;17000:104;:135;;;;;17121:14;17120:15;17000:135;16996:430;;;17210:15;;;;17164:63;;-1:-1:-1;;;17164:63:32;;-1:-1:-1;;;;;9511:32:105;;;17164:63:32;;;9493:51:105;17176:10:32;;17164:35;;9466:18:105;;17164:63:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17163:64;:150;;;;-1:-1:-1;17294:17:32;;;;;17248:65;;-1:-1:-1;;;17248:65:32;;-1:-1:-1;;;;;9511:32:105;;;17248:65:32;;;9493:51:105;17260:10:32;;17248:35;;9466:18:105;;17248:65:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17247:66;17163:150;17159:257;;;17360:1;17341:16;:20;17333:68;;;;-1:-1:-1;;;17333:68:32;;30641:2:105;17333:68:32;;;30623:21:105;30680:2;30660:18;;;30653:30;30719:34;30699:18;;;30692:62;-1:-1:-1;;;30770:18:105;;;30763:33;30813:19;;17333:68:32;30439:399:105;17333:68:32;17459:1;17440:16;:20;17436:240;;;17476:189;17517:8;:14;;;17549:16;17583:10;17611:11;17640:14;:24;;;17476:23;:189::i;:::-;17695:3;;17686:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;17798:15:32;;;;17770:24;;;;17686:12;;-1:-1:-1;;;;;;17770:43:32;;;;;;17766:3271;;17945:17;;;;;17905:59;;-1:-1:-1;;;17905:59:32;;-1:-1:-1;;;;;9511:32:105;;;17905:59:32;;;9493:51:105;17917:10:32;;17905:29;;9466:18:105;;17905:59:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17901:568;;;17993:189;18031:8;:17;;;18070:8;:14;;;18086:10;18098:11;18131:6;18139:14;18155:26;17993:16;:189::i;:::-;17984:198;;17766:3271;;17901:568;18370:14;;18329:125;;18386:10;18398:11;18431:6;18439:14;18329:19;:125::i;17766:3271::-;18577:8;:17;;;-1:-1:-1;;;;;18549:45:32;:14;:24;;;-1:-1:-1;;;;;18549:45:32;;18545:2492;;18734:15;;;;18694:57;;-1:-1:-1;;;18694:57:32;;-1:-1:-1;;;;;9511:32:105;;;18694:57:32;;;9493:51:105;18706:10:32;;18694:29;;9466:18:105;;18694:57:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;18690:934;;;18780:187;18818:8;:15;;;18855:8;:14;;;18871:10;18883:11;18916:6;18924:14;18940:26;18780:16;:187::i;18690:934::-;19108:17;;;;;19068:59;;-1:-1:-1;;;19068:59:32;;-1:-1:-1;;;;;9511:32:105;;;19068:59:32;;;9493:51:105;19080:10:32;;19068:29;;9466:18:105;;19068:59:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19064:560;;;19156:182;19202:1;19226:8;:14;;;19242:10;19254:11;19287:6;19295:14;19311:26;19156:16;:182::i;18545:2492::-;19934:15;;;;19894:57;;-1:-1:-1;;;19894:57:32;;-1:-1:-1;;;;;9511:32:105;;;19894:57:32;;;9493:51:105;19906:10:32;;19894:29;;9466:18:105;;19894:57:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:81;;;;;19974:1;19955:16;:20;19894:81;19890:314;;;20095:15;;;;20004:185;;-1:-1:-1;;;20004:185:32;;20016:10;;20004:31;;:185;;20057:6;;2504:2:42;;20004:185:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20004:185:32;;;;;;;;;;;;:::i;:::-;19995:194;;19890:314;20419:17;;;;;20379:59;;-1:-1:-1;;;20379:59:32;;-1:-1:-1;;;;;9511:32:105;;;20379:59:32;;;9493:51:105;20391:10:32;;20379:29;;9466:18:105;;20379:59:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20375:652;;;20467:189;20505:8;:17;;;20544:8;:14;;;20560:10;20572:11;20605:6;20613:14;20629:26;20467:16;:189::i;20375:652::-;20928:14;;20887:125;;20944:10;20956:11;20989:6;20997:14;20887:19;:125::i;20375:652::-;16067:4976;;;;15819:5224;;;;;;;:::o;13885:987::-;14079:19;14115:14;14131:28;14163:50;14188:8;14198:14;14163:24;:50::i;:::-;14114:99;;;;14225:10;14237:27;14268:41;14286:8;:14;;;14302:6;14268:17;:41::i;:::-;14224:85;;;;14328:5;14327:6;14319:42;;;;-1:-1:-1;;;14319:42:32;;31794:2:105;14319:42:32;;;31776:21:105;31833:2;31813:18;;;31806:30;31872:25;31852:18;;;31845:53;31915:18;;14319:42:32;31592:347:105;14319:42:32;14416:17;;;;;14376:59;;-1:-1:-1;;;14376:59:32;;-1:-1:-1;;;;;9511:32:105;;;14376:59:32;;;9493:51:105;14388:10:32;;14376:29;;9466:18:105;;14376:59:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14372:427;;;14460:174;14494:8;:17;;;14529:8;:14;;;14545:10;14557:11;14586:3;;14460:174;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14591:14:32;;-1:-1:-1;14460:174:32;-1:-1:-1;14460:16:32;;-1:-1:-1;14460:174:32:i;:::-;14451:183;;14372:427;;;14674:114;14711:8;:14;;;14727:10;14739:11;14768:3;;14674:114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14773:14:32;;-1:-1:-1;14674:19:32;;-1:-1:-1;;14674:114:32:i;:::-;14665:123;;14372:427;14834:14;;14809:56;;14850:14;14809:24;:56::i;:::-;14104:768;;;;13885:987;;;;;;:::o;5254:285:42:-;5347:185;;;;5254:285::o;55549:462:32:-;55681:21;55763:1;55725:16;:34;;;:39;;;;55718:47;;;;:::i;:::-;55827:16;;;55841:1;55827:16;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55827:16:32;55820:23;;55958:16;:34;;;55951:42;;55925:3;55892:16;:28;;;55884:37;;:44;;:110;55863:141;;55853:4;55858:1;55853:7;;;;;;;;:::i;:::-;;;;;;:151;;;;;55549:462;;;:::o;4866:579::-;5046:15;5098:1;5087:8;:12;;;5079:60;;;;-1:-1:-1;;;5079:60:32;;32278:2:105;5079:60:32;;;32260:21:105;32317:2;32297:18;;;32290:30;32356:34;32336:18;;;32329:62;-1:-1:-1;;;32407:18:105;;;32400:33;32450:19;;5079:60:32;32076:399:105;5079:60:32;-1:-1:-1;;;;;5158:45:32;5186:17;5215:23;5166:16;;;5158:45;:::i;:::-;:81;;5150:129;;;;-1:-1:-1;;;5150:129:32;;32855:2:105;5150:129:32;;;32837:21:105;32894:2;32874:18;;;32867:30;-1:-1:-1;;;32913:18:105;;;32906:52;32975:18;;5150:129:32;32653:346:105;5150:129:32;5290:25;5318:46;5336:8;5346:17;5318;:46::i;:::-;5290:74;;5382:55;5403:14;5419:17;5382:20;:55::i;56017:527::-;-1:-1:-1;;;;;;;;;;;;;;;;;56198:9:32;;;;;-1:-1:-1;56217:321:32;;-1:-1:-1;;;;;56403:40:32;;56419:23;56353:92;:34;;;:92;56505:3;56496:12;;;56512:15;56490:37;56459:68;;56217:321;56017:527;;;:::o;52599:688::-;52696:10;52708:24;;:::i;:::-;52756:9;;;;;-1:-1:-1;52775:506:32;;52837:3;52828:12;;;52800:41;;53017:3;53008:12;;;53039:16;53001:56;52975:83;;:17;;;;:83;;;;53091:49;;;;;;53102:2;53072:16;;:68;53203:41;;;;;53180:20;;;:64;52599:688;;;:::o;13050:829::-;-1:-1:-1;;;;;;;;13234:14:32;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13302:17:32;;;;-1:-1:-1;;;;;13302:31:32;13294:65;;;;-1:-1:-1;;;13294:65:32;;30291:2:105;13294:65:32;;;30273:21:105;30330:2;30310:18;;;30303:30;-1:-1:-1;;;30349:18:105;;;30342:51;30410:18;;13294:65:32;30089:345:105;13294:65:32;13379:51;13395:8;:15;;;13412:8;:17;;;13379:15;:51::i;:::-;13440:26;;;13496:15;;;;;-1:-1:-1;;;;;13476:35:32;;;:17;;;:35;;;13543:17;;;;;13521:39;;:19;;;:39;;;13596:24;;;;;13570:50;;;:23;;;:50;13652:17;;;;13630:39;;:19;;;:39;13701:23;;;;;13679:19;;;:45;13370:60;;-1:-1:-1;13742:40:32;13734:70;;;;-1:-1:-1;;;13734:70:32;;33206:2:105;13734:70:32;;;33188:21:105;33245:2;33225:18;;;33218:30;-1:-1:-1;;;33264:18:105;;;33257:47;33321:18;;13734:70:32;33004:341:105;13734:70:32;13844:1;13822:10;:19;;;:23;;;13814:58;;;;-1:-1:-1;;;13814:58:32;;33552:2:105;13814:58:32;;;33534:21:105;33591:2;33571:18;;;33564:30;-1:-1:-1;;;33610:18:105;;;33603:52;33672:18;;13814:58:32;33350:346:105;33713:6999:32;34068:3;34108:38;;:::i;:::-;-1:-1:-1;;;;;34186:27:32;;;34182:2431;;34229:47;34279:208;34334:5;34357:13;34388:10;:17;;;34434:10;:17;;;34453:10;:19;;;34423:50;;;;;;;;-1:-1:-1;;;;;26548:15:105;;;26530:34;;26600:15;;26595:2;26580:18;;26573:43;26480:2;26465:18;;26318:304;34423:50:32;;;;-1:-1:-1;;34423:50:32;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;2045:20:31;;;;;2075:24;;;;34423:50:32;-1:-1:-1;;2075:24:31;-1:-1:-1;;;2109:32:31;-1:-1:-1;;;2151:36:31;34423:50:32;1806:388:31;34279:208:32;34229:258;-1:-1:-1;34556:26:32;34546:6;:36;;;;;;;;:::i;:::-;;34542:450;;1623:13:42;34602:16:32;;;:68;34542:450;;;34705:26;34695:6;:36;;;;;;;;:::i;:::-;;34691:301;;1776:13:42;34751:16:32;;;:68;34691:301;;;1932:13:42;34906:16:32;;;:71;34691:301;35019:53;35058:8;35068:3;35019:38;:53::i;:::-;35005:67;;35155:24;;;;35201:32;;;;35122:164;;35155:24;35255:5;35262:10;35274:11;35122;:164::i;:::-;-1:-1:-1;35089:28:32;;;35087:199;-1:-1:-1;35370:23:32;;:27;;35396:1;35370:27;:::i;:::-;35362:36;;35331:8;:28;;;:67;;;;:::i;:::-;35300:28;;;:98;35440:23;;;;:34;;:32;:34::i;:::-;35412:25;;;:62;35664:26;35654:6;:36;;;;;;;;:::i;:::-;;35650:447;;1699:13:42;35710:16:32;;;:67;35650:447;;;35812:26;35802:6;:36;;;;;;;;:::i;:::-;;35798:299;;1852:13:42;35858:16:32;;;:67;35798:299;;;2011:13:42;36012:16:32;;;:70;35798:299;36138:68;36176:8;36186:4;:11;;;36199:6;36138:37;:68::i;:::-;36111:15;;;36110:96;;;;36366:17;;36110:96;;-1:-1:-1;36341:43:32;;36359:5;;36341:17;:43::i;:::-;36321:16;;;36318:66;-1:-1:-1;34182:2431:32;;-1:-1:-1;34182:2431:32;;36438:164;36471:14;:24;;;36517:14;:32;;;36571:5;36578:10;36590:11;36438;:164::i;:::-;36418:16;;;36415:187;-1:-1:-1;;34182:2431:32;36963:1;36928:4;:15;;;:32;;;:36;36924:245;;;37079:75;:64;37098:44;:4;:15;;;:32;;;:42;:44::i;:::-;37079:18;:64::i;:::-;:73;:75::i;:::-;37024:15;;;;:32;;:130;36924:245;37183:24;37261:34;:11;:23;;;:32;:34::i;:::-;37210:4;:15;;;:32;;;:85;;;;:::i;:::-;37183:112;;37430:89;37489:17;37431:35;:4;:16;;;:24;;;:33;:35::i;:::-;:75;;;;:::i;:::-;37430:87;:89::i;:::-;37403:4;:16;;;:24;;:116;;;;;37568:93;37631:17;37569:39;:4;:16;;;:28;;;:37;:39::i;37568:93::-;37537:16;;;;;:28;;:124;;;;37705:17;;37740:16;;-1:-1:-1;;;;;37679:25:32;;;;;37724:33;;:15;:33::i;:::-;37679:79;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37875:296;37920:5;37947:10;:17;;;37986:1;38028:17;38084:1;38129:14;:24;;;37875:23;:296::i;:::-;;38189:298;38234:5;38261:10;:19;;;38302:1;38344;38384:17;38445:14;:24;;;38189:23;:298::i;:::-;-1:-1:-1;38528:32:32;;;;-1:-1:-1;;;;;38520:55:32;;;:116;;;38631:5;-1:-1:-1;;;;;38595:41:32;:14;:32;;;-1:-1:-1;;;;;38595:41:32;;38520:116;38516:391;;;38766:16;;;;:24;;;;;38677:215;;-1:-1:-1;;;38677:215:32;;38689:10;;38677:39;;:215;;38738:6;;38835:17;;38677:215;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;38677:215:32;;;;;;;;;;;;:::i;:::-;38668:224;;38516:391;39177:19;;;;;39137:61;;-1:-1:-1;;;39137:61:32;;-1:-1:-1;;;;;9511:32:105;;;39137:61:32;;;9493:51:105;39149:10:32;;39137:29;;9466:18:105;;39137:61:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39133:1563;;;39306:19;;;;;39327:24;;;;39282:70;;-1:-1:-1;;;39282:70:32;;-1:-1:-1;;;;;13677:32:105;;;39282:70:32;;;13659:51:105;13726:18;;;13719:34;;;;39218:23:32;;39282;;;;;;13632:18:105;;39282:70:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;39259:93:32;;-1:-1:-1;;39393:1:32;39374:20;;39370:1312;;;39492:26;39482:6;:36;;;;;;;;:::i;:::-;;39478:1186;;39662:19;;;;;39555:215;;-1:-1:-1;;;39555:215:32;;39567:10;;39555:31;;:215;;39616:6;;2578:2:42;;39555:215:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39555:215:32;;;;;;;;;;;;:::i;:::-;39546:224;-1:-1:-1;39847:23:32;39873:330;40001:17;40002:16;40001:17;:::i;:::-;40159:43;40180:1;40183:18;40184:17;40183:18;:::i;:::-;40159:20;:43::i;:::-;39873:20;:330::i;:::-;39847:356;;40229:5;-1:-1:-1;;;;;40229:19:32;;40278:10;:17;;;40326:16;40325:17;;;:::i;:::-;40229:139;;-1:-1:-1;;;;;;40229:139:32;;;;;;;-1:-1:-1;;;;;13677:32:105;;;40229:139:32;;;13659:51:105;13726:18;;;13719:34;13632:18;;40229:139:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;40443:19:32;;;;;40394:140;;-1:-1:-1;;;40394:140:32;;-1:-1:-1;;;;;13677:32:105;;;40394:140:32;;;13659:51:105;13726:18;;;13719:34;;;40394:19:32;;;;;;13632:18:105;;40394:140:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39520:1037;39478:1186;;;40589:52;;-1:-1:-1;;;40589:52:32;;34892:2:105;40589:52:32;;;34874:21:105;34931:2;34911:18;;;34904:30;34970:34;34950:18;;;34943:62;-1:-1:-1;;;35021:18:105;;;35014:40;35071:19;;40589:52:32;34690:406:105;39478:1186:32;39200:1496;39133:1563;36845:3861;34049:6663;33713:6999;;;;;;;;;:::o;32293:1074::-;32545:19;32684:23;;;;:28;32677:36;;;;:::i;:::-;32759:19;32788:27;;:::i;:::-;32855:140;32880:14;:24;;;32918:14;:32;;;32964:5;32971:10;32983:11;32855;:140::i;:::-;33055:32;;;;32825:170;;-1:-1:-1;32825:170:32;-1:-1:-1;;;;;;;33055:41:32;;;;;;33051:310;;33199:19;;;;;33121:186;;-1:-1:-1;;;33121:186:32;;33133:10;;33121:39;;:186;;33178:3;;33259:12;;33121:186;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33121:186:32;;;;;;;;;;;;:::i;:::-;33112:195;;33051:310;;;33347:3;33338:12;;33051:310;32570:797;;32293:1074;;;;;;;:::o;46100:600::-;46346:23;;;;:78;;4015:1:42;46346:78:32;;;:135;;;46476:5;-1:-1:-1;;;;;46440:41:32;:14;:32;;;-1:-1:-1;;;;;46440:41:32;;;46346:135;46342:352;;;46551:24;;;;46577;;;;;46527:75;;-1:-1:-1;;;46527:75:32;;-1:-1:-1;;;;;13677:32:105;;;46527:75:32;;;13659:51:105;13726:18;;;13719:34;;;;46498:23:32;;46527;;;;;13632:18:105;;46527:75:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46497:105;;;;46644:1;46624:16;:21;;46616:67;;;;-1:-1:-1;;;46616:67:32;;35303:2:105;46616:67:32;;;35285:21:105;35342:2;35322:18;;;35315:30;35381:34;35361:18;;;35354:62;-1:-1:-1;;;35432:18:105;;;35425:31;35473:19;;46616:67:32;35101:397:105;46616:67:32;46483:211;46342:352;46100:600;;:::o;46706:3538::-;46942:34;46980:46;47001:5;47008:10;:17;;;46980:20;:46::i;:::-;46940:86;;;47037:26;47066:27;:8;:16;;;:25;:27::i;:::-;47037:56;;47162:28;47193:37;:18;:26;;;:35;:37::i;:::-;47162:68;-1:-1:-1;47240:32:32;47282:31;;47675:40;47162:68;47675:16;:40;:::i;:::-;47650:65;;47857:25;47884:23;47911:21;47926:5;47911:14;:21::i;:::-;47856:76;;;;47975:173;48011:16;48045:21;48084:17;48119:15;47975:18;:173::i;:::-;47946:202;;47842:317;;48231:1;48212:15;:20;48208:2030;;48481:19;48543:21;48503:37;48525:15;48503:19;:37;:::i;:::-;:61;;;;:::i;:::-;48481:83;;48611:1;48614:26;:34;;48647:1;48614:34;;;48643:1;48614:34;48600:49;;;35709:4:105;35697:17;;;48600:49:32;;;35679:36:105;35751:17;;;;35731:18;;;35724:45;35652:18;;48600:49:32;;;;;;;;;;;;48578:71;;48663:5;-1:-1:-1;;;;;48663:30:32;;48711:10;:17;;;48752:19;48862:10;49010:26;49055:10;:17;;;49107:24;:12;:22;:24::i;:::-;49213:17;:12;-1:-1:-1;;49213:17:32;:::i;:::-;48663:648;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48234:1088;48208:2030;;;49505:16;;;49516:1;49505:16;;;35679:36:105;49519:1:32;35731:18:105;;;35724:45;;;;49450:19:32;;35652:18:105;;49505:16:32;;;;;;;;;;;;49483:38;;49535:5;-1:-1:-1;;;;;49535:30:32;;49583:10;:17;;;49624:19;49733:10;49782:5;49892:10;:17;;;49944:24;:12;:22;:24::i;:::-;50026:20;:15;-1:-1:-1;;50026:20:32;:::i;:::-;49535:692;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49328:910;48208:2030;46930:3314;;;;;;46706:3538;;;;;:::o;50886:448::-;51016:15;51051:8;:13;;51063:1;51051:13;51047:27;;-1:-1:-1;51073:1:32;51066:8;;51047:27;-1:-1:-1;;;;;51149:53:32;;;51142:61;;;;:::i;:::-;51238:43;51262:17;51238:8;:43;:::i;:::-;51231:51;;51213:70;;51300:27;51319:7;51300:18;:27::i;7451:92:31:-;7509:7;7531:1;7527;:5;:13;;7539:1;7527:13;;;-1:-1:-1;7535:1:31;;7451:92;-1:-1:-1;7451:92:31:o;2200:1318::-;2527:14;;;;2478:65;;-1:-1:-1;;;2478:65:31;;-1:-1:-1;;;;;9511:32:105;;;2478:65:31;;;9493:51:105;2334:19:31;;-1:-1:-1;;;;;;2490:10:31;;2478:38;;9466:18:105;;2478:65:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2443:100;;-1:-1:-1;2443:100:31;-1:-1:-1;2443:100:31;-1:-1:-1;2443:100:31;2557:23;;;;;2572:8;2571:9;2557:23;2553:959;;;2596:19;2618:31;2637:3;2642:6;2618:18;:31::i;:::-;2596:53;;2679:6;:14;;;2668:8;:25;2698:1;2667:32;2663:688;;2719:21;2787:36;2808:6;:14;;;2787:20;:36::i;:::-;2845:12;;2935:18;;;;;2975:20;;;;3017:12;;2845;3017;;;;;;;;2743:323;;2845:12;2887:4;;2935:18;2975:20;2743:323;;;;:::i;:::-;;;;-1:-1:-1;;2743:323:31;;;;;;;;;;;;;;;-1:-1:-1;;;;;2743:323:31;-1:-1:-1;;;;;;2743:323:31;;;;;;;;;;3170:14;;;;3237;;;;3093:243;;-1:-1:-1;;;3093:243:31;;2743:323;;-1:-1:-1;3105:10:31;;3093:45;;:243;;3170:14;2743:323;;1932:13:42;3237:70:31;;;;;3329:6;;3093:243;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;3093:243:31;;;;;;;;;;;;:::i;:::-;3084:252;;2701:650;2663:688;3476:25;3494:3;3499:1;3476:17;:25::i;:::-;;2582:930;2553:959;2359:1159;;;2200:1318;;;;:::o;41208:4887:32:-;41466:19;41499:24;41537:27;;:::i;:::-;41589:18;41679:22;41797:25;41828:21;41843:5;41828:14;:21::i;:::-;41796:53;;;41867:25;41929:10;-1:-1:-1;;;;;41917:37:32;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41992:107;;-1:-1:-1;;;41992:107:32;;41867:90;;-1:-1:-1;;;;;;41992:22:32;;;;;:107;;42048:10;;42061:5;;2458:71;;41992:107;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41975:124;;43117:57;43135:10;:19;;;43156:17;43117;:57::i;:::-;43098:76;;41778:1411;;43475:34;:11;:23;;;:32;:34::i;:::-;43426:30;:11;:19;;;:28;:30::i;:::-;43380:27;:16;:25;:27::i;:::-;:76;;;;:::i;:::-;:129;;;;:::i;:::-;43365:144;;43619:59;43653:12;43620:30;:11;:19;;;:28;:30::i;43619:59::-;43606:72;;43792:14;43779:10;:27;:54;;;;;43832:1;43810:10;:19;;;:23;;;43779:54;43775:288;;;43969:34;:11;:23;;;:32;:34::i;:::-;43916:30;:11;:19;;;:28;:30::i;:::-;43868:25;:14;:23;:25::i;:::-;:78;;;;:::i;:::-;:135;;;;:::i;:::-;43853:150;;44034:14;44021:27;;43775:288;-1:-1:-1;;;;;44134:40:32;;;;;;:86;;;44215:5;-1:-1:-1;;;;;44194:26:32;:17;-1:-1:-1;;;;;44194:26:32;;;44134:86;44130:157;;;44271:1;44252:20;;44130:157;44363:237;;;;;;;;44411:1;44389:10;:19;;;:23;;;:46;;44434:1;44389:46;;;44415:16;44389:46;44363:237;;;;44453:10;:19;;;44363:237;;;;;;44490:10;44363:237;;;;44518:11;:23;;;44363:237;;;44349:251;;44614:5;-1:-1:-1;;;;;44614:25:32;;44640:10;:17;;;44659:28;44675:11;44659:15;:28::i;:::-;44614:74;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;44722:33:32;;-1:-1:-1;;;44722:33:32;44881:238;44922:5;44945:10;:17;;;45003:10;:19;;;44980:11;:20;;;:42;;;;:::i;:::-;45040:12;45070:1;45089:16;44881:23;:238::i;:::-;44854:265;;;;45226:19;;;;45285:20;;;;45263:19;;;;45162:284;;45203:5;;45226:19;;45263:42;;45285:20;45263:42;:::i;:::-;45323:1;45342;45416:16;45162:23;:284::i;:::-;45133:313;;:26;;;;:313;;;45763:19;;;;;45728:17;;;;45800:19;;;;45837:24;;45923:19;;;;45676:280;;-1:-1:-1;;;;;45676:280:32;;;;;;;;;;;;;;;45800:19;45837:24;45133:313;;45923:19;45676:280;:::i;:::-;;;;;;;;46013:10;:23;;;-1:-1:-1;;;;;45975:103:32;;46054:10;45975:103;;;;1271:25:105;;1259:2;1244:18;;1125:177;45975:103:32;;;;;;;;44708:1381;41579:4516;41208:4887;;;;;;;;;:::o;3524:1858:31:-;3699:37;;:::i;:::-;3931:14;;;;3882:65;;-1:-1:-1;;;3882:65:31;;-1:-1:-1;;;;;9511:32:105;;;3882:65:31;;;9493:51:105;3738:19:31;;-1:-1:-1;;;;;;3894:10:31;;3882:38;;9466:18:105;;3882:65:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3967:3;;-1:-1:-1;3847:100:31;;-1:-1:-1;3847:100:31;-1:-1:-1;3847:100:31;-1:-1:-1;3847:100:31;3984:23;;;;;3999:8;3998:9;3984:23;3980:1396;;;4032:34;4051:6;4059;4032:18;:34::i;:::-;4023:43;;4096:6;:14;;;4085:8;:25;4115:1;4084:32;4080:1100;;4136:21;4204:36;4225:6;:14;;;4204:20;:36::i;:::-;4262:12;;4352:18;;;;;4392:20;;;;4462:12;;4262;4462;;;;;;;;4160:351;;4262:12;4304:4;;4352:18;4392:20;4434:6;;4160:351;;;;:::i;:::-;;;;-1:-1:-1;;4160:351:31;;;;;;;;;;;;;;;-1:-1:-1;;;;;4160:351:31;-1:-1:-1;;;;;;4160:351:31;;;;;;;;;;4614:14;;;;4681;;;;4538:241;;-1:-1:-1;;;4538:241:31;;4160:351;;-1:-1:-1;4550:10:31;;4538:44;;:241;;4614:14;4160:351;;2011:13:42;4681:69:31;;;;;4772:6;;4538:241;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4538:241:31;;;;;;;;;;;;:::i;:::-;4811:41;;-1:-1:-1;;;4811:41:31;;4529:250;;-1:-1:-1;4823:10:31;;4811:33;;:41;;4529:250;;4811:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4811:41:31;;;;;;;;;;;;:::i;:::-;4798:54;;4997:167;5001:1;5004:159;5029:37;:6;:26;;;:35;:37::i;:::-;5088:74;5092:40;:10;:29;;;:38;:40::i;:::-;5134:10;:27;;;5088:3;:74::i;4997:167::-;4967:27;;;:197;-1:-1:-1;4080:1100:31;5314:51;5332:3;5337:10;:27;;;5314:17;:51::i;:::-;5305:60;;3980:1396;3763:1619;;;3524:1858;;;;;;:::o;4343:168:27:-;4399:7;4435:1;4426:5;:10;;4418:55;;;;-1:-1:-1;;;4418:55:27;;40596:2:105;4418:55:27;;;40578:21:105;;;40615:18;;;40608:30;40674:34;40654:18;;;40647:62;40726:18;;4418:55:27;40394:356:105;50614:266:32;50697:7;;50793:16;50783:26;;50782:40;;50821:1;50782:40;;;50817:1;50782:40;50763:59;;;-1:-1:-1;50871:2:32;50840:26;50763:59;50841:13;;;50840:26;:::i;:::-;50839:34;;;50614:266;-1:-1:-1;;;50614:266:32:o;51999:594::-;52315:16;;;52329:1;52315:16;;;;;;;;;52107:21;;52315:16;;;;;;;;;;;-1:-1:-1;52315:16:32;52308:23;;52573:2;52548:8;:20;;;52540:35;;52521:2;52515;52494:8;:16;;;52486:31;;:37;;52465:3;52442:8;:17;;;52427:34;;:41;;52406:3;52382:8;:18;;;52373:36;;52372:98;:152;:204;52351:235;;52341:4;52346:1;52341:7;;;;;;;;:::i;31247:976::-;31501:20;31540:21;31565:36;31586:5;31593:7;31565:20;:36::i;:::-;31537:64;;;31611:21;31704:5;:14;;;31697:22;;31635:47;31655:5;:15;;;31636:16;:34;;;;:::i;31635:47::-;:84;;;;:::i;:::-;31611:108;-1:-1:-1;31733:19:32;;31729:94;;31768:44;;-1:-1:-1;;;31768:44:32;;-1:-1:-1;;;;;13677:32:105;;;31768:44:32;;;13659:51:105;13726:18;;;13719:34;;;31768:19:32;;;;;13632:18:105;;31768:44:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31729:94;31866:13;31849:5;:14;;;:30;;;;:::i;:::-;31832:47;;:14;;;:47;31889:34;;;31950:13;;;;31949:53;;31977:12;;31950:24;;:22;:24::i;31949:53::-;31933:13;;;:69;32033:17;;;;32032:61;;32064:16;;32033:28;;:26;:28::i;32032:61::-;32012:17;;;:81;-1:-1:-1;;;;;32104:30:32;;;32135:7;32144:1;32161:22;32012:5;32161:15;:22::i;:::-;32104:80;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;32202:14:32;;;;;;31247:976;-1:-1:-1;;;;;;;;;31247:976:32:o;7357:89:31:-;7413:6;7434:1;7430;:5;:13;;7442:1;7430:13;;7549:89;7605:6;7626:1;7622;:5;:13;;7634:1;7622:13;;;-1:-1:-1;7630:1:31;7549:89;-1:-1:-1;7549:89:31:o;6392:493::-;6759:14;;;;6788:26;;;;6828:23;;;;6865:12;;6679:199;;-1:-1:-1;;;6679:199:31;;6523:19;;6691:10;;6679:39;;:199;;6732:3;;6679:199;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6679:199:31;;;;;;;;;;;;:::i;5388:998::-;5473:15;1623:13:42;5508:7:31;:60;5504:876;;-1:-1:-1;;;;5591:41:31;5388:998;-1:-1:-1;5388:998:31:o;5504:876::-;1776:13:42;5653:7:31;:60;5649:731;;-1:-1:-1;;;;5736:41:31;5388:998;-1:-1:-1;5388:998:31:o;5649:731::-;1932:13:42;5798:7:31;:63;5794:586;;-1:-1:-1;;;;5884:44:31;5388:998;-1:-1:-1;5388:998:31:o;5794:586::-;1699:13:42;5949:7:31;:59;5945:435;;-1:-1:-1;;;;6031:40:31;5388:998;-1:-1:-1;5388:998:31:o;5945:435::-;1852:13:42;6092:7:31;:59;6088:292;;-1:-1:-1;;;;6174:40:31;5388:998;-1:-1:-1;5388:998:31:o;6088:292::-;-1:-1:-1;;;;6326:43:31;5388:998;-1:-1:-1;5388:998:31:o;6088:292::-;5388:998;;;:::o;6891:287::-;7105:66;;-1:-1:-1;;;7105:66:31;;7021:19;;7117:10;;7105:38;;:66;;7144:3;;7149:21;;7105:66;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;14:149:105:-;-1:-1:-1;;;;;107:31:105;;97:42;;87:70;;153:1;150;143:12;168:609;271:6;279;287;340:2;328:9;319:7;315:23;311:32;308:52;;;356:1;353;346:12;308:52;395:9;382:23;414:49;457:5;414:49;:::i;:::-;482:5;-1:-1:-1;539:2:105;524:18;;511:32;552:51;511:32;552:51;:::i;:::-;622:7;-1:-1:-1;681:2:105;666:18;;653:32;694:51;653:32;694:51;:::i;:::-;764:7;754:17;;;168:609;;;;;:::o;1307:359::-;1401:6;1409;1462:2;1450:9;1441:7;1437:23;1433:32;1430:52;;;1478:1;1475;1468:12;1430:52;1517:9;1504:23;1536:49;1579:5;1536:49;:::i;:::-;1604:5;1656:2;1641:18;;;;1628:32;;-1:-1:-1;;;1307:359:105:o;1865:347::-;1916:8;1926:6;1980:3;1973:4;1965:6;1961:17;1957:27;1947:55;;1998:1;1995;1988:12;1947:55;-1:-1:-1;2021:20:105;;2064:18;2053:30;;2050:50;;;2096:1;2093;2086:12;2050:50;2133:4;2125:6;2121:17;2109:29;;2185:3;2178:4;2169:6;2161;2157:19;2153:30;2150:39;2147:59;;;2202:1;2199;2192:12;2217:747;2331:6;2339;2347;2355;2408:2;2396:9;2387:7;2383:23;2379:32;2376:52;;;2424:1;2421;2414:12;2376:52;2463:9;2450:23;2482:49;2525:5;2482:49;:::i;:::-;2550:5;-1:-1:-1;2607:2:105;2592:18;;2579:32;2620:51;2579:32;2620:51;:::i;:::-;2690:7;-1:-1:-1;2748:2:105;2733:18;;2720:32;2775:18;2764:30;;2761:50;;;2807:1;2804;2797:12;2761:50;2846:58;2896:7;2887:6;2876:9;2872:22;2846:58;:::i;:::-;2217:747;;;;-1:-1:-1;2923:8:105;-1:-1:-1;;;;2217:747:105:o;2969:258::-;3041:1;3051:113;3065:6;3062:1;3059:13;3051:113;;;3141:11;;;3135:18;3122:11;;;3115:39;3087:2;3080:10;3051:113;;;3182:6;3179:1;3176:13;3173:48;;;3217:1;3208:6;3203:3;3199:16;3192:27;3173:48;;2969:258;;;:::o;3232:257::-;3273:3;3311:5;3305:12;3338:6;3333:3;3326:19;3354:63;3410:6;3403:4;3398:3;3394:14;3387:4;3380:5;3376:16;3354:63;:::i;:::-;3471:2;3450:15;-1:-1:-1;;3446:29:105;3437:39;;;;3478:4;3433:50;;3232:257;-1:-1:-1;;3232:257:105:o;3494:217::-;3641:2;3630:9;3623:21;3604:4;3661:44;3701:2;3690:9;3686:18;3678:6;3661:44;:::i;4352:450::-;4446:6;4454;4507:2;4495:9;4486:7;4482:23;4478:32;4475:52;;;4523:1;4520;4513:12;4475:52;4562:9;4549:23;4581:49;4624:5;4581:49;:::i;:::-;4649:5;-1:-1:-1;4706:2:105;4691:18;;4678:32;4719:51;4678:32;4719:51;:::i;:::-;4789:7;4779:17;;;4352:450;;;;;:::o;5215:161::-;5281:20;;5341:2;5330:21;;;5320:32;;5310:60;;5366:1;5363;5356:12;5381:978;5511:6;5519;5527;5535;5543;5551;5604:3;5592:9;5583:7;5579:23;5575:33;5572:53;;;5621:1;5618;5611:12;5572:53;5660:9;5647:23;5679:49;5722:5;5679:49;:::i;:::-;5747:5;-1:-1:-1;5804:2:105;5789:18;;5776:32;5817:51;5776:32;5817:51;:::i;:::-;5887:7;-1:-1:-1;5946:2:105;5931:18;;5918:32;5959:51;5918:32;5959:51;:::i;:::-;6029:7;-1:-1:-1;6055:36:105;6087:2;6072:18;;6055:36;:::i;:::-;6045:46;;6142:3;6131:9;6127:19;6114:33;6170:18;6162:6;6159:30;6156:50;;;6202:1;6199;6192:12;6156:50;6241:58;6291:7;6282:6;6271:9;6267:22;6241:58;:::i;:::-;5381:978;;;;-1:-1:-1;5381:978:105;;-1:-1:-1;5381:978:105;;6318:8;;5381:978;-1:-1:-1;;;5381:978:105:o;6364:265::-;6423:6;6476:2;6464:9;6455:7;6451:23;6447:32;6444:52;;;6492:1;6489;6482:12;6444:52;6531:9;6518:23;6550:49;6593:5;6550:49;:::i;6634:518::-;6737:6;6745;6753;6806:2;6794:9;6785:7;6781:23;6777:32;6774:52;;;6822:1;6819;6812:12;6774:52;6861:9;6848:23;6880:49;6923:5;6880:49;:::i;:::-;6948:5;-1:-1:-1;7005:2:105;6990:18;;6977:32;7018:51;6977:32;7018:51;:::i;:::-;6634:518;;7088:7;;-1:-1:-1;;;7142:2:105;7127:18;;;;7114:32;;6634:518::o;7349:907::-;7472:6;7480;7488;7496;7504;7557:3;7545:9;7536:7;7532:23;7528:33;7525:53;;;7574:1;7571;7564:12;7525:53;7613:9;7600:23;7632:49;7675:5;7632:49;:::i;:::-;7700:5;-1:-1:-1;7757:2:105;7742:18;;7729:32;7770:51;7729:32;7770:51;:::i;:::-;7840:7;-1:-1:-1;7899:2:105;7884:18;;7871:32;7912:51;7871:32;7912:51;:::i;:::-;7982:7;-1:-1:-1;8040:2:105;8025:18;;8012:32;8067:18;8056:30;;8053:50;;;8099:1;8096;8089:12;8053:50;8138:58;8188:7;8179:6;8168:9;8164:22;8138:58;:::i;:::-;7349:907;;;;-1:-1:-1;7349:907:105;;-1:-1:-1;8215:8:105;;8112:84;7349:907;-1:-1:-1;;;7349:907:105:o;8524:818::-;8645:6;8653;8661;8669;8677;8730:3;8718:9;8709:7;8705:23;8701:33;8698:53;;;8747:1;8744;8737:12;8698:53;8786:9;8773:23;8805:49;8848:5;8805:49;:::i;:::-;8873:5;-1:-1:-1;8930:2:105;8915:18;;8902:32;8943:51;8902:32;8943:51;:::i;:::-;9013:7;-1:-1:-1;9039:36:105;9071:2;9056:18;;9039:36;:::i;9737:114::-;9821:4;9814:5;9810:16;9803:5;9800:27;9790:55;;9841:1;9838;9831:12;9856:956;9984:6;9992;10000;10008;10016;10024;10077:3;10065:9;10056:7;10052:23;10048:33;10045:53;;;10094:1;10091;10084:12;10045:53;10133:9;10120:23;10152:49;10195:5;10152:49;:::i;:::-;10220:5;-1:-1:-1;10277:2:105;10262:18;;10249:32;10290:51;10249:32;10290:51;:::i;:::-;10360:7;-1:-1:-1;10419:2:105;10404:18;;10391:32;10432:31;10391:32;10432:31;:::i;10817:361::-;10909:6;10917;10970:2;10958:9;10949:7;10945:23;10941:32;10938:52;;;10986:1;10983;10976:12;10938:52;11025:9;11012:23;11044:49;11087:5;11044:49;:::i;:::-;11112:5;-1:-1:-1;11136:36:105;11168:2;11153:18;;11136:36;:::i;:::-;11126:46;;10817:361;;;;;:::o;12211:127::-;12272:10;12267:3;12263:20;12260:1;12253:31;12303:4;12300:1;12293:15;12327:4;12324:1;12317:15;12343:381;12381:4;12426:1;12422:2;12411:17;12463:1;12459:2;12448:17;12493:1;12488:3;12484:11;12569:3;-1:-1:-1;;;;;12536:31:105;12532:41;12527:3;12523:51;12518:2;12511:10;12507:68;12504:94;;;12578:18;;:::i;:::-;12659:3;-1:-1:-1;;;;;12627:36:105;12622:3;12618:46;12614:2;12610:55;12607:81;;;12668:18;;:::i;:::-;-1:-1:-1;12705:13:105;;;12343:381;-1:-1:-1;;;12343:381:105:o;12729:397::-;12931:2;12913:21;;;12970:2;12950:18;;;12943:30;13009:34;13004:2;12989:18;;12982:62;-1:-1:-1;;;13075:2:105;13060:18;;13053:31;13116:3;13101:19;;12729:397::o;13764:305::-;13851:6;13859;13867;13920:2;13908:9;13899:7;13895:23;13891:32;13888:52;;;13936:1;13933;13926:12;13888:52;13965:9;13959:16;13949:26;;14015:2;14004:9;14000:18;13994:25;13984:35;;14059:2;14048:9;14044:18;14038:25;14028:35;;13764:305;;;;;:::o;14428:156::-;14507:13;;14529:49;14507:13;14529:49;:::i;14589:269::-;14659:6;14712:2;14700:9;14691:7;14687:23;14683:32;14680:52;;;14728:1;14725;14718:12;14680:52;14760:9;14754:16;14779:49;14822:5;14779:49;:::i;14863:184::-;14933:6;14986:2;14974:9;14965:7;14961:23;14957:32;14954:52;;;15002:1;14999;14992:12;14954:52;-1:-1:-1;15025:16:105;;14863:184;-1:-1:-1;14863:184:105:o;16310:435::-;16363:3;16401:5;16395:12;16428:6;16423:3;16416:19;16454:4;16483:2;16478:3;16474:12;16467:19;;16520:2;16513:5;16509:14;16541:1;16551:169;16565:6;16562:1;16559:13;16551:169;;;16626:13;;16614:26;;16660:12;;;;16695:15;;;;16587:1;16580:9;16551:169;;;-1:-1:-1;16736:3:105;;16310:435;-1:-1:-1;;;;;16310:435:105:o;16750:332::-;16957:6;16946:9;16939:25;17000:2;16995;16984:9;16980:18;16973:30;16920:4;17020:56;17072:2;17061:9;17057:18;17049:6;17020:56;:::i;17392:422::-;-1:-1:-1;;;;;17697:15:105;;;17679:34;;17749:15;;;;17744:2;17729:18;;17722:43;17796:2;17781:18;;17774:34;;;;17629:2;17614:18;;17392:422::o;18530:267::-;18569:4;18598:9;;;18623:10;;-1:-1:-1;;;18642:19:105;;18635:27;;18619:44;18616:70;;;18666:18;;:::i;:::-;-1:-1:-1;;;;;18713:27:105;;18706:35;;18698:44;;18695:70;;;18745:18;;:::i;:::-;-1:-1:-1;;18782:9:105;;18530:267::o;18802:553::-;18841:7;-1:-1:-1;;;;;18911:9:105;;;18939;;;18964:11;;;18983:10;;;18977:17;;18960:35;18957:61;;;18998:18;;:::i;:::-;-1:-1:-1;;;19074:1:105;19067:9;;19092:11;;;19112;;;19105:19;;19088:37;19085:63;;;19128:18;;:::i;:::-;19174:1;19171;19167:9;19157:19;;19221:1;19217:2;19212:11;19209:1;19205:19;19200:2;19196;19192:11;19188:37;19185:63;;;19228:18;;:::i;:::-;19293:1;19289:2;19284:11;19281:1;19277:19;19272:2;19268;19264:11;19260:37;19257:63;;;19300:18;;:::i;:::-;-1:-1:-1;;;19340:9:105;;;;;18802:553;-1:-1:-1;;;18802:553:105:o;20261:127::-;20322:10;20317:3;20313:20;20310:1;20303:31;20353:4;20350:1;20343:15;20377:4;20374:1;20367:15;20393:255;20465:2;20459:9;20507:6;20495:19;;20544:18;20529:34;;20565:22;;;20526:62;20523:88;;;20591:18;;:::i;:::-;20627:2;20620:22;20393:255;:::o;20653:275::-;20724:2;20718:9;20789:2;20770:13;;-1:-1:-1;;20766:27:105;20754:40;;20824:18;20809:34;;20845:22;;;20806:62;20803:88;;;20871:18;;:::i;:::-;20907:2;20900:22;20653:275;;-1:-1:-1;20653:275:105:o;20933:936::-;21028:6;21059:2;21102;21090:9;21081:7;21077:23;21073:32;21070:52;;;21118:1;21115;21108:12;21070:52;21151:9;21145:16;21180:18;21221:2;21213:6;21210:14;21207:34;;;21237:1;21234;21227:12;21207:34;21275:6;21264:9;21260:22;21250:32;;21320:7;21313:4;21309:2;21305:13;21301:27;21291:55;;21342:1;21339;21332:12;21291:55;21371:2;21365:9;21393:2;21389;21386:10;21383:36;;;21399:18;;:::i;:::-;21445:2;21442:1;21438:10;21428:20;;21468:28;21492:2;21488;21484:11;21468:28;:::i;:::-;21530:15;;;21600:11;;;21596:20;;;21561:12;;;;21628:19;;;21625:39;;;21660:1;21657;21650:12;21625:39;21684:11;;;;21704:135;21720:6;21715:3;21712:15;21704:135;;;21786:10;;21774:23;;21737:12;;;;21817;;;;21704:135;;21874:127;21935:10;21930:3;21926:20;21923:1;21916:31;21966:4;21963:1;21956:15;21990:4;21987:1;21980:15;22362:127;22423:10;22418:3;22414:20;22411:1;22404:31;22454:4;22451:1;22444:15;22478:4;22475:1;22468:15;22494:120;22534:1;22560;22550:35;;22565:18;;:::i;:::-;-1:-1:-1;22599:9:105;;22494:120::o;23433:164::-;23509:13;;23558;;23551:21;23541:32;;23531:60;;23587:1;23584;23577:12;23602:202;23669:6;23722:2;23710:9;23701:7;23697:23;23693:32;23690:52;;;23738:1;23735;23728:12;23690:52;23761:37;23788:9;23761:37;:::i;24149:134::-;24226:13;;24248:29;24226:13;24248:29;:::i;24288:177::-;24366:13;;-1:-1:-1;;;;;;24408:32:105;;24398:43;;24388:71;;24455:1;24452;24445:12;24470:496;24523:5;24576:3;24569:4;24561:6;24557:17;24553:27;24543:55;;24594:1;24591;24584:12;24543:55;24623:6;24617:13;24649:18;24645:2;24642:26;24639:52;;;24671:18;;:::i;:::-;24715:55;24758:2;24739:13;;-1:-1:-1;;24735:27:105;24764:4;24731:38;24715:55;:::i;:::-;24795:2;24786:7;24779:19;24841:3;24834:4;24829:2;24821:6;24817:15;24813:26;24810:35;24807:55;;;24858:1;24855;24848:12;24807:55;24871:64;24932:2;24925:4;24916:7;24912:18;24905:4;24897:6;24893:17;24871:64;:::i;24971:1342::-;25067:6;25120:2;25108:9;25099:7;25095:23;25091:32;25088:52;;;25136:1;25133;25126:12;25088:52;25169:9;25163:16;25198:18;25239:2;25231:6;25228:14;25225:34;;;25255:1;25252;25245:12;25225:34;25278:22;;;;25334:6;25316:16;;;25312:29;25309:49;;;25354:1;25351;25344:12;25309:49;25380:22;;:::i;:::-;25425:31;25453:2;25425:31;:::i;:::-;25418:5;25411:46;25489:40;25525:2;25521;25517:11;25489:40;:::i;:::-;25484:2;25477:5;25473:14;25466:64;25576:2;25572;25568:11;25562:18;25557:2;25550:5;25546:14;25539:42;25613;25651:2;25647;25643:11;25613:42;:::i;:::-;25608:2;25601:5;25597:14;25590:66;25689:42;25726:3;25722:2;25718:12;25689:42;:::i;:::-;25683:3;25676:5;25672:15;25665:67;25771:3;25767:2;25763:12;25757:19;25801:2;25791:8;25788:16;25785:36;;;25817:1;25814;25807:12;25785:36;25854:55;25901:7;25890:8;25886:2;25882:17;25854:55;:::i;:::-;25848:3;25841:5;25837:15;25830:80;;25957:3;25953:2;25949:12;25943:19;25937:3;25930:5;25926:15;25919:44;26010:3;26006:2;26002:12;25996:19;25990:3;25983:5;25979:15;25972:44;26035:3;26025:13;;26084:2;26080;26076:11;26070:18;26065:2;26058:5;26054:14;26047:42;26108:3;26098:13;;26143:42;26181:2;26177;26173:11;26143:42;:::i;:::-;26138:2;26131:5;26127:14;26120:66;26205:3;26195:13;;26240:42;26278:2;26274;26270:11;26240:42;:::i;:::-;26224:14;;;26217:66;;;;26228:5;24971:1342;-1:-1:-1;;;;24971:1342:105:o;26627:127::-;26688:10;26683:3;26679:20;26676:1;26669:31;26719:4;26716:1;26709:15;26743:4;26740:1;26733:15;29143:265;29182:3;29210:9;;;29235:10;;-1:-1:-1;;;;;29254:27:105;;;29247:35;;29231:52;29228:78;;;29286:18;;:::i;:::-;-1:-1:-1;;;29333:19:105;;;29326:27;;29318:36;;29315:62;;;29357:18;;:::i;:::-;-1:-1:-1;;29393:9:105;;29143:265::o;29413:193::-;29452:1;29478;29468:35;;29483:18;;:::i;:::-;-1:-1:-1;;;29519:18:105;;-1:-1:-1;;29539:13:105;;29515:38;29512:64;;;29556:18;;:::i;:::-;-1:-1:-1;29590:10:105;;29413:193::o;29611:125::-;29651:4;29679:1;29676;29673:8;29670:34;;;29684:18;;:::i;:::-;-1:-1:-1;29721:9:105;;29611:125::o;30843:404::-;31065:2;31054:9;31047:21;31028:4;31085:44;31125:2;31114:9;31110:18;31102:6;31085:44;:::i;:::-;-1:-1:-1;;;;;31165:32:105;;;;31160:2;31145:18;;31138:60;-1:-1:-1;31229:2:105;31214:18;31207:34;31077:52;30843:404;-1:-1:-1;30843:404:105:o;31252:335::-;31331:6;31384:2;31372:9;31363:7;31359:23;31355:32;31352:52;;;31400:1;31397;31390:12;31352:52;31433:9;31427:16;31466:18;31458:6;31455:30;31452:50;;;31498:1;31495;31488:12;31452:50;31521:60;31573:7;31564:6;31553:9;31549:22;31521:60;:::i;31944:127::-;32005:10;32000:3;31996:20;31993:1;31986:31;32036:4;32033:1;32026:15;32060:4;32057:1;32050:15;32480:168;32520:7;32586:1;32582;32578:6;32574:14;32571:1;32568:21;32563:1;32556:9;32549:17;32545:45;32542:71;;;32593:18;;:::i;:::-;-1:-1:-1;32633:9:105;;32480:168::o;33701:204::-;33739:3;33775:4;33772:1;33768:12;33807:4;33804:1;33800:12;33842:3;33836:4;33832:14;33827:3;33824:23;33821:49;;;33850:18;;:::i;:::-;33886:13;;33701:204;-1:-1:-1;;;33701:204:105:o;33910:357::-;34111:2;34100:9;34093:21;34074:4;34131:44;34171:2;34160:9;34156:18;34148:6;34131:44;:::i;:::-;34206:2;34191:18;;34184:34;;;;-1:-1:-1;34249:2:105;34234:18;34227:34;34123:52;33910:357;-1:-1:-1;33910:357:105:o;34272:136::-;34307:3;-1:-1:-1;;;34328:22:105;;34325:48;;34353:18;;:::i;:::-;-1:-1:-1;34393:1:105;34389:13;;34272:136::o;35780:712::-;36087:6;36076:9;36069:25;36130:3;36125:2;36114:9;36110:18;36103:31;36050:4;36151:45;36191:3;36180:9;36176:19;36168:6;36151:45;:::i;:::-;-1:-1:-1;;;;;36270:15:105;;;36265:2;36250:18;;36243:43;36329:14;;36322:22;36317:2;36302:18;;36295:50;-1:-1:-1;36382:15:105;;;;36376:3;36361:19;;36354:44;36223:3;36414:19;;36407:35;36473:3;36458:19;36451:35;;;;36143:53;35780:712;-1:-1:-1;;35780:712:105:o;36784:681::-;36822:7;36870:1;36866:2;36855:17;36907:1;36903:2;36892:17;-1:-1:-1;;;;;36982:1:105;36977:3;36973:11;37012:1;37007:3;37003:11;37059:3;37055:2;37051:12;37046:3;37043:21;37038:2;37034;37030:11;37026:39;37023:65;;;37068:18;;:::i;:::-;-1:-1:-1;;37166:1:105;37157:11;;37184;;;37206:13;;;37197:23;;37180:41;37177:67;;;37224:18;;:::i;:::-;37272:1;37267:3;37263:11;37253:21;;37321:3;37317:2;37312:13;37307:3;37303:23;37298:2;37294;37290:11;37286:41;37283:67;;;37330:18;;:::i;:::-;37397:3;37393:2;37388:13;37383:3;37379:23;37374:2;37370;37366:11;37362:41;37359:67;;;37406:18;;:::i;:::-;-1:-1:-1;;;37446:13:105;;;;;36784:681;-1:-1:-1;;;;;36784:681:105:o;37470:342::-;37552:6;37560;37568;37621:2;37609:9;37600:7;37596:23;37592:32;37589:52;;;37637:1;37634;37627:12;37589:52;37660:37;37687:9;37660:37;:::i;:::-;37650:47;;37716:46;37758:2;37747:9;37743:18;37716:46;:::i;:::-;37706:56;;37802:2;37791:9;37787:18;37781:25;37771:35;;37470:342;;;;;:::o;37817:675::-;-1:-1:-1;;;;;38158:15:105;;;38140:34;;38210:15;;38205:2;38190:18;;38183:43;38257:2;38242:18;;38235:34;;;38120:3;38300:2;38285:18;;38278:31;;;38083:4;;38332:45;;38357:19;;38349:6;38332:45;:::i;:::-;38426:9;38418:6;38414:22;38408:3;38397:9;38393:19;38386:51;38454:32;38479:6;38471;38454:32;:::i;38497:576::-;-1:-1:-1;;;;;38759:32:105;;38741:51;;38828:3;38823:2;38808:18;;38801:31;;;-1:-1:-1;;38855:45:105;;38880:19;;38872:6;38855:45;:::i;:::-;38950:6;38943:14;38936:22;38931:2;38920:9;38916:18;38909:50;39007:9;38999:6;38995:22;38990:2;38979:9;38975:18;38968:50;39035:32;39060:6;39052;39035:32;:::i;:::-;39027:40;38497:576;-1:-1:-1;;;;;;;38497:576:105:o;39078:470::-;39314:6;39310:2;39299:22;39288:9;39281:41;39373:6;39369:2;39358:22;39353:2;39342:9;39338:18;39331:50;39432:6;39428:2;39417:22;39412:2;39401:9;39397:18;39390:50;39476:3;39471:2;39460:9;39456:18;39449:31;39262:4;39497:45;39537:3;39526:9;39522:19;39514:6;39497:45;:::i;:::-;39489:53;39078:470;-1:-1:-1;;;;;;39078:470:105:o;39553:836::-;-1:-1:-1;;;;;39940:15:105;;;39922:34;;39992:15;;39987:2;39972:18;;39965:43;40039:2;40024:18;;40017:34;;;40087:3;40082:2;40067:18;;40060:31;;;39865:4;;40114:45;;40139:19;;40131:6;40114:45;:::i;:::-;40208:9;40200:6;40196:22;40190:3;40179:9;40175:19;40168:51;40242:32;40267:6;40259;40242:32;:::i;:::-;40228:46;;40323:9;40315:6;40311:22;40305:3;40294:9;40290:19;40283:51;40351:32;40376:6;40368;40351:32;:::i;40755:128::-;40795:3;40826:1;40822:6;40819:1;40816:13;40813:39;;;40832:18;;:::i;:::-;-1:-1:-1;40868:9:105;;40755:128::o;40888:379::-;40926:3;40970:1;40966:2;40955:17;41007:1;41003:2;40992:17;41037:1;41032:3;41028:11;41108:3;-1:-1:-1;;;;;41076:36:105;41071:3;41067:46;41062:2;41055:10;41051:63;41048:89;;;41117:18;;:::i;:::-;41203:3;-1:-1:-1;;;;;41170:31:105;41166:41;41161:3;41157:51;41153:2;41149:60;41146:86;;;41212:18;;:::i;:::-;-1:-1:-1;41248:13:105;;40888:379;-1:-1:-1;;;40888:379:105:o;41272:437::-;41544:1;41540;41535:3;41531:11;41527:19;41519:6;41515:32;41504:9;41497:51;41584:6;41579:2;41568:9;41564:18;41557:34;41627:2;41622;41611:9;41607:18;41600:30;41478:4;41647:56;41699:2;41688:9;41684:18;41676:6;41647:56;:::i;41714:603::-;42016:3;42005:9;41998:22;41979:4;42037:45;42077:3;42066:9;42062:19;42054:6;42037:45;:::i;:::-;-1:-1:-1;;;;;42156:15:105;;;42151:2;42136:18;;42129:43;42203:2;42188:18;;42181:34;;;;-1:-1:-1;42246:2:105;42231:18;;42224:34;;;;42295:15;;;42289:3;42274:19;;;42267:44;;;;42029:53;41714:603;-1:-1:-1;41714:603:105:o;42322:286::-;42495:2;42484:9;42477:21;42458:4;42515:44;42555:2;42544:9;42540:18;42532:6;42515:44;:::i;:::-;42507:52;;42595:6;42590:2;42579:9;42575:18;42568:34;42322:286;;;;;:::o",
30253
- "source": "// SPDX-License-Identifier: AGPLv3\npragma solidity 0.8.13;\n\nimport {\n IConstantFlowAgreementV1,\n ISuperfluidToken\n} from \"../interfaces/agreements/IConstantFlowAgreementV1.sol\";\nimport {\n ISuperfluid,\n ISuperfluidGovernance,\n ISuperApp,\n FlowOperatorDefinitions,\n SuperAppDefinitions,\n ContextDefinitions,\n SuperfluidGovernanceConfigs\n} from \"../interfaces/superfluid/ISuperfluid.sol\";\nimport { AgreementBase } from \"./AgreementBase.sol\";\n\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport { AgreementLibrary } from \"./AgreementLibrary.sol\";\n\n\n/**\n * @title ConstantFlowAgreementV1 contract\n * @author Superfluid\n * @dev Please read IConstantFlowAgreementV1 for implementation notes.\n * @dev For more technical notes, please visit protocol-monorepo wiki area.\n */\ncontract ConstantFlowAgreementV1 is\n AgreementBase,\n IConstantFlowAgreementV1\n{\n\n /**\n * E_NO_SENDER_CREATE - sender cannot create as flowOperator\n * E_NO_SENDER_UPDATE - sender cannot update as flowOperator\n * E_NO_SENDER_DELETE - sender cannot delete as flowOperator\n * E_EXCEED_FLOW_RATE_ALLOWANCE - flowRateAllowance exceeeded\n * E_NO_OPERATOR_CREATE_FLOW - operator does not have permissions to create flow\n * E_NO_OPERATOR_UPDATE_FLOW - operator does not have permissions to update flow\n * E_NO_OPERATOR_DELETE_FLOW - operator does not have permissions to delete flow\n * E_NO_SENDER_FLOW_OPERATOR - sender cannot set themselves as the flow operator\n * E_NO_NEGATIVE_ALLOWANCE - sender cannot set a negative allowance\n */\n\n /**\n * @dev Default minimum deposit value\n *\n * NOTE:\n * - It may come as a surprise that it is not 0, this is the minimum friction we have in the system for the\n * imperfect blockchain system we live in.\n * - It is related to deposit clipping, and it is always rounded-up when clipping.\n */\n uint256 public constant DEFAULT_MINIMUM_DEPOSIT = uint256(uint96(1 << 32));\n /// @dev Maximum deposit value\n uint256 public constant MAXIMUM_DEPOSIT = uint256(uint96(type(int96).max));\n\n /// @dev Maximum flow rate\n uint256 public constant MAXIMUM_FLOW_RATE = uint256(uint96(type(int96).max));\n\n bytes32 private constant CFAV1_PPP_CONFIG_KEY =\n keccak256(\"org.superfluid-finance.agreements.ConstantFlowAgreement.v1.PPPConfiguration\");\n\n bytes32 private constant SUPERTOKEN_MINIMUM_DEPOSIT_KEY =\n keccak256(\"org.superfluid-finance.superfluid.superTokenMinimumDeposit\");\n\n using SafeCast for uint256;\n using SafeCast for int256;\n\n struct FlowData {\n uint256 timestamp; // stored as uint32\n int96 flowRate; // stored also as int96\n uint256 deposit; // stored as int96 with lower 32 bits clipped to 0\n uint256 owedDeposit; // stored as int96 with lower 32 bits clipped to 0\n }\n\n struct FlowParams {\n bytes32 flowId;\n address sender;\n address receiver;\n address flowOperator;\n int96 flowRate;\n bytes userData;\n }\n\n struct FlowOperatorData {\n uint8 permissions;\n int96 flowRateAllowance;\n }\n\n // solhint-disable-next-line no-empty-blocks\n constructor(ISuperfluid host) AgreementBase(address(host)) {}\n\n /**************************************************************************\n * ISuperAgreement interface\n *************************************************************************/\n\n /// @dev ISuperAgreement.realtimeBalanceOf implementation\n function realtimeBalanceOf(\n ISuperfluidToken token,\n address account,\n uint256 time\n )\n external\n view\n override\n returns (int256 dynamicBalance, uint256 deposit, uint256 owedDeposit)\n {\n (bool exist, FlowData memory state) = _getAccountFlowState(token, account);\n if(exist) {\n dynamicBalance = ((int256(time) - (int256(state.timestamp))) * state.flowRate);\n deposit = state.deposit;\n owedDeposit = state.owedDeposit;\n }\n }\n\n /**************************************************************************\n * IConstantFlowAgreementV1 interface\n *************************************************************************/\n\n function _getMaximumFlowRateFromDepositPure(\n uint256 liquidationPeriod,\n uint256 deposit)\n internal pure\n returns (int96 flowRate)\n {\n require(deposit <= MAXIMUM_DEPOSIT, \"CFA: deposit number too big\");\n deposit = _clipDepositNumberRoundingDown(deposit);\n\n uint256 flowrate1 = deposit / liquidationPeriod;\n\n // NOTE downcasting is safe as we constrain deposit to less than\n // 2 ** 95 (MAXIMUM_DEPOSIT) so the resulting value flowRate1 will fit into int96\n return int96(int256(flowrate1));\n }\n\n function _getDepositRequiredForFlowRatePure(\n uint256 minimumDeposit,\n uint256 liquidationPeriod,\n int96 flowRate)\n internal pure\n returns (uint256 deposit)\n {\n require(flowRate > 0, \"CFA: not for non-positive flow rate\");\n require(uint256(int256(flowRate)) * liquidationPeriod <= uint256(int256(type(int96).max)),\n \"CFA: flow rate too big\");\n uint256 calculatedDeposit = _calculateDeposit(flowRate, liquidationPeriod);\n return AgreementLibrary.max(minimumDeposit, calculatedDeposit);\n }\n\n /// @dev IConstantFlowAgreementV1.getMaximumFlowRateFromDeposit implementation\n function getMaximumFlowRateFromDeposit(\n ISuperfluidToken token,\n uint256 deposit)\n external view override\n returns (int96 flowRate)\n {\n (uint256 liquidationPeriod, ) = _decode3PsData(token);\n flowRate = _getMaximumFlowRateFromDepositPure(liquidationPeriod, deposit);\n }\n\n /// @dev IConstantFlowAgreementV1.getDepositRequiredForFlowRate implementation\n function getDepositRequiredForFlowRate(\n ISuperfluidToken token,\n int96 flowRate)\n external view override\n returns (uint256 deposit)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n ISuperfluidGovernance gov = ISuperfluidGovernance(host.getGovernance());\n uint256 minimumDeposit = gov.getConfigAsUint256(host, token, SUPERTOKEN_MINIMUM_DEPOSIT_KEY);\n uint256 pppConfig = gov.getConfigAsUint256(host, token, CFAV1_PPP_CONFIG_KEY);\n (uint256 liquidationPeriod, ) = SuperfluidGovernanceConfigs.decodePPPConfig(pppConfig);\n return _getDepositRequiredForFlowRatePure(minimumDeposit, liquidationPeriod, flowRate);\n }\n\n function isPatricianPeriodNow(\n ISuperfluidToken token,\n address account)\n public view override\n returns (bool isCurrentlyPatricianPeriod, uint256 timestamp)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n timestamp = host.getNow();\n isCurrentlyPatricianPeriod = isPatricianPeriod(token, account, timestamp);\n }\n\n function isPatricianPeriod(\n ISuperfluidToken token,\n address account,\n uint256 timestamp)\n public view override\n returns (bool)\n {\n (int256 availableBalance, ,) = token.realtimeBalanceOf(account, timestamp);\n if (availableBalance >= 0) {\n return true;\n }\n\n (uint256 liquidationPeriod, uint256 patricianPeriod) = _decode3PsData(token);\n (,FlowData memory senderAccountState) = _getAccountFlowState(token, account);\n int256 signedTotalCFADeposit = senderAccountState.deposit.toInt256();\n\n return _isPatricianPeriod(\n availableBalance,\n signedTotalCFADeposit,\n liquidationPeriod,\n patricianPeriod\n );\n }\n\n /// @dev IConstantFlowAgreementV1.createFlow implementation\n function createFlow(\n ISuperfluidToken token,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = currentContext.msgSender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n\n newCtx = _createFlow(\n flowVars,\n ctx,\n currentContext\n );\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlow implementation\n function updateFlow(\n ISuperfluidToken token,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = currentContext.msgSender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n\n bytes32 flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowId);\n\n newCtx = _updateFlow(\n flowVars,\n oldFlowData,\n exist,\n ctx,\n currentContext\n );\n }\n\n /// @dev IConstantFlowAgreementV1.deleteFlow implementation\n function deleteFlow(\n ISuperfluidToken token,\n address sender,\n address receiver,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n (,uint8 permissions,) = getFlowOperatorData(token, sender, currentContext.msgSender);\n bool hasPermissions = _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.DELETE_FLOW);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = 0;\n\n newCtx = _deleteFlow(flowVars, hasPermissions, ctx, currentContext);\n }\n\n /// @dev IConstantFlowAgreementV1.getFlow implementation\n function getFlow(\n ISuperfluidToken token,\n address sender,\n address receiver\n )\n external\n view\n override\n returns (\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit\n )\n {\n (, FlowData memory data) = _getAgreementData(\n token,\n _generateFlowId(sender, receiver));\n\n return(\n data.timestamp,\n data.flowRate,\n data.deposit,\n data.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getFlow implementation\n function getFlowByID(\n ISuperfluidToken token,\n bytes32 flowId\n )\n external\n view\n override\n returns(\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit\n )\n {\n (, FlowData memory data) = _getAgreementData(\n token,\n flowId\n );\n\n return (\n data.timestamp,\n data.flowRate,\n data.deposit,\n data.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getAccountFlowInfo implementation\n function getAccountFlowInfo(\n ISuperfluidToken token,\n address account\n )\n external view override\n returns (\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n return (\n state.timestamp,\n state.flowRate,\n state.deposit,\n state.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getNetFlow implementation\n function getNetFlow(\n ISuperfluidToken token,\n address account\n )\n external view override\n returns (int96 flowRate)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n return state.flowRate;\n }\n\n /**************************************************************************\n * Internal Helper Functions\n *************************************************************************/\n\n // Stack variables for _createOrUpdateFlow function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_createOrUpdateFlow {\n ISuperfluidToken token;\n address sender;\n address receiver;\n int96 flowRate;\n }\n\n /**\n * @dev Checks conditions for both create/update flow\n * returns the flowId and flowParams\n */\n function _createOrUpdateFlowCheck(\n _StackVars_createOrUpdateFlow memory flowVars,\n ISuperfluid.Context memory currentContext\n )\n internal pure\n returns(bytes32 flowId, FlowParams memory flowParams)\n {\n require(flowVars.receiver != address(0), \"CFA: receiver is zero\");\n\n flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n flowParams.flowId = flowId;\n flowParams.sender = flowVars.sender;\n flowParams.receiver = flowVars.receiver;\n flowParams.flowOperator = currentContext.msgSender;\n flowParams.flowRate = flowVars.flowRate;\n flowParams.userData = currentContext.userData;\n require(flowParams.sender != flowParams.receiver, \"CFA: no self flow\");\n require(flowParams.flowRate > 0, \"CFA: invalid flow rate\");\n }\n\n function _createFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n (bytes32 flowId, FlowParams memory flowParams) = _createOrUpdateFlowCheck(flowVars, currentContext);\n\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowId);\n require(!exist, \"CFA: flow already exist\");\n\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext, FlowChangeType.CREATE_FLOW);\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext);\n }\n\n _requireAvailableBalance(flowVars.token, currentContext);\n }\n\n function _updateFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n FlowData memory oldFlowData,\n bool exist,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n (, FlowParams memory flowParams) = _createOrUpdateFlowCheck(flowVars, currentContext);\n\n require(exist, \"CFA: flow does not exist\");\n\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext, FlowChangeType.UPDATE_FLOW);\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext);\n }\n\n _requireAvailableBalance(flowVars.token, currentContext);\n }\n\n function _deleteFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n bool hasPermissions,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n FlowParams memory flowParams;\n require(flowVars.sender != address(0), \"CFA: sender is zero\");\n require(flowVars.receiver != address(0), \"CFA: receiver is zero\");\n flowParams.flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n flowParams.sender = flowVars.sender;\n flowParams.receiver = flowVars.receiver;\n flowParams.flowOperator = currentContext.msgSender;\n flowParams.flowRate = 0;\n flowParams.userData = currentContext.userData;\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowParams.flowId);\n require(exist, \"CFA: flow does not exist\");\n\n (int256 availableBalance,,) = flowVars.token.realtimeBalanceOf(flowVars.sender, currentContext.timestamp);\n\n // delete should only be called by sender, receiver or flowOperator\n // unless it is a liquidation (availale balance < 0)\n if (currentContext.msgSender != flowVars.sender &&\n currentContext.msgSender != flowVars.receiver &&\n !hasPermissions)\n {\n if (!ISuperfluid(msg.sender).isAppJailed(ISuperApp(flowVars.sender)) &&\n !ISuperfluid(msg.sender).isAppJailed(ISuperApp(flowVars.receiver))) {\n require(availableBalance < 0, \"CFA: sender account is not critical\");\n }\n }\n\n if (availableBalance < 0) {\n _makeLiquidationPayouts(\n flowVars.token,\n availableBalance,\n flowParams,\n oldFlowData,\n currentContext.msgSender);\n }\n\n newCtx = ctx;\n // if the sender of the flow is deleting the flow\n if (currentContext.msgSender == flowVars.sender) {\n // if the sender is deleting a flow to a super app receiver\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n } else {\n // if the receiver is not a super app (sender may be a super app or non super app)\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n // if the receiver of the flow is deleting the flow\n } else if (currentContext.msgSender == flowVars.receiver) {\n // if the flow being deleted by the receiver has a super app sender\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.sender))) {\n newCtx = _changeFlowToApp(\n flowVars.sender,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the receiver of the flow deleting the flow is a super app\n } else if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n address(0),\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the sender is not a super app (the stream is not coming to or from a super app)\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n // flowOperator case OR liquidation case (when the msgSender isn't the sender or receiver)\n } else /* liquidations or flowOperator deleting a flow */ {\n // if the sender is an app and is critical\n // we jail the app\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.sender)) && availableBalance < 0) {\n newCtx = ISuperfluid(msg.sender).jailApp(\n newCtx,\n ISuperApp(flowVars.sender),\n SuperAppDefinitions.APP_RULE_NO_CRITICAL_SENDER_ACCOUNT);\n }\n // if the stream we're deleting (possibly liquidating) has a receiver that is a super app\n // always attempt to call receiver callback\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the stream we're deleting (possibly liquidating) has a receiver that is not a super app\n // or the sender is a super app or the sender is not a super app\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n }\n }\n\n /**************************************************************************\n * ACL Functions\n *************************************************************************/\n\n /// @dev IConstantFlowAgreementV1.createFlowByOperator implementation\n function createFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n require(currentContext.msgSender != sender, \"CFA: E_NO_SENDER_CREATE\");\n\n {\n // check if flow operator has create permissions\n (\n bytes32 flowOperatorId,\n uint8 permissions,\n int96 flowRateAllowance\n ) = getFlowOperatorData(token, sender, currentContext.msgSender);\n require(\n _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.CREATE_FLOW),\n \"CFA: E_NO_OPERATOR_CREATE_FLOW\"\n );\n\n // check if desired flow rate is allowed and update flow rate allowance\n int96 updatedFlowRateAllowance = flowRateAllowance == type(int96).max\n ? flowRateAllowance\n : flowRateAllowance - flowRate;\n require(updatedFlowRateAllowance >= 0, \"CFA: E_EXCEED_FLOW_RATE_ALLOWANCE\");\n _updateFlowRateAllowance(token, flowOperatorId, permissions, updatedFlowRateAllowance);\n }\n {\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n newCtx = _createFlow(\n flowVars,\n ctx,\n currentContext\n );\n }\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlowByOperator implementation\n function updateFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n require(currentContext.msgSender != sender, \"CFA: E_NO_SENDER_UPDATE\");\n\n // check if flow exists\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(token, _generateFlowId(sender, receiver));\n\n {\n // check if flow operator has create permissions\n (\n bytes32 flowOperatorId,\n uint8 permissions,\n int96 flowRateAllowance\n ) = getFlowOperatorData(token, sender, currentContext.msgSender);\n require(\n _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.UPDATE_FLOW),\n \"E_NO_OPERATOR_UPDATE_FLOW\"\n );\n\n // check if desired flow rate is allowed and update flow rate allowance\n int96 updatedFlowRateAllowance = flowRateAllowance == type(int96).max || oldFlowData.flowRate >= flowRate\n ? flowRateAllowance\n : flowRateAllowance - (flowRate - oldFlowData.flowRate);\n require(updatedFlowRateAllowance >= 0, \"CFA: E_EXCEED_FLOW_RATE_ALLOWANCE\");\n _updateFlowRateAllowance(token, flowOperatorId, permissions, updatedFlowRateAllowance);\n }\n\n {\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n newCtx = _updateFlow(\n flowVars,\n oldFlowData,\n exist,\n ctx,\n currentContext\n );\n }\n }\n\n /// @dev IConstantFlowAgreementV1.deleteFlowByOperator implementation\n function deleteFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n (,uint8 permissions,) = getFlowOperatorData(token, sender, currentContext.msgSender);\n bool hasPermissions = _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.DELETE_FLOW);\n require(hasPermissions, \"E_NO_OPERATOR_DELETE_FLOW\");\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = 0;\n\n newCtx = _deleteFlow(flowVars, hasPermissions, ctx, currentContext);\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlowOperatorPermissions implementation\n function updateFlowOperatorPermissions(\n ISuperfluidToken token,\n address flowOperator,\n uint8 permissions,\n int96 flowRateAllowance, // flowRateBudget\n bytes calldata ctx\n ) public override returns(bytes memory newCtx) {\n newCtx = ctx;\n require(FlowOperatorDefinitions.isPermissionsClean(permissions), \"CFA: Unclean permissions\");\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n // [SECURITY] NOTE: we are holding the assumption here that ctx is correct and we validate it with\n // authorizeTokenAccess:\n require(currentContext.msgSender != flowOperator, \"CFA: E_NO_SENDER_FLOW_OPERATOR\");\n require(flowRateAllowance >= 0, \"CFA: E_NO_NEGATIVE_ALLOWANCE\");\n FlowOperatorData memory flowOperatorData;\n flowOperatorData.permissions = permissions;\n flowOperatorData.flowRateAllowance = flowRateAllowance;\n bytes32 flowOperatorId = _generateFlowOperatorId(currentContext.msgSender, flowOperator);\n token.updateAgreementData(flowOperatorId, _encodeFlowOperatorData(flowOperatorData));\n\n emit FlowOperatorUpdated(token, currentContext.msgSender, flowOperator, permissions, flowRateAllowance);\n }\n\n /// @dev IConstantFlowAgreementV1.authorizeFlowOperatorWithFullControl implementation\n function authorizeFlowOperatorWithFullControl(\n ISuperfluidToken token,\n address flowOperator,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n newCtx = updateFlowOperatorPermissions(\n token,\n flowOperator,\n FlowOperatorDefinitions.AUTHORIZE_FULL_CONTROL,\n type(int96).max,\n ctx\n );\n }\n\n /// @dev IConstantFlowAgreementV1.revokeFlowOperatorWithFullControl implementation\n function revokeFlowOperatorWithFullControl(\n ISuperfluidToken token,\n address flowOperator,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n // NOTE: REVOKE_FULL_CONTROL = 0\n newCtx = updateFlowOperatorPermissions(token, flowOperator, 0, 0, ctx);\n }\n\n /// @dev IConstantFlowAgreementV1.getFlowOperatorData implementation\n function getFlowOperatorData(\n ISuperfluidToken token,\n address sender,\n address flowOperator\n )\n public view override\n returns(bytes32 flowOperatorId, uint8 permissions, int96 flowRateAllowance)\n {\n flowOperatorId = _generateFlowOperatorId(sender, flowOperator);\n (, FlowOperatorData memory flowOperatorData) = _getFlowOperatorData(token, flowOperatorId);\n permissions = flowOperatorData.permissions;\n flowRateAllowance = flowOperatorData.flowRateAllowance;\n }\n\n /// @dev IConstantFlowAgreementV1.getFlowOperatorDataByID implementation\n function getFlowOperatorDataByID(\n ISuperfluidToken token,\n bytes32 flowOperatorId\n )\n external view override\n returns(uint8 permissions, int96 flowRateAllowance)\n {\n (, FlowOperatorData memory flowOperatorData) = _getFlowOperatorData(token, flowOperatorId);\n permissions = flowOperatorData.permissions;\n flowRateAllowance = flowOperatorData.flowRateAllowance;\n }\n\n /**************************************************************************\n * Internal State Functions\n *************************************************************************/\n\n enum FlowChangeType {\n CREATE_FLOW,\n UPDATE_FLOW,\n DELETE_FLOW\n }\n\n function _getAccountFlowState\n (\n ISuperfluidToken token,\n address account\n )\n private view\n returns(bool exist, FlowData memory)\n {\n bytes32[] memory data = token.getAgreementStateSlot(address(this), account, 0 /* slotId */, 1 /* length */);\n return _decodeFlowData(uint256(data[0]));\n }\n\n function _getAgreementData\n (\n ISuperfluidToken token,\n bytes32 dId\n )\n private view\n returns (bool exist, FlowData memory)\n {\n bytes32[] memory data = token.getAgreementData(address(this), dId, 1);\n return _decodeFlowData(uint256(data[0]));\n }\n\n function _getFlowOperatorData\n (\n ISuperfluidToken token,\n bytes32 flowOperatorId\n )\n private view\n returns (bool exist, FlowOperatorData memory)\n {\n // 1 because we are storing the flowOperator data in one word\n bytes32[] memory data = token.getAgreementData(address(this), flowOperatorId, 1);\n return _decodeFlowOperatorData(uint256(data[0]));\n }\n\n function _updateFlowRateAllowance\n (\n ISuperfluidToken token,\n bytes32 flowOperatorId,\n uint8 existingPermissions,\n int96 updatedFlowRateAllowance\n )\n private\n {\n FlowOperatorData memory flowOperatorData;\n flowOperatorData.permissions = existingPermissions;\n flowOperatorData.flowRateAllowance = updatedFlowRateAllowance;\n token.updateAgreementData(flowOperatorId, _encodeFlowOperatorData(flowOperatorData));\n }\n\n function _updateAccountFlowState(\n ISuperfluidToken token,\n address account,\n int96 flowRateDelta,\n int256 depositDelta,\n int256 owedDepositDelta,\n uint256 currentTimestamp\n )\n private\n returns (int96 newNetFlowRate)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n int256 dynamicBalance = (currentTimestamp - state.timestamp).toInt256()\n * int256(state.flowRate);\n if (dynamicBalance != 0) {\n token.settleBalance(account, dynamicBalance);\n }\n state.flowRate = state.flowRate + flowRateDelta;\n state.timestamp = currentTimestamp;\n state.deposit = (state.deposit.toInt256() + depositDelta).toUint256();\n state.owedDeposit = (state.owedDeposit.toInt256() + owedDepositDelta).toUint256();\n\n token.updateAgreementStateSlot(account, 0 /* slot id */, _encodeFlowData(state));\n\n return state.flowRate;\n }\n\n /**\n * @dev update a flow to a non-app receiver\n */\n function _changeFlowToNonApp(\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData,\n bytes memory ctx,\n ISuperfluid.Context memory currentContext\n )\n private\n returns (bytes memory newCtx)\n {\n // owed deposit should have been always zero, since an app should never become a non app\n assert(oldFlowData.owedDeposit == 0);\n\n // STEP 1: update the flow\n int256 depositDelta;\n FlowData memory newFlowData;\n (depositDelta,,newFlowData) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n\n // STEP 2: update app allowance used\n if (currentContext.appAllowanceToken == token) {\n newCtx = ISuperfluid(msg.sender).ctxUseAllowance(\n ctx,\n newFlowData.deposit, // allowanceWantedMore\n depositDelta // allowanceUsedDelta\n );\n } else {\n newCtx = ctx;\n }\n }\n\n /**\n * @dev change a flow to a app receiver\n */\n\n // Stack variables for _changeFlowToApp function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_changeFlowToApp {\n bytes cbdata;\n FlowData newFlowData;\n ISuperfluid.Context appContext;\n }\n function _changeFlowToApp(\n address appToCallback,\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData,\n bytes memory ctx,\n ISuperfluid.Context memory currentContext,\n FlowChangeType optype\n )\n private\n returns (bytes memory newCtx)\n {\n newCtx = ctx;\n // apply callbacks\n _StackVars_changeFlowToApp memory vars;\n\n // call callback\n if (appToCallback != address(0)) {\n AgreementLibrary.CallbackInputs memory cbStates = AgreementLibrary.createCallbackInputs(\n token,\n appToCallback,\n flowParams.flowId,\n abi.encode(flowParams.sender, flowParams.receiver)\n );\n\n // call the before callback\n if (optype == FlowChangeType.CREATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP;\n } else if (optype == FlowChangeType.UPDATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP;\n } else /* if (optype == FlowChangeType.DELETE_FLOW) */ {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP;\n }\n vars.cbdata = AgreementLibrary.callAppBeforeCallback(cbStates, ctx);\n\n (,cbStates.appAllowanceGranted,) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n cbStates.appAllowanceGranted = cbStates.appAllowanceGranted * uint256(currentContext.appLevel + 1);\n cbStates.appAllowanceUsed = oldFlowData.owedDeposit.toInt256();\n // - each app level can at least \"relay\" the same amount of input flow rate to others\n // - each app level get a same amount of allowance\n\n if (optype == FlowChangeType.CREATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_CREATED_NOOP;\n } else if (optype == FlowChangeType.UPDATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_UPDATED_NOOP;\n } else /* if (optype == FlowChangeType.DELETE_FLOW) */ {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP;\n }\n (vars.appContext, newCtx) = AgreementLibrary.callAppAfterCallback(cbStates, vars.cbdata, newCtx);\n\n // NB: the callback might update the same flow!!\n // reload the flow data\n (, vars.newFlowData) = _getAgreementData(token, flowParams.flowId);\n } else {\n (,,vars.newFlowData) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n }\n\n // REVIEW the re-entrace assumptions from this point on\n\n // NOTE: vars.appContext.appAllowanceUsed will be adjusted by callAppAfterCallback\n // and its range will be [0, currentContext.appAllowance]\n {\n // clipping the allowance used amount before storing\n if (vars.appContext.appAllowanceUsed > 0) {\n // give more to the app\n vars.appContext.appAllowanceUsed =\n _clipDepositNumber(vars.appContext.appAllowanceUsed.toUint256()).toInt256();\n }\n\n int256 appAllowanceDelta = vars.appContext.appAllowanceUsed\n - oldFlowData.owedDeposit.toInt256();\n\n // update flow data and account state with the allowance delta\n {\n vars.newFlowData.deposit = (vars.newFlowData.deposit.toInt256()\n + appAllowanceDelta).toUint256();\n vars.newFlowData.owedDeposit = (vars.newFlowData.owedDeposit.toInt256()\n + appAllowanceDelta).toUint256();\n token.updateAgreementData(flowParams.flowId, _encodeFlowData(vars.newFlowData));\n // update sender and receiver deposit (for sender) and owed deposit (for receiver)\n _updateAccountFlowState(\n token,\n flowParams.sender,\n 0, // flow rate delta\n appAllowanceDelta, // deposit delta\n 0, // owed deposit delta\n currentContext.timestamp\n );\n _updateAccountFlowState(\n token,\n flowParams.receiver,\n 0, // flow rate delta\n 0, // deposit delta\n appAllowanceDelta, // owed deposit delta\n currentContext.timestamp\n );\n }\n\n if (address(currentContext.appAllowanceToken) == address(0) ||\n currentContext.appAllowanceToken == token)\n {\n newCtx = ISuperfluid(msg.sender).ctxUseAllowance(\n newCtx,\n vars.newFlowData.deposit, // allowanceWantedMore\n appAllowanceDelta // allowanceUsedDelta\n );\n }\n\n // if receiver super app doesn't have enough available balance to give back app allowance\n // revert (non termination callbacks),\n // or take it from the sender and jail the app\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowParams.receiver))) {\n int256 availableBalance;\n (availableBalance,,) = token.realtimeBalanceOf(flowParams.receiver, currentContext.timestamp);\n if (availableBalance < 0) {\n // app goes broke, send the app to jail\n if (optype == FlowChangeType.DELETE_FLOW) {\n newCtx = ISuperfluid(msg.sender).jailApp(\n newCtx,\n ISuperApp(flowParams.receiver),\n SuperAppDefinitions.APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT);\n // calculate user's damage\n int256 userDamageAmount = AgreementLibrary.min(\n // user will take the damage if the app is broke,\n -availableBalance,\n // but user's damage is limited to the amount of app allowance it gives to the app\n AgreementLibrary.max(0, -appAllowanceDelta));\n token.settleBalance(\n flowParams.sender,\n -userDamageAmount\n );\n token.settleBalance(\n flowParams.receiver,\n userDamageAmount\n );\n } else {\n revert(\"CFA: APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT\");\n }\n }\n }\n }\n }\n\n // Stack variables for _changeFlow function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_changeFlow {\n int96 totalSenderFlowRate;\n int96 totalReceiverFlowRate;\n }\n\n /**\n * @dev change flow between sender and receiver with new flow rate\n *\n * NOTE:\n * - leaving owed deposit unchanged for later adjustment\n * - depositDelta output is always clipped (see _clipDepositNumber)\n */\n function _changeFlow(\n uint256 currentTimestamp,\n ISuperfluidToken appAllowanceToken,\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData\n )\n private\n returns (\n int256 depositDelta,\n uint256 appAllowanceBase,\n FlowData memory newFlowData\n )\n {\n uint256 newDeposit;\n { // enclosed block to avoid stack too deep error\n uint256 minimumDeposit;\n // STEP 1: calculate deposit required for the flow\n {\n (uint256 liquidationPeriod, ) = _decode3PsData(token);\n ISuperfluidGovernance gov = ISuperfluidGovernance(ISuperfluid(msg.sender).getGovernance());\n minimumDeposit = gov.getConfigAsUint256(\n ISuperfluid(msg.sender), token, SUPERTOKEN_MINIMUM_DEPOSIT_KEY);\n // rounding up the number for app allowance too\n // CAVEAT:\n // - Now app could create a flow rate that is slightly higher than the incoming flow rate.\n // - The app may be jailed due to negative balance if it does this without its own balance.\n // Rule of thumbs:\n // - App can use app allowance to create a flow that has the same incoming flow rate\n // - But due to deposit clipping, there is no guarantee that the sum of the out going flow\n // deposit can be covered by the allowance always.\n // - It is advisable for the app to check the allowance usages carefully, and if possible\n // Always have some its own balances to cover the deposits.\n\n // preliminary calc of new deposit required, may be changed later in step 2.\n // used as a variable holding the new deposit amount in the meantime\n appAllowanceBase = _calculateDeposit(flowParams.flowRate, liquidationPeriod);\n }\n\n // STEP 2: apply minimum deposit rule and calculate deposit delta\n // preliminary calc depositDelta (minimum deposit rule not yet applied)\n depositDelta = appAllowanceBase.toInt256()\n - oldFlowData.deposit.toInt256()\n + oldFlowData.owedDeposit.toInt256();\n\n // preliminary calc newDeposit (minimum deposit rule not yet applied)\n newDeposit = (oldFlowData.deposit.toInt256() + depositDelta).toUint256();\n\n // calc depositDelta and newDeposit with minimum deposit rule applied\n if (newDeposit < minimumDeposit && flowParams.flowRate > 0) {\n depositDelta = minimumDeposit.toInt256()\n - oldFlowData.deposit.toInt256()\n + oldFlowData.owedDeposit.toInt256();\n newDeposit = minimumDeposit;\n }\n\n // allowance should be of the same token\n if (address(appAllowanceToken) != address(0) &&\n appAllowanceToken != token)\n {\n appAllowanceBase = 0;\n }\n\n // STEP 3: update current flow info\n newFlowData = FlowData(\n flowParams.flowRate > 0 ? currentTimestamp : 0,\n flowParams.flowRate,\n newDeposit,\n oldFlowData.owedDeposit // leaving it unchanged for later adjustment\n );\n token.updateAgreementData(flowParams.flowId, _encodeFlowData(newFlowData));\n }\n {\n _StackVars_changeFlow memory vars;\n // STEP 4: update sender and receiver account flow state with the deltas\n vars.totalSenderFlowRate = _updateAccountFlowState(\n token,\n flowParams.sender,\n oldFlowData.flowRate - flowParams.flowRate,\n depositDelta,\n 0,\n currentTimestamp\n );\n vars.totalReceiverFlowRate = _updateAccountFlowState(\n token,\n flowParams.receiver,\n flowParams.flowRate - oldFlowData.flowRate,\n 0,\n 0, // leaving owed deposit unchanged for later adjustment\n currentTimestamp\n );\n\n // STEP 5: emit the FlowUpdated Event\n // NOTE we emit these two events one after the other\n // so the subgraph can properly handle this in the\n // mapping function\n emit FlowUpdated(\n token,\n flowParams.sender,\n flowParams.receiver,\n flowParams.flowRate,\n vars.totalSenderFlowRate,\n vars.totalReceiverFlowRate,\n flowParams.userData\n );\n emit FlowUpdatedExtension(\n flowParams.flowOperator,\n newDeposit\n );\n }\n }\n function _requireAvailableBalance(\n ISuperfluidToken token,\n ISuperfluid.Context memory currentContext\n )\n private view\n {\n // do not enforce balance checks during callbacks for the appAllowanceToken\n if (currentContext.callType != ContextDefinitions.CALL_INFO_CALL_TYPE_APP_CALLBACK ||\n currentContext.appAllowanceToken != token) {\n (int256 availableBalance,,) = token.realtimeBalanceOf(currentContext.msgSender, currentContext.timestamp);\n require(availableBalance >= 0, \"CFA: not enough available balance\");\n }\n }\n\n function _makeLiquidationPayouts(\n ISuperfluidToken token,\n int256 availableBalance,\n FlowParams memory flowParams,\n FlowData memory flowData,\n address liquidator\n )\n private\n {\n (,FlowData memory senderAccountState) = _getAccountFlowState(token, flowParams.sender);\n\n int256 signedSingleDeposit = flowData.deposit.toInt256();\n // TODO: GDA deposit should be considered here too\n int256 signedTotalCFADeposit = senderAccountState.deposit.toInt256();\n bytes memory liquidationTypeData;\n bool isCurrentlyPatricianPeriod;\n\n // Liquidation rules:\n // - let Available Balance = AB (is negative)\n // - Agreement Single Deposit = SD\n // - Agreement Total Deposit = TD\n // - Total Reward Left = RL = AB + TD\n // #1 Can the total account deposit still cover the available balance deficit?\n int256 totalRewardLeft = availableBalance + signedTotalCFADeposit;\n\n // To retrieve patrician period\n // Note: curly brackets are to handle stack too deep overflow issue\n {\n (uint256 liquidationPeriod, uint256 patricianPeriod) = _decode3PsData(token);\n isCurrentlyPatricianPeriod = _isPatricianPeriod(\n availableBalance,\n signedTotalCFADeposit,\n liquidationPeriod,\n patricianPeriod\n );\n }\n\n // user is in a critical state\n if (totalRewardLeft >= 0) {\n // the liquidator is always whoever triggers the liquidation, but the\n // account which receives the reward will depend on the period (Patrician or Pleb)\n // #1.a.1 yes: then reward = (SD / TD) * RL\n int256 rewardAmount = signedSingleDeposit * totalRewardLeft / signedTotalCFADeposit;\n liquidationTypeData = abi.encode(1, isCurrentlyPatricianPeriod ? 0 : 1);\n token.makeLiquidationPayoutsV2(\n flowParams.flowId, // id\n liquidationTypeData, // (1 means \"v1\" of this encoding schema) - 0 or 1 for patrician or pleb\n liquidator, // liquidatorAddress\n\n // useDefaultRewardAccount: true in patrician period, else liquidator gets reward\n isCurrentlyPatricianPeriod,\n\n flowParams.sender, // targetAccount\n rewardAmount.toUint256(), // rewardAmount: remaining deposit of the flow to be liquidated\n rewardAmount * -1 // targetAccountBalanceDelta: amount deducted from the flow sender\n );\n } else {\n // #1.b.1 no: then the liquidator takes full amount of the single deposit\n int256 rewardAmount = signedSingleDeposit;\n liquidationTypeData = abi.encode(1, 2);\n token.makeLiquidationPayoutsV2(\n flowParams.flowId, // id\n liquidationTypeData, // (1 means \"v1\" of this encoding schema) - 2 for pirate/bailout period\n liquidator, // liquidatorAddress\n false, // useDefaultRewardAccount: out of patrician period, in pirate period, so always false\n flowParams.sender, // targetAccount\n rewardAmount.toUint256(), // rewardAmount: single deposit of flow\n totalRewardLeft * -1 // targetAccountBalanceDelta: amount to bring sender AB to 0\n // NOTE: bailoutAmount = rewardAmount + targetAccountBalanceDelta + paid by rewardAccount\n );\n }\n }\n\n /**************************************************************************\n * Deposit Calculation Pure Functions\n *************************************************************************/\n\n function _clipDepositNumberRoundingDown(uint256 deposit)\n internal pure\n returns(uint256)\n {\n return ((deposit >> 32)) << 32;\n }\n\n function _clipDepositNumber(uint256 deposit)\n internal pure\n returns(uint256)\n {\n // clipping the value, rounding up\n uint256 rounding = (deposit & type(uint32).max) > 0 ? 1 : 0;\n return ((deposit >> 32) + rounding) << 32;\n }\n\n function _calculateDeposit(\n int96 flowRate,\n uint256 liquidationPeriod\n )\n internal pure\n returns(uint256 deposit)\n {\n if (flowRate == 0) return 0;\n\n // NOTE: safecast for int96 with extra assertion\n assert(liquidationPeriod <= uint256(int256(type(int96).max)));\n deposit = uint256(int256(flowRate * int96(uint96(liquidationPeriod))));\n return _clipDepositNumber(deposit);\n }\n\n /**************************************************************************\n * Flow Data Pure Functions\n *************************************************************************/\n\n function _generateFlowId(address sender, address receiver) private pure returns(bytes32 id) {\n return keccak256(abi.encode(sender, receiver));\n }\n\n //\n // Data packing:\n //\n // WORD A: | timestamp | flowRate | deposit | owedDeposit |\n // | 32b | 96b | 64 | 64 |\n //\n // NOTE:\n // - flowRate has 96 bits length\n // - deposit has 96 bits length too, but 32 bits are clipped-off when storing\n\n function _encodeFlowData\n (\n FlowData memory flowData\n )\n internal pure\n returns(bytes32[] memory data)\n {\n // enable these for debugging\n // assert(flowData.deposit & type(uint32).max == 0);\n // assert(flowData.owedDeposit & type(uint32).max == 0);\n data = new bytes32[](1);\n data[0] = bytes32(\n ((uint256(flowData.timestamp)) << 224) |\n ((uint256(uint96(flowData.flowRate)) << 128)) |\n (uint256(flowData.deposit) >> 32 << 64) |\n (uint256(flowData.owedDeposit) >> 32)\n );\n }\n\n function _decodeFlowData\n (\n uint256 wordA\n )\n internal pure\n returns(bool exist, FlowData memory flowData)\n {\n exist = wordA > 0;\n if (exist) {\n flowData.timestamp = uint32(wordA >> 224);\n // NOTE because we are upcasting from type(uint96).max to uint256 to int256, we do not need to use safecast\n flowData.flowRate = int96(int256(wordA >> 128) & int256(uint256(type(uint96).max)));\n flowData.deposit = ((wordA >> 64) & uint256(type(uint64).max)) << 32 /* recover clipped bits*/;\n flowData.owedDeposit = (wordA & uint256(type(uint64).max)) << 32 /* recover clipped bits*/;\n }\n }\n\n /**************************************************************************\n * 3P's Pure Functions\n *************************************************************************/\n\n //\n // Data packing:\n //\n // WORD A: | reserved | patricianPeriod | liquidationPeriod |\n // | 192 | 32 | 32 |\n //\n // NOTE:\n // - liquidation period has 32 bits length\n // - patrician period also has 32 bits length\n\n function _decode3PsData(\n ISuperfluidToken token\n )\n internal view\n returns(uint256 liquidationPeriod, uint256 patricianPeriod)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n ISuperfluidGovernance gov = ISuperfluidGovernance(host.getGovernance());\n uint256 pppConfig = gov.getConfigAsUint256(host, token, CFAV1_PPP_CONFIG_KEY);\n (liquidationPeriod, patricianPeriod) = SuperfluidGovernanceConfigs.decodePPPConfig(pppConfig);\n }\n\n function _isPatricianPeriod(\n int256 availableBalance,\n int256 signedTotalCFADeposit,\n uint256 liquidationPeriod,\n uint256 patricianPeriod\n )\n internal pure\n returns (bool)\n {\n int256 totalRewardLeft = availableBalance + signedTotalCFADeposit;\n int256 totalCFAOutFlowrate = signedTotalCFADeposit / int256(liquidationPeriod);\n // divisor cannot be zero with existing outflow\n return totalRewardLeft / totalCFAOutFlowrate > int256(liquidationPeriod - patricianPeriod);\n }\n\n /**************************************************************************\n * ACL Pure Functions\n *************************************************************************/\n\n function _generateFlowOperatorId(address sender, address flowOperator) private pure returns(bytes32 id) {\n return keccak256(abi.encode(\"flowOperator\", sender, flowOperator));\n }\n\n //\n // Data packing:\n //\n // WORD A: | reserved | permissions | reserved | flowRateAllowance |\n // | 120 | 8 | 32 | 96 |\n //\n // NOTE:\n // - flowRateAllowance has 96 bits length\n // - permissions is an 8-bit octo bitmask\n // - ...0 0 0 (...delete update create)\n\n function _encodeFlowOperatorData\n (\n FlowOperatorData memory flowOperatorData\n )\n internal pure\n returns(bytes32[] memory data)\n {\n assert(flowOperatorData.flowRateAllowance >= 0); // flowRateAllowance must not be less than 0\n data = new bytes32[](1);\n data[0] = bytes32(\n uint256(flowOperatorData.permissions) << 128 |\n uint256(int256(flowOperatorData.flowRateAllowance))\n );\n }\n\n function _decodeFlowOperatorData\n (\n uint256 wordA\n )\n internal pure\n returns(bool exist, FlowOperatorData memory flowOperatorData)\n {\n exist = wordA > 0;\n if (exist) {\n // NOTE: For safecast, doing extra bitmasking to not to have any trust assumption of token storage\n flowOperatorData.flowRateAllowance = int96(int256(wordA & uint256(int256(type(int96).max))));\n flowOperatorData.permissions = uint8(wordA >> 128) & type(uint8).max;\n }\n }\n\n function _getBooleanFlowOperatorPermissions\n (\n uint8 permissions,\n FlowChangeType flowChangeType\n )\n internal pure\n returns (bool flowchangeTypeAllowed)\n {\n if (flowChangeType == FlowChangeType.CREATE_FLOW) {\n flowchangeTypeAllowed = permissions & uint8(1) == 1;\n } else if (flowChangeType == FlowChangeType.UPDATE_FLOW) {\n flowchangeTypeAllowed = (permissions >> 1) & uint8(1) == 1;\n } else { /** flowChangeType === FlowChangeType.DELETE_FLOW */\n flowchangeTypeAllowed = (permissions >> 2) & uint8(1) == 1;\n }\n }\n}\n",
30253
+ "source": "// SPDX-License-Identifier: AGPLv3\npragma solidity 0.8.14;\n\nimport {\n IConstantFlowAgreementV1,\n ISuperfluidToken\n} from \"../interfaces/agreements/IConstantFlowAgreementV1.sol\";\nimport {\n ISuperfluid,\n ISuperfluidGovernance,\n ISuperApp,\n FlowOperatorDefinitions,\n SuperAppDefinitions,\n ContextDefinitions,\n SuperfluidGovernanceConfigs\n} from \"../interfaces/superfluid/ISuperfluid.sol\";\nimport { AgreementBase } from \"./AgreementBase.sol\";\n\nimport { SafeCast } from \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport { AgreementLibrary } from \"./AgreementLibrary.sol\";\n\n\n/**\n * @title ConstantFlowAgreementV1 contract\n * @author Superfluid\n * @dev Please read IConstantFlowAgreementV1 for implementation notes.\n * @dev For more technical notes, please visit protocol-monorepo wiki area.\n */\ncontract ConstantFlowAgreementV1 is\n AgreementBase,\n IConstantFlowAgreementV1\n{\n\n /**\n * E_NO_SENDER_CREATE - sender cannot create as flowOperator\n * E_NO_SENDER_UPDATE - sender cannot update as flowOperator\n * E_NO_SENDER_DELETE - sender cannot delete as flowOperator\n * E_EXCEED_FLOW_RATE_ALLOWANCE - flowRateAllowance exceeeded\n * E_NO_OPERATOR_CREATE_FLOW - operator does not have permissions to create flow\n * E_NO_OPERATOR_UPDATE_FLOW - operator does not have permissions to update flow\n * E_NO_OPERATOR_DELETE_FLOW - operator does not have permissions to delete flow\n * E_NO_SENDER_FLOW_OPERATOR - sender cannot set themselves as the flow operator\n * E_NO_NEGATIVE_ALLOWANCE - sender cannot set a negative allowance\n */\n\n /**\n * @dev Default minimum deposit value\n *\n * NOTE:\n * - It may come as a surprise that it is not 0, this is the minimum friction we have in the system for the\n * imperfect blockchain system we live in.\n * - It is related to deposit clipping, and it is always rounded-up when clipping.\n */\n uint256 public constant DEFAULT_MINIMUM_DEPOSIT = uint256(uint96(1 << 32));\n /// @dev Maximum deposit value\n uint256 public constant MAXIMUM_DEPOSIT = uint256(uint96(type(int96).max));\n\n /// @dev Maximum flow rate\n uint256 public constant MAXIMUM_FLOW_RATE = uint256(uint96(type(int96).max));\n\n bytes32 private constant CFAV1_PPP_CONFIG_KEY =\n keccak256(\"org.superfluid-finance.agreements.ConstantFlowAgreement.v1.PPPConfiguration\");\n\n bytes32 private constant SUPERTOKEN_MINIMUM_DEPOSIT_KEY =\n keccak256(\"org.superfluid-finance.superfluid.superTokenMinimumDeposit\");\n\n using SafeCast for uint256;\n using SafeCast for int256;\n\n struct FlowData {\n uint256 timestamp; // stored as uint32\n int96 flowRate; // stored also as int96\n uint256 deposit; // stored as int96 with lower 32 bits clipped to 0\n uint256 owedDeposit; // stored as int96 with lower 32 bits clipped to 0\n }\n\n struct FlowParams {\n bytes32 flowId;\n address sender;\n address receiver;\n address flowOperator;\n int96 flowRate;\n bytes userData;\n }\n\n struct FlowOperatorData {\n uint8 permissions;\n int96 flowRateAllowance;\n }\n\n // solhint-disable-next-line no-empty-blocks\n constructor(ISuperfluid host) AgreementBase(address(host)) {}\n\n /**************************************************************************\n * ISuperAgreement interface\n *************************************************************************/\n\n /// @dev ISuperAgreement.realtimeBalanceOf implementation\n function realtimeBalanceOf(\n ISuperfluidToken token,\n address account,\n uint256 time\n )\n external\n view\n override\n returns (int256 dynamicBalance, uint256 deposit, uint256 owedDeposit)\n {\n (bool exist, FlowData memory state) = _getAccountFlowState(token, account);\n if(exist) {\n dynamicBalance = ((int256(time) - (int256(state.timestamp))) * state.flowRate);\n deposit = state.deposit;\n owedDeposit = state.owedDeposit;\n }\n }\n\n /**************************************************************************\n * IConstantFlowAgreementV1 interface\n *************************************************************************/\n\n function _getMaximumFlowRateFromDepositPure(\n uint256 liquidationPeriod,\n uint256 deposit)\n internal pure\n returns (int96 flowRate)\n {\n require(deposit <= MAXIMUM_DEPOSIT, \"CFA: deposit number too big\");\n deposit = _clipDepositNumberRoundingDown(deposit);\n\n uint256 flowrate1 = deposit / liquidationPeriod;\n\n // NOTE downcasting is safe as we constrain deposit to less than\n // 2 ** 95 (MAXIMUM_DEPOSIT) so the resulting value flowRate1 will fit into int96\n return int96(int256(flowrate1));\n }\n\n function _getDepositRequiredForFlowRatePure(\n uint256 minimumDeposit,\n uint256 liquidationPeriod,\n int96 flowRate)\n internal pure\n returns (uint256 deposit)\n {\n require(flowRate > 0, \"CFA: not for non-positive flow rate\");\n require(uint256(int256(flowRate)) * liquidationPeriod <= uint256(int256(type(int96).max)),\n \"CFA: flow rate too big\");\n uint256 calculatedDeposit = _calculateDeposit(flowRate, liquidationPeriod);\n return AgreementLibrary.max(minimumDeposit, calculatedDeposit);\n }\n\n /// @dev IConstantFlowAgreementV1.getMaximumFlowRateFromDeposit implementation\n function getMaximumFlowRateFromDeposit(\n ISuperfluidToken token,\n uint256 deposit)\n external view override\n returns (int96 flowRate)\n {\n (uint256 liquidationPeriod, ) = _decode3PsData(token);\n flowRate = _getMaximumFlowRateFromDepositPure(liquidationPeriod, deposit);\n }\n\n /// @dev IConstantFlowAgreementV1.getDepositRequiredForFlowRate implementation\n function getDepositRequiredForFlowRate(\n ISuperfluidToken token,\n int96 flowRate)\n external view override\n returns (uint256 deposit)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n ISuperfluidGovernance gov = ISuperfluidGovernance(host.getGovernance());\n uint256 minimumDeposit = gov.getConfigAsUint256(host, token, SUPERTOKEN_MINIMUM_DEPOSIT_KEY);\n uint256 pppConfig = gov.getConfigAsUint256(host, token, CFAV1_PPP_CONFIG_KEY);\n (uint256 liquidationPeriod, ) = SuperfluidGovernanceConfigs.decodePPPConfig(pppConfig);\n return _getDepositRequiredForFlowRatePure(minimumDeposit, liquidationPeriod, flowRate);\n }\n\n function isPatricianPeriodNow(\n ISuperfluidToken token,\n address account)\n public view override\n returns (bool isCurrentlyPatricianPeriod, uint256 timestamp)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n timestamp = host.getNow();\n isCurrentlyPatricianPeriod = isPatricianPeriod(token, account, timestamp);\n }\n\n function isPatricianPeriod(\n ISuperfluidToken token,\n address account,\n uint256 timestamp)\n public view override\n returns (bool)\n {\n (int256 availableBalance, ,) = token.realtimeBalanceOf(account, timestamp);\n if (availableBalance >= 0) {\n return true;\n }\n\n (uint256 liquidationPeriod, uint256 patricianPeriod) = _decode3PsData(token);\n (,FlowData memory senderAccountState) = _getAccountFlowState(token, account);\n int256 signedTotalCFADeposit = senderAccountState.deposit.toInt256();\n\n return _isPatricianPeriod(\n availableBalance,\n signedTotalCFADeposit,\n liquidationPeriod,\n patricianPeriod\n );\n }\n\n /// @dev IConstantFlowAgreementV1.createFlow implementation\n function createFlow(\n ISuperfluidToken token,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = currentContext.msgSender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n\n newCtx = _createFlow(\n flowVars,\n ctx,\n currentContext\n );\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlow implementation\n function updateFlow(\n ISuperfluidToken token,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = currentContext.msgSender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n\n bytes32 flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowId);\n\n newCtx = _updateFlow(\n flowVars,\n oldFlowData,\n exist,\n ctx,\n currentContext\n );\n }\n\n /// @dev IConstantFlowAgreementV1.deleteFlow implementation\n function deleteFlow(\n ISuperfluidToken token,\n address sender,\n address receiver,\n bytes calldata ctx\n )\n external\n override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n (,uint8 permissions,) = getFlowOperatorData(token, sender, currentContext.msgSender);\n bool hasPermissions = _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.DELETE_FLOW);\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = 0;\n\n newCtx = _deleteFlow(flowVars, hasPermissions, ctx, currentContext);\n }\n\n /// @dev IConstantFlowAgreementV1.getFlow implementation\n function getFlow(\n ISuperfluidToken token,\n address sender,\n address receiver\n )\n external\n view\n override\n returns (\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit\n )\n {\n (, FlowData memory data) = _getAgreementData(\n token,\n _generateFlowId(sender, receiver));\n\n return(\n data.timestamp,\n data.flowRate,\n data.deposit,\n data.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getFlow implementation\n function getFlowByID(\n ISuperfluidToken token,\n bytes32 flowId\n )\n external\n view\n override\n returns(\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit\n )\n {\n (, FlowData memory data) = _getAgreementData(\n token,\n flowId\n );\n\n return (\n data.timestamp,\n data.flowRate,\n data.deposit,\n data.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getAccountFlowInfo implementation\n function getAccountFlowInfo(\n ISuperfluidToken token,\n address account\n )\n external view override\n returns (\n uint256 timestamp,\n int96 flowRate,\n uint256 deposit,\n uint256 owedDeposit)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n return (\n state.timestamp,\n state.flowRate,\n state.deposit,\n state.owedDeposit\n );\n }\n\n /// @dev IConstantFlowAgreementV1.getNetFlow implementation\n function getNetFlow(\n ISuperfluidToken token,\n address account\n )\n external view override\n returns (int96 flowRate)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n return state.flowRate;\n }\n\n /**************************************************************************\n * Internal Helper Functions\n *************************************************************************/\n\n // Stack variables for _createOrUpdateFlow function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_createOrUpdateFlow {\n ISuperfluidToken token;\n address sender;\n address receiver;\n int96 flowRate;\n }\n\n /**\n * @dev Checks conditions for both create/update flow\n * returns the flowId and flowParams\n */\n function _createOrUpdateFlowCheck(\n _StackVars_createOrUpdateFlow memory flowVars,\n ISuperfluid.Context memory currentContext\n )\n internal pure\n returns(bytes32 flowId, FlowParams memory flowParams)\n {\n require(flowVars.receiver != address(0), \"CFA: receiver is zero\");\n\n flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n flowParams.flowId = flowId;\n flowParams.sender = flowVars.sender;\n flowParams.receiver = flowVars.receiver;\n flowParams.flowOperator = currentContext.msgSender;\n flowParams.flowRate = flowVars.flowRate;\n flowParams.userData = currentContext.userData;\n require(flowParams.sender != flowParams.receiver, \"CFA: no self flow\");\n require(flowParams.flowRate > 0, \"CFA: invalid flow rate\");\n }\n\n function _createFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n (bytes32 flowId, FlowParams memory flowParams) = _createOrUpdateFlowCheck(flowVars, currentContext);\n\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowId);\n require(!exist, \"CFA: flow already exist\");\n\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext, FlowChangeType.CREATE_FLOW);\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext);\n }\n\n _requireAvailableBalance(flowVars.token, currentContext);\n }\n\n function _updateFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n FlowData memory oldFlowData,\n bool exist,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n (, FlowParams memory flowParams) = _createOrUpdateFlowCheck(flowVars, currentContext);\n\n require(exist, \"CFA: flow does not exist\");\n\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext, FlowChangeType.UPDATE_FLOW);\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n ctx, currentContext);\n }\n\n _requireAvailableBalance(flowVars.token, currentContext);\n }\n\n function _deleteFlow(\n _StackVars_createOrUpdateFlow memory flowVars,\n bool hasPermissions,\n bytes calldata ctx,\n ISuperfluid.Context memory currentContext\n )\n internal\n returns(bytes memory newCtx)\n {\n FlowParams memory flowParams;\n require(flowVars.sender != address(0), \"CFA: sender is zero\");\n require(flowVars.receiver != address(0), \"CFA: receiver is zero\");\n flowParams.flowId = _generateFlowId(flowVars.sender, flowVars.receiver);\n flowParams.sender = flowVars.sender;\n flowParams.receiver = flowVars.receiver;\n flowParams.flowOperator = currentContext.msgSender;\n flowParams.flowRate = 0;\n flowParams.userData = currentContext.userData;\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(flowVars.token, flowParams.flowId);\n require(exist, \"CFA: flow does not exist\");\n\n (int256 availableBalance,,) = flowVars.token.realtimeBalanceOf(flowVars.sender, currentContext.timestamp);\n\n // delete should only be called by sender, receiver or flowOperator\n // unless it is a liquidation (availale balance < 0)\n if (currentContext.msgSender != flowVars.sender &&\n currentContext.msgSender != flowVars.receiver &&\n !hasPermissions)\n {\n if (!ISuperfluid(msg.sender).isAppJailed(ISuperApp(flowVars.sender)) &&\n !ISuperfluid(msg.sender).isAppJailed(ISuperApp(flowVars.receiver))) {\n require(availableBalance < 0, \"CFA: sender account is not critical\");\n }\n }\n\n if (availableBalance < 0) {\n _makeLiquidationPayouts(\n flowVars.token,\n availableBalance,\n flowParams,\n oldFlowData,\n currentContext.msgSender);\n }\n\n newCtx = ctx;\n // if the sender of the flow is deleting the flow\n if (currentContext.msgSender == flowVars.sender) {\n // if the sender is deleting a flow to a super app receiver\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n } else {\n // if the receiver is not a super app (sender may be a super app or non super app)\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n // if the receiver of the flow is deleting the flow\n } else if (currentContext.msgSender == flowVars.receiver) {\n // if the flow being deleted by the receiver has a super app sender\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.sender))) {\n newCtx = _changeFlowToApp(\n flowVars.sender,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the receiver of the flow deleting the flow is a super app\n } else if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n address(0),\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the sender is not a super app (the stream is not coming to or from a super app)\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n // flowOperator case OR liquidation case (when the msgSender isn't the sender or receiver)\n } else /* liquidations or flowOperator deleting a flow */ {\n // if the sender is an app and is critical\n // we jail the app\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.sender)) && availableBalance < 0) {\n newCtx = ISuperfluid(msg.sender).jailApp(\n newCtx,\n ISuperApp(flowVars.sender),\n SuperAppDefinitions.APP_RULE_NO_CRITICAL_SENDER_ACCOUNT);\n }\n // if the stream we're deleting (possibly liquidating) has a receiver that is a super app\n // always attempt to call receiver callback\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowVars.receiver))) {\n newCtx = _changeFlowToApp(\n flowVars.receiver,\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext, FlowChangeType.DELETE_FLOW);\n // if the stream we're deleting (possibly liquidating) has a receiver that is not a super app\n // or the sender is a super app or the sender is not a super app\n } else {\n newCtx = _changeFlowToNonApp(\n flowVars.token, flowParams, oldFlowData,\n newCtx, currentContext);\n }\n }\n }\n\n /**************************************************************************\n * ACL Functions\n *************************************************************************/\n\n /// @dev IConstantFlowAgreementV1.createFlowByOperator implementation\n function createFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n require(currentContext.msgSender != sender, \"CFA: E_NO_SENDER_CREATE\");\n\n {\n // check if flow operator has create permissions\n (\n bytes32 flowOperatorId,\n uint8 permissions,\n int96 flowRateAllowance\n ) = getFlowOperatorData(token, sender, currentContext.msgSender);\n require(\n _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.CREATE_FLOW),\n \"CFA: E_NO_OPERATOR_CREATE_FLOW\"\n );\n\n // check if desired flow rate is allowed and update flow rate allowance\n int96 updatedFlowRateAllowance = flowRateAllowance == type(int96).max\n ? flowRateAllowance\n : flowRateAllowance - flowRate;\n require(updatedFlowRateAllowance >= 0, \"CFA: E_EXCEED_FLOW_RATE_ALLOWANCE\");\n _updateFlowRateAllowance(token, flowOperatorId, permissions, updatedFlowRateAllowance);\n }\n {\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n newCtx = _createFlow(\n flowVars,\n ctx,\n currentContext\n );\n }\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlowByOperator implementation\n function updateFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n int96 flowRate,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n require(currentContext.msgSender != sender, \"CFA: E_NO_SENDER_UPDATE\");\n\n // check if flow exists\n (bool exist, FlowData memory oldFlowData) = _getAgreementData(token, _generateFlowId(sender, receiver));\n\n {\n // check if flow operator has create permissions\n (\n bytes32 flowOperatorId,\n uint8 permissions,\n int96 flowRateAllowance\n ) = getFlowOperatorData(token, sender, currentContext.msgSender);\n require(\n _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.UPDATE_FLOW),\n \"E_NO_OPERATOR_UPDATE_FLOW\"\n );\n\n // check if desired flow rate is allowed and update flow rate allowance\n int96 updatedFlowRateAllowance = flowRateAllowance == type(int96).max || oldFlowData.flowRate >= flowRate\n ? flowRateAllowance\n : flowRateAllowance - (flowRate - oldFlowData.flowRate);\n require(updatedFlowRateAllowance >= 0, \"CFA: E_EXCEED_FLOW_RATE_ALLOWANCE\");\n _updateFlowRateAllowance(token, flowOperatorId, permissions, updatedFlowRateAllowance);\n }\n\n {\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = flowRate;\n newCtx = _updateFlow(\n flowVars,\n oldFlowData,\n exist,\n ctx,\n currentContext\n );\n }\n }\n\n /// @dev IConstantFlowAgreementV1.deleteFlowByOperator implementation\n function deleteFlowByOperator(\n ISuperfluidToken token,\n address sender,\n address receiver,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n (,uint8 permissions,) = getFlowOperatorData(token, sender, currentContext.msgSender);\n bool hasPermissions = _getBooleanFlowOperatorPermissions(permissions, FlowChangeType.DELETE_FLOW);\n require(hasPermissions, \"E_NO_OPERATOR_DELETE_FLOW\");\n\n _StackVars_createOrUpdateFlow memory flowVars;\n flowVars.token = token;\n flowVars.sender = sender;\n flowVars.receiver = receiver;\n flowVars.flowRate = 0;\n\n newCtx = _deleteFlow(flowVars, hasPermissions, ctx, currentContext);\n }\n\n /// @dev IConstantFlowAgreementV1.updateFlowOperatorPermissions implementation\n function updateFlowOperatorPermissions(\n ISuperfluidToken token,\n address flowOperator,\n uint8 permissions,\n int96 flowRateAllowance, // flowRateBudget\n bytes calldata ctx\n ) public override returns(bytes memory newCtx) {\n newCtx = ctx;\n require(FlowOperatorDefinitions.isPermissionsClean(permissions), \"CFA: Unclean permissions\");\n ISuperfluid.Context memory currentContext = AgreementLibrary.authorizeTokenAccess(token, ctx);\n // [SECURITY] NOTE: we are holding the assumption here that ctx is correct and we validate it with\n // authorizeTokenAccess:\n require(currentContext.msgSender != flowOperator, \"CFA: E_NO_SENDER_FLOW_OPERATOR\");\n require(flowRateAllowance >= 0, \"CFA: E_NO_NEGATIVE_ALLOWANCE\");\n FlowOperatorData memory flowOperatorData;\n flowOperatorData.permissions = permissions;\n flowOperatorData.flowRateAllowance = flowRateAllowance;\n bytes32 flowOperatorId = _generateFlowOperatorId(currentContext.msgSender, flowOperator);\n token.updateAgreementData(flowOperatorId, _encodeFlowOperatorData(flowOperatorData));\n\n emit FlowOperatorUpdated(token, currentContext.msgSender, flowOperator, permissions, flowRateAllowance);\n }\n\n /// @dev IConstantFlowAgreementV1.authorizeFlowOperatorWithFullControl implementation\n function authorizeFlowOperatorWithFullControl(\n ISuperfluidToken token,\n address flowOperator,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n newCtx = updateFlowOperatorPermissions(\n token,\n flowOperator,\n FlowOperatorDefinitions.AUTHORIZE_FULL_CONTROL,\n type(int96).max,\n ctx\n );\n }\n\n /// @dev IConstantFlowAgreementV1.revokeFlowOperatorWithFullControl implementation\n function revokeFlowOperatorWithFullControl(\n ISuperfluidToken token,\n address flowOperator,\n bytes calldata ctx\n )\n external override\n returns(bytes memory newCtx)\n {\n // NOTE: REVOKE_FULL_CONTROL = 0\n newCtx = updateFlowOperatorPermissions(token, flowOperator, 0, 0, ctx);\n }\n\n /// @dev IConstantFlowAgreementV1.getFlowOperatorData implementation\n function getFlowOperatorData(\n ISuperfluidToken token,\n address sender,\n address flowOperator\n )\n public view override\n returns(bytes32 flowOperatorId, uint8 permissions, int96 flowRateAllowance)\n {\n flowOperatorId = _generateFlowOperatorId(sender, flowOperator);\n (, FlowOperatorData memory flowOperatorData) = _getFlowOperatorData(token, flowOperatorId);\n permissions = flowOperatorData.permissions;\n flowRateAllowance = flowOperatorData.flowRateAllowance;\n }\n\n /// @dev IConstantFlowAgreementV1.getFlowOperatorDataByID implementation\n function getFlowOperatorDataByID(\n ISuperfluidToken token,\n bytes32 flowOperatorId\n )\n external view override\n returns(uint8 permissions, int96 flowRateAllowance)\n {\n (, FlowOperatorData memory flowOperatorData) = _getFlowOperatorData(token, flowOperatorId);\n permissions = flowOperatorData.permissions;\n flowRateAllowance = flowOperatorData.flowRateAllowance;\n }\n\n /**************************************************************************\n * Internal State Functions\n *************************************************************************/\n\n enum FlowChangeType {\n CREATE_FLOW,\n UPDATE_FLOW,\n DELETE_FLOW\n }\n\n function _getAccountFlowState\n (\n ISuperfluidToken token,\n address account\n )\n private view\n returns(bool exist, FlowData memory)\n {\n bytes32[] memory data = token.getAgreementStateSlot(address(this), account, 0 /* slotId */, 1 /* length */);\n return _decodeFlowData(uint256(data[0]));\n }\n\n function _getAgreementData\n (\n ISuperfluidToken token,\n bytes32 dId\n )\n private view\n returns (bool exist, FlowData memory)\n {\n bytes32[] memory data = token.getAgreementData(address(this), dId, 1);\n return _decodeFlowData(uint256(data[0]));\n }\n\n function _getFlowOperatorData\n (\n ISuperfluidToken token,\n bytes32 flowOperatorId\n )\n private view\n returns (bool exist, FlowOperatorData memory)\n {\n // 1 because we are storing the flowOperator data in one word\n bytes32[] memory data = token.getAgreementData(address(this), flowOperatorId, 1);\n return _decodeFlowOperatorData(uint256(data[0]));\n }\n\n function _updateFlowRateAllowance\n (\n ISuperfluidToken token,\n bytes32 flowOperatorId,\n uint8 existingPermissions,\n int96 updatedFlowRateAllowance\n )\n private\n {\n FlowOperatorData memory flowOperatorData;\n flowOperatorData.permissions = existingPermissions;\n flowOperatorData.flowRateAllowance = updatedFlowRateAllowance;\n token.updateAgreementData(flowOperatorId, _encodeFlowOperatorData(flowOperatorData));\n }\n\n function _updateAccountFlowState(\n ISuperfluidToken token,\n address account,\n int96 flowRateDelta,\n int256 depositDelta,\n int256 owedDepositDelta,\n uint256 currentTimestamp\n )\n private\n returns (int96 newNetFlowRate)\n {\n (, FlowData memory state) = _getAccountFlowState(token, account);\n int256 dynamicBalance = (currentTimestamp - state.timestamp).toInt256()\n * int256(state.flowRate);\n if (dynamicBalance != 0) {\n token.settleBalance(account, dynamicBalance);\n }\n state.flowRate = state.flowRate + flowRateDelta;\n state.timestamp = currentTimestamp;\n state.deposit = (state.deposit.toInt256() + depositDelta).toUint256();\n state.owedDeposit = (state.owedDeposit.toInt256() + owedDepositDelta).toUint256();\n\n token.updateAgreementStateSlot(account, 0 /* slot id */, _encodeFlowData(state));\n\n return state.flowRate;\n }\n\n /**\n * @dev update a flow to a non-app receiver\n */\n function _changeFlowToNonApp(\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData,\n bytes memory ctx,\n ISuperfluid.Context memory currentContext\n )\n private\n returns (bytes memory newCtx)\n {\n // owed deposit should have been always zero, since an app should never become a non app\n assert(oldFlowData.owedDeposit == 0);\n\n // STEP 1: update the flow\n int256 depositDelta;\n FlowData memory newFlowData;\n (depositDelta,,newFlowData) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n\n // STEP 2: update app allowance used\n if (currentContext.appAllowanceToken == token) {\n newCtx = ISuperfluid(msg.sender).ctxUseAllowance(\n ctx,\n newFlowData.deposit, // allowanceWantedMore\n depositDelta // allowanceUsedDelta\n );\n } else {\n newCtx = ctx;\n }\n }\n\n /**\n * @dev change a flow to a app receiver\n */\n\n // Stack variables for _changeFlowToApp function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_changeFlowToApp {\n bytes cbdata;\n FlowData newFlowData;\n ISuperfluid.Context appContext;\n }\n function _changeFlowToApp(\n address appToCallback,\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData,\n bytes memory ctx,\n ISuperfluid.Context memory currentContext,\n FlowChangeType optype\n )\n private\n returns (bytes memory newCtx)\n {\n newCtx = ctx;\n // apply callbacks\n _StackVars_changeFlowToApp memory vars;\n\n // call callback\n if (appToCallback != address(0)) {\n AgreementLibrary.CallbackInputs memory cbStates = AgreementLibrary.createCallbackInputs(\n token,\n appToCallback,\n flowParams.flowId,\n abi.encode(flowParams.sender, flowParams.receiver)\n );\n\n // call the before callback\n if (optype == FlowChangeType.CREATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP;\n } else if (optype == FlowChangeType.UPDATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP;\n } else /* if (optype == FlowChangeType.DELETE_FLOW) */ {\n cbStates.noopBit = SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP;\n }\n vars.cbdata = AgreementLibrary.callAppBeforeCallback(cbStates, ctx);\n\n (,cbStates.appAllowanceGranted,) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n cbStates.appAllowanceGranted = cbStates.appAllowanceGranted * uint256(currentContext.appLevel + 1);\n cbStates.appAllowanceUsed = oldFlowData.owedDeposit.toInt256();\n // - each app level can at least \"relay\" the same amount of input flow rate to others\n // - each app level get a same amount of allowance\n\n if (optype == FlowChangeType.CREATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_CREATED_NOOP;\n } else if (optype == FlowChangeType.UPDATE_FLOW) {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_UPDATED_NOOP;\n } else /* if (optype == FlowChangeType.DELETE_FLOW) */ {\n cbStates.noopBit = SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP;\n }\n (vars.appContext, newCtx) = AgreementLibrary.callAppAfterCallback(cbStates, vars.cbdata, newCtx);\n\n // NB: the callback might update the same flow!!\n // reload the flow data\n (, vars.newFlowData) = _getAgreementData(token, flowParams.flowId);\n } else {\n (,,vars.newFlowData) = _changeFlow(\n currentContext.timestamp,\n currentContext.appAllowanceToken,\n token, flowParams, oldFlowData);\n }\n\n // REVIEW the re-entrace assumptions from this point on\n\n // NOTE: vars.appContext.appAllowanceUsed will be adjusted by callAppAfterCallback\n // and its range will be [0, currentContext.appAllowance]\n {\n // clipping the allowance used amount before storing\n if (vars.appContext.appAllowanceUsed > 0) {\n // give more to the app\n vars.appContext.appAllowanceUsed =\n _clipDepositNumber(vars.appContext.appAllowanceUsed.toUint256()).toInt256();\n }\n\n int256 appAllowanceDelta = vars.appContext.appAllowanceUsed\n - oldFlowData.owedDeposit.toInt256();\n\n // update flow data and account state with the allowance delta\n {\n vars.newFlowData.deposit = (vars.newFlowData.deposit.toInt256()\n + appAllowanceDelta).toUint256();\n vars.newFlowData.owedDeposit = (vars.newFlowData.owedDeposit.toInt256()\n + appAllowanceDelta).toUint256();\n token.updateAgreementData(flowParams.flowId, _encodeFlowData(vars.newFlowData));\n // update sender and receiver deposit (for sender) and owed deposit (for receiver)\n _updateAccountFlowState(\n token,\n flowParams.sender,\n 0, // flow rate delta\n appAllowanceDelta, // deposit delta\n 0, // owed deposit delta\n currentContext.timestamp\n );\n _updateAccountFlowState(\n token,\n flowParams.receiver,\n 0, // flow rate delta\n 0, // deposit delta\n appAllowanceDelta, // owed deposit delta\n currentContext.timestamp\n );\n }\n\n if (address(currentContext.appAllowanceToken) == address(0) ||\n currentContext.appAllowanceToken == token)\n {\n newCtx = ISuperfluid(msg.sender).ctxUseAllowance(\n newCtx,\n vars.newFlowData.deposit, // allowanceWantedMore\n appAllowanceDelta // allowanceUsedDelta\n );\n }\n\n // if receiver super app doesn't have enough available balance to give back app allowance\n // revert (non termination callbacks),\n // or take it from the sender and jail the app\n if (ISuperfluid(msg.sender).isApp(ISuperApp(flowParams.receiver))) {\n int256 availableBalance;\n (availableBalance,,) = token.realtimeBalanceOf(flowParams.receiver, currentContext.timestamp);\n if (availableBalance < 0) {\n // app goes broke, send the app to jail\n if (optype == FlowChangeType.DELETE_FLOW) {\n newCtx = ISuperfluid(msg.sender).jailApp(\n newCtx,\n ISuperApp(flowParams.receiver),\n SuperAppDefinitions.APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT);\n // calculate user's damage\n int256 userDamageAmount = AgreementLibrary.min(\n // user will take the damage if the app is broke,\n -availableBalance,\n // but user's damage is limited to the amount of app allowance it gives to the app\n AgreementLibrary.max(0, -appAllowanceDelta));\n token.settleBalance(\n flowParams.sender,\n -userDamageAmount\n );\n token.settleBalance(\n flowParams.receiver,\n userDamageAmount\n );\n } else {\n revert(\"CFA: APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT\");\n }\n }\n }\n }\n }\n\n // Stack variables for _changeFlow function, to avoid stack too deep issue\n // solhint-disable-next-line contract-name-camelcase\n struct _StackVars_changeFlow {\n int96 totalSenderFlowRate;\n int96 totalReceiverFlowRate;\n }\n\n /**\n * @dev change flow between sender and receiver with new flow rate\n *\n * NOTE:\n * - leaving owed deposit unchanged for later adjustment\n * - depositDelta output is always clipped (see _clipDepositNumber)\n */\n function _changeFlow(\n uint256 currentTimestamp,\n ISuperfluidToken appAllowanceToken,\n ISuperfluidToken token,\n FlowParams memory flowParams,\n FlowData memory oldFlowData\n )\n private\n returns (\n int256 depositDelta,\n uint256 appAllowanceBase,\n FlowData memory newFlowData\n )\n {\n uint256 newDeposit;\n { // enclosed block to avoid stack too deep error\n uint256 minimumDeposit;\n // STEP 1: calculate deposit required for the flow\n {\n (uint256 liquidationPeriod, ) = _decode3PsData(token);\n ISuperfluidGovernance gov = ISuperfluidGovernance(ISuperfluid(msg.sender).getGovernance());\n minimumDeposit = gov.getConfigAsUint256(\n ISuperfluid(msg.sender), token, SUPERTOKEN_MINIMUM_DEPOSIT_KEY);\n // rounding up the number for app allowance too\n // CAVEAT:\n // - Now app could create a flow rate that is slightly higher than the incoming flow rate.\n // - The app may be jailed due to negative balance if it does this without its own balance.\n // Rule of thumbs:\n // - App can use app allowance to create a flow that has the same incoming flow rate\n // - But due to deposit clipping, there is no guarantee that the sum of the out going flow\n // deposit can be covered by the allowance always.\n // - It is advisable for the app to check the allowance usages carefully, and if possible\n // Always have some its own balances to cover the deposits.\n\n // preliminary calc of new deposit required, may be changed later in step 2.\n // used as a variable holding the new deposit amount in the meantime\n appAllowanceBase = _calculateDeposit(flowParams.flowRate, liquidationPeriod);\n }\n\n // STEP 2: apply minimum deposit rule and calculate deposit delta\n // preliminary calc depositDelta (minimum deposit rule not yet applied)\n depositDelta = appAllowanceBase.toInt256()\n - oldFlowData.deposit.toInt256()\n + oldFlowData.owedDeposit.toInt256();\n\n // preliminary calc newDeposit (minimum deposit rule not yet applied)\n newDeposit = (oldFlowData.deposit.toInt256() + depositDelta).toUint256();\n\n // calc depositDelta and newDeposit with minimum deposit rule applied\n if (newDeposit < minimumDeposit && flowParams.flowRate > 0) {\n depositDelta = minimumDeposit.toInt256()\n - oldFlowData.deposit.toInt256()\n + oldFlowData.owedDeposit.toInt256();\n newDeposit = minimumDeposit;\n }\n\n // allowance should be of the same token\n if (address(appAllowanceToken) != address(0) &&\n appAllowanceToken != token)\n {\n appAllowanceBase = 0;\n }\n\n // STEP 3: update current flow info\n newFlowData = FlowData(\n flowParams.flowRate > 0 ? currentTimestamp : 0,\n flowParams.flowRate,\n newDeposit,\n oldFlowData.owedDeposit // leaving it unchanged for later adjustment\n );\n token.updateAgreementData(flowParams.flowId, _encodeFlowData(newFlowData));\n }\n {\n _StackVars_changeFlow memory vars;\n // STEP 4: update sender and receiver account flow state with the deltas\n vars.totalSenderFlowRate = _updateAccountFlowState(\n token,\n flowParams.sender,\n oldFlowData.flowRate - flowParams.flowRate,\n depositDelta,\n 0,\n currentTimestamp\n );\n vars.totalReceiverFlowRate = _updateAccountFlowState(\n token,\n flowParams.receiver,\n flowParams.flowRate - oldFlowData.flowRate,\n 0,\n 0, // leaving owed deposit unchanged for later adjustment\n currentTimestamp\n );\n\n // STEP 5: emit the FlowUpdated Event\n // NOTE we emit these two events one after the other\n // so the subgraph can properly handle this in the\n // mapping function\n emit FlowUpdated(\n token,\n flowParams.sender,\n flowParams.receiver,\n flowParams.flowRate,\n vars.totalSenderFlowRate,\n vars.totalReceiverFlowRate,\n flowParams.userData\n );\n emit FlowUpdatedExtension(\n flowParams.flowOperator,\n newDeposit\n );\n }\n }\n function _requireAvailableBalance(\n ISuperfluidToken token,\n ISuperfluid.Context memory currentContext\n )\n private view\n {\n // do not enforce balance checks during callbacks for the appAllowanceToken\n if (currentContext.callType != ContextDefinitions.CALL_INFO_CALL_TYPE_APP_CALLBACK ||\n currentContext.appAllowanceToken != token) {\n (int256 availableBalance,,) = token.realtimeBalanceOf(currentContext.msgSender, currentContext.timestamp);\n require(availableBalance >= 0, \"CFA: not enough available balance\");\n }\n }\n\n function _makeLiquidationPayouts(\n ISuperfluidToken token,\n int256 availableBalance,\n FlowParams memory flowParams,\n FlowData memory flowData,\n address liquidator\n )\n private\n {\n (,FlowData memory senderAccountState) = _getAccountFlowState(token, flowParams.sender);\n\n int256 signedSingleDeposit = flowData.deposit.toInt256();\n // TODO: GDA deposit should be considered here too\n int256 signedTotalCFADeposit = senderAccountState.deposit.toInt256();\n bytes memory liquidationTypeData;\n bool isCurrentlyPatricianPeriod;\n\n // Liquidation rules:\n // - let Available Balance = AB (is negative)\n // - Agreement Single Deposit = SD\n // - Agreement Total Deposit = TD\n // - Total Reward Left = RL = AB + TD\n // #1 Can the total account deposit still cover the available balance deficit?\n int256 totalRewardLeft = availableBalance + signedTotalCFADeposit;\n\n // To retrieve patrician period\n // Note: curly brackets are to handle stack too deep overflow issue\n {\n (uint256 liquidationPeriod, uint256 patricianPeriod) = _decode3PsData(token);\n isCurrentlyPatricianPeriod = _isPatricianPeriod(\n availableBalance,\n signedTotalCFADeposit,\n liquidationPeriod,\n patricianPeriod\n );\n }\n\n // user is in a critical state\n if (totalRewardLeft >= 0) {\n // the liquidator is always whoever triggers the liquidation, but the\n // account which receives the reward will depend on the period (Patrician or Pleb)\n // #1.a.1 yes: then reward = (SD / TD) * RL\n int256 rewardAmount = signedSingleDeposit * totalRewardLeft / signedTotalCFADeposit;\n liquidationTypeData = abi.encode(1, isCurrentlyPatricianPeriod ? 0 : 1);\n token.makeLiquidationPayoutsV2(\n flowParams.flowId, // id\n liquidationTypeData, // (1 means \"v1\" of this encoding schema) - 0 or 1 for patrician or pleb\n liquidator, // liquidatorAddress\n\n // useDefaultRewardAccount: true in patrician period, else liquidator gets reward\n isCurrentlyPatricianPeriod,\n\n flowParams.sender, // targetAccount\n rewardAmount.toUint256(), // rewardAmount: remaining deposit of the flow to be liquidated\n rewardAmount * -1 // targetAccountBalanceDelta: amount deducted from the flow sender\n );\n } else {\n // #1.b.1 no: then the liquidator takes full amount of the single deposit\n int256 rewardAmount = signedSingleDeposit;\n liquidationTypeData = abi.encode(1, 2);\n token.makeLiquidationPayoutsV2(\n flowParams.flowId, // id\n liquidationTypeData, // (1 means \"v1\" of this encoding schema) - 2 for pirate/bailout period\n liquidator, // liquidatorAddress\n false, // useDefaultRewardAccount: out of patrician period, in pirate period, so always false\n flowParams.sender, // targetAccount\n rewardAmount.toUint256(), // rewardAmount: single deposit of flow\n totalRewardLeft * -1 // targetAccountBalanceDelta: amount to bring sender AB to 0\n // NOTE: bailoutAmount = rewardAmount + targetAccountBalanceDelta + paid by rewardAccount\n );\n }\n }\n\n /**************************************************************************\n * Deposit Calculation Pure Functions\n *************************************************************************/\n\n function _clipDepositNumberRoundingDown(uint256 deposit)\n internal pure\n returns(uint256)\n {\n return ((deposit >> 32)) << 32;\n }\n\n function _clipDepositNumber(uint256 deposit)\n internal pure\n returns(uint256)\n {\n // clipping the value, rounding up\n uint256 rounding = (deposit & type(uint32).max) > 0 ? 1 : 0;\n return ((deposit >> 32) + rounding) << 32;\n }\n\n function _calculateDeposit(\n int96 flowRate,\n uint256 liquidationPeriod\n )\n internal pure\n returns(uint256 deposit)\n {\n if (flowRate == 0) return 0;\n\n // NOTE: safecast for int96 with extra assertion\n assert(liquidationPeriod <= uint256(int256(type(int96).max)));\n deposit = uint256(int256(flowRate * int96(uint96(liquidationPeriod))));\n return _clipDepositNumber(deposit);\n }\n\n /**************************************************************************\n * Flow Data Pure Functions\n *************************************************************************/\n\n function _generateFlowId(address sender, address receiver) private pure returns(bytes32 id) {\n return keccak256(abi.encode(sender, receiver));\n }\n\n //\n // Data packing:\n //\n // WORD A: | timestamp | flowRate | deposit | owedDeposit |\n // | 32b | 96b | 64 | 64 |\n //\n // NOTE:\n // - flowRate has 96 bits length\n // - deposit has 96 bits length too, but 32 bits are clipped-off when storing\n\n function _encodeFlowData\n (\n FlowData memory flowData\n )\n internal pure\n returns(bytes32[] memory data)\n {\n // enable these for debugging\n // assert(flowData.deposit & type(uint32).max == 0);\n // assert(flowData.owedDeposit & type(uint32).max == 0);\n data = new bytes32[](1);\n data[0] = bytes32(\n ((uint256(flowData.timestamp)) << 224) |\n ((uint256(uint96(flowData.flowRate)) << 128)) |\n (uint256(flowData.deposit) >> 32 << 64) |\n (uint256(flowData.owedDeposit) >> 32)\n );\n }\n\n function _decodeFlowData\n (\n uint256 wordA\n )\n internal pure\n returns(bool exist, FlowData memory flowData)\n {\n exist = wordA > 0;\n if (exist) {\n flowData.timestamp = uint32(wordA >> 224);\n // NOTE because we are upcasting from type(uint96).max to uint256 to int256, we do not need to use safecast\n flowData.flowRate = int96(int256(wordA >> 128) & int256(uint256(type(uint96).max)));\n flowData.deposit = ((wordA >> 64) & uint256(type(uint64).max)) << 32 /* recover clipped bits*/;\n flowData.owedDeposit = (wordA & uint256(type(uint64).max)) << 32 /* recover clipped bits*/;\n }\n }\n\n /**************************************************************************\n * 3P's Pure Functions\n *************************************************************************/\n\n //\n // Data packing:\n //\n // WORD A: | reserved | patricianPeriod | liquidationPeriod |\n // | 192 | 32 | 32 |\n //\n // NOTE:\n // - liquidation period has 32 bits length\n // - patrician period also has 32 bits length\n\n function _decode3PsData(\n ISuperfluidToken token\n )\n internal view\n returns(uint256 liquidationPeriod, uint256 patricianPeriod)\n {\n ISuperfluid host = ISuperfluid(token.getHost());\n ISuperfluidGovernance gov = ISuperfluidGovernance(host.getGovernance());\n uint256 pppConfig = gov.getConfigAsUint256(host, token, CFAV1_PPP_CONFIG_KEY);\n (liquidationPeriod, patricianPeriod) = SuperfluidGovernanceConfigs.decodePPPConfig(pppConfig);\n }\n\n function _isPatricianPeriod(\n int256 availableBalance,\n int256 signedTotalCFADeposit,\n uint256 liquidationPeriod,\n uint256 patricianPeriod\n )\n internal pure\n returns (bool)\n {\n int256 totalRewardLeft = availableBalance + signedTotalCFADeposit;\n int256 totalCFAOutFlowrate = signedTotalCFADeposit / int256(liquidationPeriod);\n // divisor cannot be zero with existing outflow\n return totalRewardLeft / totalCFAOutFlowrate > int256(liquidationPeriod - patricianPeriod);\n }\n\n /**************************************************************************\n * ACL Pure Functions\n *************************************************************************/\n\n function _generateFlowOperatorId(address sender, address flowOperator) private pure returns(bytes32 id) {\n return keccak256(abi.encode(\"flowOperator\", sender, flowOperator));\n }\n\n //\n // Data packing:\n //\n // WORD A: | reserved | permissions | reserved | flowRateAllowance |\n // | 120 | 8 | 32 | 96 |\n //\n // NOTE:\n // - flowRateAllowance has 96 bits length\n // - permissions is an 8-bit octo bitmask\n // - ...0 0 0 (...delete update create)\n\n function _encodeFlowOperatorData\n (\n FlowOperatorData memory flowOperatorData\n )\n internal pure\n returns(bytes32[] memory data)\n {\n assert(flowOperatorData.flowRateAllowance >= 0); // flowRateAllowance must not be less than 0\n data = new bytes32[](1);\n data[0] = bytes32(\n uint256(flowOperatorData.permissions) << 128 |\n uint256(int256(flowOperatorData.flowRateAllowance))\n );\n }\n\n function _decodeFlowOperatorData\n (\n uint256 wordA\n )\n internal pure\n returns(bool exist, FlowOperatorData memory flowOperatorData)\n {\n exist = wordA > 0;\n if (exist) {\n // NOTE: For safecast, doing extra bitmasking to not to have any trust assumption of token storage\n flowOperatorData.flowRateAllowance = int96(int256(wordA & uint256(int256(type(int96).max))));\n flowOperatorData.permissions = uint8(wordA >> 128) & type(uint8).max;\n }\n }\n\n function _getBooleanFlowOperatorPermissions\n (\n uint8 permissions,\n FlowChangeType flowChangeType\n )\n internal pure\n returns (bool flowchangeTypeAllowed)\n {\n if (flowChangeType == FlowChangeType.CREATE_FLOW) {\n flowchangeTypeAllowed = permissions & uint8(1) == 1;\n } else if (flowChangeType == FlowChangeType.UPDATE_FLOW) {\n flowchangeTypeAllowed = (permissions >> 1) & uint8(1) == 1;\n } else { /** flowChangeType === FlowChangeType.DELETE_FLOW */\n flowchangeTypeAllowed = (permissions >> 2) & uint8(1) == 1;\n }\n }\n}\n",
30254
30254
  "sourcePath": "/home/runner/work/protocol-monorepo/protocol-monorepo/packages/ethereum-contracts/contracts/agreements/ConstantFlowAgreementV1.sol",
30255
30255
  "ast": {
30256
30256
  "absolutePath": "project:/contracts/agreements/ConstantFlowAgreementV1.sol",
@@ -30304,7 +30304,7 @@
30304
30304
  "literals": [
30305
30305
  "solidity",
30306
30306
  "0.8",
30307
- ".13"
30307
+ ".14"
30308
30308
  ],
30309
30309
  "nodeType": "PragmaDirective",
30310
30310
  "src": "35:23:32"
@@ -30562,7 +30562,7 @@
30562
30562
  16383,
30563
30563
  4375,
30564
30564
  17271,
30565
- 34838,
30565
+ 34857,
30566
30566
  762
30567
30567
  ],
30568
30568
  "name": "ConstantFlowAgreementV1",
@@ -80429,11 +80429,11 @@
80429
80429
  },
80430
80430
  "compiler": {
80431
80431
  "name": "solc",
80432
- "version": "0.8.13+commit.abaa5c0e.Emscripten.clang"
80432
+ "version": "0.8.14+commit.80d49f37.Emscripten.clang"
80433
80433
  },
80434
80434
  "networks": {},
80435
80435
  "schemaVersion": "3.4.7",
80436
- "updatedAt": "2022-06-03T09:45:13.887Z",
80436
+ "updatedAt": "2022-06-15T22:18:50.194Z",
80437
80437
  "devdoc": {
80438
80438
  "author": "Superfluid",
80439
80439
  "details": "Please read IConstantFlowAgreementV1 for implementation notes.For more technical notes, please visit protocol-monorepo wiki area.",