madeonsol-x402 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -475,6 +475,17 @@ export interface WebhookTestResult {
475
475
  status_code?: number;
476
476
  response_time_ms: number;
477
477
  error?: string;
478
+ /** Which event type the sample delivery used. Returned by servers from 2026-09-25 on. */
479
+ event?: string;
480
+ }
481
+ /** Options for `testWebhook`. */
482
+ export interface WebhookTestOptions {
483
+ /**
484
+ * Which of the webhook's subscribed events to sample (sent as `event`).
485
+ * Omit it to sample the first subscribed event. An event the webhook is not
486
+ * subscribed to is answered with 400.
487
+ */
488
+ event?: WebhookEvent | (string & {});
478
489
  }
479
490
  export interface StreamToken {
480
491
  token: string;
@@ -1253,20 +1264,58 @@ export interface CopyTradeSubscription {
1253
1264
  sizing_amount: number;
1254
1265
  delivery_mode: CopyTradeDeliveryMode;
1255
1266
  webhook_url: string | null;
1267
+ /** Market-cap band (USD) on the source trade; `null` = no bound. */
1268
+ min_mc_usd: number | null;
1269
+ max_mc_usd: number | null;
1256
1270
  is_active: boolean;
1257
1271
  created_at: string;
1258
1272
  updated_at?: string;
1273
+ /**
1274
+ * Source wallets that are tracked KOL wallets (can produce signals), read at
1275
+ * response time. `null` when the tracking lookup failed (see `warnings`).
1276
+ * Returned by servers from 2026-09-25 on; absent on older ones.
1277
+ */
1278
+ source_wallets_tracked?: string[] | null;
1279
+ /** Source wallets that are NOT tracked KOL wallets: they never produce a signal. */
1280
+ source_wallets_untracked?: string[] | null;
1281
+ /** Present when at least one wallet is untracked, or tracking could not be determined. */
1282
+ warnings?: CopyTradeRuleWarning[];
1283
+ }
1284
+ /** A non-fatal note on a copy-trade rule. The rule is saved unchanged. */
1285
+ export interface CopyTradeRuleWarning {
1286
+ code: "untracked_source_wallets" | "source_wallet_tracking_unavailable" | (string & {});
1287
+ message: string;
1259
1288
  }
1289
+ /**
1290
+ * Create body for POST /copytrade/subscriptions.
1291
+ *
1292
+ * `source_wallets`: the per-rule limit is set by your tier and enforced by the
1293
+ * server (Pro 5, Ultra 50, Business and Enterprise 250; `GET /me` reports
1294
+ * yours as `copytrade_wallets_per_rule`). Signals fire only for trades by
1295
+ * wallets MadeOnSol tracks as KOLs (`GET /kol/wallets`). Any valid Solana
1296
+ * address is accepted into a rule, but an untracked wallet never produces a signal.
1297
+ */
1260
1298
  export interface CopyTradeCreateParams {
1261
1299
  name?: string;
1262
1300
  source_wallets: string[];
1263
1301
  min_trade_sol?: number;
1302
+ /** Default `"buy"` (server side) when omitted. */
1264
1303
  only_action?: CopyTradeAction;
1304
+ /** `proportional` and `percent_source` are the same maths: source size × `sizing_amount`. */
1265
1305
  sizing_mode?: CopyTradeSizingMode;
1306
+ /** SOL when `fixed`; otherwise a multiplier / fraction (0.25 = a quarter of the source size), never a percent. */
1266
1307
  sizing_amount: number;
1267
1308
  delivery_mode?: CopyTradeDeliveryMode;
1268
1309
  webhook_url?: string;
1310
+ /**
1311
+ * Market-cap band (USD, 0 to 1e12, min ≤ max) on the source trade's market
1312
+ * cap at trade time. When either bound is set, trades with an unknown market
1313
+ * cap are dropped.
1314
+ */
1315
+ min_mc_usd?: number | null;
1316
+ max_mc_usd?: number | null;
1269
1317
  }
1318
+ /** PATCH body. Omit a field to leave it unchanged; pass `null` to clear an MC bound. */
1270
1319
  export interface CopyTradeUpdateParams {
1271
1320
  name?: string | null;
1272
1321
  source_wallets?: string[];
@@ -1277,12 +1326,30 @@ export interface CopyTradeUpdateParams {
1277
1326
  delivery_mode?: CopyTradeDeliveryMode;
1278
1327
  webhook_url?: string | null;
1279
1328
  is_active?: boolean;
1329
+ min_mc_usd?: number | null;
1330
+ max_mc_usd?: number | null;
1280
1331
  }
1281
1332
  export interface CopyTradeCreateResponse {
1282
1333
  subscription: CopyTradeSubscription;
1283
1334
  /** Returned ONCE on creation when `webhook_url` is set — store it to verify HMAC signatures. */
1284
1335
  webhook_secret: string | null;
1285
1336
  note?: string;
1337
+ /** Same as `subscription.warnings`, repeated at top level when present. */
1338
+ warnings?: CopyTradeRuleWarning[];
1339
+ }
1340
+ /** Response of PATCH /copytrade/subscriptions/{id} (and GET of one rule). */
1341
+ export interface CopyTradeUpdateResponse {
1342
+ subscription: CopyTradeSubscription;
1343
+ /** Same as `subscription.warnings`, repeated at top level when present. */
1344
+ warnings?: CopyTradeRuleWarning[];
1345
+ /**
1346
+ * Returned ONCE, only when this PATCH set a `webhook_url` on a rule that had
1347
+ * no signing secret yet (for example a websocket-only rule). Store it. An
1348
+ * existing secret is never rotated or re-shown.
1349
+ */
1350
+ webhook_secret?: string;
1351
+ /** Explains the one-time `webhook_secret` when it is present. */
1352
+ note?: string;
1286
1353
  }
1287
1354
  export interface CopyTradeSignal {
1288
1355
  id: number;
@@ -1313,6 +1380,10 @@ export interface CopyTradeSignalsParams {
1313
1380
  since?: string;
1314
1381
  /** 1–500, default 50. */
1315
1382
  limit?: number;
1383
+ /** Keep signals whose source trade's market cap (USD) was at least this. Drops unknown-MC signals. */
1384
+ min_mc_usd?: number;
1385
+ /** Keep signals whose source trade's market cap (USD) was at most this. Drops unknown-MC signals. */
1386
+ max_mc_usd?: number;
1316
1387
  }
1317
1388
  export interface WalletTrackerEntry {
1318
1389
  wallet_address: string;
@@ -1333,34 +1404,72 @@ export interface WalletTrackerUpdateResponse {
1333
1404
  updated: boolean;
1334
1405
  watchlist: WalletTrackerEntry;
1335
1406
  }
1336
- export type WalletTrackerAction = "buy" | "sell" | "transfer_in" | "transfer_out";
1407
+ /**
1408
+ * The `action` filter and field. Swaps only: a swap is `buy` or `sell`.
1409
+ * Transfers carry `action: null` (their direction is not stored), so select
1410
+ * them with `event_type: "transfer"`. The API answers any other value with 400.
1411
+ * Before 2.6.0 this union also listed `transfer_in` / `transfer_out`, which the
1412
+ * API never accepted.
1413
+ */
1414
+ export type WalletTrackerAction = "buy" | "sell";
1337
1415
  export type WalletTrackerEventType = "swap" | "transfer";
1338
1416
  export interface WalletTrackerTradesParams {
1339
1417
  wallet?: string;
1418
+ /** Swaps only; see {@link WalletTrackerAction}. */
1340
1419
  action?: WalletTrackerAction;
1341
1420
  event_type?: WalletTrackerEventType;
1342
1421
  /** 1–200, default 50. */
1343
1422
  limit?: number;
1344
- /** Pagination cursor — block_time of the last event from previous page. */
1423
+ /**
1424
+ * Sort column. `slot` = on-chain position (the default on a first page).
1425
+ * `block_time` = our INGEST clock (the default when you pass the legacy
1426
+ * `before` cursor). An explicit value always wins.
1427
+ */
1428
+ order?: "slot" | "block_time";
1429
+ /** Cursor for `order: "block_time"`: the previous page's `next_cursor`. */
1345
1430
  before?: number;
1431
+ /** Cursor for `order: "slot"`: the previous page's `next_cursor_slot`. */
1432
+ before_slot?: number;
1346
1433
  }
1434
+ /** One event of GET /wallet-tracker/trades. The field set mirrors the route. */
1347
1435
  export interface WalletTrackerTrade {
1348
- block_time: number;
1349
- wallet: string;
1350
- action: WalletTrackerAction;
1436
+ wallet_address: string;
1437
+ label: string | null;
1351
1438
  event_type: WalletTrackerEventType;
1352
- token_mint?: string;
1353
- token_symbol?: string;
1354
- sol_amount?: number;
1355
- token_amount?: number;
1356
- tx_signature?: string;
1439
+ /** `buy` / `sell` on swaps, `null` on transfers. */
1440
+ action: WalletTrackerAction | null;
1441
+ token_mint: string | null;
1442
+ token_symbol: string | null;
1443
+ token_name: string | null;
1444
+ sol_amount: number | null;
1445
+ token_amount: number | null;
1446
+ /** Present only when a counterparty was matched (the key is absent otherwise). */
1357
1447
  counterparty?: string;
1358
- label?: string | null;
1448
+ tx_signature: string;
1449
+ /** Unix seconds on the tracker's INGEST clock, not chain time. Use `slot` for chain order. */
1450
+ block_time: number;
1451
+ /** On-chain slot. `null` on rows written before slot tracking existed. */
1452
+ slot: number | null;
1453
+ /** `true` when the row arrived through a replay (reconnect or restart recovery), not live delivery. */
1454
+ replayed: boolean;
1455
+ /** ISO 8601 form of `block_time` (ingest time). */
1456
+ ingested_at: string;
1457
+ /** Alias of `ingested_at`, kept for older consumers. It never meant chain time. */
1458
+ timestamp: string;
1359
1459
  }
1460
+ /**
1461
+ * Response of GET /wallet-tracker/trades. Before 2.6.0 this type declared
1462
+ * `trades` / `has_more` / `next`, which the API never returned.
1463
+ */
1360
1464
  export interface WalletTrackerTradesResponse {
1361
- trades: WalletTrackerTrade[];
1362
- has_more: boolean;
1363
- next?: number;
1465
+ events: WalletTrackerTrade[];
1466
+ count: number;
1467
+ /** Which column this page was ordered by. */
1468
+ ordered_by: "slot" | "block_time";
1469
+ /** `block_time` cursor for the next page (`before`); `null` on the last page. */
1470
+ next_cursor: number | null;
1471
+ /** Slot cursor for the next page (`before_slot`); `null` on the last page or on a page of pre-slot rows. */
1472
+ next_cursor_slot: number | null;
1364
1473
  }
1365
1474
  export interface WalletTrackerSummaryParams {
1366
1475
  /** "24h" | "7d" | "30d" — default "7d" */
@@ -1742,7 +1851,9 @@ export interface MeResponse {
1742
1851
  limit: number;
1743
1852
  used: number;
1744
1853
  };
1854
+ /** `limit` = the watchlist cap POST /wallet-tracker/watchlist enforces (servers from 2026-09-25 on). */
1745
1855
  wallet_tracker_watchlist: {
1856
+ limit?: number;
1746
1857
  used: number;
1747
1858
  };
1748
1859
  };
@@ -2964,6 +3075,257 @@ export interface TokenUnlockScheduleEvent extends TokenLockLifecycleBase {
2964
3075
  }
2965
3076
  /** Any lifecycle payload on `token:locks` — narrow on the frame's `event`. */
2966
3077
  export type TokenLockLifecycleEvent = TokenLockClaimedEvent | TokenLockCancelledEvent | TokenLockClosedEvent | TokenLockUpdatedEvent | TokenUnlockScheduleEvent;
3078
+ /**
3079
+ * `token:candles` subscribe filters (PRO+). `mints` is REQUIRED (base58) and
3080
+ * capped per CONNECTION across named subscriptions — PRO 25 / ULTRA 100 /
3081
+ * BUSINESS 250, a budget separate from `token:prices`. Over the cap, a missing
3082
+ * scope or a non-boolean `updates` rejects the channel, never truncates.
3083
+ */
3084
+ export interface TokenCandlesFilters {
3085
+ mints: string[];
3086
+ /** Also receive the in-progress minute as `candle:update` (a state stream). Default false. */
3087
+ updates?: boolean;
3088
+ }
3089
+ /**
3090
+ * `candle:closed` frame `data` on `token:candles` — the STORED 1-minute row
3091
+ * (`token_ohlc_1m`), identical live and on a durable resume. Every key is
3092
+ * always present (null when unknown). Frame id =
3093
+ * `candle:solana:<mint>:<bucket_start epoch s>` (not event-prefixed). A fully
3094
+ * flat zero-trade candle (o = h = l = c, trades 0) is never emitted.
3095
+ */
3096
+ export interface TokenCandleClosedEvent {
3097
+ chain: "solana";
3098
+ mint: string;
3099
+ bucket_start: string;
3100
+ /** bucket_start + 60 s. */
3101
+ bucket_end: string;
3102
+ /** When the row was first written (≈ ≤ 25 s after bucket_end). */
3103
+ closed_at: string | null;
3104
+ open_price_usd: number | null;
3105
+ high_price_usd: number | null;
3106
+ low_price_usd: number | null;
3107
+ close_price_usd: number | null;
3108
+ open_mc_usd: number | null;
3109
+ high_mc_usd: number | null;
3110
+ low_mc_usd: number | null;
3111
+ close_mc_usd: number | null;
3112
+ open_liquidity_usd: number | null;
3113
+ close_liquidity_usd: number | null;
3114
+ close_supply: number | null;
3115
+ volume_usd: number | null;
3116
+ volume_mev_usd: number | null;
3117
+ buy_volume_usd: number | null;
3118
+ sell_volume_usd: number | null;
3119
+ trades: number | null;
3120
+ buy_count: number | null;
3121
+ sell_count: number | null;
3122
+ dex: string | null;
3123
+ pool_address: string | null;
3124
+ write_id: string | null;
3125
+ final: true;
3126
+ source: "token_ohlc_1m";
3127
+ }
3128
+ /**
3129
+ * `candle:update` frame `data` (only with `filters.updates: true`) — the
3130
+ * producer's in-progress minute, ≤ 1 per mint per second. A state stream: no
3131
+ * id / seq, never replayed, no snapshot on subscribe.
3132
+ */
3133
+ export interface TokenCandleUpdateEvent {
3134
+ chain: "solana";
3135
+ mint: string;
3136
+ bucket_start: string;
3137
+ bucket_end: string;
3138
+ open_price_usd: number | null;
3139
+ high_price_usd: number | null;
3140
+ low_price_usd: number | null;
3141
+ close_price_usd: number | null;
3142
+ close_mc_usd: number | null;
3143
+ volume_usd: number | null;
3144
+ trades: number | null;
3145
+ final: false;
3146
+ /** The producer's timestamp of this state (ISO). */
3147
+ as_of: string | null;
3148
+ source: "mc-tracker:open_candle";
3149
+ }
3150
+ /** Event types on `token:risk`. */
3151
+ export type TokenRiskEventName = "risk:authority_changed" | "risk:supply_inflated";
3152
+ /**
3153
+ * `token:risk` subscribe filters (PRO+). `mints` is REQUIRED (base58), capped
3154
+ * per connection PRO 25 / ULTRA 100 / BUSINESS 250. Invalid values reject the
3155
+ * channel (`channels_rejected`) or the whole update (`invalid_filters`).
3156
+ */
3157
+ export interface TokenRiskFilters {
3158
+ mints: string[];
3159
+ /** Non-empty subset of the channel's event types. */
3160
+ risk_events?: TokenRiskEventName[];
3161
+ /** Send one `risk:inputs` snapshot per mint on subscribe / scope change / resume. Default true. */
3162
+ risk_snapshot?: boolean;
3163
+ }
3164
+ /**
3165
+ * `risk:authority_changed` — the stored mint / freeze authority went from not
3166
+ * revoked to revoked (once per mint + field, ever), or the Token-2022 transfer
3167
+ * fee changed with both values known. Never a re-enable, never a first
3168
+ * observation. Frame id = `risk:authority_changed:<event_key>`.
3169
+ */
3170
+ export interface TokenRiskAuthorityChangedEvent {
3171
+ chain: "solana";
3172
+ mint: string;
3173
+ /** `<mint>:mint_authority:revoked` | `<mint>:freeze_authority:revoked` | `<mint>:transfer_fee:<before>><after>:<observed_at ms>`. */
3174
+ event_key: string;
3175
+ field: "mint_authority" | "freeze_authority" | "transfer_fee";
3176
+ /** `{revoked}` for the authorities, `{transfer_fee_bps}` for the fee. */
3177
+ before: {
3178
+ revoked: boolean;
3179
+ } | {
3180
+ transfer_fee_bps: number;
3181
+ };
3182
+ after: {
3183
+ revoked: boolean;
3184
+ } | {
3185
+ transfer_fee_bps: number;
3186
+ };
3187
+ /** The full picture after the change. */
3188
+ mint_authority_revoked: boolean | null;
3189
+ freeze_authority_revoked: boolean | null;
3190
+ transfer_fee_bps: number | null;
3191
+ is_token_2022: boolean | null;
3192
+ /** When mc-tracker parsed the mint account that showed the change. */
3193
+ observed_at: string | null;
3194
+ /** The parse before: the change happened on chain in between. */
3195
+ previous_observed_at: string | null;
3196
+ written_at: string;
3197
+ slot: null;
3198
+ source: "token_prices";
3199
+ }
3200
+ /**
3201
+ * `risk:supply_inflated` — the first `supply_drift_events` row for the mint
3202
+ * reaching a level (warn 0.5 % / danger 5 %). Per-observation drift, not a
3203
+ * cumulative inflation. Frame id = `risk:supply_inflated:<event_key>`.
3204
+ */
3205
+ export interface TokenRiskSupplyInflatedEvent {
3206
+ chain: "solana";
3207
+ mint: string;
3208
+ /** `<mint>:supply_inflated:warn` | `<mint>:supply_inflated:danger`. */
3209
+ event_key: string;
3210
+ level: "warn" | "danger";
3211
+ /** 0.5 (warn) | 5 (danger). */
3212
+ threshold_pct: number;
3213
+ /** drift / expected of one drift row, in percent, 4 dp. */
3214
+ inflation_pct: number;
3215
+ /** Integer strings. */
3216
+ expected_supply_raw: string;
3217
+ onchain_supply_raw: string;
3218
+ drift_raw: string;
3219
+ detected_at: string;
3220
+ drift_event_id: number;
3221
+ window_days: 30;
3222
+ written_at: string;
3223
+ slot: null;
3224
+ source: "supply_drift_events";
3225
+ }
3226
+ /**
3227
+ * `risk:inputs` snapshot frame `data` (frame `snapshot: true`, no id / seq):
3228
+ * the CURRENT stored risk inputs of one scoped mint. Not the score or band —
3229
+ * `GET /tokens/{mint}/risk` computes those.
3230
+ */
3231
+ export interface TokenRiskInputsSnapshot {
3232
+ chain: "solana";
3233
+ mint: string;
3234
+ /** false = the mint is not in the price table (every input null). */
3235
+ tracked: boolean;
3236
+ mint_authority_revoked: boolean | null;
3237
+ freeze_authority_revoked: boolean | null;
3238
+ transfer_fee_bps: number | null;
3239
+ is_token_2022: boolean | null;
3240
+ authority_observed_at: string | null;
3241
+ /** Worst positive supply drift in the last 30 days; null when none. `level` null below 0.5 %. */
3242
+ supply_inflation: {
3243
+ inflation_pct: number;
3244
+ level: "warn" | "danger" | null;
3245
+ detected_at: string | null;
3246
+ window_days: 30;
3247
+ } | null;
3248
+ source: "token_prices+supply_drift_events";
3249
+ }
3250
+ /** Any event payload on `token:risk` — narrow on the frame's `event`. */
3251
+ export type TokenRiskEvent = TokenRiskAuthorityChangedEvent | TokenRiskSupplyInflatedEvent;
3252
+ /** Event types on `wallet:scores`. */
3253
+ export type WalletScoreEventName = "deployer:tier_changed" | "kol:score_state_changed";
3254
+ /**
3255
+ * `wallet:scores` subscribe filters (PRO+). `wallets` is REQUIRED — base58
3256
+ * deployer or KOL wallets — capped per connection per chain PRO 25 / ULTRA 100
3257
+ * / BUSINESS 250. A subscription that also holds `rhc:wallet_scores` may mix
3258
+ * in 0x addresses; an entry of a chain the subscription does not hold is refused.
3259
+ */
3260
+ export interface WalletScoresFilters {
3261
+ wallets: string[];
3262
+ /** Optional subset of the held channels' event types (e.g. `"rhc:deployer_tier_changed"` when mixing chains). */
3263
+ score_events?: Array<WalletScoreEventName | "rhc:deployer_tier_changed">;
3264
+ }
3265
+ /**
3266
+ * Where a score event came from. `computed_at` means "recomputed at T", not
3267
+ * "changed at T": `live_write` = a bond / deploy re-classified the deployer
3268
+ * (real time); `scheduled_recompute` = the 6-hourly stats worker (can lag the
3269
+ * stats by hours); `matview_refresh` = the KOL diff after each 10-min refresh.
3270
+ */
3271
+ export type WalletScoreSource = "live_write" | "scheduled_recompute" | "matview_refresh";
3272
+ /** Solana deployer tier values on `deployer:tier_changed`. */
3273
+ export type DeployerTierChangeValue = "elite" | "good" | "rising" | "moderate" | "cold" | "unranked";
3274
+ /**
3275
+ * `deployer:tier_changed` — `deployers.tier` changed. Frame id =
3276
+ * `deployer:tier_changed:<event_key>`. A wallet appearing is not an event;
3277
+ * entering a ranked tier is (`entered_ranking: true`, `tier_before: "unranked"`).
3278
+ */
3279
+ export interface DeployerTierChangedEvent {
3280
+ /** `<wallet>:<tier_before>><tier_after>:<txid>`. */
3281
+ event_key: string;
3282
+ chain: "solana";
3283
+ wallet: string;
3284
+ tier_before: DeployerTierChangeValue | null;
3285
+ tier_after: DeployerTierChangeValue | null;
3286
+ entered_ranking: boolean;
3287
+ is_tracked: boolean | null;
3288
+ /** As of the write. */
3289
+ stats: {
3290
+ total_tokens_deployed: number | null;
3291
+ total_bonded: number | null;
3292
+ instant_bonds: number | null;
3293
+ bonding_rate: number | null;
3294
+ recent_bond_rate: number | null;
3295
+ recent_outcomes: string | null;
3296
+ };
3297
+ computed_at: string;
3298
+ source: WalletScoreSource;
3299
+ }
3300
+ /** The categorical KOL score fields diffed on `kol:score_state_changed`. */
3301
+ export interface KolScoreState {
3302
+ is_cold: boolean | null;
3303
+ is_heating_up: boolean | null;
3304
+ auto_strategy_tag: KolStrategy | null;
3305
+ }
3306
+ /**
3307
+ * `kol:score_state_changed` — one event per KOL per `mv_kol_scores` refresh
3308
+ * where `is_cold`, `is_heating_up` or `auto_strategy_tag` differs (fields never
3309
+ * split). Frame id = `kol:score_state_changed:<event_key>`.
3310
+ */
3311
+ export interface KolScoreStateChangedEvent {
3312
+ /** `<wallet>:<computed_at epoch ms>`. */
3313
+ event_key: string;
3314
+ chain: "solana";
3315
+ wallet: string;
3316
+ kol_wallet_id: string | null;
3317
+ kol_name: string | null;
3318
+ /** All three for a KOL first seen after the seed. */
3319
+ changed: Array<keyof KolScoreState>;
3320
+ /** null for a first appearance. */
3321
+ before: KolScoreState | null;
3322
+ after: KolScoreState;
3323
+ computed_at: string;
3324
+ source: "matview_refresh";
3325
+ matview: "mv_kol_scores";
3326
+ }
3327
+ /** Any event payload on `wallet:scores` — narrow on the frame's `event`. */
3328
+ export type WalletScoreEvent = DeployerTierChangedEvent | KolScoreStateChangedEvent;
2967
3329
  /** pump.fun fee event types (`creator_claim` is excluded from the feed unless requested via `type=`). */
2968
3330
  export type TokenFeeEventType = "shares_created" | "shares_updated" | "shares_reset" | "distribution" | "social_pda_created" | "social_claim" | "creator_transferred" | "creator_claim";
2969
3331
  /** A shareholder on a SharingConfig: `{ address, share_bps }` (bps of the creator fee). */