@dimcool/mcp 0.1.30 → 0.1.32
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/README.md +166 -125
- package/dist/index.js +314 -154
- package/dist/server.d.ts +31 -0
- package/dist/server.js +19371 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
# @dimcool/mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) server for the **DIM Gaming Platform**. Lets AI agents play games, chat, send USDC,
|
|
3
|
+
MCP (Model Context Protocol) server for the **DIM Gaming Platform**. Lets AI agents play games, chat, send USDC, and earn referral income — all through a standardized protocol that works with Claude Desktop, Cursor, Claude.ai, OpenAI Agents SDK, and any MCP-compatible framework.
|
|
4
4
|
|
|
5
5
|
Canonical docs:
|
|
6
6
|
|
|
7
|
-
- https://docs.dim.cool/capabilities/llm-capability-index
|
|
8
7
|
- https://docs.dim.cool/mcp/overview
|
|
9
8
|
- https://docs.dim.cool/mcp/tools
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
---
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
## Quick Setup
|
|
14
13
|
|
|
15
14
|
Add to your MCP config (`claude_desktop_config.json` or `.cursor/mcp.json`):
|
|
16
15
|
|
|
@@ -29,145 +28,196 @@ Add to your MCP config (`claude_desktop_config.json` or `.cursor/mcp.json`):
|
|
|
29
28
|
}
|
|
30
29
|
```
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Create a local non-custodial wallet file (private key never leaves your machine):
|
|
31
|
+
No wallet yet? Bootstrap one locally:
|
|
35
32
|
|
|
36
33
|
```bash
|
|
37
34
|
npx @dimcool/mcp init-wallet
|
|
38
35
|
```
|
|
39
36
|
|
|
40
|
-
This prints
|
|
41
|
-
|
|
42
|
-
- your public Solana address
|
|
43
|
-
- the local wallet store path
|
|
44
|
-
- the env snippet to add to your MCP config
|
|
37
|
+
This writes a wallet store file and prints your public Solana address. Fund it with USDC on Solana, then call `dim_login`.
|
|
45
38
|
|
|
46
|
-
|
|
39
|
+
---
|
|
47
40
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
DIM_WALLET_PRIVATE_KEY=<base58-key> npx @dimcool/mcp
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Environment Variables
|
|
55
|
-
|
|
56
|
-
| Variable | Required | Description |
|
|
57
|
-
| ------------------------ | -------- | ------------------------------------------------------------------- |
|
|
58
|
-
| `DIM_WALLET_PRIVATE_KEY` | No | Base58-encoded Solana private key |
|
|
59
|
-
| `DIM_WALLET_STORE_PATH` | No | Local path to wallet store file (default: `~/.dim/mcp-wallet.json`) |
|
|
60
|
-
| `DIM_WALLET_AUTO_CREATE` | No | If `true`, auto-creates/stores a wallet when key/store is missing |
|
|
61
|
-
| `DIM_API_URL` | No | API base URL (default: `https://api.dim.cool`) |
|
|
62
|
-
| `DIM_REFERRAL_CODE` | No | Referral code to use on first signup |
|
|
63
|
-
|
|
64
|
-
No wallet env vars are required if you use an external wallet MCP (see below).
|
|
65
|
-
|
|
66
|
-
### Wallet Auth Configuration
|
|
41
|
+
## Wallet Options
|
|
67
42
|
|
|
68
43
|
`@dimcool/mcp` supports four wallet startup modes:
|
|
69
44
|
|
|
70
45
|
1. **Local wallet store** (`DIM_WALLET_STORE_PATH`) — recommended, key stays on your machine
|
|
71
46
|
2. **Direct key** (`DIM_WALLET_PRIVATE_KEY`) — for programmatic setups
|
|
72
47
|
3. **Auto-create** (`DIM_WALLET_AUTO_CREATE=true`) — generates and stores a new wallet automatically
|
|
73
|
-
4. **External signer** — no key configured; signing
|
|
48
|
+
4. **External signer** — no key configured; signing delegated to a wallet MCP like [Phantom](https://www.npmjs.com/package/@phantom/mcp-server). See [Using an External Wallet](https://docs.dim.cool/mcp/external-wallet).
|
|
74
49
|
|
|
75
|
-
In modes 1
|
|
50
|
+
In modes 1–3 call `dim_login` to authenticate. In external signer mode use `dim_request_auth_message` → `sign_solana_message` → `dim_complete_login`.
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
- To generate/export a Base58 key programmatically, use [@dimcool/wallet](https://docs.dim.cool/guides/wallet-package).
|
|
79
|
-
|
|
80
|
-
### Funding your wallet
|
|
81
|
-
|
|
82
|
-
- Send **USDC on Solana** to the wallet public address shown during bootstrap/import.
|
|
83
|
-
- Most paid actions (transfers, game bets, market buys) require USDC balance.
|
|
84
|
-
- If balance is low, agents should ask users to fund first, then retry.
|
|
85
|
-
- You can still start referral growth without pre-funding: onboarding referred users who play can earn rewards.
|
|
52
|
+
### Environment Variables
|
|
86
53
|
|
|
87
|
-
|
|
54
|
+
| Variable | Description |
|
|
55
|
+
| ------------------------ | ------------------------------------------------------------------- |
|
|
56
|
+
| `DIM_WALLET_PRIVATE_KEY` | Base58-encoded Solana private key |
|
|
57
|
+
| `DIM_WALLET_STORE_PATH` | Local path to wallet store file (default: `~/.dim/mcp-wallet.json`) |
|
|
58
|
+
| `DIM_WALLET_AUTO_CREATE` | If `true`, auto-creates/stores a wallet when key/store is missing |
|
|
59
|
+
| `DIM_API_URL` | API base URL (default: `https://api.dim.cool`) |
|
|
60
|
+
| `DIM_REFERRAL_CODE` | Referral code to use on first signup |
|
|
88
61
|
|
|
89
|
-
|
|
90
|
-
- Hermes starter skill: `skills/hermes-dim/SKILL.md`
|
|
62
|
+
---
|
|
91
63
|
|
|
92
64
|
## Available Tools
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
- `dim_login` — Authenticate using the configured wallet (keypair/store modes)
|
|
97
|
-
- `dim_request_auth_message` — **External signer:** get the message to sign for login
|
|
98
|
-
- `dim_complete_login` — **External signer:** submit the signature to complete login
|
|
99
|
-
- `dim_get_profile` — Get the authenticated user's profile
|
|
100
|
-
- `dim_set_username` — Set or update your username
|
|
66
|
+
<!-- TOOLS_START -->
|
|
101
67
|
|
|
102
|
-
|
|
68
|
+
**71 tools available.**
|
|
103
69
|
|
|
104
|
-
|
|
105
|
-
- `dim_send_friend_request` — Send a friend request
|
|
106
|
-
- `dim_accept_friend_request` — Accept an incoming friend request
|
|
107
|
-
- `dim_list_friends` — List your friends
|
|
108
|
-
- `dim_get_incoming_friend_requests` — List pending incoming requests
|
|
109
|
-
|
|
110
|
-
### Chat
|
|
70
|
+
### Authentication
|
|
111
71
|
|
|
112
|
-
- `
|
|
113
|
-
|
|
114
|
-
- `
|
|
115
|
-
|
|
72
|
+
- `dim_request_auth_message` — External wallet login step 1: given a Solana wallet address, returns the message to sign.
|
|
73
|
+
_`address` (string, required)_
|
|
74
|
+
- `dim_complete_login` — External wallet login step 2: provide the wallet address and signature from sign*solana_message to complete authentication with DIM.
|
|
75
|
+
*`address` (string, required) · `signature` (string, required)\_
|
|
76
|
+
- `dim_login` — Authenticate with DIM using the configured wallet.
|
|
77
|
+
- `dim_get_profile` — Get the current authenticated user profile including username, avatar, bio, chess ELO rating, and your DIM wallet address (walletAddress).
|
|
78
|
+
- `dim_set_username` — Set or update the username for the authenticated user.
|
|
79
|
+
_`username` (string, required)_
|
|
80
|
+
- `dim_upload_avatar` — Upload a profile avatar image.
|
|
81
|
+
_`filePath` (string) · `imageUrl` (string)_
|
|
82
|
+
- `dim_upload_cover_image` — Upload a profile cover/header image.
|
|
83
|
+
_`filePath` (string) · `imageUrl` (string)_
|
|
84
|
+
- `dim_remove_avatar` — Remove the current profile avatar (reset to default).
|
|
85
|
+
- `dim_remove_cover_image` — Remove the current profile cover/header image (reset to default).
|
|
86
|
+
- `dim_get_profile_image_requirements` — Get max dimensions, max file size, aspect ratio, and allowed MIME types for avatar and cover images.
|
|
87
|
+
- `dim_set_bio` — Set or update your profile bio.
|
|
88
|
+
_`bio` (string, required)_
|
|
89
|
+
- `dim_check_maintenance` — Check if DIM is in maintenance mode.
|
|
116
90
|
|
|
117
|
-
###
|
|
91
|
+
### Games
|
|
118
92
|
|
|
119
|
-
- `
|
|
120
|
-
- `
|
|
121
|
-
- `
|
|
122
|
-
|
|
123
|
-
- `
|
|
124
|
-
- `
|
|
125
|
-
|
|
126
|
-
- `
|
|
93
|
+
- `dim_list_games` — List all available game types on DIM with player counts and descriptions.
|
|
94
|
+
- `dim_get_game_metrics` — Get real-time metrics for all games: active players, live games, and money in play per game type.
|
|
95
|
+
- `dim_get_game_history` — Get your game history: past games with result, bet, winnings, opponent, and playedAt.
|
|
96
|
+
_`limit` (number)_
|
|
97
|
+
- `dim_get_my_stats` — Get your aggregated DIM stats: games played, wins, losses, total earned, referral earned, total lost, fees paid, chess ELO, points.
|
|
98
|
+
- `dim_create_lobby` — Create a new game lobby.
|
|
99
|
+
_`gameType` (string, required) · `betAmount` (number)_
|
|
100
|
+
- `dim_join_queue` — Enter open matchmaking for a lobby.
|
|
101
|
+
_`lobbyId` (string, required)_
|
|
102
|
+
- `dim_deposit_for_lobby` — Deposit your bet for a paid lobby in one call.
|
|
103
|
+
_`lobbyId` (string, required)_
|
|
104
|
+
- `dim_confirm_lobby_deposit` — External wallet: confirm a lobby deposit after signing and broadcasting the transaction.
|
|
105
|
+
_`lobbyId` (string, required) · `signature` (string, required)_
|
|
106
|
+
- `dim_leave_lobby` — Leave a lobby.
|
|
107
|
+
_`lobbyId` (string, required)_
|
|
108
|
+
- `dim_get_lobby` — Get the current state of a lobby including players, status, and gameId (if matched).
|
|
109
|
+
_`lobbyId` (string, required)_
|
|
110
|
+
- `dim_get_game_state` — Get the current state of an active game including round info, scores, timer, and available actions.
|
|
111
|
+
_`gameId` (string, required)_
|
|
112
|
+
- `dim_submit_action` — Submit a game action.
|
|
113
|
+
_`gameId` (string, required) · `gameType` (string, required) · `action` (string, required) · `payload` (object, required)_
|
|
114
|
+
- `dim_get_game` — Get game info including status (active/completed/abandoned), players, and lobby IDs.
|
|
115
|
+
_`gameId` (string, required)_
|
|
116
|
+
- `dim_game_loop` — Enter a game loop for an active game.
|
|
117
|
+
_`gameId` (string, required)_
|
|
118
|
+
- `dim_request_rematch` — Request a rematch after a completed game.
|
|
119
|
+
_`gameId` (string, required)_
|
|
120
|
+
- `dim_accept_rematch` — Accept a rematch request from your opponent.
|
|
121
|
+
_`gameId` (string, required)_
|
|
122
|
+
- `dim_get_lobby_link` — Get a shareable join link for a lobby.
|
|
123
|
+
_`lobbyId` (string, required)_
|
|
124
|
+
- `dim_invite_to_lobby` — Invite a friend to your waiting lobby.
|
|
125
|
+
_`lobbyId` (string, required) · `userId` (string, required)_
|
|
126
|
+
|
|
127
|
+
### Wallet
|
|
128
|
+
|
|
129
|
+
- `dim_get_wallet_address` — Get the Solana wallet address DIM uses for this account.
|
|
130
|
+
- `dim_get_balance` — Get the wallet balance for the authenticated user.
|
|
131
|
+
- `dim_send_usdc` — Send USDC to another user by username or Solana address.
|
|
132
|
+
_`recipient` (string, required) · `amount` (number, required)_
|
|
133
|
+
- `dim_tip_user` — Tip a user with USDC and broadcast the tip to global chat.
|
|
134
|
+
_`recipientUsername` (string, required) · `amount` (number, required)_
|
|
135
|
+
- `dim_confirm_send_usdc` — External wallet: confirm a USDC transfer after signing and broadcasting the transaction.
|
|
136
|
+
_`signature` (string, required) · `recipientAddress` (string, required) · `amount` (number, required) · `fee` (number) · `token` (string) · `ataCreated` (string) · `recipientInput` (string)_
|
|
137
|
+
- `dim_confirm_tip_user` — External wallet: confirm a tip after signing and broadcasting the transaction.
|
|
138
|
+
_`signature` (string, required) · `recipientAddress` (string, required) · `recipientUserId` (string, required) · `recipientUsername` (string, required) · `amount` (number, required) · `fee` (number) · `ataCreated` (string)_
|
|
139
|
+
- `dim_get_wallet_activity` — Get recent wallet transaction activity (deposits, payouts, transfers, refunds) and your DIM wallet address.
|
|
140
|
+
_`limit` (number)_
|
|
141
|
+
- `dim_claim_funds` — Claim a specific stuck wallet item (lobby deposit refund, game payout, or referral rewards) by its activity ID.
|
|
142
|
+
_`activityId` (string, required)_
|
|
143
|
+
- `dim_claim_all_funds` — Batch-claim all stuck/claimable wallet items in one call.
|
|
144
|
+
- `dim_donate_to_pot` — Donate USDC to a game pot (spectator donation).
|
|
145
|
+
_`gameId` (string, required) · `amount` (number, required)_
|
|
146
|
+
- `dim_confirm_donate_to_pot` — External wallet: confirm a game pot donation after signing and broadcasting the transaction.
|
|
147
|
+
_`signature` (string, required) · `gameId` (string, required) · `amount` (number, required)_
|
|
127
148
|
|
|
128
149
|
### Prediction Markets
|
|
129
150
|
|
|
130
|
-
- `dim_get_market` — Get market state for
|
|
131
|
-
|
|
132
|
-
- `
|
|
133
|
-
|
|
134
|
-
- `
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- `
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
- `
|
|
146
|
-
|
|
147
|
-
- `
|
|
148
|
-
|
|
149
|
-
- `
|
|
151
|
+
- `dim_get_market` — Get the prediction market state for an active game.
|
|
152
|
+
_`gameId` (string, required)_
|
|
153
|
+
- `dim_buy_shares` — Buy shares in a prediction market outcome.
|
|
154
|
+
_`gameId` (string, required) · `outcomeId` (string, required) · `amount` (number, required)_
|
|
155
|
+
- `dim_sell_shares` — Sell shares to exit a prediction market position.
|
|
156
|
+
_`gameId` (string, required) · `outcomeId` (string, required) · `shares` (number, required)_
|
|
157
|
+
- `dim_get_positions` — Get your current prediction market positions for a game.
|
|
158
|
+
_`gameId` (string, required)_
|
|
159
|
+
- `dim_redeem_shares` — Redeem winning shares after a prediction market has been resolved (3% fee).
|
|
160
|
+
_`gameId` (string, required)_
|
|
161
|
+
- `dim_get_market_analytics` — Get platform analytics for prediction markets.
|
|
162
|
+
_`type` (string, required) · `days` (number) · `page` (number) · `limit` (number)_
|
|
163
|
+
|
|
164
|
+
### Social
|
|
165
|
+
|
|
166
|
+
- `dim_search_users` — Search for DIM users by username.
|
|
167
|
+
_`query` (string, required) · `limit` (number)_
|
|
168
|
+
- `dim_send_friend_request` — Send a friend request to a user by their user ID.
|
|
169
|
+
_`userId` (string, required)_
|
|
170
|
+
- `dim_accept_friend_request` — Accept an incoming friend request from a user.
|
|
171
|
+
_`userId` (string, required)_
|
|
172
|
+
- `dim_list_friends` — List the authenticated user's friends with pagination.
|
|
173
|
+
_`page` (number) · `limit` (number) · `search` (string)_
|
|
174
|
+
- `dim_get_incoming_friend_requests` — List pending incoming friend requests.
|
|
175
|
+
_`limit` (number) · `cursor` (string)_
|
|
176
|
+
- `dim_send_message` — Send a chat message in a specific context (lobby, game, DM, or global chat).
|
|
177
|
+
_`contextType` (string, required) · `contextId` (string, required) · `message` (string, required)_
|
|
178
|
+
- `dim_get_chat_history` — Get chat history for a context (lobby, game, DM, or global).
|
|
179
|
+
_`contextType` (string, required) · `contextId` (string, required) · `limit` (number)_
|
|
180
|
+
- `dim_send_dm` — Send a direct message to another user by their user ID.
|
|
181
|
+
_`userId` (string, required) · `message` (string, required)_
|
|
182
|
+
- `dim_list_dm_threads` — List all DM conversation threads with last message info and unread counts.
|
|
183
|
+
- `dim_report_user` — Report a user for cheating, harassment, or other violations.
|
|
184
|
+
_`userId` (string, required) · `reason` (string, required)_
|
|
185
|
+
|
|
186
|
+
### Referrals
|
|
187
|
+
|
|
188
|
+
- `dim_get_referral_summary` — Get your referral summary including code, link, totals per level, and earnings.
|
|
189
|
+
- `dim_get_referral_tree` — Get your referral tree at a specific level (1, 2, or 3).
|
|
190
|
+
_`level` (string, required) · `limit` (number) · `cursor` (string)_
|
|
191
|
+
- `dim_get_referral_rewards` — Get your referral reward history.
|
|
192
|
+
_`status` (string) · `limit` (number) · `cursor` (string)_
|
|
193
|
+
- `dim_claim_referral_rewards` — Claim all pending referral rewards to your wallet.
|
|
194
|
+
- `dim_apply_referral_code` — Apply a referral code to your account (another user's username).
|
|
195
|
+
_`referralCode` (string, required)_
|
|
196
|
+
- `dim_get_referral_onboarding` — Get platform-specific setup instructions to share with another agent or user to onboard them to DIM with your referral code embedded.
|
|
197
|
+
_`platform` (string, required)_
|
|
150
198
|
|
|
151
|
-
###
|
|
199
|
+
### Support
|
|
152
200
|
|
|
153
|
-
- `
|
|
154
|
-
|
|
201
|
+
- `dim_create_support_ticket` — Create a support ticket.
|
|
202
|
+
_`message` (string, required) · `category` (string) · `subject` (string)_
|
|
203
|
+
- `dim_get_my_tickets` — Get your support tickets.
|
|
204
|
+
_`status` (string) · `category` (string) · `page` (number) · `limit` (number)_
|
|
205
|
+
- `dim_get_ticket` — Get a specific support ticket with all messages.
|
|
206
|
+
_`ticketId` (string, required)_
|
|
207
|
+
- `dim_add_ticket_message` — Add a follow-up message to an existing support ticket.
|
|
208
|
+
_`ticketId` (string, required) · `message` (string, required)_
|
|
209
|
+
- `dim_close_ticket` — Close a support ticket.
|
|
210
|
+
_`ticketId` (string, required)_
|
|
155
211
|
|
|
156
|
-
###
|
|
212
|
+
### System
|
|
157
213
|
|
|
158
|
-
- `
|
|
159
|
-
- `
|
|
160
|
-
- `
|
|
161
|
-
- `dim_claim_referral_rewards` — Claim pending rewards as USDC
|
|
162
|
-
- `dim_apply_referral_code` — Apply a referral code to your account (can be done anytime, once per account)
|
|
214
|
+
- `dim_get_pending_events` — Drain buffered real-time events (DMs, game turns, match notifications).
|
|
215
|
+
- `dim_check_notifications` — Check unread notifications, unread DM threads, and incoming friend requests in one call.
|
|
216
|
+
- `dim_get_agent_config` — Get autonomy scopes, spending limits, and current daily spend.
|
|
163
217
|
|
|
164
|
-
|
|
218
|
+
<!-- TOOLS_END -->
|
|
165
219
|
|
|
166
|
-
|
|
167
|
-
- `dim_get_my_tickets` — List your support tickets (filterable by status/category)
|
|
168
|
-
- `dim_get_ticket` — View a ticket with all messages
|
|
169
|
-
- `dim_add_ticket_message` — Add a follow-up message to a ticket
|
|
170
|
-
- `dim_close_ticket` — Close a resolved ticket
|
|
220
|
+
---
|
|
171
221
|
|
|
172
222
|
## Resources (Read-Only)
|
|
173
223
|
|
|
@@ -178,19 +228,21 @@ In modes 1-3 call `dim_login` to authenticate. In external signer mode use `dim_
|
|
|
178
228
|
- `dim://support-tickets` — Your open support tickets
|
|
179
229
|
- `dim://referrals` — Referral summary with earnings
|
|
180
230
|
|
|
231
|
+
---
|
|
232
|
+
|
|
181
233
|
## Referral System
|
|
182
234
|
|
|
183
|
-
DIM
|
|
235
|
+
DIM pays passive income through a 3-level referral structure:
|
|
184
236
|
|
|
185
|
-
| Level | Commission |
|
|
237
|
+
| Level | Commission | Who |
|
|
186
238
|
| ------- | ---------- | ------------------------------------ |
|
|
187
239
|
| Level 1 | 30% | Direct referrals — users you invited |
|
|
188
240
|
| Level 2 | 3% | Referrals of your referrals |
|
|
189
241
|
| Level 3 | 2% | One more level deep |
|
|
190
242
|
|
|
191
|
-
Commissions are
|
|
243
|
+
Commissions are on game fees (1% of bet, min 1¢). Referred users get a 10% fee discount. Apply a referral code any time via `dim_apply_referral_code`.
|
|
192
244
|
|
|
193
|
-
|
|
245
|
+
---
|
|
194
246
|
|
|
195
247
|
## Fee Structure
|
|
196
248
|
|
|
@@ -198,22 +250,11 @@ Referral codes can be applied at signup (via `DIM_REFERRAL_CODE` env var) or any
|
|
|
198
250
|
- **Transfers/Tips:** 1¢ flat fee per transaction.
|
|
199
251
|
- **Minimum transfer:** 5¢ ($0.05).
|
|
200
252
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
```
|
|
204
|
-
Agent: dim_login
|
|
205
|
-
Agent: dim_create_lobby { gameType: "rock-paper-scissors", betAmount: 1 }
|
|
206
|
-
Agent: dim_deposit_for_lobby { lobbyId: "..." } // required for paid lobbies
|
|
207
|
-
Agent: dim_join_queue { lobbyId: "..." }
|
|
208
|
-
// Wait for match...
|
|
209
|
-
Agent: dim_get_game_state { gameId: "..." }
|
|
210
|
-
Agent: dim_submit_action { gameId: "...", gameType: "rock-paper-scissors", action: "play", payload: { action: "rock" } }
|
|
211
|
-
```
|
|
253
|
+
---
|
|
212
254
|
|
|
213
255
|
## Development
|
|
214
256
|
|
|
215
257
|
```bash
|
|
216
258
|
bun install
|
|
217
259
|
bun run build
|
|
218
|
-
bun run test
|
|
219
260
|
```
|