@bitgo-beta/sdk-coin-sol 7.6.4-beta.62 → 7.6.4-beta.621
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.
- package/dist/cjs/src/bigint-buffer-guard.d.ts.map +1 -0
- package/dist/cjs/src/bigint-buffer-guard.js +29 -0
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/index.js +1 -1
- package/dist/cjs/src/lib/ataInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/ataInitializationBuilder.js +201 -0
- package/dist/cjs/src/lib/closeAtaBuilder.d.ts +51 -0
- package/dist/cjs/src/lib/closeAtaBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/closeAtaBuilder.js +147 -0
- package/dist/{src → cjs/src}/lib/constants.d.ts +45 -2
- package/dist/cjs/src/lib/constants.d.ts.map +1 -0
- package/dist/cjs/src/lib/constants.js +216 -0
- package/dist/cjs/src/lib/customInstructionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/customInstructionBuilder.js +289 -0
- package/dist/cjs/src/lib/explainTransactionWasm.d.ts +21 -0
- package/dist/cjs/src/lib/explainTransactionWasm.d.ts.map +1 -0
- package/dist/cjs/src/lib/explainTransactionWasm.js +264 -0
- package/dist/{src → cjs/src}/lib/iface.d.ts +79 -2
- package/dist/cjs/src/lib/iface.d.ts.map +1 -0
- package/dist/cjs/src/lib/iface.js +7 -0
- package/dist/{src → cjs/src}/lib/index.d.ts +3 -0
- package/dist/cjs/src/lib/index.d.ts.map +1 -0
- package/dist/cjs/src/lib/index.js +89 -0
- package/dist/{src → cjs/src}/lib/instructionParamsFactory.d.ts +3 -1
- package/dist/cjs/src/lib/instructionParamsFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/instructionParamsFactory.js +1122 -0
- package/dist/cjs/src/lib/jitoStakePoolOperations.d.ts.map +1 -0
- package/dist/cjs/src/lib/jitoStakePoolOperations.js +200 -0
- package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
- package/dist/cjs/src/lib/keyPair.js +63 -0
- package/dist/cjs/src/lib/messages/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/lib/messages/index.js +1 -1
- package/dist/cjs/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/messages/messageBuilderFactory.js +19 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts +25 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.js +90 -0
- package/dist/cjs/src/lib/solInstructionFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/solInstructionFactory.js +649 -0
- package/dist/cjs/src/lib/stakingActivateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingActivateBuilder.js +120 -0
- package/dist/cjs/src/lib/stakingAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingAuthorizeBuilder.js +89 -0
- package/dist/cjs/src/lib/stakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingDeactivateBuilder.js +208 -0
- package/dist/cjs/src/lib/stakingDelegateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingDelegateBuilder.js +120 -0
- package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.js +110 -0
- package/dist/cjs/src/lib/stakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingWithdrawBuilder.js +78 -0
- package/dist/cjs/src/lib/token2022Resolve.d.ts +106 -0
- package/dist/cjs/src/lib/token2022Resolve.d.ts.map +1 -0
- package/dist/cjs/src/lib/token2022Resolve.js +199 -0
- package/dist/cjs/src/lib/tokenExtensions.d.ts +31 -0
- package/dist/cjs/src/lib/tokenExtensions.d.ts.map +1 -0
- package/dist/cjs/src/lib/tokenExtensions.js +112 -0
- package/dist/{src → cjs/src}/lib/tokenTransferBuilder.d.ts +27 -1
- package/dist/cjs/src/lib/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/tokenTransferBuilder.js +237 -0
- package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
- package/dist/cjs/src/lib/transaction.js +612 -0
- package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilder.js +380 -0
- package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +5 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.js +209 -0
- package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transferBuilder.js +70 -0
- package/dist/cjs/src/lib/transferBuilderV2.d.ts +69 -0
- package/dist/cjs/src/lib/transferBuilderV2.d.ts.map +1 -0
- package/dist/cjs/src/lib/transferBuilderV2.js +254 -0
- package/dist/{src → cjs/src}/lib/utils.d.ts +5 -0
- package/dist/cjs/src/lib/utils.d.ts.map +1 -0
- package/dist/cjs/src/lib/utils.js +635 -0
- package/dist/cjs/src/lib/walletInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/walletInitializationBuilder.js +71 -0
- package/dist/cjs/src/register.d.ts +5 -0
- package/dist/cjs/src/register.d.ts.map +1 -0
- package/dist/cjs/src/register.js +29 -0
- package/dist/{src → cjs/src}/sol.d.ts +112 -3
- package/dist/cjs/src/sol.d.ts.map +1 -0
- package/dist/cjs/src/sol.js +1617 -0
- package/dist/{src → cjs/src}/solToken.d.ts +7 -0
- package/dist/cjs/src/solToken.d.ts.map +1 -0
- package/dist/cjs/src/solToken.js +79 -0
- package/dist/cjs/src/tsol.d.ts.map +1 -0
- package/dist/cjs/src/tsol.js +24 -0
- package/dist/{test → cjs/test}/fixtures/sol.d.ts.map +1 -1
- package/dist/cjs/test/fixtures/sol.js +1433 -0
- package/dist/{test → cjs/test}/resources/sol.d.ts +29 -29
- package/dist/cjs/test/resources/sol.d.ts.map +1 -0
- package/dist/cjs/test/resources/sol.js +320 -0
- package/dist/cjs/test/unit/explainTransactionWasm.d.ts +5 -0
- package/dist/cjs/test/unit/explainTransactionWasm.d.ts.map +1 -0
- package/dist/cjs/test/unit/explainTransactionWasm.js +26 -0
- package/dist/cjs/test/unit/fixtures/solBackupKey.d.ts.map +1 -0
- package/dist/cjs/test/unit/fixtures/solBackupKey.js +8 -0
- package/dist/cjs/test/unit/getBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/getBuilderFactory.js +10 -0
- package/dist/cjs/test/unit/instructionParamsFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/instructionParamsFactory.js +425 -0
- package/dist/cjs/test/unit/instructionParamsFactory.staking.d.ts.map +1 -0
- package/dist/cjs/test/unit/instructionParamsFactory.staking.js +1059 -0
- package/dist/cjs/test/unit/jitoWasmVerification.d.ts +2 -0
- package/dist/cjs/test/unit/jitoWasmVerification.d.ts.map +1 -0
- package/dist/cjs/test/unit/jitoWasmVerification.js +78 -0
- package/dist/{test → cjs/test}/unit/keyPair.d.ts.map +1 -1
- package/dist/cjs/test/unit/keyPair.js +177 -0
- package/dist/cjs/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/messages/messageBuilderFactory.js +118 -0
- package/dist/cjs/test/unit/messages/simpleMessageBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/messages/simpleMessageBuilder.js +194 -0
- package/dist/cjs/test/unit/register.d.ts +2 -0
- package/dist/cjs/test/unit/register.d.ts.map +1 -0
- package/dist/cjs/test/unit/register.js +65 -0
- package/dist/{test → cjs/test}/unit/sol.d.ts.map +1 -1
- package/dist/cjs/test/unit/sol.js +4790 -0
- package/dist/cjs/test/unit/solInstructionFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/solInstructionFactory.js +611 -0
- package/dist/cjs/test/unit/solToken.d.ts.map +1 -0
- package/dist/cjs/test/unit/solToken.js +37 -0
- package/dist/cjs/test/unit/token2022Resolve.d.ts +2 -0
- package/dist/cjs/test/unit/token2022Resolve.d.ts.map +1 -0
- package/dist/cjs/test/unit/token2022Resolve.js +252 -0
- package/dist/cjs/test/unit/tokenExtensions.d.ts +2 -0
- package/dist/cjs/test/unit/tokenExtensions.d.ts.map +1 -0
- package/dist/cjs/test/unit/tokenExtensions.js +32 -0
- package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
- package/dist/cjs/test/unit/transaction.js +1108 -0
- package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.js +202 -0
- package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.js +471 -0
- package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.d.ts +2 -0
- package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.js +333 -0
- package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.js +413 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.js +430 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +157 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.js +384 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.js +224 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +259 -0
- package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.js +926 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.js +495 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +286 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.js +910 -0
- package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.js +259 -0
- package/dist/{test → cjs/test}/unit/utils.d.ts.map +1 -1
- package/dist/cjs/test/unit/utils.js +557 -0
- package/dist/cjs/test/unit/versionedTransaction.d.ts.map +1 -0
- package/dist/cjs/test/unit/versionedTransaction.js +207 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/bigint-buffer-guard.d.ts +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/lib/ataInitializationBuilder.d.ts +47 -0
- package/dist/{src → esm}/lib/ataInitializationBuilder.d.ts.map +1 -1
- package/dist/esm/lib/ataInitializationBuilder.js +161 -0
- package/dist/esm/lib/closeAtaBuilder.d.ts +51 -0
- package/dist/esm/lib/closeAtaBuilder.d.ts.map +1 -0
- package/dist/esm/lib/closeAtaBuilder.js +140 -0
- package/dist/esm/lib/constants.d.ts +183 -0
- package/dist/esm/lib/constants.d.ts.map +1 -0
- package/dist/esm/lib/constants.js +213 -0
- package/dist/esm/lib/customInstructionBuilder.d.ts +72 -0
- package/dist/esm/lib/customInstructionBuilder.js +282 -0
- package/dist/esm/lib/explainTransactionWasm.d.ts +21 -0
- package/dist/esm/lib/explainTransactionWasm.d.ts.map +1 -0
- package/dist/esm/lib/explainTransactionWasm.js +261 -0
- package/dist/esm/lib/iface.d.ts +321 -0
- package/dist/esm/lib/iface.d.ts.map +1 -0
- package/dist/esm/lib/iface.js +3 -0
- package/dist/esm/lib/index.d.ts +25 -0
- package/dist/{src → esm}/lib/index.d.ts.map +1 -1
- package/dist/esm/lib/index.js +25 -0
- package/dist/esm/lib/instructionParamsFactory.d.ts +14 -0
- package/dist/esm/lib/instructionParamsFactory.d.ts.map +1 -0
- package/dist/esm/lib/instructionParamsFactory.js +1114 -0
- package/dist/esm/lib/jitoStakePoolOperations.d.ts +113 -0
- package/dist/esm/lib/jitoStakePoolOperations.js +189 -0
- package/dist/esm/lib/keyPair.d.ts +26 -0
- package/dist/esm/lib/keyPair.js +59 -0
- package/dist/esm/lib/messages/index.d.ts +2 -0
- package/dist/esm/lib/messages/index.js +2 -0
- package/dist/esm/lib/messages/messageBuilderFactory.d.ts +7 -0
- package/dist/{src → esm}/lib/messages/messageBuilderFactory.js +5 -9
- package/dist/esm/lib/recoverNestedAtaBuilder.d.ts +25 -0
- package/dist/esm/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
- package/dist/esm/lib/recoverNestedAtaBuilder.js +83 -0
- package/dist/esm/lib/solInstructionFactory.d.ts +10 -0
- package/dist/esm/lib/solInstructionFactory.d.ts.map +1 -0
- package/dist/esm/lib/solInstructionFactory.js +643 -0
- package/dist/esm/lib/stakingActivateBuilder.d.ts +59 -0
- package/dist/esm/lib/stakingActivateBuilder.js +113 -0
- package/dist/esm/lib/stakingAuthorizeBuilder.d.ts +43 -0
- package/dist/esm/lib/stakingAuthorizeBuilder.js +82 -0
- package/dist/esm/lib/stakingDeactivateBuilder.d.ts +81 -0
- package/dist/{src → esm}/lib/stakingDeactivateBuilder.js +31 -38
- package/dist/esm/lib/stakingDelegateBuilder.d.ts +42 -0
- package/dist/esm/lib/stakingDelegateBuilder.js +113 -0
- package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.d.ts +33 -0
- package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.js +103 -0
- package/dist/esm/lib/stakingWithdrawBuilder.d.ts +31 -0
- package/dist/esm/lib/stakingWithdrawBuilder.js +71 -0
- package/dist/esm/lib/token2022Resolve.d.ts +106 -0
- package/dist/esm/lib/token2022Resolve.d.ts.map +1 -0
- package/dist/esm/lib/token2022Resolve.js +194 -0
- package/dist/esm/lib/tokenExtensions.d.ts +31 -0
- package/dist/esm/lib/tokenExtensions.d.ts.map +1 -0
- package/dist/esm/lib/tokenExtensions.js +105 -0
- package/dist/esm/lib/tokenTransferBuilder.d.ts +67 -0
- package/dist/esm/lib/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/esm/lib/tokenTransferBuilder.js +230 -0
- package/dist/esm/lib/transaction.d.ts +103 -0
- package/dist/esm/lib/transaction.d.ts.map +1 -0
- package/dist/esm/lib/transaction.js +605 -0
- package/dist/esm/lib/transactionBuilder.d.ts +128 -0
- package/dist/esm/lib/transactionBuilder.js +373 -0
- package/dist/esm/lib/transactionBuilderFactory.d.ts +120 -0
- package/dist/esm/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/esm/lib/transactionBuilderFactory.js +205 -0
- package/dist/esm/lib/transferBuilder.d.ts +26 -0
- package/dist/esm/lib/transferBuilder.js +63 -0
- package/dist/esm/lib/transferBuilderV2.d.ts +69 -0
- package/dist/esm/lib/transferBuilderV2.d.ts.map +1 -0
- package/dist/esm/lib/transferBuilderV2.js +247 -0
- package/dist/esm/lib/utils.d.ts +205 -0
- package/dist/{src → esm}/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +597 -0
- package/dist/esm/lib/walletInitializationBuilder.d.ts +26 -0
- package/dist/esm/lib/walletInitializationBuilder.js +64 -0
- package/dist/esm/register.d.ts +5 -0
- package/dist/esm/register.d.ts.map +1 -0
- package/dist/esm/register.js +24 -0
- package/dist/esm/sol.d.ts +349 -0
- package/dist/esm/sol.d.ts.map +1 -0
- package/dist/esm/sol.js +1576 -0
- package/dist/esm/solToken.d.ts +44 -0
- package/dist/esm/solToken.d.ts.map +1 -0
- package/dist/esm/solToken.js +75 -0
- package/dist/esm/tsol.d.ts +11 -0
- package/dist/esm/tsol.js +20 -0
- package/package.json +35 -16
- package/dist/src/config/token2022StaticConfig.d.ts +0 -3
- package/dist/src/config/token2022StaticConfig.d.ts.map +0 -1
- package/dist/src/config/token2022StaticConfig.js +0 -50
- package/dist/src/lib/ataInitializationBuilder.js +0 -196
- package/dist/src/lib/closeAtaBuilder.d.ts +0 -19
- package/dist/src/lib/closeAtaBuilder.d.ts.map +0 -1
- package/dist/src/lib/closeAtaBuilder.js +0 -69
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -171
- package/dist/src/lib/customInstructionBuilder.js +0 -289
- package/dist/src/lib/iface.d.ts.map +0 -1
- package/dist/src/lib/iface.js +0 -7
- package/dist/src/lib/index.js +0 -77
- package/dist/src/lib/instructionParamsFactory.d.ts.map +0 -1
- package/dist/src/lib/instructionParamsFactory.js +0 -1036
- package/dist/src/lib/jitoStakePoolOperations.js +0 -200
- package/dist/src/lib/keyPair.js +0 -63
- package/dist/src/lib/solInstructionFactory.d.ts.map +0 -1
- package/dist/src/lib/solInstructionFactory.js +0 -572
- package/dist/src/lib/stakingActivateBuilder.js +0 -120
- package/dist/src/lib/stakingAuthorizeBuilder.js +0 -89
- package/dist/src/lib/stakingDelegateBuilder.js +0 -120
- package/dist/src/lib/stakingRawMsgAuthorizeBuilder.js +0 -110
- package/dist/src/lib/stakingWithdrawBuilder.js +0 -78
- package/dist/src/lib/token2022Config.d.ts +0 -44
- package/dist/src/lib/token2022Config.d.ts.map +0 -1
- package/dist/src/lib/token2022Config.js +0 -27
- package/dist/src/lib/tokenTransferBuilder.d.ts.map +0 -1
- package/dist/src/lib/tokenTransferBuilder.js +0 -188
- package/dist/src/lib/transaction.d.ts.map +0 -1
- package/dist/src/lib/transaction.js +0 -595
- package/dist/src/lib/transactionBuilder.js +0 -380
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +0 -1
- package/dist/src/lib/transactionBuilderFactory.js +0 -202
- package/dist/src/lib/transferBuilder.js +0 -70
- package/dist/src/lib/transferBuilderV2.d.ts +0 -43
- package/dist/src/lib/transferBuilderV2.d.ts.map +0 -1
- package/dist/src/lib/transferBuilderV2.js +0 -210
- package/dist/src/lib/utils.js +0 -589
- package/dist/src/lib/walletInitializationBuilder.js +0 -71
- package/dist/src/register.d.ts +0 -3
- package/dist/src/register.d.ts.map +0 -1
- package/dist/src/register.js +0 -15
- package/dist/src/sol.d.ts.map +0 -1
- package/dist/src/sol.js +0 -1324
- package/dist/src/solToken.d.ts.map +0 -1
- package/dist/src/solToken.js +0 -69
- package/dist/src/tsol.js +0 -24
- package/dist/test/fixtures/sol.js +0 -1433
- package/dist/test/resources/sol.d.ts.map +0 -1
- package/dist/test/resources/sol.js +0 -320
- package/dist/test/unit/fixtures/solBackupKey.d.ts.map +0 -1
- package/dist/test/unit/fixtures/solBackupKey.js +0 -8
- package/dist/test/unit/getBuilderFactory.d.ts.map +0 -1
- package/dist/test/unit/getBuilderFactory.js +0 -10
- package/dist/test/unit/instructionParamsFactory.d.ts.map +0 -1
- package/dist/test/unit/instructionParamsFactory.js +0 -412
- package/dist/test/unit/instructionParamsFactory.staking.d.ts.map +0 -1
- package/dist/test/unit/instructionParamsFactory.staking.js +0 -1059
- package/dist/test/unit/keyPair.js +0 -177
- package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +0 -1
- package/dist/test/unit/messages/messageBuilderFactory.js +0 -118
- package/dist/test/unit/messages/simpleMessageBuilder.d.ts.map +0 -1
- package/dist/test/unit/messages/simpleMessageBuilder.js +0 -194
- package/dist/test/unit/sol.js +0 -3180
- package/dist/test/unit/solInstructionFactory.d.ts.map +0 -1
- package/dist/test/unit/solInstructionFactory.js +0 -454
- package/dist/test/unit/solToken.d.ts.map +0 -1
- package/dist/test/unit/solToken.js +0 -31
- package/dist/test/unit/transaction.d.ts.map +0 -1
- package/dist/test/unit/transaction.js +0 -983
- package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.js +0 -202
- package/dist/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/ataInitBuilder.js +0 -471
- package/dist/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/customInstructionBuilder.js +0 -413
- package/dist/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingActivateBuilder.js +0 -430
- package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +0 -157
- package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.js +0 -384
- package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.js +0 -224
- package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +0 -259
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +0 -787
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transactionBuilder.js +0 -495
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transferBuilder.js +0 -286
- package/dist/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transferBuilderV2.js +0 -862
- package/dist/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/walletInitBuilder.js +0 -259
- package/dist/test/unit/utils.js +0 -517
- package/dist/test/unit/versionedTransaction.d.ts.map +0 -1
- package/dist/test/unit/versionedTransaction.js +0 -207
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/{src → cjs/src}/bigint-buffer-guard.d.ts +0 -0
- /package/dist/{src → cjs/src}/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/ataInitializationBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/customInstructionBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/jitoStakePoolOperations.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/keyPair.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/messages/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/messages/messageBuilderFactory.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/solInstructionFactory.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingActivateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingAuthorizeBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingDeactivateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingDelegateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingWithdrawBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/walletInitializationBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/tsol.d.ts +0 -0
- /package/dist/{test → cjs/test}/fixtures/sol.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/fixtures/solBackupKey.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/getBuilderFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/instructionParamsFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/instructionParamsFactory.staking.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/keyPair.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/messages/messageBuilderFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/messages/simpleMessageBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/sol.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/solInstructionFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/solToken.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transaction.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/StakingWithdrawBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/ataInitBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/customInstructionBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingActivateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDeactivateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDelegateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/tokenTransferBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transactionBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilderV2.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/walletInitBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/utils.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/versionedTransaction.d.ts +0 -0
- /package/dist/{src → esm}/bigint-buffer-guard.d.ts.map +0 -0
- /package/dist/{src → esm}/bigint-buffer-guard.js +0 -0
- /package/dist/{src → esm}/index.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/customInstructionBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/jitoStakePoolOperations.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/keyPair.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/messages/index.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/messages/messageBuilderFactory.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingActivateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingAuthorizeBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingDeactivateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingDelegateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingWithdrawBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transactionBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/walletInitializationBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/tsol.d.ts.map +0 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
import { BuildTransactionError, isValidXpub, NotSupported, ParseTransactionError, TransactionType, UtilsError, } from '@bitgo-beta/sdk-core';
|
|
2
|
+
import { CoinNotDefinedError, coins, SolCoin } from '@bitgo-beta/statics';
|
|
3
|
+
import { ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, decodeInstruction, TokenInstruction, TransferFeeInstruction, } from '@solana/spl-token';
|
|
4
|
+
import { Keypair, PublicKey, Transaction as SolTransaction, StakeInstruction, StakeProgram, SystemInstruction, SystemProgram, ComputeBudgetInstruction, } from '@solana/web3.js';
|
|
5
|
+
import assert from 'assert';
|
|
6
|
+
import BigNumber from 'bignumber.js';
|
|
7
|
+
import bs58 from 'bs58';
|
|
8
|
+
import nacl from 'tweetnacl';
|
|
9
|
+
import { ataCloseInstructionIndexes, ataInitInstructionIndexes, ataRecoverNestedInstructionIndexes, MAX_MEMO_LENGTH, MEMO_PROGRAM_PK, nonceAdvanceInstruction, stakingActivateInstructionsIndexes, marinadeStakingActivateInstructionsIndexes, stakingAuthorizeInstructionsIndexes, stakingDeactivateInstructionsIndexes, marinadeStakingDeactivateInstructionsIndexes, stakingDelegateInstructionsIndexes, stakingPartialDeactivateInstructionsIndexes, stakingWithdrawInstructionsIndexes, VALID_SYSTEM_INSTRUCTION_TYPES, validInstructionData, validInstructionData2, ValidInstructionTypesEnum, walletInitInstructionIndexes, jitoStakingActivateInstructionsIndexes, jitoStakingDeactivateInstructionsIndexes, jitoStakingActivateWithATAInstructionsIndexes, TOKEN_ACL_PROGRAM_ID, } from './constants';
|
|
10
|
+
import { STAKE_POOL_INSTRUCTION_LAYOUTS, STAKE_POOL_PROGRAM_ID } from '@solana/spl-stake-pool';
|
|
11
|
+
const DECODED_BLOCK_HASH_LENGTH = 32; // https://docs.solana.com/developing/programming-model/transactions#blockhash-format
|
|
12
|
+
const DECODED_SIGNATURE_LENGTH = 64; // https://docs.solana.com/terminology#signature
|
|
13
|
+
const BASE_58_ENCONDING_REGEX = '[1-9A-HJ-NP-Za-km-z]';
|
|
14
|
+
const COMPUTE_BUDGET = 'ComputeBudget111111111111111111111111111111';
|
|
15
|
+
/**
|
|
16
|
+
* Checks if an ATA instruction is idempotent (discriminator byte = 1).
|
|
17
|
+
*
|
|
18
|
+
* Idempotent ATA instructions use Buffer.from([1]) as instruction data, created by
|
|
19
|
+
* @solana/spl-token's createAssociatedTokenAccountIdempotentInstruction() (v0.4.1+).
|
|
20
|
+
* An idempotent ATA instruction succeed even if account exists,
|
|
21
|
+
* preventing race condition errors in concurrent scenarios.
|
|
22
|
+
*
|
|
23
|
+
* @param {TransactionInstruction} instruction - The instruction to validate
|
|
24
|
+
* @returns {boolean} True if instruction data is a single byte with value 1
|
|
25
|
+
*/
|
|
26
|
+
export function isIdempotentAtaInstruction(instruction) {
|
|
27
|
+
return instruction.data.length === 1 && instruction.data[0] === 1;
|
|
28
|
+
}
|
|
29
|
+
/** @inheritdoc */
|
|
30
|
+
export function isValidAddress(address) {
|
|
31
|
+
return isValidPublicKey(address);
|
|
32
|
+
}
|
|
33
|
+
/** @inheritdoc */
|
|
34
|
+
export function isValidBlockId(hash) {
|
|
35
|
+
try {
|
|
36
|
+
return (!!hash && new RegExp(BASE_58_ENCONDING_REGEX).test(hash) && bs58.decode(hash).length === DECODED_BLOCK_HASH_LENGTH);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** @inheritdoc */
|
|
43
|
+
export function isValidPrivateKey(prvKey) {
|
|
44
|
+
try {
|
|
45
|
+
const key = typeof prvKey === 'string' ? base58ToUint8Array(prvKey) : prvKey;
|
|
46
|
+
return !!Keypair.fromSecretKey(key);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** @inheritdoc */
|
|
53
|
+
export function isValidPublicKey(pubKey) {
|
|
54
|
+
try {
|
|
55
|
+
if (isValidXpub(pubKey))
|
|
56
|
+
return true;
|
|
57
|
+
new PublicKey(pubKey);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** @inheritdoc */
|
|
65
|
+
export function isValidSignature(signature) {
|
|
66
|
+
try {
|
|
67
|
+
return !!signature && bs58.decode(signature).length === DECODED_SIGNATURE_LENGTH;
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** @inheritdoc */
|
|
74
|
+
// TransactionId are the first signature on a Transaction
|
|
75
|
+
export function isValidTransactionId(txId) {
|
|
76
|
+
return isValidSignature(txId);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Returns whether or not the string is a valid amount of lamports number
|
|
80
|
+
*
|
|
81
|
+
* @param {string} amount - the string to validate
|
|
82
|
+
* @returns {boolean} - the validation result
|
|
83
|
+
*/
|
|
84
|
+
export function isValidAmount(amount) {
|
|
85
|
+
const bigNumberAmount = new BigNumber(amount);
|
|
86
|
+
return bigNumberAmount.isInteger() && bigNumberAmount.isGreaterThanOrEqualTo(0);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if the string is a valid amount of lamports number on staking
|
|
90
|
+
*
|
|
91
|
+
* @param {string} amount - the string to validate
|
|
92
|
+
* @returns {boolean} - the validation result
|
|
93
|
+
*/
|
|
94
|
+
export function isValidStakingAmount(amount) {
|
|
95
|
+
const bigNumberAmount = new BigNumber(amount);
|
|
96
|
+
return bigNumberAmount.isInteger() && bigNumberAmount.isGreaterThan(0);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if this is a valid memo or not.
|
|
100
|
+
*
|
|
101
|
+
* @param memo - the memo string
|
|
102
|
+
* @returns {boolean} - the validation result
|
|
103
|
+
*/
|
|
104
|
+
export function isValidMemo(memo) {
|
|
105
|
+
return Buffer.from(memo).length <= MAX_MEMO_LENGTH;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Checks if a string is valid base64 encoded data
|
|
109
|
+
* @param str - The string to validate
|
|
110
|
+
* @returns True if the string is valid base64, false otherwise
|
|
111
|
+
*/
|
|
112
|
+
export function isValidBase64(str) {
|
|
113
|
+
try {
|
|
114
|
+
const decoded = Buffer.from(str, 'base64').toString('base64');
|
|
115
|
+
return decoded === str;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks if a string is valid hexadecimal data
|
|
123
|
+
* @param str - The string to validate
|
|
124
|
+
* @returns True if the string is valid hex, false otherwise
|
|
125
|
+
*/
|
|
126
|
+
export function isValidHex(str) {
|
|
127
|
+
return /^[0-9A-Fa-f]*$/.test(str) && str.length % 2 === 0;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Checks if raw transaction can be deserialized
|
|
131
|
+
*
|
|
132
|
+
* @param {string} rawTransaction - transaction in base64 string format
|
|
133
|
+
* @param {boolean} requireAllSignatures - require all signatures to be present
|
|
134
|
+
* @param {boolean} verifySignatures - verify signatures
|
|
135
|
+
* @returns {boolean} - the validation result
|
|
136
|
+
*/
|
|
137
|
+
export function isValidRawTransaction(rawTransaction, requireAllSignatures = false, verifySignatures = false) {
|
|
138
|
+
try {
|
|
139
|
+
const tx = SolTransaction.from(Buffer.from(rawTransaction, 'base64'));
|
|
140
|
+
tx.serialize({ requireAllSignatures, verifySignatures });
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Verifies if signature for message is valid.
|
|
149
|
+
*
|
|
150
|
+
* @param {Buffer} serializedTx - tx as a base64 string
|
|
151
|
+
* @param {string} signature - signature as a string
|
|
152
|
+
* @param {string} publicKey - public key as base 58
|
|
153
|
+
* @returns {Boolean} true if signature is valid.
|
|
154
|
+
*/
|
|
155
|
+
export function verifySignature(serializedTx, signature, publicKey) {
|
|
156
|
+
if (!isValidRawTransaction(serializedTx)) {
|
|
157
|
+
throw new UtilsError('Invalid serializedTx');
|
|
158
|
+
}
|
|
159
|
+
if (!isValidPublicKey(publicKey)) {
|
|
160
|
+
throw new UtilsError('Invalid publicKey');
|
|
161
|
+
}
|
|
162
|
+
if (!isValidSignature(signature)) {
|
|
163
|
+
throw new UtilsError('Invalid signature');
|
|
164
|
+
}
|
|
165
|
+
const msg = SolTransaction.from(Buffer.from(serializedTx, 'base64')).serializeMessage();
|
|
166
|
+
const sig = base58ToUint8Array(signature);
|
|
167
|
+
const pub = new PublicKey(publicKey);
|
|
168
|
+
return nacl.sign.detached.verify(msg, sig, pub.toBuffer());
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Converts a base58 string into a Uint8Array.
|
|
172
|
+
*
|
|
173
|
+
* @param {string} input - a string in base58
|
|
174
|
+
* @returns {Uint8Array} - an Uint8Array
|
|
175
|
+
*/
|
|
176
|
+
export function base58ToUint8Array(input) {
|
|
177
|
+
return new Uint8Array(bs58.decode(input));
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Converts a Uint8Array to a base58 string.
|
|
181
|
+
*
|
|
182
|
+
* @param {Uint8Array} input - an Uint8Array
|
|
183
|
+
* @returns {string} - a string in base58
|
|
184
|
+
*/
|
|
185
|
+
export function Uint8ArrayTobase58(input) {
|
|
186
|
+
return bs58.encode(input);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Count the amount of signatures are not null.
|
|
190
|
+
*
|
|
191
|
+
* @param {SignaturePubkeyPair[]} signatures - an array of SignaturePubkeyPair
|
|
192
|
+
* @returns {number} - the amount of valid signatures
|
|
193
|
+
*/
|
|
194
|
+
export function countNotNullSignatures(signatures) {
|
|
195
|
+
return signatures.filter((sig) => !!sig.signature).length;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if all signatures are completed.
|
|
199
|
+
*
|
|
200
|
+
* @param {SignaturePubkeyPair[]} signatures - signatures
|
|
201
|
+
* @returns {boolean}
|
|
202
|
+
*/
|
|
203
|
+
export function requiresAllSignatures(signatures) {
|
|
204
|
+
return signatures.length > 0 && countNotNullSignatures(signatures) === signatures.length;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Check the transaction type matching instructions by order. Memo and AdvanceNonceAccount instructions
|
|
208
|
+
* are ignored.
|
|
209
|
+
*
|
|
210
|
+
* @param {TransactionInstruction[]} instructions - the array of supported Solana instructions to be parsed
|
|
211
|
+
* @param {Record<string, number>} instructionIndexes - the instructions indexes of the current transaction
|
|
212
|
+
* @returns true if it matches by order.
|
|
213
|
+
*/
|
|
214
|
+
export function matchTransactionTypeByInstructionsOrder(instructions, instructionIndexes) {
|
|
215
|
+
const instructionsCopy = [...instructions]; // Make a copy since we may modify the array below
|
|
216
|
+
// AdvanceNonceAccount is optional and the first instruction added, it does not matter to match the type
|
|
217
|
+
if (instructionsCopy.length > 0) {
|
|
218
|
+
if (getInstructionType(instructions[0]) === 'AdvanceNonceAccount') {
|
|
219
|
+
instructionsCopy.shift();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Memo is optional and the last instruction added, it does not matter to match the type
|
|
223
|
+
// Why have it in instructionKeys if we are going to ignore it?
|
|
224
|
+
const instructionsKeys = Object.keys(instructionIndexes);
|
|
225
|
+
if (instructionsKeys[instructionsKeys.length - 1] === 'Memo') {
|
|
226
|
+
instructionsKeys.pop();
|
|
227
|
+
}
|
|
228
|
+
// Check instructions by order using the index.
|
|
229
|
+
for (const keyName of instructionsKeys) {
|
|
230
|
+
const index = instructionIndexes[keyName];
|
|
231
|
+
if (index >= instructionsCopy.length) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
const result = getInstructionType(instructionsCopy[index]);
|
|
235
|
+
if (result !== keyName) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Returns the transaction Type based on the transaction instructions.
|
|
243
|
+
* Wallet initialization, Transfer and Staking transactions are supported.
|
|
244
|
+
*
|
|
245
|
+
* @param {SolTransaction} transaction - the solana transaction
|
|
246
|
+
* @returns {TransactionType} - the type of transaction
|
|
247
|
+
*/
|
|
248
|
+
export function getTransactionType(transaction) {
|
|
249
|
+
const { instructions } = transaction;
|
|
250
|
+
if (validateRawMsgInstruction(instructions)) {
|
|
251
|
+
return TransactionType.StakingAuthorizeRaw;
|
|
252
|
+
}
|
|
253
|
+
validateIntructionTypes(instructions);
|
|
254
|
+
// check if deactivate instruction does not exist because deactivate can be include a transfer instruction
|
|
255
|
+
const memoInstruction = instructions.find((instruction) => getInstructionType(instruction) === 'Memo');
|
|
256
|
+
const memoData = memoInstruction?.data.toString('utf-8');
|
|
257
|
+
if (memoData?.includes('WalletConnectDefiCustomTx')) {
|
|
258
|
+
return TransactionType.CustomTx;
|
|
259
|
+
}
|
|
260
|
+
// Check for close ATA instructions before classifying as Send.
|
|
261
|
+
// A bulk close-ATA tx contains only closeAccount instructions (zero-balance ATAs).
|
|
262
|
+
// Note: This assumes close-ATA transactions never contain TokenTransfer instructions.
|
|
263
|
+
// This holds for Phase 1 where non-zero balance ATAs are rejected (user must consolidate first).
|
|
264
|
+
// If atomic transfer+close is added in the future, this detection needs refinement.
|
|
265
|
+
const hasCloseAta = instructions.some((instruction) => getInstructionType(instruction) === ValidInstructionTypesEnum.CloseAssociatedTokenAccount);
|
|
266
|
+
if (hasCloseAta) {
|
|
267
|
+
return TransactionType.CloseAssociatedTokenAccount;
|
|
268
|
+
}
|
|
269
|
+
if (instructions.filter((instruction) => getInstructionType(instruction) === 'Deactivate').length === 0) {
|
|
270
|
+
for (const instruction of instructions) {
|
|
271
|
+
const instructionType = getInstructionType(instruction);
|
|
272
|
+
// Check if memo instruction is there and if it contains 'PrepareForRevoke' because Marinade staking deactivate transaction will have this
|
|
273
|
+
if ((instructionType === ValidInstructionTypesEnum.Transfer && !memoData?.includes('PrepareForRevoke')) ||
|
|
274
|
+
instructionType === ValidInstructionTypesEnum.TokenTransfer) {
|
|
275
|
+
return TransactionType.Send;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (matchTransactionTypeByInstructionsOrder(instructions, walletInitInstructionIndexes)) {
|
|
280
|
+
return TransactionType.WalletInitialization;
|
|
281
|
+
}
|
|
282
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, marinadeStakingActivateInstructionsIndexes) ||
|
|
283
|
+
matchTransactionTypeByInstructionsOrder(instructions, jitoStakingActivateInstructionsIndexes) ||
|
|
284
|
+
matchTransactionTypeByInstructionsOrder(instructions, jitoStakingActivateWithATAInstructionsIndexes) ||
|
|
285
|
+
matchTransactionTypeByInstructionsOrder(instructions, stakingActivateInstructionsIndexes)) {
|
|
286
|
+
return TransactionType.StakingActivate;
|
|
287
|
+
}
|
|
288
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, stakingAuthorizeInstructionsIndexes)) {
|
|
289
|
+
return TransactionType.StakingAuthorize;
|
|
290
|
+
}
|
|
291
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, stakingDelegateInstructionsIndexes)) {
|
|
292
|
+
return TransactionType.StakingDelegate;
|
|
293
|
+
}
|
|
294
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, marinadeStakingDeactivateInstructionsIndexes) ||
|
|
295
|
+
matchTransactionTypeByInstructionsOrder(instructions, stakingDeactivateInstructionsIndexes) ||
|
|
296
|
+
matchTransactionTypeByInstructionsOrder(instructions, stakingPartialDeactivateInstructionsIndexes) ||
|
|
297
|
+
matchTransactionTypeByInstructionsOrder(instructions, jitoStakingDeactivateInstructionsIndexes)) {
|
|
298
|
+
return TransactionType.StakingDeactivate;
|
|
299
|
+
}
|
|
300
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, stakingWithdrawInstructionsIndexes)) {
|
|
301
|
+
return TransactionType.StakingWithdraw;
|
|
302
|
+
}
|
|
303
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, ataInitInstructionIndexes)) {
|
|
304
|
+
return TransactionType.AssociatedTokenAccountInitialization;
|
|
305
|
+
}
|
|
306
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, ataCloseInstructionIndexes)) {
|
|
307
|
+
return TransactionType.CloseAssociatedTokenAccount;
|
|
308
|
+
}
|
|
309
|
+
else if (matchTransactionTypeByInstructionsOrder(instructions, ataRecoverNestedInstructionIndexes)) {
|
|
310
|
+
return TransactionType.CloseAssociatedTokenAccount;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return TransactionType.CustomTx;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Returns the instruction Type based on the solana instructions.
|
|
318
|
+
* Throws if the solana instruction program is not supported
|
|
319
|
+
*
|
|
320
|
+
* @param {TransactionInstruction} instruction - a solana instruction
|
|
321
|
+
* @returns {ValidInstructionTypes} - a solana instruction type
|
|
322
|
+
*/
|
|
323
|
+
export function getInstructionType(instruction) {
|
|
324
|
+
switch (instruction.programId.toString()) {
|
|
325
|
+
case new PublicKey(MEMO_PROGRAM_PK).toString():
|
|
326
|
+
return 'Memo';
|
|
327
|
+
case SystemProgram.programId.toString():
|
|
328
|
+
return SystemInstruction.decodeInstructionType(instruction);
|
|
329
|
+
case TOKEN_PROGRAM_ID.toString():
|
|
330
|
+
case TOKEN_2022_PROGRAM_ID.toString():
|
|
331
|
+
if (instruction.programId.equals(TOKEN_2022_PROGRAM_ID) &&
|
|
332
|
+
instruction.data.length >= 2 &&
|
|
333
|
+
instruction.data[0] === TokenInstruction.TransferFeeExtension &&
|
|
334
|
+
instruction.data[1] === TransferFeeInstruction.TransferCheckedWithFee) {
|
|
335
|
+
return 'TokenTransfer';
|
|
336
|
+
}
|
|
337
|
+
let decodedInstruction;
|
|
338
|
+
try {
|
|
339
|
+
decodedInstruction = decodeInstruction(instruction, instruction.programId);
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
// decodeInstruction only supports the base token instruction set —
|
|
343
|
+
// extension-family instructions (Pause, PermissionedBurn, transfer
|
|
344
|
+
// fee ops, ...) throw TokenInvalidInstructionTypeError at EVERY
|
|
345
|
+
// @solana/spl-token version. Those must not crash classification:
|
|
346
|
+
// fall back to CustomInstruction, the same path used below for
|
|
347
|
+
// decodable-but-unmapped instruction types.
|
|
348
|
+
return 'CustomInstruction';
|
|
349
|
+
}
|
|
350
|
+
const instructionTypeMap = new Map();
|
|
351
|
+
instructionTypeMap.set(TokenInstruction.CloseAccount, 'CloseAssociatedTokenAccount');
|
|
352
|
+
instructionTypeMap.set(TokenInstruction.Burn, 'Burn');
|
|
353
|
+
instructionTypeMap.set(TokenInstruction.MintTo, 'MintTo');
|
|
354
|
+
instructionTypeMap.set(TokenInstruction.Approve, 'Approve');
|
|
355
|
+
instructionTypeMap.set(TokenInstruction.TransferChecked, 'TokenTransfer');
|
|
356
|
+
const validInstruction = instructionTypeMap.get(decodedInstruction.data.instruction);
|
|
357
|
+
if (!validInstruction) {
|
|
358
|
+
return 'CustomInstruction';
|
|
359
|
+
}
|
|
360
|
+
return validInstruction;
|
|
361
|
+
case STAKE_POOL_PROGRAM_ID.toString():
|
|
362
|
+
const discriminator = instruction.data.readUint8(0);
|
|
363
|
+
const layoutKey = Object.entries(STAKE_POOL_INSTRUCTION_LAYOUTS).find(([_, v]) => v.index === discriminator)?.[0];
|
|
364
|
+
if (layoutKey === undefined) {
|
|
365
|
+
throw new Error('Instruction type incorrect; unknown discriminator');
|
|
366
|
+
}
|
|
367
|
+
const instructionKey = layoutKey;
|
|
368
|
+
return instructionKey;
|
|
369
|
+
case StakeProgram.programId.toString():
|
|
370
|
+
return StakeInstruction.decodeInstructionType(instruction);
|
|
371
|
+
case TOKEN_ACL_PROGRAM_ID:
|
|
372
|
+
// The Token ACL program has a single instruction the SDK builds — the permissionless thaw.
|
|
373
|
+
return ValidInstructionTypesEnum.PermissionlessThawIdempotent;
|
|
374
|
+
case ASSOCIATED_TOKEN_PROGRAM_ID.toString():
|
|
375
|
+
// TODO: change this when @spl-token supports decoding associated token instructions
|
|
376
|
+
// Support both legacy ATA creation (data.length === 0) and idempotent ATA creation (discriminator = 1)
|
|
377
|
+
// Both instruction types are treated as 'InitializeAssociatedTokenAccount' for compatibility
|
|
378
|
+
if (instruction.data.length === 0 || isIdempotentAtaInstruction(instruction)) {
|
|
379
|
+
return 'InitializeAssociatedTokenAccount';
|
|
380
|
+
}
|
|
381
|
+
else if (instruction.data.length === 1 && instruction.data[0] === 2) {
|
|
382
|
+
return 'RecoverNestedAssociatedTokenAccount';
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
throw new NotSupported('Invalid transaction, instruction program id not supported: ' + instruction.programId.toString());
|
|
386
|
+
}
|
|
387
|
+
case COMPUTE_BUDGET:
|
|
388
|
+
if (ComputeBudgetInstruction.decodeInstructionType(instruction) === 'SetComputeUnitLimit') {
|
|
389
|
+
return 'SetComputeUnitLimit';
|
|
390
|
+
}
|
|
391
|
+
return 'SetPriorityFee';
|
|
392
|
+
default:
|
|
393
|
+
return 'CustomInstruction';
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Validate solana instructions types to see if they are supported by the builder.
|
|
398
|
+
* Throws if the instruction type is invalid.
|
|
399
|
+
*
|
|
400
|
+
* @param {TransactionInstruction} instructions - a solana instruction
|
|
401
|
+
* @returns {void}
|
|
402
|
+
*/
|
|
403
|
+
export function validateIntructionTypes(instructions) {
|
|
404
|
+
for (const instruction of instructions) {
|
|
405
|
+
if (!VALID_SYSTEM_INSTRUCTION_TYPES.includes(getInstructionType(instruction))) {
|
|
406
|
+
throw new NotSupported('Invalid transaction, instruction type not supported: ' + getInstructionType(instruction));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Validate solana instructions match raw msg authorize transaction
|
|
412
|
+
*
|
|
413
|
+
* @param {TransactionInstruction} instructions - a solana instruction
|
|
414
|
+
* @returns {boolean} true if the instructions match the raw msg authorize transaction
|
|
415
|
+
*/
|
|
416
|
+
export function validateRawMsgInstruction(instructions) {
|
|
417
|
+
// as web3.js cannot decode authorize instruction from CLI, we need to check it manually first
|
|
418
|
+
if (instructions.length === 2) {
|
|
419
|
+
const programId1 = instructions[0].programId.toString();
|
|
420
|
+
const programId2 = instructions[1].programId.toString();
|
|
421
|
+
if (programId1 === SystemProgram.programId.toString() && programId2 === StakeProgram.programId.toString()) {
|
|
422
|
+
const instructionName1 = SystemInstruction.decodeInstructionType(instructions[0]);
|
|
423
|
+
const data = instructions[1].data.toString('hex');
|
|
424
|
+
if (instructionName1 === nonceAdvanceInstruction &&
|
|
425
|
+
(data === validInstructionData || data === validInstructionData2)) {
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (instructions.length === 3) {
|
|
431
|
+
const programId1 = instructions[0].programId.toString();
|
|
432
|
+
const programId2 = instructions[1].programId.toString();
|
|
433
|
+
const programId3 = instructions[2].programId.toString();
|
|
434
|
+
if (programId1 === SystemProgram.programId.toString() &&
|
|
435
|
+
programId2 === StakeProgram.programId.toString() &&
|
|
436
|
+
programId3 === StakeProgram.programId.toString()) {
|
|
437
|
+
const instructionName1 = SystemInstruction.decodeInstructionType(instructions[0]);
|
|
438
|
+
const data = instructions[1].data.toString('hex');
|
|
439
|
+
const data2 = instructions[2].data.toString('hex');
|
|
440
|
+
if (instructionName1 === nonceAdvanceInstruction &&
|
|
441
|
+
(data === validInstructionData || data === validInstructionData2) &&
|
|
442
|
+
(data2 === validInstructionData || data2 === validInstructionData2)) {
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Check the raw transaction has a valid format in the blockchain context, throw otherwise.
|
|
451
|
+
*
|
|
452
|
+
* @param {string} rawTransaction - Transaction in base64 string format
|
|
453
|
+
*/
|
|
454
|
+
export function validateRawTransaction(rawTransaction, requireAllSignatures = false, verifySignatures = false) {
|
|
455
|
+
if (!rawTransaction) {
|
|
456
|
+
throw new ParseTransactionError('Invalid raw transaction: Undefined');
|
|
457
|
+
}
|
|
458
|
+
if (!isValidRawTransaction(rawTransaction, requireAllSignatures, verifySignatures)) {
|
|
459
|
+
throw new ParseTransactionError('Invalid raw transaction');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Validates address to check if it exists and is a valid Solana public key
|
|
464
|
+
*
|
|
465
|
+
* @param {string} address The address to be validated
|
|
466
|
+
* @param {string} fieldName Name of the field to validate, its needed to return which field is failing on case of error.
|
|
467
|
+
*/
|
|
468
|
+
export function validateAddress(address, fieldName) {
|
|
469
|
+
if (!address || !isValidPublicKey(address)) {
|
|
470
|
+
throw new BuildTransactionError(`Invalid or missing ${fieldName}, got: ${address}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get the statics coin object matching a given Solana token address if it exists
|
|
475
|
+
*
|
|
476
|
+
* @param tokenAddress The token address to match against
|
|
477
|
+
* @param network Solana Mainnet or Testnet
|
|
478
|
+
* @returns statics BaseCoin object for the matching token
|
|
479
|
+
*/
|
|
480
|
+
export function getSolTokenFromAddress(tokenAddress, network) {
|
|
481
|
+
const tokens = coins.filter((coin) => {
|
|
482
|
+
if (coin instanceof SolCoin) {
|
|
483
|
+
return coin.network.type === network.type && coin.tokenAddress.toLowerCase() === tokenAddress.toLowerCase();
|
|
484
|
+
}
|
|
485
|
+
return false;
|
|
486
|
+
});
|
|
487
|
+
const tokensArray = tokens.map((token) => token);
|
|
488
|
+
if (tokensArray.length >= 1) {
|
|
489
|
+
// there should never be two tokens with the same contract address, so we assert that here
|
|
490
|
+
assert(tokensArray.length === 1);
|
|
491
|
+
return tokensArray[0];
|
|
492
|
+
}
|
|
493
|
+
return undefined;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Get the statics coin object matching a given Solana token address if it exists
|
|
497
|
+
*
|
|
498
|
+
* @param tokenAddress The token address to match against
|
|
499
|
+
* @param network Solana Mainnet or Testnet
|
|
500
|
+
* @returns statics BaseCoin object for the matching token
|
|
501
|
+
*/
|
|
502
|
+
export function getSolTokenFromAddressOnly(tokenAddress) {
|
|
503
|
+
const tokens = coins.filter((coin) => {
|
|
504
|
+
if (coin instanceof SolCoin) {
|
|
505
|
+
return coin.tokenAddress.toLowerCase() === tokenAddress.toLowerCase();
|
|
506
|
+
}
|
|
507
|
+
return false;
|
|
508
|
+
});
|
|
509
|
+
const tokensArray = tokens.map((token) => token);
|
|
510
|
+
if (tokensArray.length >= 1) {
|
|
511
|
+
// there should never be two tokens with the same contract address, so we assert that here
|
|
512
|
+
assert(tokensArray.length === 1);
|
|
513
|
+
return tokensArray[0];
|
|
514
|
+
}
|
|
515
|
+
return undefined;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Get the solana token object from token name
|
|
519
|
+
* @param tokenName The token name to match against
|
|
520
|
+
* */
|
|
521
|
+
export function getSolTokenFromTokenName(tokenName) {
|
|
522
|
+
try {
|
|
523
|
+
const token = coins.get(tokenName);
|
|
524
|
+
if (!(token.isToken && token instanceof SolCoin)) {
|
|
525
|
+
return undefined;
|
|
526
|
+
}
|
|
527
|
+
return token;
|
|
528
|
+
}
|
|
529
|
+
catch (e) {
|
|
530
|
+
if (!(e instanceof CoinNotDefinedError)) {
|
|
531
|
+
throw e;
|
|
532
|
+
}
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Get the solana associated token account address
|
|
538
|
+
* @param tokenAddress token mint address
|
|
539
|
+
* @param ownerAddress The owner of the associated token account
|
|
540
|
+
* @returns The associated token account address
|
|
541
|
+
* */
|
|
542
|
+
export async function getAssociatedTokenAccountAddress(tokenMintAddress, ownerAddress, allowOwnerOffCurve = false, programId) {
|
|
543
|
+
const mintPublicKey = new PublicKey(tokenMintAddress);
|
|
544
|
+
const ownerPublicKey = new PublicKey(ownerAddress);
|
|
545
|
+
// tokenAddress are not on ed25519 curve, so they can't be used as ownerAddress
|
|
546
|
+
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(ownerPublicKey.toBuffer())) {
|
|
547
|
+
throw new UtilsError('Invalid ownerAddress - address off ed25519 curve, got: ' + ownerAddress);
|
|
548
|
+
}
|
|
549
|
+
if (!programId) {
|
|
550
|
+
const coin = getSolTokenFromAddressOnly(tokenMintAddress);
|
|
551
|
+
if (coin && coin instanceof SolCoin && 'programId' in coin && coin.programId) {
|
|
552
|
+
programId = coin.programId.toString();
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
programId = TOKEN_PROGRAM_ID.toString();
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
let ataAddress;
|
|
559
|
+
if (programId === TOKEN_2022_PROGRAM_ID.toString()) {
|
|
560
|
+
ataAddress = await getAssociatedTokenAddress(mintPublicKey, ownerPublicKey, allowOwnerOffCurve, TOKEN_2022_PROGRAM_ID);
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
ataAddress = await getAssociatedTokenAddress(mintPublicKey, ownerPublicKey, allowOwnerOffCurve);
|
|
564
|
+
}
|
|
565
|
+
return ataAddress.toString();
|
|
566
|
+
}
|
|
567
|
+
export function validateMintAddress(mintAddress) {
|
|
568
|
+
if (!mintAddress || !isValidAddress(mintAddress)) {
|
|
569
|
+
throw new BuildTransactionError('Invalid or missing mintAddress, got: ' + mintAddress);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
export function validateOwnerAddress(ownerAddress) {
|
|
573
|
+
if (!ownerAddress || !isValidAddress(ownerAddress)) {
|
|
574
|
+
throw new BuildTransactionError('Invalid or missing ownerAddress, got: ' + ownerAddress);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Type predicate to check if an instruction is a legacy SolInstruction.
|
|
579
|
+
* Uses 'programId' property as the discriminator since it's unique to legacy instructions
|
|
580
|
+
* Versioned instructions have 'programIdIndex' property.
|
|
581
|
+
*
|
|
582
|
+
* @param instruction - The instruction to check
|
|
583
|
+
* @returns True if the instruction is a SolInstruction (has programId field)
|
|
584
|
+
*/
|
|
585
|
+
export function isSolLegacyInstruction(instruction) {
|
|
586
|
+
return 'programId' in instruction;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Token-2022 transfer fee: min(amount * basisPoints / 10000, maximumFee), in raw base units.
|
|
590
|
+
* All math in BigInt to avoid precision loss.
|
|
591
|
+
*/
|
|
592
|
+
export function computeTransferFee(amount, basisPoints, maximumFee) {
|
|
593
|
+
const raw = (BigInt(amount) * BigInt(basisPoints)) / 10000n;
|
|
594
|
+
const cap = BigInt(maximumFee);
|
|
595
|
+
return (raw < cap ? raw : cap).toString();
|
|
596
|
+
}
|
|
597
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsV0FBVyxFQUNYLFlBQVksRUFDWixxQkFBcUIsRUFHckIsZUFBZSxFQUNmLFVBQVUsR0FDWCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBeUIsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pHLE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IseUJBQXlCLEVBQ3pCLGdCQUFnQixFQUNoQixxQkFBcUIsRUFDckIsaUJBQWlCLEVBRWpCLGdCQUFnQixFQUNoQixzQkFBc0IsR0FDdkIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQ0wsT0FBTyxFQUNQLFNBQVMsRUFFVCxXQUFXLElBQUksY0FBYyxFQUM3QixnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixhQUFhLEVBRWIsd0JBQXdCLEdBQ3pCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sU0FBUyxNQUFNLGNBQWMsQ0FBQztBQUNyQyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQzdCLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIseUJBQXlCLEVBQ3pCLGtDQUFrQyxFQUNsQyxlQUFlLEVBQ2YsZUFBZSxFQUNmLHVCQUF1QixFQUN2QixrQ0FBa0MsRUFDbEMsMENBQTBDLEVBQzFDLG1DQUFtQyxFQUNuQyxvQ0FBb0MsRUFDcEMsNENBQTRDLEVBQzVDLGtDQUFrQyxFQUNsQywyQ0FBMkMsRUFDM0Msa0NBQWtDLEVBQ2xDLDhCQUE4QixFQUM5QixvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLHlCQUF5QixFQUN6Qiw0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LENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDO0lBQzVELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMvQixPQUFPLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQnVpbGRUcmFuc2FjdGlvbkVycm9yLFxuICBpc1ZhbGlkWHB1YixcbiAgTm90U3VwcG9ydGVkLFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG4gIFNvbEluc3RydWN0aW9uLFxuICBTb2xWZXJzaW9uZWRJbnN0cnVjdGlvbixcbiAgVHJhbnNhY3Rpb25UeXBlLFxuICBVdGlsc0Vycm9yLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29pbiwgQmFzZU5ldHdvcmssIENvaW5Ob3REZWZpbmVkRXJyb3IsIGNvaW5zLCBTb2xDb2luIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQge1xuICBBU1NPQ0lBVEVEX1RPS0VOX1BST0dSQU1fSUQsXG4gIGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3MsXG4gIFRPS0VOX1BST0dSQU1fSUQsXG4gIFRPS0VOXzIwMjJfUFJPR1JBTV9JRCxcbiAgZGVjb2RlSW5zdHJ1Y3Rpb24sXG4gIERlY29kZWRJbnN0cnVjdGlvbixcbiAgVG9rZW5JbnN0cnVjdGlvbixcbiAgVHJhbnNmZXJGZWVJbnN0cnVjdGlvbixcbn0gZnJvbSAnQHNvbGFuYS9zcGwtdG9rZW4nO1xuaW1wb3J0IHtcbiAgS2V5cGFpcixcbiAgUHVibGljS2V5LFxuICBTaWduYXR1cmVQdWJrZXlQYWlyLFxuICBUcmFuc2FjdGlvbiBhcyBTb2xUcmFuc2FjdGlvbixcbiAgU3Rha2VJbnN0cnVjdGlvbixcbiAgU3Rha2VQcm9ncmFtLFxuICBTeXN0ZW1JbnN0cnVjdGlvbixcbiAgU3lzdGVtUHJvZ3JhbSxcbiAgVHJhbnNhY3Rpb25JbnN0cnVjdGlvbixcbiAgQ29tcHV0ZUJ1ZGdldEluc3RydWN0aW9uLFxufSBmcm9tICdAc29sYW5hL3dlYjMuanMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0IGJzNTggZnJvbSAnYnM1OCc7XG5pbXBvcnQgbmFjbCBmcm9tICd0d2VldG5hY2wnO1xuaW1wb3J0IHtcbiAgYXRhQ2xvc2VJbnN0cnVjdGlvbkluZGV4ZXMsXG4gIGF0YUluaXRJbnN0cnVjdGlvbkluZGV4ZXMsXG4gIGF0YVJlY292ZXJOZXN0ZWRJbnN0cnVjdGlvbkluZGV4ZXMsXG4gIE1BWF9NRU1PX0xFTkdUSCxcbiAgTUVNT19QUk9HUkFNX1BLLFxuICBub25jZUFkdmFuY2VJbnN0cnVjdGlvbixcbiAgc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgbWFyaW5hZGVTdGFraW5nQWN0aXZhdGVJbnN0cnVjdGlvbnNJbmRleGVzLFxuICBzdGFraW5nQXV0aG9yaXplSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnNJbmRleGVzLFxuICBtYXJpbmFkZVN0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgc3Rha2luZ0RlbGVnYXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgc3Rha2luZ1BhcnRpYWxEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgc3Rha2luZ1dpdGhkcmF3SW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgVkFMSURfU1lTVEVNX0lOU1RSVUNUSU9OX1RZUEVTLFxuICB2YWxpZEluc3RydWN0aW9uRGF0YSxcbiAgdmFsaWRJbnN0cnVjdGlvbkRhdGEyLFxuICBWYWxpZEluc3RydWN0aW9uVHlwZXNFbnVtLFxuICB3YWxsZXRJbml0SW5zdHJ1Y3Rpb25JbmRleGVzLFxuICBqaXRvU3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgaml0b1N0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcyxcbiAgaml0b1N0YWtpbmdBY3RpdmF0ZVdpdGhBVEFJbnN0cnVjdGlvbnNJbmRleGVzLFxuICBUT0tFTl9BQ0xfUFJPR1JBTV9JRCxcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgVmFsaWRJbnN0cnVjdGlvblR5cGVzIH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgeyBTVEFLRV9QT09MX0lOU1RSVUNUSU9OX0xBWU9VVFMsIFNUQUtFX1BPT0xfUFJPR1JBTV9JRCB9IGZyb20gJ0Bzb2xhbmEvc3BsLXN0YWtlLXBvb2wnO1xuXG5jb25zdCBERUNPREVEX0JMT0NLX0hBU0hfTEVOR1RIID0gMzI7IC8vIGh0dHBzOi8vZG9jcy5zb2xhbmEuY29tL2RldmVsb3BpbmcvcHJvZ3JhbW1pbmctbW9kZWwvdHJhbnNhY3Rpb25zI2Jsb2NraGFzaC1mb3JtYXRcbmNvbnN0IERFQ09ERURfU0lHTkFUVVJFX0xFTkdUSCA9IDY0OyAvLyBodHRwczovL2RvY3Muc29sYW5hLmNvbS90ZXJtaW5vbG9neSNzaWduYXR1cmVcbmNvbnN0IEJBU0VfNThfRU5DT05ESU5HX1JFR0VYID0gJ1sxLTlBLUhKLU5QLVphLWttLXpdJztcbmNvbnN0IENPTVBVVEVfQlVER0VUID0gJ0NvbXB1dGVCdWRnZXQxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEnO1xuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBBVEEgaW5zdHJ1Y3Rpb24gaXMgaWRlbXBvdGVudCAoZGlzY3JpbWluYXRvciBieXRlID0gMSkuXG4gKlxuICogSWRlbXBvdGVudCBBVEEgaW5zdHJ1Y3Rpb25zIHVzZSBCdWZmZXIuZnJvbShbMV0pIGFzIGluc3RydWN0aW9uIGRhdGEsIGNyZWF0ZWQgYnlcbiAqIEBzb2xhbmEvc3BsLXRva2VuJ3MgY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudElkZW1wb3RlbnRJbnN0cnVjdGlvbigpICh2MC40LjErKS5cbiAqIEFuIGlkZW1wb3RlbnQgQVRBIGluc3RydWN0aW9uIHN1Y2NlZWQgZXZlbiBpZiBhY2NvdW50IGV4aXN0cyxcbiAqIHByZXZlbnRpbmcgcmFjZSBjb25kaXRpb24gZXJyb3JzIGluIGNvbmN1cnJlbnQgc2NlbmFyaW9zLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb25JbnN0cnVjdGlvbn0gaW5zdHJ1Y3Rpb24gLSBUaGUgaW5zdHJ1Y3Rpb24gdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGluc3RydWN0aW9uIGRhdGEgaXMgYSBzaW5nbGUgYnl0ZSB3aXRoIHZhbHVlIDFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSWRlbXBvdGVudEF0YUluc3RydWN0aW9uKGluc3RydWN0aW9uOiBUcmFuc2FjdGlvbkluc3RydWN0aW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiBpbnN0cnVjdGlvbi5kYXRhLmxlbmd0aCA9PT0gMSAmJiBpbnN0cnVjdGlvbi5kYXRhWzBdID09PSAxO1xufVxuXG4vKiogQGluaGVyaXRkb2MgKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzVmFsaWRQdWJsaWNLZXkoYWRkcmVzcyk7XG59XG5cbi8qKiBAaW5oZXJpdGRvYyAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRCbG9ja0lkKGhhc2g6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHJldHVybiAoXG4gICAgICAhIWhhc2ggJiYgbmV3IFJlZ0V4cChCQVNFXzU4X0VOQ09ORElOR19SRUdFWCkudGVzdChoYXNoKSAmJiBiczU4LmRlY29kZShoYXNoKS5sZW5ndGggPT09IERFQ09ERURfQkxPQ0tfSEFTSF9MRU5HVEhcbiAgICApO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKiBAaW5oZXJpdGRvYyAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRQcml2YXRlS2V5KHBydktleTogc3RyaW5nIHwgVWludDhBcnJheSk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIGNvbnN0IGtleTogVWludDhBcnJheSA9IHR5cGVvZiBwcnZLZXkgPT09ICdzdHJpbmcnID8gYmFzZTU4VG9VaW50OEFycmF5KHBydktleSkgOiBwcnZLZXk7XG4gICAgcmV0dXJuICEhS2V5cGFpci5mcm9tU2VjcmV0S2V5KGtleSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIEBpbmhlcml0ZG9jICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZFB1YmxpY0tleShwdWJLZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIGlmIChpc1ZhbGlkWHB1YihwdWJLZXkpKSByZXR1cm4gdHJ1ZTtcbiAgICBuZXcgUHVibGljS2V5KHB1YktleSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKiogQGluaGVyaXRkb2MgKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkU2lnbmF0dXJlKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhc2lnbmF0dXJlICYmIGJzNTguZGVjb2RlKHNpZ25hdHVyZSkubGVuZ3RoID09PSBERUNPREVEX1NJR05BVFVSRV9MRU5HVEg7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIEBpbmhlcml0ZG9jICovXG4vLyBUcmFuc2FjdGlvbklkIGFyZSB0aGUgZmlyc3Qgc2lnbmF0dXJlIG9uIGEgVHJhbnNhY3Rpb25cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkVHJhbnNhY3Rpb25JZCh0eElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzVmFsaWRTaWduYXR1cmUodHhJZCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgYW1vdW50IG9mIGxhbXBvcnRzIG51bWJlclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhbW91bnQgLSB0aGUgc3RyaW5nIHRvIHZhbGlkYXRlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRBbW91bnQoYW1vdW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgYmlnTnVtYmVyQW1vdW50ID0gbmV3IEJpZ051bWJlcihhbW91bnQpO1xuICByZXR1cm4gYmlnTnVtYmVyQW1vdW50LmlzSW50ZWdlcigpICYmIGJpZ051bWJlckFtb3VudC5pc0dyZWF0ZXJUaGFuT3JFcXVhbFRvKDApO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBzdHJpbmcgaXMgYSB2YWxpZCBhbW91bnQgb2YgbGFtcG9ydHMgbnVtYmVyIG9uIHN0YWtpbmdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYW1vdW50IC0gdGhlIHN0cmluZyB0byB2YWxpZGF0ZVxuICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkU3Rha2luZ0Ftb3VudChhbW91bnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBiaWdOdW1iZXJBbW91bnQgPSBuZXcgQmlnTnVtYmVyKGFtb3VudCk7XG4gIHJldHVybiBiaWdOdW1iZXJBbW91bnQuaXNJbnRlZ2VyKCkgJiYgYmlnTnVtYmVyQW1vdW50LmlzR3JlYXRlclRoYW4oMCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBpcyBhIHZhbGlkIG1lbW8gb3Igbm90LlxuICpcbiAqIEBwYXJhbSBtZW1vIC0gdGhlIG1lbW8gc3RyaW5nXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRNZW1vKG1lbW86IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gQnVmZmVyLmZyb20obWVtbykubGVuZ3RoIDw9IE1BWF9NRU1PX0xFTkdUSDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgdmFsaWQgYmFzZTY0IGVuY29kZWQgZGF0YVxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHN0cmluZyBpcyB2YWxpZCBiYXNlNjQsIGZhbHNlIG90aGVyd2lzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNWYWxpZEJhc2U2NChzdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIGNvbnN0IGRlY29kZWQgPSBCdWZmZXIuZnJvbShzdHIsICdiYXNlNjQnKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgcmV0dXJuIGRlY29kZWQgPT09IHN0cjtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgc3RyaW5nIGlzIHZhbGlkIGhleGFkZWNpbWFsIGRhdGFcbiAqIEBwYXJhbSBzdHIgLSBUaGUgc3RyaW5nIHRvIHZhbGlkYXRlXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBzdHJpbmcgaXMgdmFsaWQgaGV4LCBmYWxzZSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRIZXgoc3RyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eWzAtOUEtRmEtZl0qJC8udGVzdChzdHIpICYmIHN0ci5sZW5ndGggJSAyID09PSAwO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiByYXcgdHJhbnNhY3Rpb24gY2FuIGJlIGRlc2VyaWFsaXplZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSByYXdUcmFuc2FjdGlvbiAtIHRyYW5zYWN0aW9uIGluIGJhc2U2NCBzdHJpbmcgZm9ybWF0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHJlcXVpcmVBbGxTaWduYXR1cmVzIC0gcmVxdWlyZSBhbGwgc2lnbmF0dXJlcyB0byBiZSBwcmVzZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHZlcmlmeVNpZ25hdHVyZXMgLSB2ZXJpZnkgc2lnbmF0dXJlc1xuICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkUmF3VHJhbnNhY3Rpb24oXG4gIHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcsXG4gIHJlcXVpcmVBbGxTaWduYXR1cmVzID0gZmFsc2UsXG4gIHZlcmlmeVNpZ25hdHVyZXMgPSBmYWxzZVxuKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgY29uc3QgdHggPSBTb2xUcmFuc2FjdGlvbi5mcm9tKEJ1ZmZlci5mcm9tKHJhd1RyYW5zYWN0aW9uLCAnYmFzZTY0JykpO1xuICAgIHR4LnNlcmlhbGl6ZSh7IHJlcXVpcmVBbGxTaWduYXR1cmVzLCB2ZXJpZnlTaWduYXR1cmVzIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogVmVyaWZpZXMgaWYgc2lnbmF0dXJlIGZvciBtZXNzYWdlIGlzIHZhbGlkLlxuICpcbiAqIEBwYXJhbSB7QnVmZmVyfSBzZXJpYWxpemVkVHggLSB0eCBhcyBhIGJhc2U2NCBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzaWduYXR1cmUgLSBzaWduYXR1cmUgYXMgYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBwdWJsaWNLZXkgLSBwdWJsaWMga2V5IGFzIGJhc2UgNThcbiAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHNpZ25hdHVyZSBpcyB2YWxpZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeVNpZ25hdHVyZShzZXJpYWxpemVkVHg6IHN0cmluZywgc2lnbmF0dXJlOiBzdHJpbmcsIHB1YmxpY0tleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmICghaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHNlcmlhbGl6ZWRUeCkpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignSW52YWxpZCBzZXJpYWxpemVkVHgnKTtcbiAgfVxuICBpZiAoIWlzVmFsaWRQdWJsaWNLZXkocHVibGljS2V5KSkge1xuICAgIHRocm93IG5ldyBVdGlsc0Vycm9yKCdJbnZhbGlkIHB1YmxpY0tleScpO1xuICB9XG4gIGlmICghaXNWYWxpZFNpZ25hdHVyZShzaWduYXR1cmUpKSB7XG4gICAgdGhyb3cgbmV3IFV0aWxzRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH1cbiAgY29uc3QgbXNnID0gU29sVHJhbnNhY3Rpb24uZnJvbShCdWZmZXIuZnJvbShzZXJpYWxpemVkVHgsICdiYXNlNjQnKSkuc2VyaWFsaXplTWVzc2FnZSgpO1xuICBjb25zdCBzaWcgPSBiYXNlNThUb1VpbnQ4QXJyYXkoc2lnbmF0dXJlKTtcbiAgY29uc3QgcHViID0gbmV3IFB1YmxpY0tleShwdWJsaWNLZXkpO1xuICByZXR1cm4gbmFjbC5zaWduLmRldGFjaGVkLnZlcmlmeShtc2csIHNpZywgcHViLnRvQnVmZmVyKCkpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgYmFzZTU4IHN0cmluZyBpbnRvIGEgVWludDhBcnJheS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgLSBhIHN0cmluZyBpbiBiYXNlNThcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSAtIGFuIFVpbnQ4QXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJhc2U1OFRvVWludDhBcnJheShpbnB1dDogc3RyaW5nKTogVWludDhBcnJheSB7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShiczU4LmRlY29kZShpbnB1dCkpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgVWludDhBcnJheSB0byBhIGJhc2U1OCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSBpbnB1dCAtIGFuIFVpbnQ4QXJyYXlcbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gYSBzdHJpbmcgaW4gYmFzZTU4XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBVaW50OEFycmF5VG9iYXNlNTgoaW5wdXQ6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gYnM1OC5lbmNvZGUoaW5wdXQpO1xufVxuXG4vKipcbiAqIENvdW50IHRoZSBhbW91bnQgb2Ygc2lnbmF0dXJlcyBhcmUgbm90IG51bGwuXG4gKlxuICogQHBhcmFtIHtTaWduYXR1cmVQdWJrZXlQYWlyW119IHNpZ25hdHVyZXMgLSBhbiBhcnJheSBvZiBTaWduYXR1cmVQdWJrZXlQYWlyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSAtIHRoZSBhbW91bnQgb2YgdmFsaWQgc2lnbmF0dXJlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY291bnROb3ROdWxsU2lnbmF0dXJlcyhzaWduYXR1cmVzOiBTaWduYXR1cmVQdWJrZXlQYWlyW10pOiBudW1iZXIge1xuICByZXR1cm4gc2lnbmF0dXJlcy5maWx0ZXIoKHNpZykgPT4gISFzaWcuc2lnbmF0dXJlKS5sZW5ndGg7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYWxsIHNpZ25hdHVyZXMgYXJlIGNvbXBsZXRlZC5cbiAqXG4gKiBAcGFyYW0ge1NpZ25hdHVyZVB1YmtleVBhaXJbXX0gc2lnbmF0dXJlcyAtIHNpZ25hdHVyZXNcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZXNBbGxTaWduYXR1cmVzKHNpZ25hdHVyZXM6IFNpZ25hdHVyZVB1YmtleVBhaXJbXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2lnbmF0dXJlcy5sZW5ndGggPiAwICYmIGNvdW50Tm90TnVsbFNpZ25hdHVyZXMoc2lnbmF0dXJlcykgPT09IHNpZ25hdHVyZXMubGVuZ3RoO1xufVxuXG4vKipcbiAqIENoZWNrIHRoZSB0cmFuc2FjdGlvbiB0eXBlIG1hdGNoaW5nIGluc3RydWN0aW9ucyBieSBvcmRlci4gTWVtbyBhbmQgQWR2YW5jZU5vbmNlQWNjb3VudCBpbnN0cnVjdGlvbnNcbiAqIGFyZSBpZ25vcmVkLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb25JbnN0cnVjdGlvbltdfSBpbnN0cnVjdGlvbnMgLSB0aGUgYXJyYXkgb2Ygc3VwcG9ydGVkIFNvbGFuYSBpbnN0cnVjdGlvbnMgdG8gYmUgcGFyc2VkXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlcj59IGluc3RydWN0aW9uSW5kZXhlcyAtIHRoZSBpbnN0cnVjdGlvbnMgaW5kZXhlcyBvZiB0aGUgY3VycmVudCB0cmFuc2FjdGlvblxuICogQHJldHVybnMgdHJ1ZSBpZiBpdCBtYXRjaGVzIGJ5IG9yZGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKFxuICBpbnN0cnVjdGlvbnM6IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb25bXSxcbiAgaW5zdHJ1Y3Rpb25JbmRleGVzOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+XG4pOiBib29sZWFuIHtcbiAgY29uc3QgaW5zdHJ1Y3Rpb25zQ29weSA9IFsuLi5pbnN0cnVjdGlvbnNdOyAvLyBNYWtlIGEgY29weSBzaW5jZSB3ZSBtYXkgbW9kaWZ5IHRoZSBhcnJheSBiZWxvd1xuICAvLyBBZHZhbmNlTm9uY2VBY2NvdW50IGlzIG9wdGlvbmFsIGFuZCB0aGUgZmlyc3QgaW5zdHJ1Y3Rpb24gYWRkZWQsIGl0IGRvZXMgbm90IG1hdHRlciB0byBtYXRjaCB0aGUgdHlwZVxuICBpZiAoaW5zdHJ1Y3Rpb25zQ29weS5sZW5ndGggPiAwKSB7XG4gICAgaWYgKGdldEluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbnNbMF0pID09PSAnQWR2YW5jZU5vbmNlQWNjb3VudCcpIHtcbiAgICAgIGluc3RydWN0aW9uc0NvcHkuc2hpZnQoKTtcbiAgICB9XG4gIH1cblxuICAvLyBNZW1vIGlzIG9wdGlvbmFsIGFuZCB0aGUgbGFzdCBpbnN0cnVjdGlvbiBhZGRlZCwgaXQgZG9lcyBub3QgbWF0dGVyIHRvIG1hdGNoIHRoZSB0eXBlXG4gIC8vIFdoeSBoYXZlIGl0IGluIGluc3RydWN0aW9uS2V5cyBpZiB3ZSBhcmUgZ29pbmcgdG8gaWdub3JlIGl0P1xuICBjb25zdCBpbnN0cnVjdGlvbnNLZXlzID0gT2JqZWN0LmtleXMoaW5zdHJ1Y3Rpb25JbmRleGVzKTtcbiAgaWYgKGluc3RydWN0aW9uc0tleXNbaW5zdHJ1Y3Rpb25zS2V5cy5sZW5ndGggLSAxXSA9PT0gJ01lbW8nKSB7XG4gICAgaW5zdHJ1Y3Rpb25zS2V5cy5wb3AoKTtcbiAgfVxuXG4gIC8vIENoZWNrIGluc3RydWN0aW9ucyBieSBvcmRlciB1c2luZyB0aGUgaW5kZXguXG4gIGZvciAoY29uc3Qga2V5TmFtZSBvZiBpbnN0cnVjdGlvbnNLZXlzKSB7XG4gICAgY29uc3QgaW5kZXggPSBpbnN0cnVjdGlvbkluZGV4ZXNba2V5TmFtZV07XG4gICAgaWYgKGluZGV4ID49IGluc3RydWN0aW9uc0NvcHkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGdldEluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbnNDb3B5W2luZGV4XSk7XG4gICAgaWYgKHJlc3VsdCAhPT0ga2V5TmFtZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0cmFuc2FjdGlvbiBUeXBlIGJhc2VkIG9uIHRoZSAgdHJhbnNhY3Rpb24gaW5zdHJ1Y3Rpb25zLlxuICogV2FsbGV0IGluaXRpYWxpemF0aW9uLCBUcmFuc2ZlciBhbmQgU3Rha2luZyB0cmFuc2FjdGlvbnMgYXJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge1NvbFRyYW5zYWN0aW9ufSB0cmFuc2FjdGlvbiAtIHRoZSBzb2xhbmEgdHJhbnNhY3Rpb25cbiAqIEByZXR1cm5zIHtUcmFuc2FjdGlvblR5cGV9IC0gdGhlIHR5cGUgb2YgdHJhbnNhY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zYWN0aW9uVHlwZSh0cmFuc2FjdGlvbjogU29sVHJhbnNhY3Rpb24pOiBUcmFuc2FjdGlvblR5cGUge1xuICBjb25zdCB7IGluc3RydWN0aW9ucyB9ID0gdHJhbnNhY3Rpb247XG4gIGlmICh2YWxpZGF0ZVJhd01zZ0luc3RydWN0aW9uKGluc3RydWN0aW9ucykpIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBdXRob3JpemVSYXc7XG4gIH1cbiAgdmFsaWRhdGVJbnRydWN0aW9uVHlwZXMoaW5zdHJ1Y3Rpb25zKTtcbiAgLy8gY2hlY2sgaWYgZGVhY3RpdmF0ZSBpbnN0cnVjdGlvbiBkb2VzIG5vdCBleGlzdCBiZWNhdXNlIGRlYWN0aXZhdGUgY2FuIGJlIGluY2x1ZGUgYSB0cmFuc2ZlciBpbnN0cnVjdGlvblxuICBjb25zdCBtZW1vSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbnMuZmluZCgoaW5zdHJ1Y3Rpb24pID0+IGdldEluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbikgPT09ICdNZW1vJyk7XG4gIGNvbnN0IG1lbW9EYXRhID0gbWVtb0luc3RydWN0aW9uPy5kYXRhLnRvU3RyaW5nKCd1dGYtOCcpO1xuICBpZiAobWVtb0RhdGE/LmluY2x1ZGVzKCdXYWxsZXRDb25uZWN0RGVmaUN1c3RvbVR4JykpIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLkN1c3RvbVR4O1xuICB9XG4gIC8vIENoZWNrIGZvciBjbG9zZSBBVEEgaW5zdHJ1Y3Rpb25zIGJlZm9yZSBjbGFzc2lmeWluZyBhcyBTZW5kLlxuICAvLyBBIGJ1bGsgY2xvc2UtQVRBIHR4IGNvbnRhaW5zIG9ubHkgY2xvc2VBY2NvdW50IGluc3RydWN0aW9ucyAoemVyby1iYWxhbmNlIEFUQXMpLlxuICAvLyBOb3RlOiBUaGlzIGFzc3VtZXMgY2xvc2UtQVRBIHRyYW5zYWN0aW9ucyBuZXZlciBjb250YWluIFRva2VuVHJhbnNmZXIgaW5zdHJ1Y3Rpb25zLlxuICAvLyBUaGlzIGhvbGRzIGZvciBQaGFzZSAxIHdoZXJlIG5vbi16ZXJvIGJhbGFuY2UgQVRBcyBhcmUgcmVqZWN0ZWQgKHVzZXIgbXVzdCBjb25zb2xpZGF0ZSBmaXJzdCkuXG4gIC8vIElmIGF0b21pYyB0cmFuc2ZlcitjbG9zZSBpcyBhZGRlZCBpbiB0aGUgZnV0dXJlLCB0aGlzIGRldGVjdGlvbiBuZWVkcyByZWZpbmVtZW50LlxuICBjb25zdCBoYXNDbG9zZUF0YSA9IGluc3RydWN0aW9ucy5zb21lKFxuICAgIChpbnN0cnVjdGlvbikgPT4gZ2V0SW5zdHJ1Y3Rpb25UeXBlKGluc3RydWN0aW9uKSA9PT0gVmFsaWRJbnN0cnVjdGlvblR5cGVzRW51bS5DbG9zZUFzc29jaWF0ZWRUb2tlbkFjY291bnRcbiAgKTtcbiAgaWYgKGhhc0Nsb3NlQXRhKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5DbG9zZUFzc29jaWF0ZWRUb2tlbkFjY291bnQ7XG4gIH1cblxuICBpZiAoaW5zdHJ1Y3Rpb25zLmZpbHRlcigoaW5zdHJ1Y3Rpb24pID0+IGdldEluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbikgPT09ICdEZWFjdGl2YXRlJykubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChjb25zdCBpbnN0cnVjdGlvbiBvZiBpbnN0cnVjdGlvbnMpIHtcbiAgICAgIGNvbnN0IGluc3RydWN0aW9uVHlwZSA9IGdldEluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbik7XG4gICAgICAvLyBDaGVjayBpZiBtZW1vIGluc3RydWN0aW9uIGlzIHRoZXJlIGFuZCBpZiBpdCBjb250YWlucyAnUHJlcGFyZUZvclJldm9rZScgYmVjYXVzZSBNYXJpbmFkZSBzdGFraW5nIGRlYWN0aXZhdGUgdHJhbnNhY3Rpb24gd2lsbCBoYXZlIHRoaXNcbiAgICAgIGlmIChcbiAgICAgICAgKGluc3RydWN0aW9uVHlwZSA9PT0gVmFsaWRJbnN0cnVjdGlvblR5cGVzRW51bS5UcmFuc2ZlciAmJiAhbWVtb0RhdGE/LmluY2x1ZGVzKCdQcmVwYXJlRm9yUmV2b2tlJykpIHx8XG4gICAgICAgIGluc3RydWN0aW9uVHlwZSA9PT0gVmFsaWRJbnN0cnVjdGlvblR5cGVzRW51bS5Ub2tlblRyYW5zZmVyXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAobWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgd2FsbGV0SW5pdEluc3RydWN0aW9uSW5kZXhlcykpIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uO1xuICB9IGVsc2UgaWYgKFxuICAgIG1hdGNoVHJhbnNhY3Rpb25UeXBlQnlJbnN0cnVjdGlvbnNPcmRlcihpbnN0cnVjdGlvbnMsIG1hcmluYWRlU3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcykgfHxcbiAgICBtYXRjaFRyYW5zYWN0aW9uVHlwZUJ5SW5zdHJ1Y3Rpb25zT3JkZXIoaW5zdHJ1Y3Rpb25zLCBqaXRvU3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcykgfHxcbiAgICBtYXRjaFRyYW5zYWN0aW9uVHlwZUJ5SW5zdHJ1Y3Rpb25zT3JkZXIoaW5zdHJ1Y3Rpb25zLCBqaXRvU3Rha2luZ0FjdGl2YXRlV2l0aEFUQUluc3RydWN0aW9uc0luZGV4ZXMpIHx8XG4gICAgbWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgc3Rha2luZ0FjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcylcbiAgKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQWN0aXZhdGU7XG4gIH0gZWxzZSBpZiAobWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgc3Rha2luZ0F1dGhvcml6ZUluc3RydWN0aW9uc0luZGV4ZXMpKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQXV0aG9yaXplO1xuICB9IGVsc2UgaWYgKG1hdGNoVHJhbnNhY3Rpb25UeXBlQnlJbnN0cnVjdGlvbnNPcmRlcihpbnN0cnVjdGlvbnMsIHN0YWtpbmdEZWxlZ2F0ZUluc3RydWN0aW9uc0luZGV4ZXMpKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVsZWdhdGU7XG4gIH0gZWxzZSBpZiAoXG4gICAgbWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgbWFyaW5hZGVTdGFraW5nRGVhY3RpdmF0ZUluc3RydWN0aW9uc0luZGV4ZXMpIHx8XG4gICAgbWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgc3Rha2luZ0RlYWN0aXZhdGVJbnN0cnVjdGlvbnNJbmRleGVzKSB8fFxuICAgIG1hdGNoVHJhbnNhY3Rpb25UeXBlQnlJbnN0cnVjdGlvbnNPcmRlcihpbnN0cnVjdGlvbnMsIHN0YWtpbmdQYXJ0aWFsRGVhY3RpdmF0ZUluc3RydWN0aW9uc0luZGV4ZXMpIHx8XG4gICAgbWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgaml0b1N0YWtpbmdEZWFjdGl2YXRlSW5zdHJ1Y3Rpb25zSW5kZXhlcylcbiAgKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZTtcbiAgfSBlbHNlIGlmIChtYXRjaFRyYW5zYWN0aW9uVHlwZUJ5SW5zdHJ1Y3Rpb25zT3JkZXIoaW5zdHJ1Y3Rpb25zLCBzdGFraW5nV2l0aGRyYXdJbnN0cnVjdGlvbnNJbmRleGVzKSkge1xuICAgIHJldHVybiBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1dpdGhkcmF3O1xuICB9IGVsc2UgaWYgKG1hdGNoVHJhbnNhY3Rpb25UeXBlQnlJbnN0cnVjdGlvbnNPcmRlcihpbnN0cnVjdGlvbnMsIGF0YUluaXRJbnN0cnVjdGlvbkluZGV4ZXMpKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5Bc3NvY2lhdGVkVG9rZW5BY2NvdW50SW5pdGlhbGl6YXRpb247XG4gIH0gZWxzZSBpZiAobWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgYXRhQ2xvc2VJbnN0cnVjdGlvbkluZGV4ZXMpKSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uVHlwZS5DbG9zZUFzc29jaWF0ZWRUb2tlbkFjY291bnQ7XG4gIH0gZWxzZSBpZiAobWF0Y2hUcmFuc2FjdGlvblR5cGVCeUluc3RydWN0aW9uc09yZGVyKGluc3RydWN0aW9ucywgYXRhUmVjb3Zlck5lc3RlZEluc3RydWN0aW9uSW5kZXhlcykpIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLkNsb3NlQXNzb2NpYXRlZFRva2VuQWNjb3VudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gVHJhbnNhY3Rpb25UeXBlLkN1c3RvbVR4O1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW5zdHJ1Y3Rpb24gVHlwZSBiYXNlZCBvbiB0aGUgc29sYW5hIGluc3RydWN0aW9ucy5cbiAqIFRocm93cyBpZiB0aGUgc29sYW5hIGluc3RydWN0aW9uIHByb2dyYW0gaXMgbm90IHN1cHBvcnRlZFxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb25JbnN0cnVjdGlvbn0gaW5zdHJ1Y3Rpb24gLSBhIHNvbGFuYSBpbnN0cnVjdGlvblxuICogQHJldHVybnMge1ZhbGlkSW5zdHJ1Y3Rpb25UeXBlc30gLSBhIHNvbGFuYSBpbnN0cnVjdGlvbiB0eXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnN0cnVjdGlvblR5cGUoaW5zdHJ1Y3Rpb246IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24pOiBWYWxpZEluc3RydWN0aW9uVHlwZXMge1xuICBzd2l0Y2ggKGluc3RydWN0aW9uLnByb2dyYW1JZC50b1N0cmluZygpKSB7XG4gICAgY2FzZSBuZXcgUHVibGljS2V5KE1FTU9fUFJPR1JBTV9QSykudG9TdHJpbmcoKTpcbiAgICAgIHJldHVybiAnTWVtbyc7XG4gICAgY2FzZSBTeXN0ZW1Qcm9ncmFtLnByb2dyYW1JZC50b1N0cmluZygpOlxuICAgICAgcmV0dXJuIFN5c3RlbUluc3RydWN0aW9uLmRlY29kZUluc3RydWN0aW9uVHlwZShpbnN0cnVjdGlvbik7XG4gICAgY2FzZSBUT0tFTl9QUk9HUkFNX0lELnRvU3RyaW5nKCk6XG4gICAgY2FzZSBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKTpcbiAgICAgIGlmIChcbiAgICAgICAgaW5zdHJ1Y3Rpb24ucHJvZ3JhbUlkLmVxdWFscyhUT0tFTl8yMDIyX1BST0dSQU1fSUQpICYmXG4gICAgICAgIGluc3RydWN0aW9uLmRhdGEubGVuZ3RoID49IDIgJiZcbiAgICAgICAgaW5zdHJ1Y3Rpb24uZGF0YVswXSA9PT0gVG9rZW5JbnN0cnVjdGlvbi5UcmFuc2ZlckZlZUV4dGVuc2lvbiAmJlxuICAgICAgICBpbnN0cnVjdGlvbi5kYXRhWzFdID09PSBUcmFuc2ZlckZlZUluc3RydWN0aW9uLlRyYW5zZmVyQ2hlY2tlZFdpdGhGZWVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gJ1Rva2VuVHJhbnNmZXInO1xuICAgICAgfVxuICAgICAgbGV0IGRlY29kZWRJbnN0cnVjdGlvbjogRGVjb2RlZEluc3RydWN0aW9uO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZGVjb2RlZEluc3RydWN0aW9uID0gZGVjb2RlSW5zdHJ1Y3Rpb24oaW5zdHJ1Y3Rpb24sIGluc3RydWN0aW9uLnByb2dyYW1JZCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGRlY29kZUluc3RydWN0aW9uIG9ubHkgc3VwcG9ydHMgdGhlIGJhc2UgdG9rZW4gaW5zdHJ1Y3Rpb24gc2V0IOKAlFxuICAgICAgICAvLyBleHRlbnNpb24tZmFtaWx5IGluc3RydWN0aW9ucyAoUGF1c2UsIFBlcm1pc3Npb25lZEJ1cm4sIHRyYW5zZmVyXG4gICAgICAgIC8vIGZlZSBvcHMsIC4uLikgdGhyb3cgVG9rZW5JbnZhbGlkSW5zdHJ1Y3Rpb25UeXBlRXJyb3IgYXQgRVZFUllcbiAgICAgICAgLy8gQHNvbGFuYS9zcGwtdG9rZW4gdmVyc2lvbi4gVGhvc2UgbXVzdCBub3QgY3Jhc2ggY2xhc3NpZmljYXRpb246XG4gICAgICAgIC8vIGZhbGwgYmFjayB0byBDdXN0b21JbnN0cnVjdGlvbiwgdGhlIHNhbWUgcGF0aCB1c2VkIGJlbG93IGZvclxuICAgICAgICAvLyBkZWNvZGFibGUtYnV0LXVubWFwcGVkIGluc3RydWN0aW9uIHR5cGVzLlxuICAgICAgICByZXR1cm4gJ0N1c3RvbUluc3RydWN0aW9uJztcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluc3RydWN0aW9uVHlwZU1hcDogTWFwPFRva2VuSW5zdHJ1Y3Rpb24sIFZhbGlkSW5zdHJ1Y3Rpb25UeXBlcz4gPSBuZXcgTWFwKCk7XG4gICAgICBpbnN0cnVjdGlvblR5cGVNYXAuc2V0KFRva2VuSW5zdHJ1Y3Rpb24uQ2xvc2VBY2NvdW50LCAnQ2xvc2VBc3NvY2lhdGVkVG9rZW5BY2NvdW50Jyk7XG4gICAgICBpbnN0cnVjdGlvblR5cGVNYXAuc2V0KFRva2VuSW5zdHJ1Y3Rpb24uQnVybiwgJ0J1cm4nKTtcbiAgICAgIGluc3RydWN0aW9uVHlwZU1hcC5zZXQoVG9rZW5JbnN0cnVjdGlvbi5NaW50VG8sICdNaW50VG8nKTtcbiAgICAgIGluc3RydWN0aW9uVHlwZU1hcC5zZXQoVG9rZW5JbnN0cnVjdGlvbi5BcHByb3ZlLCAnQXBwcm92ZScpO1xuICAgICAgaW5zdHJ1Y3Rpb25UeXBlTWFwLnNldChUb2tlbkluc3RydWN0aW9uLlRyYW5zZmVyQ2hlY2tlZCwgJ1Rva2VuVHJhbnNmZXInKTtcbiAgICAgIGNvbnN0IHZhbGlkSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvblR5cGVNYXAuZ2V0KGRlY29kZWRJbnN0cnVjdGlvbi5kYXRhLmluc3RydWN0aW9uKTtcbiAgICAgIGlmICghdmFsaWRJbnN0cnVjdGlvbikge1xuICAgICAgICByZXR1cm4gJ0N1c3RvbUluc3RydWN0aW9uJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWxpZEluc3RydWN0aW9uO1xuICAgIGNhc2UgU1RBS0VfUE9PTF9QUk9HUkFNX0lELnRvU3RyaW5nKCk6XG4gICAgICBjb25zdCBkaXNjcmltaW5hdG9yID0gaW5zdHJ1Y3Rpb24uZGF0YS5yZWFkVWludDgoMCk7XG4gICAgICBjb25zdCBsYXlvdXRLZXkgPSBPYmplY3QuZW50cmllcyhTVEFLRV9QT09MX0lOU1RSVUNUSU9OX0xBWU9VVFMpLmZpbmQoKFtfLCB2XSkgPT4gdi5pbmRleCA9PT0gZGlzY3JpbWluYXRvcik/LlswXTtcbiAgICAgIGlmIChsYXlvdXRLZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luc3RydWN0aW9uIHR5cGUgaW5jb3JyZWN0OyB1bmtub3duIGRpc2NyaW1pbmF0b3InKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluc3RydWN0aW9uS2V5ID0gbGF5b3V0S2V5IGFzIGtleW9mIHR5cGVvZiBTVEFLRV9QT09MX0lOU1RSVUNUSU9OX0xBWU9VVFM7XG4gICAgICByZXR1cm4gaW5zdHJ1Y3Rpb25LZXk7XG4gICAgY2FzZSBTdGFrZVByb2dyYW0ucHJvZ3JhbUlkLnRvU3RyaW5nKCk6XG4gICAgICByZXR1cm4gU3Rha2VJbnN0cnVjdGlvbi5kZWNvZGVJbnN0cnVjdGlvblR5cGUoaW5zdHJ1Y3Rpb24pO1xuICAgIGNhc2UgVE9LRU5fQUNMX1BST0dSQU1fSUQ6XG4gICAgICAvLyBUaGUgVG9rZW4gQUNMIHByb2dyYW0gaGFzIGEgc2luZ2xlIGluc3RydWN0aW9uIHRoZSBTREsgYnVpbGRzIOKAlCB0aGUgcGVybWlzc2lvbmxlc3MgdGhhdy5cbiAgICAgIHJldHVybiBWYWxpZEluc3RydWN0aW9uVHlwZXNFbnVtLlBlcm1pc3Npb25sZXNzVGhhd0lkZW1wb3RlbnQ7XG4gICAgY2FzZSBBU1NPQ0lBVEVEX1RPS0VOX1BST0dSQU1fSUQudG9TdHJpbmcoKTpcbiAgICAgIC8vIFRPRE86IGNoYW5nZSB0aGlzIHdoZW4gQHNwbC10b2tlbiBzdXBwb3J0cyBkZWNvZGluZyBhc3NvY2lhdGVkIHRva2VuIGluc3RydWN0aW9uc1xuICAgICAgLy8gU3VwcG9ydCBib3RoIGxlZ2FjeSBBVEEgY3JlYXRpb24gKGRhdGEubGVuZ3RoID09PSAwKSBhbmQgaWRlbXBvdGVudCBBVEEgY3JlYXRpb24gKGRpc2NyaW1pbmF0b3IgPSAxKVxuICAgICAgLy8gQm90aCBpbnN0cnVjdGlvbiB0eXBlcyBhcmUgdHJlYXRlZCBhcyAnSW5pdGlhbGl6ZUFzc29jaWF0ZWRUb2tlbkFjY291bnQnIGZvciBjb21wYXRpYmlsaXR5XG4gICAgICBpZiAoaW5zdHJ1Y3Rpb24uZGF0YS5sZW5ndGggPT09IDAgfHwgaXNJZGVtcG90ZW50QXRhSW5zdHJ1Y3Rpb24oaW5zdHJ1Y3Rpb24pKSB7XG4gICAgICAgIHJldHVybiAnSW5pdGlhbGl6ZUFzc29jaWF0ZWRUb2tlbkFjY291bnQnO1xuICAgICAgfSBlbHNlIGlmIChpbnN0cnVjdGlvbi5kYXRhLmxlbmd0aCA9PT0gMSAmJiBpbnN0cnVjdGlvbi5kYXRhWzBdID09PSAyKSB7XG4gICAgICAgIHJldHVybiAnUmVjb3Zlck5lc3RlZEFzc29jaWF0ZWRUb2tlbkFjY291bnQnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZChcbiAgICAgICAgICAnSW52YWxpZCB0cmFuc2FjdGlvbiwgaW5zdHJ1Y3Rpb24gcHJvZ3JhbSBpZCBub3Qgc3VwcG9ydGVkOiAnICsgaW5zdHJ1Y3Rpb24ucHJvZ3JhbUlkLnRvU3RyaW5nKClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICBjYXNlIENPTVBVVEVfQlVER0VUOlxuICAgICAgaWYgKENvbXB1dGVCdWRnZXRJbnN0cnVjdGlvbi5kZWNvZGVJbnN0cnVjdGlvblR5cGUoaW5zdHJ1Y3Rpb24pID09PSAnU2V0Q29tcHV0ZVVuaXRMaW1pdCcpIHtcbiAgICAgICAgcmV0dXJuICdTZXRDb21wdXRlVW5pdExpbWl0JztcbiAgICAgIH1cbiAgICAgIHJldHVybiAnU2V0UHJpb3JpdHlGZWUnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ0N1c3RvbUluc3RydWN0aW9uJztcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlIHNvbGFuYSBpbnN0cnVjdGlvbnMgdHlwZXMgdG8gc2VlIGlmIHRoZXkgYXJlIHN1cHBvcnRlZCBieSB0aGUgYnVpbGRlci5cbiAqIFRocm93cyBpZiB0aGUgaW5zdHJ1Y3Rpb24gdHlwZSBpcyBpbnZhbGlkLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb25JbnN0cnVjdGlvbn0gaW5zdHJ1Y3Rpb25zIC0gYSBzb2xhbmEgaW5zdHJ1Y3Rpb25cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVJbnRydWN0aW9uVHlwZXMoaW5zdHJ1Y3Rpb25zOiBUcmFuc2FjdGlvbkluc3RydWN0aW9uW10pOiB2b2lkIHtcbiAgZm9yIChjb25zdCBpbnN0cnVjdGlvbiBvZiBpbnN0cnVjdGlvbnMpIHtcbiAgICBpZiAoIVZBTElEX1NZU1RFTV9JTlNUUlVDVElPTl9UWVBFUy5pbmNsdWRlcyhnZXRJbnN0cnVjdGlvblR5cGUoaW5zdHJ1Y3Rpb24pKSkge1xuICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZCgnSW52YWxpZCB0cmFuc2FjdGlvbiwgaW5zdHJ1Y3Rpb24gdHlwZSBub3Qgc3VwcG9ydGVkOiAnICsgZ2V0SW5zdHJ1Y3Rpb25UeXBlKGluc3RydWN0aW9uKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGUgc29sYW5hIGluc3RydWN0aW9ucyBtYXRjaCByYXcgbXNnIGF1dGhvcml6ZSB0cmFuc2FjdGlvblxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb25JbnN0cnVjdGlvbn0gaW5zdHJ1Y3Rpb25zIC0gYSBzb2xhbmEgaW5zdHJ1Y3Rpb25cbiAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBpbnN0cnVjdGlvbnMgbWF0Y2ggdGhlIHJhdyBtc2cgYXV0aG9yaXplIHRyYW5zYWN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJhd01zZ0luc3RydWN0aW9uKGluc3RydWN0aW9uczogVHJhbnNhY3Rpb25JbnN0cnVjdGlvbltdKTogYm9vbGVhbiB7XG4gIC8vIGFzIHdlYjMuanMgY2Fubm90IGRlY29kZSBhdXRob3JpemUgaW5zdHJ1Y3Rpb24gZnJvbSBDTEksIHdlIG5lZWQgdG8gY2hlY2sgaXQgbWFudWFsbHkgZmlyc3RcbiAgaWYgKGluc3RydWN0aW9ucy5sZW5ndGggPT09IDIpIHtcbiAgICBjb25zdCBwcm9ncmFtSWQxID0gaW5zdHJ1Y3Rpb25zWzBdLnByb2dyYW1JZC50b1N0cmluZygpO1xuICAgIGNvbnN0IHByb2dyYW1JZDIgPSBpbnN0cnVjdGlvbnNbMV0ucHJvZ3JhbUlkLnRvU3RyaW5nKCk7XG4gICAgaWYgKHByb2dyYW1JZDEgPT09IFN5c3RlbVByb2dyYW0ucHJvZ3JhbUlkLnRvU3RyaW5nKCkgJiYgcHJvZ3JhbUlkMiA9PT0gU3Rha2VQcm9ncmFtLnByb2dyYW1JZC50b1N0cmluZygpKSB7XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbk5hbWUxID0gU3lzdGVtSW5zdHJ1Y3Rpb24uZGVjb2RlSW5zdHJ1Y3Rpb25UeXBlKGluc3RydWN0aW9uc1swXSk7XG4gICAgICBjb25zdCBkYXRhID0gaW5zdHJ1Y3Rpb25zWzFdLmRhdGEudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgaWYgKFxuICAgICAgICBpbnN0cnVjdGlvbk5hbWUxID09PSBub25jZUFkdmFuY2VJbnN0cnVjdGlvbiAmJlxuICAgICAgICAoZGF0YSA9PT0gdmFsaWRJbnN0cnVjdGlvbkRhdGEgfHwgZGF0YSA9PT0gdmFsaWRJbnN0cnVjdGlvbkRhdGEyKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoaW5zdHJ1Y3Rpb25zLmxlbmd0aCA9PT0gMykge1xuICAgIGNvbnN0IHByb2dyYW1JZDEgPSBpbnN0cnVjdGlvbnNbMF0ucHJvZ3JhbUlkLnRvU3RyaW5nKCk7XG4gICAgY29uc3QgcHJvZ3JhbUlkMiA9IGluc3RydWN0aW9uc1sxXS5wcm9ncmFtSWQudG9TdHJpbmcoKTtcbiAgICBjb25zdCBwcm9ncmFtSWQzID0gaW5zdHJ1Y3Rpb25zWzJdLnByb2dyYW1JZC50b1N0cmluZygpO1xuICAgIGlmIChcbiAgICAgIHByb2dyYW1JZDEgPT09IFN5c3RlbVByb2dyYW0ucHJvZ3JhbUlkLnRvU3RyaW5nKCkgJiZcbiAgICAgIHByb2dyYW1JZDIgPT09IFN0YWtlUHJvZ3JhbS5wcm9ncmFtSWQudG9TdHJpbmcoKSAmJlxuICAgICAgcHJvZ3JhbUlkMyA9PT0gU3Rha2VQcm9ncmFtLnByb2dyYW1JZC50b1N0cmluZygpXG4gICAgKSB7XG4gICAgICBjb25zdCBpbnN0cnVjdGlvbk5hbWUxID0gU3lzdGVtSW5zdHJ1Y3Rpb24uZGVjb2RlSW5zdHJ1Y3Rpb25UeXBlKGluc3RydWN0aW9uc1swXSk7XG4gICAgICBjb25zdCBkYXRhID0gaW5zdHJ1Y3Rpb25zWzFdLmRhdGEudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgZGF0YTIgPSBpbnN0cnVjdGlvbnNbMl0uZGF0YS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBpZiAoXG4gICAgICAgIGluc3RydWN0aW9uTmFtZTEgPT09IG5vbmNlQWR2YW5jZUluc3RydWN0aW9uICYmXG4gICAgICAgIChkYXRhID09PSB2YWxpZEluc3RydWN0aW9uRGF0YSB8fCBkYXRhID09PSB2YWxpZEluc3RydWN0aW9uRGF0YTIpICYmXG4gICAgICAgIChkYXRhMiA9PT0gdmFsaWRJbnN0cnVjdGlvbkRhdGEgfHwgZGF0YTIgPT09IHZhbGlkSW5zdHJ1Y3Rpb25EYXRhMilcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBDaGVjayB0aGUgcmF3IHRyYW5zYWN0aW9uIGhhcyBhIHZhbGlkIGZvcm1hdCBpbiB0aGUgYmxvY2tjaGFpbiBjb250ZXh0LCB0aHJvdyBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHJhd1RyYW5zYWN0aW9uIC0gVHJhbnNhY3Rpb24gaW4gYmFzZTY0IHN0cmluZyAgZm9ybWF0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKFxuICByYXdUcmFuc2FjdGlvbjogc3RyaW5nLFxuICByZXF1aXJlQWxsU2lnbmF0dXJlcyA9IGZhbHNlLFxuICB2ZXJpZnlTaWduYXR1cmVzID0gZmFsc2Vcbik6IHZvaWQge1xuICBpZiAoIXJhd1RyYW5zYWN0aW9uKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCByYXcgdHJhbnNhY3Rpb246IFVuZGVmaW5lZCcpO1xuICB9XG4gIGlmICghaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHJhd1RyYW5zYWN0aW9uLCByZXF1aXJlQWxsU2lnbmF0dXJlcywgdmVyaWZ5U2lnbmF0dXJlcykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2VUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGFkZHJlc3MgdG8gY2hlY2sgaWYgaXQgZXhpc3RzIGFuZCBpcyBhIHZhbGlkIFNvbGFuYSBwdWJsaWMga2V5XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgVGhlIGFkZHJlc3MgdG8gYmUgdmFsaWRhdGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gZmllbGROYW1lIE5hbWUgb2YgdGhlIGZpZWxkIHRvIHZhbGlkYXRlLCBpdHMgbmVlZGVkIHRvIHJldHVybiB3aGljaCBmaWVsZCBpcyBmYWlsaW5nIG9uIGNhc2Ugb2YgZXJyb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUFkZHJlc3MoYWRkcmVzczogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoIWFkZHJlc3MgfHwgIWlzVmFsaWRQdWJsaWNLZXkoYWRkcmVzcykpIHtcbiAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIG9yIG1pc3NpbmcgJHtmaWVsZE5hbWV9LCBnb3Q6ICR7YWRkcmVzc31gKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgc3RhdGljcyBjb2luIG9iamVjdCBtYXRjaGluZyBhIGdpdmVuIFNvbGFuYSB0b2tlbiBhZGRyZXNzIGlmIGl0IGV4aXN0c1xuICpcbiAqIEBwYXJhbSB0b2tlbkFkZHJlc3MgVGhlIHRva2VuIGFkZHJlc3MgdG8gbWF0Y2ggYWdhaW5zdFxuICogQHBhcmFtIG5ldHdvcmsgU29sYW5hIE1haW5uZXQgb3IgVGVzdG5ldFxuICogQHJldHVybnMgc3RhdGljcyBCYXNlQ29pbiBvYmplY3QgZm9yIHRoZSBtYXRjaGluZyB0b2tlblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U29sVG9rZW5Gcm9tQWRkcmVzcyh0b2tlbkFkZHJlc3M6IHN0cmluZywgbmV0d29yazogQmFzZU5ldHdvcmspOiBSZWFkb25seTxCYXNlQ29pbj4gfCB1bmRlZmluZWQge1xuICBjb25zdCB0b2tlbnMgPSBjb2lucy5maWx0ZXIoKGNvaW4pID0+IHtcbiAgICBpZiAoY29pbiBpbnN0YW5jZW9mIFNvbENvaW4pIHtcbiAgICAgIHJldHVybiBjb2luLm5ldHdvcmsudHlwZSA9PT0gbmV0d29yay50eXBlICYmIGNvaW4udG9rZW5BZGRyZXNzLnRvTG93ZXJDYXNlKCkgPT09IHRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xuICBjb25zdCB0b2tlbnNBcnJheSA9IHRva2Vucy5tYXAoKHRva2VuKSA9PiB0b2tlbik7XG4gIGlmICh0b2tlbnNBcnJheS5sZW5ndGggPj0gMSkge1xuICAgIC8vIHRoZXJlIHNob3VsZCBuZXZlciBiZSB0d28gdG9rZW5zIHdpdGggdGhlIHNhbWUgY29udHJhY3QgYWRkcmVzcywgc28gd2UgYXNzZXJ0IHRoYXQgaGVyZVxuICAgIGFzc2VydCh0b2tlbnNBcnJheS5sZW5ndGggPT09IDEpO1xuICAgIHJldHVybiB0b2tlbnNBcnJheVswXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEdldCB0aGUgc3RhdGljcyBjb2luIG9iamVjdCBtYXRjaGluZyBhIGdpdmVuIFNvbGFuYSB0b2tlbiBhZGRyZXNzIGlmIGl0IGV4aXN0c1xuICpcbiAqIEBwYXJhbSB0b2tlbkFkZHJlc3MgVGhlIHRva2VuIGFkZHJlc3MgdG8gbWF0Y2ggYWdhaW5zdFxuICogQHBhcmFtIG5ldHdvcmsgU29sYW5hIE1haW5uZXQgb3IgVGVzdG5ldFxuICogQHJldHVybnMgc3RhdGljcyBCYXNlQ29pbiBvYmplY3QgZm9yIHRoZSBtYXRjaGluZyB0b2tlblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U29sVG9rZW5Gcm9tQWRkcmVzc09ubHkodG9rZW5BZGRyZXNzOiBzdHJpbmcpOiBSZWFkb25seTxCYXNlQ29pbj4gfCB1bmRlZmluZWQge1xuICBjb25zdCB0b2tlbnMgPSBjb2lucy5maWx0ZXIoKGNvaW4pID0+IHtcbiAgICBpZiAoY29pbiBpbnN0YW5jZW9mIFNvbENvaW4pIHtcbiAgICAgIHJldHVybiBjb2luLnRva2VuQWRkcmVzcy50b0xvd2VyQ2FzZSgpID09PSB0b2tlbkFkZHJlc3MudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbiAgY29uc3QgdG9rZW5zQXJyYXkgPSB0b2tlbnMubWFwKCh0b2tlbikgPT4gdG9rZW4pO1xuICBpZiAodG9rZW5zQXJyYXkubGVuZ3RoID49IDEpIHtcbiAgICAvLyB0aGVyZSBzaG91bGQgbmV2ZXIgYmUgdHdvIHRva2VucyB3aXRoIHRoZSBzYW1lIGNvbnRyYWN0IGFkZHJlc3MsIHNvIHdlIGFzc2VydCB0aGF0IGhlcmVcbiAgICBhc3NlcnQodG9rZW5zQXJyYXkubGVuZ3RoID09PSAxKTtcbiAgICByZXR1cm4gdG9rZW5zQXJyYXlbMF07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHNvbGFuYSB0b2tlbiBvYmplY3QgZnJvbSB0b2tlbiBuYW1lXG4gKiBAcGFyYW0gdG9rZW5OYW1lIFRoZSB0b2tlbiBuYW1lIHRvIG1hdGNoIGFnYWluc3RcbiAqICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U29sVG9rZW5Gcm9tVG9rZW5OYW1lKHRva2VuTmFtZTogc3RyaW5nKTogUmVhZG9ubHk8U29sQ29pbj4gfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIGNvbnN0IHRva2VuID0gY29pbnMuZ2V0KHRva2VuTmFtZSk7XG4gICAgaWYgKCEodG9rZW4uaXNUb2tlbiAmJiB0b2tlbiBpbnN0YW5jZW9mIFNvbENvaW4pKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gdG9rZW47XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIShlIGluc3RhbmNlb2YgQ29pbk5vdERlZmluZWRFcnJvcikpIHtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIHNvbGFuYSBhc3NvY2lhdGVkIHRva2VuIGFjY291bnQgYWRkcmVzc1xuICogQHBhcmFtIHRva2VuQWRkcmVzcyB0b2tlbiBtaW50IGFkZHJlc3NcbiAqIEBwYXJhbSBvd25lckFkZHJlc3MgVGhlIG93bmVyIG9mIHRoZSBhc3NvY2lhdGVkIHRva2VuIGFjY291bnRcbiAqIEByZXR1cm5zIFRoZSBhc3NvY2lhdGVkIHRva2VuIGFjY291bnQgYWRkcmVzc1xuICogKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgdG9rZW5NaW50QWRkcmVzczogc3RyaW5nLFxuICBvd25lckFkZHJlc3M6IHN0cmluZyxcbiAgYWxsb3dPd25lck9mZkN1cnZlID0gZmFsc2UsXG4gIHByb2dyYW1JZD86IHN0cmluZ1xuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgbWludFB1YmxpY0tleSA9IG5ldyBQdWJsaWNLZXkodG9rZW5NaW50QWRkcmVzcyk7XG4gIGNvbnN0IG93bmVyUHVibGljS2V5ID0gbmV3IFB1YmxpY0tleShvd25lckFkZHJlc3MpO1xuXG4gIC8vIHRva2VuQWRkcmVzcyBhcmUgbm90IG9uIGVkMjU1MTkgY3VydmUsIHNvIHRoZXkgY2FuJ3QgYmUgdXNlZCBhcyBvd25lckFkZHJlc3NcbiAgaWYgKCFhbGxvd093bmVyT2ZmQ3VydmUgJiYgIVB1YmxpY0tleS5pc09uQ3VydmUob3duZXJQdWJsaWNLZXkudG9CdWZmZXIoKSkpIHtcbiAgICB0aHJvdyBuZXcgVXRpbHNFcnJvcignSW52YWxpZCBvd25lckFkZHJlc3MgLSBhZGRyZXNzIG9mZiBlZDI1NTE5IGN1cnZlLCBnb3Q6ICcgKyBvd25lckFkZHJlc3MpO1xuICB9XG5cbiAgaWYgKCFwcm9ncmFtSWQpIHtcbiAgICBjb25zdCBjb2luID0gZ2V0U29sVG9rZW5Gcm9tQWRkcmVzc09ubHkodG9rZW5NaW50QWRkcmVzcyk7XG4gICAgaWYgKGNvaW4gJiYgY29pbiBpbnN0YW5jZW9mIFNvbENvaW4gJiYgJ3Byb2dyYW1JZCcgaW4gY29pbiAmJiBjb2luLnByb2dyYW1JZCkge1xuICAgICAgcHJvZ3JhbUlkID0gY29pbi5wcm9ncmFtSWQudG9TdHJpbmcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvZ3JhbUlkID0gVE9LRU5fUFJPR1JBTV9JRC50b1N0cmluZygpO1xuICAgIH1cbiAgfVxuXG4gIGxldCBhdGFBZGRyZXNzOiBQdWJsaWNLZXk7XG4gIGlmIChwcm9ncmFtSWQgPT09IFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpKSB7XG4gICAgYXRhQWRkcmVzcyA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3MoXG4gICAgICBtaW50UHVibGljS2V5LFxuICAgICAgb3duZXJQdWJsaWNLZXksXG4gICAgICBhbGxvd093bmVyT2ZmQ3VydmUsXG4gICAgICBUT0tFTl8yMDIyX1BST0dSQU1fSURcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGF0YUFkZHJlc3MgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzKG1pbnRQdWJsaWNLZXksIG93bmVyUHVibGljS2V5LCBhbGxvd093bmVyT2ZmQ3VydmUpO1xuICB9XG4gIHJldHVybiBhdGFBZGRyZXNzLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZU1pbnRBZGRyZXNzKG1pbnRBZGRyZXNzOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKCFtaW50QWRkcmVzcyB8fCAhaXNWYWxpZEFkZHJlc3MobWludEFkZHJlc3MpKSB7XG4gICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBvciBtaXNzaW5nIG1pbnRBZGRyZXNzLCBnb3Q6ICcgKyBtaW50QWRkcmVzcyk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlT3duZXJBZGRyZXNzKG93bmVyQWRkcmVzczogc3RyaW5nKTogdm9pZCB7XG4gIGlmICghb3duZXJBZGRyZXNzIHx8ICFpc1ZhbGlkQWRkcmVzcyhvd25lckFkZHJlc3MpKSB7XG4gICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBvciBtaXNzaW5nIG93bmVyQWRkcmVzcywgZ290OiAnICsgb3duZXJBZGRyZXNzKTtcbiAgfVxufVxuXG4vKipcbiAqIFR5cGUgcHJlZGljYXRlIHRvIGNoZWNrIGlmIGFuIGluc3RydWN0aW9uIGlzIGEgbGVnYWN5IFNvbEluc3RydWN0aW9uLlxuICogVXNlcyAncHJvZ3JhbUlkJyBwcm9wZXJ0eSBhcyB0aGUgZGlzY3JpbWluYXRvciBzaW5jZSBpdCdzIHVuaXF1ZSB0byBsZWdhY3kgaW5zdHJ1Y3Rpb25zXG4gKiBWZXJzaW9uZWQgaW5zdHJ1Y3Rpb25zIGhhdmUgJ3Byb2dyYW1JZEluZGV4JyBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0gaW5zdHJ1Y3Rpb24gLSBUaGUgaW5zdHJ1Y3Rpb24gdG8gY2hlY2tcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGluc3RydWN0aW9uIGlzIGEgU29sSW5zdHJ1Y3Rpb24gKGhhcyBwcm9ncmFtSWQgZmllbGQpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NvbExlZ2FjeUluc3RydWN0aW9uKFxuICBpbnN0cnVjdGlvbjogU29sSW5zdHJ1Y3Rpb24gfCBTb2xWZXJzaW9uZWRJbnN0cnVjdGlvblxuKTogaW5zdHJ1Y3Rpb24gaXMgU29sSW5zdHJ1Y3Rpb24ge1xuICByZXR1cm4gJ3Byb2dyYW1JZCcgaW4gaW5zdHJ1Y3Rpb247XG59XG5cbi8qKlxuICogVG9rZW4tMjAyMiB0cmFuc2ZlciBmZWU6IG1pbihhbW91bnQgKiBiYXNpc1BvaW50cyAvIDEwMDAwLCBtYXhpbXVtRmVlKSwgaW4gcmF3IGJhc2UgdW5pdHMuXG4gKiBBbGwgbWF0aCBpbiBCaWdJbnQgdG8gYXZvaWQgcHJlY2lzaW9uIGxvc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlVHJhbnNmZXJGZWUoYW1vdW50OiBzdHJpbmcsIGJhc2lzUG9pbnRzOiBudW1iZXIsIG1heGltdW1GZWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJhdyA9IChCaWdJbnQoYW1vdW50KSAqIEJpZ0ludChiYXNpc1BvaW50cykpIC8gMTAwMDBuO1xuICBjb25zdCBjYXAgPSBCaWdJbnQobWF4aW11bUZlZSk7XG4gIHJldHVybiAocmF3IDwgY2FwID8gcmF3IDogY2FwKS50b1N0cmluZygpO1xufVxuIl19
|