@meshsdk/contract 1.6.0-alpha.21 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/index.cjs +37 -0
  2. package/dist/{index.d.mts → index.d.cts} +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +28 -1803
  5. package/package.json +30 -14
  6. package/.turbo/turbo-build$colon$docs.log +0 -8
  7. package/.turbo/turbo-build$colon$mesh.log +0 -19
  8. package/dist/index.mjs +0 -1834
  9. package/src/common.ts +0 -186
  10. package/src/coupon-bond-guaranteed/aiken-workspace/readme.md +0 -0
  11. package/src/coupon-bond-guaranteed/offchain.ts +0 -3
  12. package/src/coupon-bond-guaranteed/readme.md +0 -3
  13. package/src/escrow/aiken-workspace/aiken.lock +0 -26
  14. package/src/escrow/aiken-workspace/aiken.toml +0 -19
  15. package/src/escrow/aiken-workspace/lib/escrow/types.ak +0 -21
  16. package/src/escrow/aiken-workspace/lib/escrow/validators/escrow.ak +0 -122
  17. package/src/escrow/aiken-workspace/plutus.json +0 -238
  18. package/src/escrow/aiken-workspace/readme.md +0 -55
  19. package/src/escrow/aiken-workspace/validators/escrow.ak +0 -9
  20. package/src/escrow/aiken-workspace/validators/tests/escrow.ak +0 -462
  21. package/src/escrow/index.ts +0 -1
  22. package/src/escrow/offchain.ts +0 -254
  23. package/src/escrow/readme.md +0 -38
  24. package/src/giftcard/aiken-workspace/aiken.lock +0 -26
  25. package/src/giftcard/aiken-workspace/aiken.toml +0 -19
  26. package/src/giftcard/aiken-workspace/plutus.json +0 -138
  27. package/src/giftcard/aiken-workspace/readme.md +0 -55
  28. package/src/giftcard/aiken-workspace/validators/oneshot.ak +0 -173
  29. package/src/giftcard/index.ts +0 -1
  30. package/src/giftcard/offchain.ts +0 -184
  31. package/src/giftcard/readme.md +0 -36
  32. package/src/hello-world/aiken-workspace/README.md +0 -19
  33. package/src/hello-world/aiken-workspace/aiken.lock +0 -15
  34. package/src/hello-world/aiken-workspace/aiken.toml +0 -14
  35. package/src/hello-world/aiken-workspace/contract.md +0 -27
  36. package/src/hello-world/aiken-workspace/plutus.json +0 -69
  37. package/src/hello-world/aiken-workspace/validators/hello_world.ak +0 -24
  38. package/src/hello-world/index.ts +0 -1
  39. package/src/hello-world/offchain.ts +0 -24
  40. package/src/hello-world/readme.md +0 -1
  41. package/src/index.ts +0 -6
  42. package/src/marketplace/aiken-workspace/aiken.lock +0 -26
  43. package/src/marketplace/aiken-workspace/aiken.toml +0 -19
  44. package/src/marketplace/aiken-workspace/lib/marketplace/types.ak +0 -15
  45. package/src/marketplace/aiken-workspace/lib/marketplace/validators/marketplace.ak +0 -52
  46. package/src/marketplace/aiken-workspace/plutus.json +0 -204
  47. package/src/marketplace/aiken-workspace/readme.md +0 -55
  48. package/src/marketplace/aiken-workspace/validators/marketplace.ak +0 -14
  49. package/src/marketplace/aiken-workspace/validators/tests/marketplace.ak +0 -218
  50. package/src/marketplace/index.ts +0 -1
  51. package/src/marketplace/offchain.ts +0 -248
  52. package/src/marketplace/readme.md +0 -45
  53. package/src/payment-splitter/aiken-workspace/aiken.lock +0 -15
  54. package/src/payment-splitter/aiken-workspace/aiken.toml +0 -14
  55. package/src/payment-splitter/aiken-workspace/plutus.json +0 -83
  56. package/src/payment-splitter/aiken-workspace/validators/payment-splitter.ak +0 -329
  57. package/src/payment-splitter/index.ts +0 -1
  58. package/src/payment-splitter/offchain.ts +0 -143
  59. package/src/payment-splitter/readme.md +0 -100
  60. package/src/swap/aiken-workspace/aiken.lock +0 -26
  61. package/src/swap/aiken-workspace/aiken.toml +0 -19
  62. package/src/swap/aiken-workspace/plutus.json +0 -208
  63. package/src/swap/aiken-workspace/readme.md +0 -55
  64. package/src/swap/aiken-workspace/validators/swap.ak +0 -188
  65. package/src/swap/index.ts +0 -1
  66. package/src/swap/offchain.ts +0 -139
  67. package/src/swap/readme.md +0 -35
  68. package/src/vesting/aiken-workspace/README.md +0 -24
  69. package/src/vesting/aiken-workspace/aiken.lock +0 -26
  70. package/src/vesting/aiken-workspace/aiken.toml +0 -19
  71. package/src/vesting/aiken-workspace/lib/vesting/types.ak +0 -8
  72. package/src/vesting/aiken-workspace/lib/vesting/validators/vesting.ak +0 -19
  73. package/src/vesting/aiken-workspace/plutus.json +0 -67
  74. package/src/vesting/aiken-workspace/validators/tests/vesting.ak +0 -108
  75. package/src/vesting/aiken-workspace/validators/vesting.ak +0 -9
  76. package/src/vesting/index.ts +0 -1
  77. package/src/vesting/offchain.ts +0 -117
  78. package/src/vesting/readme.md +0 -36
  79. package/tsconfig.json +0 -5
@@ -1 +0,0 @@
1
- export * from './offchain';
@@ -1,184 +0,0 @@
1
- import {
2
- builtinByteString,
3
- BuiltinByteString,
4
- Integer,
5
- List,
6
- mConStr0,
7
- mConStr1,
8
- PlutusScript,
9
- stringToHex,
10
- txOutRef,
11
- } from "@meshsdk/common";
12
- import {
13
- Asset,
14
- deserializeDatum,
15
- resolveScriptHash,
16
- serializePlutusScript,
17
- UTxO,
18
- } from "@meshsdk/core";
19
- import { applyParamsToScript } from "@meshsdk/core-csl";
20
-
21
- import { MeshTxInitiator, MeshTxInitiatorInput } from "../common";
22
- import blueprint from "./aiken-workspace/plutus.json";
23
-
24
- export const MeshGiftCardBlueprint = blueprint;
25
-
26
- export class MeshGiftCardContract extends MeshTxInitiator {
27
- tokenNameHex: string = "";
28
- paramUtxo: UTxO["input"] = { outputIndex: 0, txHash: "" };
29
-
30
- giftCardCbor = (tokenNameHex: string, utxoTxHash: string, utxoTxId: number) =>
31
- applyParamsToScript(
32
- blueprint.validators[0]!.compiledCode,
33
- [builtinByteString(tokenNameHex), txOutRef(utxoTxHash, utxoTxId)],
34
- "JSON",
35
- );
36
-
37
- redeemCbor = (tokenNameHex: string, policyId: string) =>
38
- applyParamsToScript(blueprint.validators[1]!.compiledCode, [
39
- tokenNameHex,
40
- policyId,
41
- ]);
42
-
43
- constructor(
44
- inputs: MeshTxInitiatorInput,
45
- tokenNameHex?: string,
46
- paramUtxo?: UTxO["input"],
47
- ) {
48
- super(inputs);
49
- if (tokenNameHex) {
50
- this.tokenNameHex = tokenNameHex;
51
- }
52
- if (paramUtxo) {
53
- this.paramUtxo = paramUtxo;
54
- }
55
- }
56
-
57
- createGiftCard = async (
58
- tokenName: string,
59
- giftValue: Asset[],
60
- ): Promise<string> => {
61
- const { utxos, walletAddress, collateral } =
62
- await this.getWalletInfoForTx();
63
- const tokenNameHex = stringToHex(tokenName);
64
- const firstUtxo = utxos[0];
65
- if (firstUtxo === undefined) throw new Error("No UTXOs available");
66
- const remainingUtxos = utxos.slice(1);
67
- const giftCardScript = this.giftCardCbor(
68
- tokenNameHex,
69
- firstUtxo.input.txHash,
70
- firstUtxo.input.outputIndex,
71
- );
72
-
73
- const giftCardPolicy = resolveScriptHash(giftCardScript, "V2");
74
-
75
- const redeemScript: PlutusScript = {
76
- code: this.redeemCbor(tokenNameHex, giftCardPolicy),
77
- version: "V2",
78
- };
79
-
80
- const redeemAddr = serializePlutusScript(
81
- redeemScript,
82
- undefined,
83
- this.networkId,
84
- ).address;
85
-
86
- await this.mesh
87
- .txIn(
88
- firstUtxo.input.txHash,
89
- firstUtxo.input.outputIndex,
90
- firstUtxo.output.amount,
91
- firstUtxo.output.address,
92
- )
93
- .mintPlutusScriptV2()
94
- .mint("1", giftCardPolicy, tokenNameHex)
95
- .mintingScript(giftCardScript)
96
- .mintRedeemerValue(mConStr0([]))
97
- .txOut(redeemAddr, [
98
- ...giftValue,
99
- { unit: giftCardPolicy + tokenNameHex, quantity: "1" },
100
- ])
101
- .txOutInlineDatumValue([
102
- firstUtxo.input.txHash,
103
- firstUtxo.input.outputIndex,
104
- tokenNameHex,
105
- ])
106
- .changeAddress(walletAddress)
107
- .txInCollateral(
108
- collateral.input.txHash,
109
- collateral.input.outputIndex,
110
- collateral.output.amount,
111
- collateral.output.address,
112
- )
113
- .selectUtxosFrom(remainingUtxos)
114
- .complete();
115
-
116
- this.tokenNameHex = tokenNameHex;
117
- this.paramUtxo = firstUtxo.input;
118
-
119
- return this.mesh.txHex;
120
- };
121
-
122
- redeemGiftCard = async (giftCardUtxo: UTxO): Promise<string> => {
123
- const { utxos, walletAddress, collateral } =
124
- await this.getWalletInfoForTx();
125
-
126
- const inlineDatum = deserializeDatum<List>(
127
- giftCardUtxo.output.plutusData!,
128
- ).list;
129
- const paramTxHash = (inlineDatum[0] as BuiltinByteString).bytes;
130
- const paramTxId = (inlineDatum[1] as Integer).int as number;
131
- const tokenNameHex = (inlineDatum[2] as BuiltinByteString).bytes;
132
- const giftCardScript = this.giftCardCbor(
133
- tokenNameHex,
134
- paramTxHash,
135
- paramTxId,
136
- );
137
-
138
- const giftCardPolicy = resolveScriptHash(giftCardScript, "V2");
139
-
140
- const redeemScript = this.redeemCbor(tokenNameHex, giftCardPolicy);
141
-
142
- await this.mesh
143
- .spendingPlutusScriptV2()
144
- .txIn(
145
- giftCardUtxo.input.txHash,
146
- giftCardUtxo.input.outputIndex,
147
- giftCardUtxo.output.amount,
148
- giftCardUtxo.output.address,
149
- )
150
- .spendingReferenceTxInInlineDatumPresent()
151
- .spendingReferenceTxInRedeemerValue("")
152
- .txInScript(redeemScript)
153
- .mintPlutusScriptV2()
154
- .mint("-1", giftCardPolicy, tokenNameHex)
155
- .mintingScript(giftCardScript)
156
- .mintRedeemerValue(mConStr1([]))
157
- .changeAddress(walletAddress)
158
- .txInCollateral(
159
- collateral.input.txHash,
160
- collateral.input.outputIndex,
161
- collateral.output.amount,
162
- collateral.output.address,
163
- )
164
- .selectUtxosFrom(utxos)
165
- .complete();
166
- return this.mesh.txHex;
167
- };
168
-
169
- getUtxoByTxHash = async (txHash: string): Promise<UTxO | undefined> => {
170
- const { redeemScript } = this.getScripts();
171
- return await this._getUtxoByTxHash(redeemScript, txHash);
172
- };
173
-
174
- private getScripts = () => {
175
- const giftCardScript = this.giftCardCbor(
176
- this.tokenNameHex,
177
- this.paramUtxo.txHash,
178
- this.paramUtxo.outputIndex,
179
- );
180
- const giftCardPolicy = resolveScriptHash(giftCardScript, "V2");
181
- const redeemScript = this.redeemCbor(this.tokenNameHex, giftCardPolicy);
182
- return { giftCardScript, redeemScript };
183
- };
184
- }
@@ -1,36 +0,0 @@
1
- # Giftcard contract
2
-
3
- Giftcard contract allows users to create a transactions to lock assets into the smart contract, which can be redeemed by any user.
4
-
5
- [Demo](https://meshjs.dev/smart-contracts/giftcard)
6
-
7
- Creating a giftcard will mint a token and send the assets to the contract. While redeeming will burn the token and send the assets to the redeemer.
8
-
9
- There are 2 actions (or endpoints) available to interact with this smart contract:
10
-
11
- - create giftcard
12
- - redeem giftcard
13
-
14
- To initialize the escrow, we need to initialize a provider, MeshTxBuilder and MeshGiftCardContract.
15
-
16
- ```
17
- import { BlockfrostProvider, MeshTxBuilder } from '@meshsdk/core';
18
- import { MeshGiftCardContract } from '@meshsdk/contracts';
19
- import { useWallet } from '@meshsdk/react';
20
-
21
- const { connected, wallet } = useWallet();
22
-
23
- const blockchainProvider = new BlockfrostProvider(APIKEY);
24
-
25
- const meshTxBuilder = new MeshTxBuilder({
26
- fetcher: blockchainProvider,
27
- submitter: blockchainProvider,
28
- });
29
-
30
- const contract = new MeshGiftCardContract({
31
- mesh: meshTxBuilder,
32
- fetcher: blockchainProvider,
33
- wallet: wallet,
34
- networkId: 0,
35
- });
36
- ```
@@ -1,19 +0,0 @@
1
- # Hello World - Specification
2
-
3
- ### Parameter - no parameter
4
-
5
- ### Datum
6
-
7
- - `owner`: Owner's pub key hash
8
- - `message`: Must be a string, e.g. "Hello, World!"
9
-
10
- ### User Action
11
-
12
- 1. Unlock by owner
13
-
14
- - Signed by `owner`
15
-
16
- 2. Unlock by owner
17
-
18
- - Signed by `beneficiary`
19
- - Only valid after `lock_until`
@@ -1,15 +0,0 @@
1
- # This file was generated by Aiken
2
- # You typically do not need to edit this file
3
-
4
- [[requirements]]
5
- name = "aiken-lang/stdlib"
6
- version = "1.9.0"
7
- source = "github"
8
-
9
- [[packages]]
10
- name = "aiken-lang/stdlib"
11
- version = "1.9.0"
12
- requirements = []
13
- source = "github"
14
-
15
- [etags]
@@ -1,14 +0,0 @@
1
- name = "meshjs/aiken"
2
- version = "0.0.0"
3
- license = "Apache-2.0"
4
- description = "Aiken on MeshJS"
5
-
6
- [repository]
7
- user = "jingles"
8
- project = "test1"
9
- platform = "github"
10
-
11
- [[dependencies]]
12
- name = "aiken-lang/stdlib"
13
- version = "1.9.0"
14
- source = "github"
@@ -1,27 +0,0 @@
1
-
2
- ```
3
- use aiken/hash.{Blake2b_224, Hash}
4
- use aiken/list
5
- use aiken/transaction.{ScriptContext}
6
- use aiken/transaction/credential.{VerificationKey}
7
-
8
- type Datum {
9
- owner: Hash<Blake2b_224, VerificationKey>,
10
- }
11
-
12
- type Redeemer {
13
- msg: ByteArray,
14
- }
15
-
16
- validator {
17
- fn hello_world(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
18
- let must_say_hello =
19
- redeemer.msg == "Hello, World!"
20
-
21
- let must_be_signed =
22
- list.has(context.transaction.extra_signatories, datum.owner)
23
-
24
- must_say_hello && must_be_signed
25
- }
26
- }
27
- ```
@@ -1,69 +0,0 @@
1
- {
2
- "preamble": {
3
- "title": "meshjs/aiken",
4
- "description": "Aiken on MeshJS",
5
- "version": "0.0.0",
6
- "plutusVersion": "v2",
7
- "compiler": {
8
- "name": "Aiken",
9
- "version": "v1.0.29-alpha+unknown"
10
- },
11
- "license": "Apache-2.0"
12
- },
13
- "validators": [
14
- {
15
- "title": "hello_world.hello_world",
16
- "datum": {
17
- "title": "datum",
18
- "schema": {
19
- "$ref": "#/definitions/hello_world~1Datum"
20
- }
21
- },
22
- "redeemer": {
23
- "title": "redeemer",
24
- "schema": {
25
- "$ref": "#/definitions/hello_world~1Redeemer"
26
- }
27
- },
28
- "compiledCode": "58e901000032323232323223223225333006323253330083371e6eb8c008c028dd5002a4410d48656c6c6f2c20576f726c642100100114a06644646600200200644a66601c00229404c94ccc030cdc79bae301000200414a226600600600260200026eb0c02cc030c030c030c030c030c030c030c030c024dd5180098049baa002375c600260126ea80188c02c0045261365653330043370e900018029baa001132325333009300b002149858dd7180480098031baa0011653330023370e900018019baa0011323253330073009002149858dd7180380098021baa001165734aae7555cf2ab9f5742ae881",
29
- "hash": "c1fe430f19ac248a8a7ea47db106002c4327e542c3fdc60ad6481103"
30
- }
31
- ],
32
- "definitions": {
33
- "ByteArray": {
34
- "dataType": "bytes"
35
- },
36
- "hello_world/Datum": {
37
- "title": "Datum",
38
- "anyOf": [
39
- {
40
- "title": "Datum",
41
- "dataType": "constructor",
42
- "index": 0,
43
- "fields": [
44
- {
45
- "title": "owner",
46
- "$ref": "#/definitions/ByteArray"
47
- }
48
- ]
49
- }
50
- ]
51
- },
52
- "hello_world/Redeemer": {
53
- "title": "Redeemer",
54
- "anyOf": [
55
- {
56
- "title": "Redeemer",
57
- "dataType": "constructor",
58
- "index": 0,
59
- "fields": [
60
- {
61
- "title": "msg",
62
- "$ref": "#/definitions/ByteArray"
63
- }
64
- ]
65
- }
66
- ]
67
- }
68
- }
69
- }
@@ -1,24 +0,0 @@
1
- use aiken/hash.{Blake2b_224, Hash}
2
- use aiken/list
3
- use aiken/transaction.{ScriptContext}
4
- use aiken/transaction/credential.{VerificationKey}
5
-
6
- type Datum {
7
- owner: Hash<Blake2b_224, VerificationKey>,
8
- }
9
-
10
- type Redeemer {
11
- msg: ByteArray,
12
- }
13
-
14
- validator {
15
- fn hello_world(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
16
- let must_say_hello =
17
- redeemer.msg == "Hello, World!"
18
-
19
- let must_be_signed =
20
- list.has(context.transaction.extra_signatories, datum.owner)
21
-
22
- must_say_hello && must_be_signed
23
- }
24
- }
@@ -1 +0,0 @@
1
- export * from './offchain';
@@ -1,24 +0,0 @@
1
- import { BuiltinByteString, ConStr0, Integer } from "@meshsdk/common";
2
- import { UTxO } from "@meshsdk/core";
3
- import { applyParamsToScript } from "@meshsdk/core-csl";
4
-
5
- import { MeshTxInitiator, MeshTxInitiatorInput } from "../common";
6
- import blueprint from "./aiken-workspace/plutus.json";
7
-
8
- export type HelloWorldDatum = ConStr0<
9
- [Integer, BuiltinByteString, BuiltinByteString]
10
- >;
11
-
12
- export const MeshHelloWorldBlueprint = blueprint;
13
-
14
- export class MeshHelloWorldContract extends MeshTxInitiator {
15
- scriptCbor = applyParamsToScript(blueprint.validators[0]!.compiledCode, []);
16
-
17
- constructor(inputs: MeshTxInitiatorInput) {
18
- super(inputs);
19
- }
20
-
21
- getUtxoByTxHash = async (txHash: string): Promise<UTxO | undefined> => {
22
- return await this._getUtxoByTxHash(this.scriptCbor, txHash);
23
- };
24
- }
@@ -1 +0,0 @@
1
- # Hello World Contract
package/src/index.ts DELETED
@@ -1,6 +0,0 @@
1
- export * from './marketplace';
2
- export * from './vesting';
3
- export * from './escrow';
4
- export * from './giftcard';
5
- export * from './payment-splitter';
6
- export * from './swap';
@@ -1,26 +0,0 @@
1
- # This file was generated by Aiken
2
- # You typically do not need to edit this file
3
-
4
- [[requirements]]
5
- name = "aiken-lang/stdlib"
6
- version = "1.9.0"
7
- source = "github"
8
-
9
- [[requirements]]
10
- name = "sidan-lab/aiken-utils"
11
- version = "0.1.6-beta"
12
- source = "github"
13
-
14
- [[packages]]
15
- name = "aiken-lang/stdlib"
16
- version = "1.9.0"
17
- requirements = []
18
- source = "github"
19
-
20
- [[packages]]
21
- name = "sidan-lab/aiken-utils"
22
- version = "0.1.6-beta"
23
- requirements = []
24
- source = "github"
25
-
26
- [etags]
@@ -1,19 +0,0 @@
1
- name = "meshjs/marketplace"
2
- version = "0.0.0"
3
- license = "Apache-2.0"
4
- description = "Aiken contracts for project 'meshjs/marketplace'"
5
-
6
- [repository]
7
- user = "meshjs"
8
- project = "marketplace"
9
- platform = "github"
10
-
11
- [[dependencies]]
12
- name = "aiken-lang/stdlib"
13
- version = "1.9.0"
14
- source = "github"
15
-
16
- [[dependencies]]
17
- name = "sidan-lab/aiken-utils"
18
- version = "0.1.6-beta"
19
- source = "github"
@@ -1,15 +0,0 @@
1
- use aiken/transaction/credential.{Address}
2
-
3
- pub type MarketplaceDatum {
4
- MarketplaceDatum {
5
- seller: Address,
6
- price: Int,
7
- policy: ByteArray,
8
- tokenName: ByteArray,
9
- }
10
- }
11
-
12
- pub type MarketplaceRedeemer {
13
- Buy
14
- Close
15
- }
@@ -1,52 +0,0 @@
1
- use aiken/transaction.{ScriptContext, Spend, find_input}
2
- use aiken/transaction/credential.{Address}
3
- use aiken/transaction/value.{from_lovelace, lovelace_of}
4
- use marketplace/types.{Buy, Close, MarketplaceDatum, MarketplaceRedeemer}
5
- use sidan_utils/address.{address_pub_key}
6
- use sidan_utils/extra_signatories.{key_signed}
7
- use sidan_utils/inputs.{inputs_at}
8
- use sidan_utils/value.{get_all_value_to, value_geq} as sidan_value
9
-
10
- pub fn marketplace_logic(
11
- owner: Address,
12
- fee_percentage_basis_point: Int,
13
- datum: MarketplaceDatum,
14
- redeemer: MarketplaceRedeemer,
15
- ctx: ScriptContext,
16
- ) -> Bool {
17
- when ctx.purpose is {
18
- Spend(utxo) ->
19
- when redeemer is {
20
- Buy -> {
21
- expect Some(own_input) = find_input(ctx.transaction.inputs, utxo)
22
- let own_address = own_input.output.address
23
- let is_only_one_input_from_script =
24
- when inputs_at(ctx.transaction.inputs, own_address) is {
25
- [_] -> True
26
- _ -> False
27
- }
28
-
29
- let is_proceed_paid =
30
- get_all_value_to(ctx.transaction.outputs, datum.seller)
31
- |> value_geq(
32
- from_lovelace(
33
- datum.price + lovelace_of(own_input.output.value),
34
- ),
35
- )
36
- let is_fee_paid =
37
- get_all_value_to(ctx.transaction.outputs, owner)
38
- |> value_geq(
39
- from_lovelace(
40
- datum.price * fee_percentage_basis_point / 10000,
41
- ),
42
- )
43
- is_only_one_input_from_script && is_fee_paid && is_proceed_paid
44
- }
45
- Close -> {
46
- expect Some(pub_key) = address_pub_key(datum.seller)
47
- key_signed(ctx.transaction.extra_signatories, pub_key)
48
- }
49
- }
50
- _ -> False
51
- }
52
- }