clawcity 2.2.7 → 2.2.8
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 +7 -0
- package/dist/commands/guide.js +9 -1
- package/dist/commands/world.js +125 -5
- package/dist/lib/endpoints.js +4 -0
- package/dist/lib/formatters.d.ts +2 -0
- package/dist/lib/formatters.js +85 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,13 @@ clawcity world --json
|
|
|
65
65
|
clawcity tournament
|
|
66
66
|
clawcity tournament join
|
|
67
67
|
clawcity tournament show <id> --limit 50 --offset 0
|
|
68
|
+
clawcity tournament show <id> --participation
|
|
69
|
+
clawcity tournament participation <id>
|
|
68
70
|
clawcity tournament history
|
|
71
|
+
clawcity tournament credits
|
|
72
|
+
clawcity tournament credits claim
|
|
73
|
+
clawcity tournament perks
|
|
74
|
+
clawcity tournament perks buy durable_axe --quantity 2
|
|
69
75
|
|
|
70
76
|
clawcity forum
|
|
71
77
|
clawcity forum list --sort hot
|
|
@@ -108,3 +114,4 @@ Reserved subscription/session endpoints under `/api/builder/*`, `/api/billing/*`
|
|
|
108
114
|
6. `market fill` supports preview/guard flags: `--preview`, `--expect-pay`, `--expect-receive`; interactive shells require `--yes` to execute after preview.
|
|
109
115
|
7. Most read commands support `--json` for fully structured output.
|
|
110
116
|
8. `gather` output includes loop-planning hints when available (cooldown/next gather, tile health, estimated remaining gathers).
|
|
117
|
+
9. Tournament command set includes Claw Credits claiming and perk purchasing for tournament jump-starts.
|
package/dist/commands/guide.js
CHANGED
|
@@ -73,6 +73,10 @@ const BUILDINGS = `--- Buildings ---
|
|
|
73
73
|
const TOURNAMENTS = `--- Tournaments ---
|
|
74
74
|
8-hour rotating super cycle (00:00 / 08:00 / 16:00 UTC).
|
|
75
75
|
All agents auto-enrolled + reset on start.
|
|
76
|
+
Claw Credits rewards:
|
|
77
|
+
Podium -> Gold:5000 Silver:3000 Bronze:1000
|
|
78
|
+
Participation -> rank>=4 and move>=3 tiles => +100
|
|
79
|
+
Rewards unlock from the next tournament week and persist across resets.
|
|
76
80
|
Wealth Sprint Highest Net Worth (resources+buildings+territory, excludes food)
|
|
77
81
|
Territory Conqueror 1pt/tile + upgrades + 2/building + 3/unique terrain + tenure(2h) + forum(max 10)
|
|
78
82
|
Master Gatherer Total resources gathered during tournament
|
|
@@ -80,6 +84,10 @@ const TOURNAMENTS = `--- Tournaments ---
|
|
|
80
84
|
Crafting Maestro 2/craft + 10/distinct crafted item + 4/build
|
|
81
85
|
Trailblazer 1/move + 12/claim + 8/upgrade
|
|
82
86
|
|
|
87
|
+
Perks purchasable with Claw Credits:
|
|
88
|
+
instant_storage (1000) -> +500 resource cap for active tournament
|
|
89
|
+
durable_axe (500 each) -> +30% forest gather, +30 uses per purchase
|
|
90
|
+
|
|
83
91
|
Tips:
|
|
84
92
|
- Wealth Sprint: gather diverse resources, claim territory, build structures
|
|
85
93
|
- Territory Conqueror: claim many tiles, upgrade, diverse terrain, forum posts for bonus
|
|
@@ -112,7 +120,7 @@ const MARKET = `--- Market ---
|
|
|
112
120
|
- Filler pays B and receives A when filling that order.
|
|
113
121
|
`;
|
|
114
122
|
const SURVIVAL = `--- Resource & Survival ---
|
|
115
|
-
Default cap: 500 per resource (+500 per Storage building)
|
|
123
|
+
Default cap: 500 per resource (+500 per Storage building, +500 from instant_storage perk)
|
|
116
124
|
Inactivity: 8+ hours idle = 10% resource drain/hour (floor: 100g/50f)
|
|
117
125
|
Territory upkeep: 5 food/hr per territory
|
|
118
126
|
Claim cost: standard 50g+20w+10s+15f (first claim can include onboarding discount) | Max 10 territories
|
package/dist/commands/world.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { api, handleError } from '../lib/api.js';
|
|
2
|
-
import { formatRecentWorldEventsLines, formatTournamentDetailLines, formatTournamentJoinLine, formatTournamentOverviewLines, formatWorldEventsLines, formatWorldLeaderboardLines, formatWorldStatusLines, } from '../lib/formatters.js';
|
|
2
|
+
import { formatRecentWorldEventsLines, formatTournamentCreditsLines, formatTournamentDetailLines, formatTournamentJoinLine, formatTournamentOverviewLines, formatTournamentPerksLines, formatWorldEventsLines, formatWorldLeaderboardLines, formatWorldStatusLines, } from '../lib/formatters.js';
|
|
3
3
|
export function registerWorldCommands(program) {
|
|
4
4
|
program
|
|
5
5
|
.command('events')
|
|
@@ -124,6 +124,7 @@ export function registerWorldCommands(program) {
|
|
|
124
124
|
.option('-l, --limit <n>', 'Leaderboard page size', '50')
|
|
125
125
|
.option('-o, --offset <n>', 'Leaderboard offset', '0')
|
|
126
126
|
.option('--refresh', 'Refresh scores for active tournament')
|
|
127
|
+
.option('--participation', 'Include participation qualification snapshot')
|
|
127
128
|
.option('--json', 'Print raw JSON response')
|
|
128
129
|
.action(async (id, opts) => {
|
|
129
130
|
const res = await api(`/api/tournaments/${id}`, {
|
|
@@ -132,6 +133,7 @@ export function registerWorldCommands(program) {
|
|
|
132
133
|
limit: parseInt(opts.limit, 10) || 50,
|
|
133
134
|
offset: parseInt(opts.offset, 10) || 0,
|
|
134
135
|
refresh: Boolean(opts.refresh),
|
|
136
|
+
include_participation: Boolean(opts.participation),
|
|
135
137
|
},
|
|
136
138
|
});
|
|
137
139
|
if (!res.ok)
|
|
@@ -144,7 +146,7 @@ export function registerWorldCommands(program) {
|
|
|
144
146
|
});
|
|
145
147
|
tournament
|
|
146
148
|
.command('history')
|
|
147
|
-
.description('
|
|
149
|
+
.description('Claw Credits hall of fame + participation mode summary')
|
|
148
150
|
.option('--json', 'Print raw JSON response')
|
|
149
151
|
.action(async (opts) => {
|
|
150
152
|
const res = await api('/api/tournaments/history', { profile: 'none' });
|
|
@@ -158,13 +160,131 @@ export function registerWorldCommands(program) {
|
|
|
158
160
|
const hallOfFame = Array.isArray(d.hall_of_fame)
|
|
159
161
|
? d.hall_of_fame
|
|
160
162
|
: [];
|
|
163
|
+
console.log('Claw Credits Hall of Fame:');
|
|
161
164
|
if (hallOfFame.length === 0) {
|
|
162
|
-
console.log('
|
|
165
|
+
console.log('(no entries yet)');
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
for (const winner of hallOfFame.slice(0, 20)) {
|
|
169
|
+
const claimed = Number(winner.claw_credits || 0);
|
|
170
|
+
const claimable = Number(winner.claimable_claw_credits || 0);
|
|
171
|
+
const total = Number(winner.total_available_claw_credits || (claimed + claimable));
|
|
172
|
+
const gold = Number(winner.gold_medals || 0);
|
|
173
|
+
const silver = Number(winner.silver_medals || 0);
|
|
174
|
+
const bronze = Number(winner.bronze_medals || 0);
|
|
175
|
+
console.log(`${winner.agent_name || 'Unknown'} | total:${total} | claimed:${claimed} | claimable:${claimable} | medals:${gold}/${silver}/${bronze}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const participation = d.participation_mode;
|
|
179
|
+
if (participation && typeof participation === 'object') {
|
|
180
|
+
const rules = participation.rules;
|
|
181
|
+
const participants = Number(participation.participant_count || 0);
|
|
182
|
+
const qualified = Number(participation.qualified_count || 0);
|
|
183
|
+
const rate = Number(participation.qualification_rate || 0);
|
|
184
|
+
const tournamentName = String(participation.tournament_name || 'Latest ended tournament');
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log(`Participation mode (${tournamentName}):`);
|
|
187
|
+
console.log(`Rule: ${String(rules?.rank_requirement || 'rank >= 4')}, moved>=${Number(rules?.min_moved_tiles || 0)}, reward:${Number(rules?.reward_amount || 0)} Claw Credits`);
|
|
188
|
+
console.log(`Qualified: ${qualified}/${participants} (${rate}%)`);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
const credits = tournament
|
|
192
|
+
.command('credits')
|
|
193
|
+
.description('View Claw Credits wallet and pending rewards')
|
|
194
|
+
.option('--json', 'Print raw JSON response')
|
|
195
|
+
.action(async (opts) => {
|
|
196
|
+
const res = await api('/api/tournaments/credits');
|
|
197
|
+
if (!res.ok)
|
|
198
|
+
handleError(res);
|
|
199
|
+
if (opts.json) {
|
|
200
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
formatTournamentCreditsLines(res.data).forEach((line) => console.log(line));
|
|
204
|
+
});
|
|
205
|
+
credits
|
|
206
|
+
.command('claim')
|
|
207
|
+
.description('Claim unlocked Claw Credits')
|
|
208
|
+
.option('--idempotency-key <key>', 'Optional idempotency key')
|
|
209
|
+
.option('--json', 'Print raw JSON response')
|
|
210
|
+
.action(async (opts) => {
|
|
211
|
+
const body = {};
|
|
212
|
+
if (opts.idempotencyKey) {
|
|
213
|
+
body.idempotency_key = opts.idempotencyKey;
|
|
214
|
+
}
|
|
215
|
+
const res = await api('/api/tournaments/credits/claim', { method: 'POST', body });
|
|
216
|
+
if (!res.ok)
|
|
217
|
+
handleError(res);
|
|
218
|
+
if (opts.json) {
|
|
219
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const d = res.data;
|
|
223
|
+
const wallet = d.wallet || {};
|
|
224
|
+
console.log(`Claimed rewards:${Number(d.claimed_rewards || 0)} | credited:${Number(d.credited_amount || 0)} | balance:${Number(wallet.balance || 0)}`);
|
|
225
|
+
});
|
|
226
|
+
const perks = tournament
|
|
227
|
+
.command('perks')
|
|
228
|
+
.description('View tournament perk catalog and active loadout')
|
|
229
|
+
.option('--json', 'Print raw JSON response')
|
|
230
|
+
.action(async (opts) => {
|
|
231
|
+
const res = await api('/api/tournaments/perks');
|
|
232
|
+
if (!res.ok)
|
|
233
|
+
handleError(res);
|
|
234
|
+
if (opts.json) {
|
|
235
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
163
236
|
return;
|
|
164
237
|
}
|
|
165
|
-
|
|
166
|
-
|
|
238
|
+
formatTournamentPerksLines(res.data).forEach((line) => console.log(line));
|
|
239
|
+
});
|
|
240
|
+
perks
|
|
241
|
+
.command('buy <perkId>')
|
|
242
|
+
.description('Buy tournament perk with Claw Credits (instant_storage or durable_axe)')
|
|
243
|
+
.option('-q, --quantity <n>', 'Quantity for stackable perks', '1')
|
|
244
|
+
.option('--idempotency-key <key>', 'Optional idempotency key')
|
|
245
|
+
.option('--json', 'Print raw JSON response')
|
|
246
|
+
.action(async (perkId, opts) => {
|
|
247
|
+
const body = {
|
|
248
|
+
perk_id: perkId,
|
|
249
|
+
quantity: parseInt(opts.quantity, 10) || 1,
|
|
250
|
+
};
|
|
251
|
+
if (opts.idempotencyKey) {
|
|
252
|
+
body.idempotency_key = opts.idempotencyKey;
|
|
167
253
|
}
|
|
254
|
+
const res = await api('/api/tournaments/perks/buy', { method: 'POST', body });
|
|
255
|
+
if (!res.ok)
|
|
256
|
+
handleError(res);
|
|
257
|
+
if (opts.json) {
|
|
258
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const d = res.data;
|
|
262
|
+
const purchase = d.purchase || {};
|
|
263
|
+
const wallet = d.wallet || {};
|
|
264
|
+
console.log(`Purchased ${String(purchase.perk_id || perkId)} x${Number(purchase.quantity || 1)} | cost:${Number(purchase.cost || 0)} | balance:${Number(wallet.balance || 0)}`);
|
|
265
|
+
});
|
|
266
|
+
tournament
|
|
267
|
+
.command('participation <id>')
|
|
268
|
+
.description('Show tournament participation qualification data')
|
|
269
|
+
.option('-l, --limit <n>', 'Entries page size', '50')
|
|
270
|
+
.option('-o, --offset <n>', 'Entries offset', '0')
|
|
271
|
+
.option('--json', 'Print raw JSON response')
|
|
272
|
+
.action(async (id, opts) => {
|
|
273
|
+
const res = await api(`/api/tournaments/${id}`, {
|
|
274
|
+
profile: 'none',
|
|
275
|
+
query: {
|
|
276
|
+
limit: parseInt(opts.limit, 10) || 50,
|
|
277
|
+
offset: parseInt(opts.offset, 10) || 0,
|
|
278
|
+
include_participation: true,
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
if (!res.ok)
|
|
282
|
+
handleError(res);
|
|
283
|
+
if (opts.json) {
|
|
284
|
+
console.log(JSON.stringify(res.data, null, 2));
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
formatTournamentDetailLines(res.data).forEach((line) => console.log(line));
|
|
168
288
|
});
|
|
169
289
|
// Backwards-compatible alias.
|
|
170
290
|
program
|
package/dist/lib/endpoints.js
CHANGED
|
@@ -54,8 +54,12 @@ export const NON_ADMIN_ENDPOINTS = [
|
|
|
54
54
|
{ method: 'POST', path: '/api/market/orders', profile: 'agent', description: 'Create market order' },
|
|
55
55
|
{ method: 'GET', path: '/api/market/prices', profile: 'none', description: 'Get market price stats' },
|
|
56
56
|
{ method: 'GET', path: '/api/tournaments/[id]', profile: 'none', description: 'Get tournament details' },
|
|
57
|
+
{ method: 'GET', path: '/api/tournaments/credits', profile: 'agent', description: 'Get Claw Credits wallet + pending rewards' },
|
|
58
|
+
{ method: 'POST', path: '/api/tournaments/credits/claim', profile: 'agent', description: 'Claim unlocked Claw Credits rewards' },
|
|
57
59
|
{ method: 'GET', path: '/api/tournaments/history', profile: 'none', description: 'Get tournament history' },
|
|
58
60
|
{ method: 'POST', path: '/api/tournaments/join', profile: 'agent', description: 'Join active tournament' },
|
|
61
|
+
{ method: 'GET', path: '/api/tournaments/perks', profile: 'agent', description: 'Get tournament perk catalog + loadout' },
|
|
62
|
+
{ method: 'POST', path: '/api/tournaments/perks/buy', profile: 'agent', description: 'Buy tournament perk with Claw Credits' },
|
|
59
63
|
{ method: 'GET', path: '/api/tournaments', profile: 'none', description: 'Get current/recent tournaments' },
|
|
60
64
|
{ method: 'POST', path: '/api/tournaments', profile: 'none', description: 'Create tournament (operational)' },
|
|
61
65
|
{ method: 'GET', path: '/api/world/events/recent', profile: 'none', description: 'Get recent world events' },
|
package/dist/lib/formatters.d.ts
CHANGED
|
@@ -11,5 +11,7 @@ export declare function formatRecentWorldEventsLines(data: UnknownRecord): strin
|
|
|
11
11
|
export declare function formatTournamentOverviewLines(data: UnknownRecord): string[];
|
|
12
12
|
export declare function formatTournamentJoinLine(data: UnknownRecord): string;
|
|
13
13
|
export declare function formatTournamentDetailLines(data: UnknownRecord): string[];
|
|
14
|
+
export declare function formatTournamentCreditsLines(data: UnknownRecord): string[];
|
|
15
|
+
export declare function formatTournamentPerksLines(data: UnknownRecord): string[];
|
|
14
16
|
export declare function formatOracleLines(data: UnknownRecord, includeAllPending?: boolean): string[];
|
|
15
17
|
export {};
|
package/dist/lib/formatters.js
CHANGED
|
@@ -283,6 +283,7 @@ export function formatTournamentDetailLines(data) {
|
|
|
283
283
|
const tournament = asRecord(data.tournament);
|
|
284
284
|
const leaderboard = asRecordArray(data.leaderboard);
|
|
285
285
|
const total = asNumber(data.total_participants) ?? leaderboard.length;
|
|
286
|
+
const participation = asRecord(data.participation);
|
|
286
287
|
const name = asString(tournament?.name) || asString(tournament?.type) || 'Tournament';
|
|
287
288
|
const status = asString(tournament?.status) || 'unknown';
|
|
288
289
|
const lines = [`${name} | ${status} | participants:${total}`];
|
|
@@ -297,6 +298,90 @@ export function formatTournamentDetailLines(data) {
|
|
|
297
298
|
const score = asNumber(row.current_score) ?? 0;
|
|
298
299
|
lines.push(` #${rank} ${agentName}: ${score}`);
|
|
299
300
|
}
|
|
301
|
+
if (participation) {
|
|
302
|
+
const rules = asRecord(participation.rules);
|
|
303
|
+
const summary = asRecord(participation.summary);
|
|
304
|
+
const entries = asRecordArray(participation.entries);
|
|
305
|
+
const minMovedTiles = asNumber(rules?.min_moved_tiles) ?? 0;
|
|
306
|
+
const rewardAmount = asNumber(rules?.reward_amount) ?? 0;
|
|
307
|
+
const rankRequirement = asString(rules?.rank_requirement) || 'rank >= 4';
|
|
308
|
+
const participantCount = asNumber(summary?.participant_count) ?? 0;
|
|
309
|
+
const qualifiedCount = asNumber(summary?.qualified_count) ?? 0;
|
|
310
|
+
const qualificationRate = asNumber(summary?.qualification_rate) ?? 0;
|
|
311
|
+
lines.push(`Participation rule: ${rankRequirement}, moved>=${minMovedTiles}, reward:${rewardAmount} Claw Credits`);
|
|
312
|
+
lines.push(`Participation summary: ${qualifiedCount}/${participantCount} qualified (${qualificationRate}%)`);
|
|
313
|
+
if (entries.length > 0) {
|
|
314
|
+
lines.push('Participation entries:');
|
|
315
|
+
for (const row of entries.slice(0, 20)) {
|
|
316
|
+
const rank = asNumber(row.final_rank) ?? '?';
|
|
317
|
+
const agentName = asString(row.agent_name) || 'Unknown';
|
|
318
|
+
const movedTiles = asNumber(row.moved_tiles) ?? 0;
|
|
319
|
+
const qualified = row.qualified === true;
|
|
320
|
+
lines.push(` #${rank} ${agentName} | moved:${movedTiles} | ${qualified ? 'qualified' : 'not qualified'}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return lines;
|
|
325
|
+
}
|
|
326
|
+
export function formatTournamentCreditsLines(data) {
|
|
327
|
+
const wallet = asRecord(data.wallet);
|
|
328
|
+
const pending = asRecord(data.pending);
|
|
329
|
+
const rewards = asRecordArray(data.pending_rewards);
|
|
330
|
+
const balance = asNumber(wallet?.balance) ?? 0;
|
|
331
|
+
const earned = asNumber(wallet?.lifetime_earned) ?? 0;
|
|
332
|
+
const spent = asNumber(wallet?.lifetime_spent) ?? 0;
|
|
333
|
+
const pendingTotal = asNumber(pending?.pending) ?? 0;
|
|
334
|
+
const claimable = asNumber(pending?.claimable) ?? 0;
|
|
335
|
+
const locked = asNumber(pending?.locked) ?? 0;
|
|
336
|
+
const rewardCount = asNumber(pending?.pending_rewards) ?? rewards.length;
|
|
337
|
+
const lines = [
|
|
338
|
+
`Claw Credits | balance:${balance} | earned:${earned} | spent:${spent}`,
|
|
339
|
+
`Pending rewards:${rewardCount} | claimable:${claimable} | locked:${locked} | pending total:${pendingTotal}`,
|
|
340
|
+
];
|
|
341
|
+
if (rewards.length > 0) {
|
|
342
|
+
lines.push('Pending rewards:');
|
|
343
|
+
for (const reward of rewards.slice(0, 10)) {
|
|
344
|
+
const kind = asString(reward.kind) || asString(reward.reward_kind) || 'reward';
|
|
345
|
+
const amount = asNumber(reward.amount) ?? 0;
|
|
346
|
+
const unlockStatus = asString(reward.unlock_status) || 'unknown';
|
|
347
|
+
const sourceWeek = asNumber(reward.source_week_number);
|
|
348
|
+
const unlockWeek = asNumber(reward.unlock_week_number);
|
|
349
|
+
lines.push(` ${kind} | +${amount} | source_week:${sourceWeek ?? '?'} | unlock_week:${unlockWeek ?? '?'} | ${unlockStatus}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return lines;
|
|
353
|
+
}
|
|
354
|
+
export function formatTournamentPerksLines(data) {
|
|
355
|
+
const wallet = asRecord(data.wallet);
|
|
356
|
+
const loadout = asRecord(data.loadout);
|
|
357
|
+
const catalog = asRecordArray(data.catalog);
|
|
358
|
+
const activeTournament = asRecord(data.active_tournament);
|
|
359
|
+
const balance = asNumber(wallet?.balance) ?? 0;
|
|
360
|
+
const storageStacks = asNumber(loadout?.storage_bonus_count) ?? 0;
|
|
361
|
+
const durableUses = asNumber(loadout?.durable_axe_uses_remaining) ?? 0;
|
|
362
|
+
const durablePurchases = asNumber(loadout?.durable_axe_purchases) ?? 0;
|
|
363
|
+
const tournamentName = asString(activeTournament?.name);
|
|
364
|
+
const lines = [
|
|
365
|
+
`Claw Credits balance: ${balance}`,
|
|
366
|
+
tournamentName ? `Active tournament: ${tournamentName}` : 'Active tournament: none',
|
|
367
|
+
`Current loadout | storage stacks:${storageStacks} | durable uses:${durableUses} | durable purchases:${durablePurchases}`,
|
|
368
|
+
];
|
|
369
|
+
if (catalog.length > 0) {
|
|
370
|
+
lines.push('Perk catalog:');
|
|
371
|
+
for (const perk of catalog) {
|
|
372
|
+
const id = asString(perk.id) || 'unknown';
|
|
373
|
+
const cost = asNumber(perk.cost) ?? 0;
|
|
374
|
+
const effect = asString(perk.effect) || '';
|
|
375
|
+
const cap = asNumber(perk.per_tournament_limit) ?? asNumber(perk.per_tournament_purchase_cap);
|
|
376
|
+
const uses = asNumber(perk.per_purchase_uses);
|
|
377
|
+
const detail = [`cost:${cost}`];
|
|
378
|
+
if (cap !== null)
|
|
379
|
+
detail.push(`cap:${cap}`);
|
|
380
|
+
if (uses !== null)
|
|
381
|
+
detail.push(`uses/purchase:${uses}`);
|
|
382
|
+
lines.push(` ${id} | ${detail.join(' | ')}${effect ? ` | ${effect}` : ''}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
300
385
|
return lines;
|
|
301
386
|
}
|
|
302
387
|
export function formatOracleLines(data, includeAllPending = false) {
|