@carrierllc/mcp 0.10.7 → 0.11.5

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.
@@ -1792,7 +1792,7 @@ function storefrontScreen(input) {
1792
1792
  // package.json
1793
1793
  var package_default = {
1794
1794
  name: "@carrierllc/mcp",
1795
- version: "0.10.7",
1795
+ version: "0.11.5",
1796
1796
  description: "Carrier MCP \u2014 natural-language control of MVNO/eSIM fleets via eSIMVault OCS. Stdio mode for direct integration with Claude Desktop, Cursor, Windsurf, and MCP-compatible clients. Ships the `carrier` CLI (plugin install + white-label eSIM storefront scaffold).",
1797
1797
  license: "MIT",
1798
1798
  author: "Carrier (Lifecycle Innovations Limited)",
@@ -1829,7 +1829,7 @@ var package_default = {
1829
1829
  },
1830
1830
  dependencies: {
1831
1831
  "@clack/prompts": "^0.7.0",
1832
- "@clerk/backend": "^3.14.0",
1832
+ "@clerk/backend": "^3.17.1",
1833
1833
  "@modelcontextprotocol/ext-apps": "^1.7.5",
1834
1834
  "@modelcontextprotocol/sdk": "^1.29.0",
1835
1835
  "@noble/hashes": "^2.3.0",
@@ -1840,7 +1840,7 @@ var package_default = {
1840
1840
  zod: "^4.4.3"
1841
1841
  },
1842
1842
  devDependencies: {
1843
- "@cloudflare/workers-types": "^5.20260819.1",
1843
+ "@cloudflare/workers-types": "^5.20260903.1",
1844
1844
  "@types/node": "^26.1.2",
1845
1845
  "@typescript-eslint/eslint-plugin": "^8.59.4",
1846
1846
  "@typescript-eslint/parser": "^8.67.0",
@@ -2219,7 +2219,7 @@ async function runWithBudget(method, attempt, budget = ocsBudgetFor(method)) {
2219
2219
  throw lastTimeout ?? new OcsTimeoutError(method, budget.attemptMs, budget.totalMs, Math.max(attempts, 1));
2220
2220
  }
2221
2221
 
2222
- // ../../packages/ocs-client/dist/chunk-CKDDVZ7A.js
2222
+ // ../../packages/ocs-client/dist/chunk-QAHO3AI3.js
2223
2223
  var RATE_LIMIT = 10;
2224
2224
  var WINDOW_MS = 1e3;
2225
2225
  var windows = /* @__PURE__ */ new Map();
@@ -2674,8 +2674,12 @@ var OcsClient = class {
2674
2674
  } else {
2675
2675
  payload = json[method] ?? json;
2676
2676
  }
2677
+ } else if (json[method] !== void 0) {
2678
+ payload = json[method];
2679
+ } else if (Object.keys(json).some((k) => k !== "status")) {
2680
+ payload = json;
2677
2681
  } else {
2678
- payload = json[method] ?? json;
2682
+ payload = null;
2679
2683
  }
2680
2684
  if (this._validateResponses) {
2681
2685
  const schema = RESPONSE_SCHEMAS[method];
@@ -2890,16 +2894,16 @@ function emptyEsimStatusCounts() {
2890
2894
  function addEsimStatusRow(acc, rec) {
2891
2895
  const count = Number(rec.count ?? 0);
2892
2896
  if (!Number.isFinite(count) || count === 0) return;
2893
- const str = String(rec.statusStr ?? rec.name ?? rec.status ?? "").toUpperCase();
2894
- if (str === "ACTIVATED" || str === "ACTIVE" || str === "AFFECTED") {
2897
+ const str2 = String(rec.statusStr ?? rec.name ?? rec.status ?? "").toUpperCase();
2898
+ if (str2 === "ACTIVATED" || str2 === "ACTIVE" || str2 === "AFFECTED") {
2895
2899
  acc.active += count;
2896
2900
  return;
2897
2901
  }
2898
- if (str === "SUSPENDED") {
2902
+ if (str2 === "SUSPENDED") {
2899
2903
  acc.suspended += count;
2900
2904
  return;
2901
2905
  }
2902
- if (str === "FREE" || str === "INVENTORY" || str === "NOT_ACTIVATED" || str === "AVAILABLE") {
2906
+ if (str2 === "FREE" || str2 === "INVENTORY" || str2 === "NOT_ACTIVATED" || str2 === "AVAILABLE") {
2903
2907
  acc.inventory += count;
2904
2908
  return;
2905
2909
  }
@@ -3061,6 +3065,502 @@ function normalizePackageTemplateChanges(changes) {
3061
3065
  return out;
3062
3066
  }
3063
3067
 
3068
+ // ../../packages/ocs-spec/src/mcc-iso.ts
3069
+ var MCC_TO_ISO = {
3070
+ // Europe
3071
+ 202: "GR",
3072
+ // Greece
3073
+ 204: "NL",
3074
+ // Netherlands
3075
+ 206: "BE",
3076
+ // Belgium
3077
+ 208: "FR",
3078
+ // France
3079
+ 212: "MC",
3080
+ // Monaco
3081
+ 213: "AD",
3082
+ // Andorra
3083
+ 214: "ES",
3084
+ // Spain
3085
+ 216: "HU",
3086
+ // Hungary
3087
+ 218: "BA",
3088
+ // Bosnia and Herzegovina
3089
+ 219: "HR",
3090
+ // Croatia
3091
+ 220: "RS",
3092
+ // Serbia
3093
+ 221: "XK",
3094
+ // Kosovo
3095
+ 222: "IT",
3096
+ // Italy
3097
+ 225: "VA",
3098
+ // Vatican City
3099
+ 226: "RO",
3100
+ // Romania
3101
+ 228: "CH",
3102
+ // Switzerland
3103
+ 230: "CZ",
3104
+ // Czech Republic
3105
+ 231: "SK",
3106
+ // Slovakia
3107
+ 232: "AT",
3108
+ // Austria
3109
+ 234: "GB",
3110
+ // United Kingdom
3111
+ 235: "GB",
3112
+ // United Kingdom
3113
+ 238: "DK",
3114
+ // Denmark
3115
+ 240: "SE",
3116
+ // Sweden
3117
+ 242: "NO",
3118
+ // Norway
3119
+ 244: "FI",
3120
+ // Finland
3121
+ 246: "LT",
3122
+ // Lithuania
3123
+ 247: "LV",
3124
+ // Latvia
3125
+ 248: "EE",
3126
+ // Estonia
3127
+ 250: "RU",
3128
+ // Russia
3129
+ 255: "UA",
3130
+ // Ukraine
3131
+ 257: "BY",
3132
+ // Belarus
3133
+ 259: "MD",
3134
+ // Moldova
3135
+ 260: "PL",
3136
+ // Poland
3137
+ 262: "DE",
3138
+ // Germany
3139
+ 266: "GI",
3140
+ // Gibraltar
3141
+ 268: "PT",
3142
+ // Portugal
3143
+ 270: "LU",
3144
+ // Luxembourg
3145
+ 272: "IE",
3146
+ // Ireland
3147
+ 274: "IS",
3148
+ // Iceland
3149
+ 276: "AL",
3150
+ // Albania
3151
+ 278: "MT",
3152
+ // Malta
3153
+ 280: "CY",
3154
+ // Cyprus
3155
+ 282: "GE",
3156
+ // Georgia
3157
+ 283: "AM",
3158
+ // Armenia
3159
+ 284: "BG",
3160
+ // Bulgaria
3161
+ 286: "TR",
3162
+ // Turkey
3163
+ 288: "FO",
3164
+ // Faroe Islands
3165
+ 289: "GE",
3166
+ // Abkhazia (Georgia)
3167
+ 290: "GL",
3168
+ // Greenland
3169
+ 292: "SM",
3170
+ // San Marino
3171
+ 293: "SI",
3172
+ // Slovenia
3173
+ 294: "MK",
3174
+ // North Macedonia
3175
+ 295: "LI",
3176
+ // Liechtenstein
3177
+ 297: "ME",
3178
+ // Montenegro
3179
+ // Commonwealth of Independent States / Former USSR
3180
+ 401: "KZ",
3181
+ // Kazakhstan
3182
+ 402: "BT",
3183
+ // Bhutan
3184
+ 404: "IN",
3185
+ // India
3186
+ 405: "IN",
3187
+ // India
3188
+ 406: "IN",
3189
+ // India
3190
+ 410: "PK",
3191
+ // Pakistan
3192
+ 412: "AF",
3193
+ // Afghanistan
3194
+ 413: "LK",
3195
+ // Sri Lanka
3196
+ 414: "MM",
3197
+ // Myanmar
3198
+ 415: "LB",
3199
+ // Lebanon
3200
+ 416: "JO",
3201
+ // Jordan
3202
+ 417: "SY",
3203
+ // Syria
3204
+ 418: "IQ",
3205
+ // Iraq
3206
+ 419: "KW",
3207
+ // Kuwait
3208
+ 420: "SA",
3209
+ // Saudi Arabia
3210
+ 421: "YE",
3211
+ // Yemen
3212
+ 422: "OM",
3213
+ // Oman
3214
+ 424: "AE",
3215
+ // United Arab Emirates
3216
+ 425: "IL",
3217
+ // Israel
3218
+ 426: "BH",
3219
+ // Bahrain
3220
+ 427: "QA",
3221
+ // Qatar
3222
+ 428: "MN",
3223
+ // Mongolia
3224
+ 429: "NP",
3225
+ // Nepal
3226
+ 430: "AE",
3227
+ // United Arab Emirates
3228
+ 431: "AE",
3229
+ // United Arab Emirates
3230
+ 432: "IR",
3231
+ // Iran
3232
+ 434: "UZ",
3233
+ // Uzbekistan
3234
+ 436: "TJ",
3235
+ // Tajikistan
3236
+ 437: "KG",
3237
+ // Kyrgyzstan
3238
+ 438: "TM",
3239
+ // Turkmenistan
3240
+ 440: "JP",
3241
+ // Japan
3242
+ 441: "JP",
3243
+ // Japan
3244
+ 450: "KR",
3245
+ // South Korea
3246
+ 452: "VN",
3247
+ // Vietnam
3248
+ 454: "HK",
3249
+ // Hong Kong
3250
+ 455: "MO",
3251
+ // Macau
3252
+ 456: "KH",
3253
+ // Cambodia
3254
+ 457: "LA",
3255
+ // Laos
3256
+ 460: "CN",
3257
+ // China
3258
+ 461: "CN",
3259
+ // China
3260
+ 466: "TW",
3261
+ // Taiwan
3262
+ 467: "KP",
3263
+ // North Korea
3264
+ 470: "BD",
3265
+ // Bangladesh
3266
+ 472: "MV",
3267
+ // Maldives
3268
+ 502: "MY",
3269
+ // Malaysia
3270
+ 505: "AU",
3271
+ // Australia
3272
+ 510: "ID",
3273
+ // Indonesia
3274
+ 514: "TL",
3275
+ // East Timor
3276
+ 515: "PH",
3277
+ // Philippines
3278
+ 520: "TH",
3279
+ // Thailand
3280
+ 525: "SG",
3281
+ // Singapore
3282
+ 528: "BN",
3283
+ // Brunei
3284
+ 530: "NZ",
3285
+ // New Zealand
3286
+ 536: "NR",
3287
+ // Nauru
3288
+ 537: "PG",
3289
+ // Papua New Guinea
3290
+ 539: "TO",
3291
+ // Tonga
3292
+ 540: "SB",
3293
+ // Solomon Islands
3294
+ 541: "VU",
3295
+ // Vanuatu
3296
+ 542: "FJ",
3297
+ // Fiji
3298
+ 544: "AS",
3299
+ // American Samoa
3300
+ 545: "KI",
3301
+ // Kiribati
3302
+ 546: "NC",
3303
+ // New Caledonia
3304
+ 547: "PF",
3305
+ // French Polynesia
3306
+ 548: "CK",
3307
+ // Cook Islands
3308
+ 549: "WS",
3309
+ // Samoa
3310
+ 550: "FM",
3311
+ // Micronesia
3312
+ 551: "MH",
3313
+ // Marshall Islands
3314
+ 552: "PW",
3315
+ // Palau
3316
+ 553: "TV",
3317
+ // Tuvalu
3318
+ 555: "NU",
3319
+ // Niue
3320
+ // Africa (ITU-T E.212)
3321
+ 602: "EG",
3322
+ // Egypt
3323
+ 603: "DZ",
3324
+ // Algeria
3325
+ 604: "MA",
3326
+ // Morocco
3327
+ 605: "TN",
3328
+ // Tunisia
3329
+ 606: "LY",
3330
+ // Libya
3331
+ 607: "GM",
3332
+ // Gambia
3333
+ 608: "SN",
3334
+ // Senegal
3335
+ 609: "MR",
3336
+ // Mauritania
3337
+ 610: "ML",
3338
+ // Mali
3339
+ 611: "GN",
3340
+ // Guinea
3341
+ 612: "CI",
3342
+ // Côte d'Ivoire
3343
+ 613: "BF",
3344
+ // Burkina Faso
3345
+ 614: "NE",
3346
+ // Niger
3347
+ 615: "TG",
3348
+ // Togo
3349
+ 616: "BJ",
3350
+ // Benin
3351
+ 617: "MU",
3352
+ // Mauritius
3353
+ 618: "LR",
3354
+ // Liberia
3355
+ 619: "SL",
3356
+ // Sierra Leone
3357
+ 620: "GH",
3358
+ // Ghana
3359
+ 621: "NG",
3360
+ // Nigeria
3361
+ 622: "TD",
3362
+ // Chad
3363
+ 623: "CF",
3364
+ // Central African Republic
3365
+ 624: "CM",
3366
+ // Cameroon
3367
+ 625: "CV",
3368
+ // Cape Verde
3369
+ 626: "ST",
3370
+ // São Tomé and Príncipe
3371
+ 627: "GQ",
3372
+ // Equatorial Guinea
3373
+ 628: "GA",
3374
+ // Gabon
3375
+ 629: "CG",
3376
+ // Republic of the Congo
3377
+ 630: "CD",
3378
+ // Democratic Republic of the Congo
3379
+ 631: "AO",
3380
+ // Angola
3381
+ 632: "GW",
3382
+ // Guinea-Bissau
3383
+ 633: "SC",
3384
+ // Seychelles
3385
+ 634: "SD",
3386
+ // Sudan
3387
+ 635: "RW",
3388
+ // Rwanda
3389
+ 636: "ET",
3390
+ // Ethiopia
3391
+ 637: "SO",
3392
+ // Somalia
3393
+ 638: "DJ",
3394
+ // Djibouti
3395
+ 639: "KE",
3396
+ // Kenya
3397
+ 640: "TZ",
3398
+ // Tanzania
3399
+ 641: "UG",
3400
+ // Uganda
3401
+ 642: "BI",
3402
+ // Burundi
3403
+ 643: "MZ",
3404
+ // Mozambique
3405
+ 645: "ZM",
3406
+ // Zambia
3407
+ 646: "MG",
3408
+ // Madagascar
3409
+ 647: "RE",
3410
+ // Réunion / French Indian Ocean
3411
+ 648: "ZW",
3412
+ // Zimbabwe
3413
+ 649: "NA",
3414
+ // Namibia
3415
+ 650: "MW",
3416
+ // Malawi
3417
+ 651: "LS",
3418
+ // Lesotho
3419
+ 652: "BW",
3420
+ // Botswana
3421
+ 653: "SZ",
3422
+ // Eswatini
3423
+ 654: "KM",
3424
+ // Comoros
3425
+ 655: "ZA",
3426
+ // South Africa
3427
+ 657: "ER",
3428
+ // Eritrea
3429
+ 658: "SH",
3430
+ // Saint Helena
3431
+ 659: "SS",
3432
+ // South Sudan
3433
+ 702: "BZ",
3434
+ // Belize
3435
+ 704: "GT",
3436
+ // Guatemala
3437
+ 706: "SV",
3438
+ // El Salvador
3439
+ 708: "HN",
3440
+ // Honduras
3441
+ 710: "NI",
3442
+ // Nicaragua
3443
+ 712: "CR",
3444
+ // Costa Rica
3445
+ 714: "PA",
3446
+ // Panama
3447
+ 716: "PE",
3448
+ // Peru
3449
+ 722: "AR",
3450
+ // Argentina
3451
+ 724: "BR",
3452
+ // Brazil
3453
+ 730: "CL",
3454
+ // Chile
3455
+ 732: "CO",
3456
+ // Colombia
3457
+ 734: "VE",
3458
+ // Venezuela
3459
+ 736: "BO",
3460
+ // Bolivia
3461
+ 738: "GY",
3462
+ // Guyana
3463
+ 740: "EC",
3464
+ // Ecuador
3465
+ 742: "GF",
3466
+ // French Guiana
3467
+ 744: "PY",
3468
+ // Paraguay
3469
+ 746: "SR",
3470
+ // Suriname
3471
+ 748: "UY",
3472
+ // Uruguay
3473
+ 750: "FK",
3474
+ // Falkland Islands
3475
+ // North America, Caribbean
3476
+ 302: "CA",
3477
+ // Canada
3478
+ 308: "PM",
3479
+ // Saint Pierre and Miquelon
3480
+ 310: "US",
3481
+ // United States
3482
+ 311: "US",
3483
+ // United States
3484
+ 312: "US",
3485
+ // United States
3486
+ 313: "US",
3487
+ // United States
3488
+ 314: "US",
3489
+ // United States
3490
+ 315: "US",
3491
+ // United States
3492
+ 316: "US",
3493
+ // United States
3494
+ 330: "PR",
3495
+ // Puerto Rico
3496
+ 332: "VI",
3497
+ // U.S. Virgin Islands
3498
+ 334: "MX",
3499
+ // Mexico
3500
+ 338: "JM",
3501
+ // Jamaica
3502
+ 340: "GP",
3503
+ // Guadeloupe
3504
+ 342: "BB",
3505
+ // Barbados
3506
+ 344: "AG",
3507
+ // Antigua and Barbuda
3508
+ 346: "KY",
3509
+ // Cayman Islands
3510
+ 348: "VG",
3511
+ // British Virgin Islands
3512
+ 350: "BM",
3513
+ // Bermuda
3514
+ 352: "GD",
3515
+ // Grenada
3516
+ 354: "MS",
3517
+ // Montserrat
3518
+ 356: "KN",
3519
+ // Saint Kitts and Nevis
3520
+ 358: "LC",
3521
+ // Saint Lucia
3522
+ 360: "VC",
3523
+ // Saint Vincent and the Grenadines
3524
+ 362: "CW",
3525
+ // Curaçao / Netherlands Antilles
3526
+ 363: "AW",
3527
+ // Aruba
3528
+ 364: "BS",
3529
+ // Bahamas
3530
+ 365: "AI",
3531
+ // Anguilla
3532
+ 366: "DM",
3533
+ // Dominica
3534
+ 368: "CU",
3535
+ // Cuba
3536
+ 370: "DO",
3537
+ // Dominican Republic
3538
+ 372: "HT",
3539
+ // Haiti
3540
+ 374: "TT",
3541
+ // Trinidad and Tobago
3542
+ 376: "TC",
3543
+ // Turks and Caicos Islands
3544
+ // Special / Test MCCs
3545
+ 999: "XX",
3546
+ // Test network
3547
+ 901: "XX"
3548
+ // International / satellite
3549
+ };
3550
+ function mccToIso(mcc) {
3551
+ if (mcc == null) return null;
3552
+ let n;
3553
+ if (typeof mcc === "string") {
3554
+ const trimmed = mcc.trim();
3555
+ if (trimmed === "" || !/^\d+$/.test(trimmed)) return null;
3556
+ n = parseInt(trimmed, 10);
3557
+ } else {
3558
+ n = mcc;
3559
+ }
3560
+ if (!Number.isFinite(n)) return null;
3561
+ return MCC_TO_ISO[n] ?? null;
3562
+ }
3563
+
3064
3564
  // ../../packages/ocs-client/dist/index.js
3065
3565
  function buildListSubscriberParams(args) {
3066
3566
  const params = {};
@@ -3401,12 +3901,26 @@ function subscriberSimId(record) {
3401
3901
  function prepaidPackageRows(data) {
3402
3902
  return ocsArray(data, PREPAID_PACKAGE_KEYS);
3403
3903
  }
3404
- function isActivePackage(pkg) {
3904
+ function isFlaggedActive(pkg) {
3405
3905
  if (typeof pkg.active === "boolean") return pkg.active;
3406
3906
  const status = pkg.status;
3407
3907
  if (typeof status === "string") return status.toUpperCase() === "ACTIVE";
3408
3908
  return false;
3409
3909
  }
3910
+ function isExpiredPackage(pkg, now = /* @__PURE__ */ new Date()) {
3911
+ const expiry = packageExpiry(pkg);
3912
+ if (!expiry) return false;
3913
+ const hasZone = /(?:Z|[+-]\d{2}:?\d{2})$/.test(expiry);
3914
+ const ms = Date.parse(hasZone ? expiry : `${expiry}Z`);
3915
+ if (!Number.isFinite(ms)) return false;
3916
+ return ms <= now.getTime();
3917
+ }
3918
+ function isActivePackage(pkg, now = /* @__PURE__ */ new Date()) {
3919
+ return isFlaggedActive(pkg) && !isExpiredPackage(pkg, now);
3920
+ }
3921
+ function staleActivePackages(pkgs, now = /* @__PURE__ */ new Date()) {
3922
+ return pkgs.filter((p) => isFlaggedActive(p) && isExpiredPackage(p, now));
3923
+ }
3410
3924
  function firstNumber(pkg, keys) {
3411
3925
  for (const key of keys) {
3412
3926
  const v = pkg[key];
@@ -3491,6 +4005,158 @@ function summarizeNetworkEvents(rows) {
3491
4005
  lastEventTime
3492
4006
  };
3493
4007
  }
4008
+ function extractGyEvents(response) {
4009
+ if (!response || typeof response !== "object") return [];
4010
+ const root = response;
4011
+ const candidates = [
4012
+ root.subscriberNetworkEventsOverPeriod,
4013
+ root.data,
4014
+ root
4015
+ ];
4016
+ for (const candidate of candidates) {
4017
+ if (!candidate || typeof candidate !== "object") continue;
4018
+ const gy = candidate.gyAnswer;
4019
+ if (Array.isArray(gy)) {
4020
+ return gy.filter((e) => !!e && typeof e === "object");
4021
+ }
4022
+ if (gy && typeof gy === "object") {
4023
+ const events = gy.events;
4024
+ if (Array.isArray(events)) {
4025
+ return events.filter((e) => !!e && typeof e === "object");
4026
+ }
4027
+ }
4028
+ }
4029
+ return [];
4030
+ }
4031
+ function gyUsedBytes(event) {
4032
+ const raw = event.usedUnits;
4033
+ if (typeof raw === "number") return Number.isFinite(raw) ? raw : 0;
4034
+ if (typeof raw !== "string") return 0;
4035
+ const trimmed = raw.trim();
4036
+ if (trimmed === "" || trimmed.toUpperCase() === "N/A") return 0;
4037
+ const n = Number(trimmed);
4038
+ return Number.isFinite(n) ? n : 0;
4039
+ }
4040
+ function gyCountryIso(event) {
4041
+ const alpha2 = event.countryAlpha2;
4042
+ if (typeof alpha2 === "string" && /^[A-Za-z]{2}$/.test(alpha2.trim())) {
4043
+ return alpha2.trim().toUpperCase();
4044
+ }
4045
+ const mcc = event.userLocationInfoMCC;
4046
+ if (typeof mcc === "string" || typeof mcc === "number") return mccToIso(mcc);
4047
+ return null;
4048
+ }
4049
+ function str(value) {
4050
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
4051
+ }
4052
+ function meaningful(value) {
4053
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
4054
+ const s = str(value);
4055
+ return s && s.toUpperCase() !== "N/A" ? s : null;
4056
+ }
4057
+ function normalise(events) {
4058
+ const rows = [];
4059
+ let skipped = 0;
4060
+ for (const event of events) {
4061
+ const time = str(event.eventTime);
4062
+ const country = gyCountryIso(event);
4063
+ if (!time || !country) {
4064
+ skipped++;
4065
+ continue;
4066
+ }
4067
+ rows.push({
4068
+ time,
4069
+ country,
4070
+ countryName: meaningful(event.countryName),
4071
+ operator: meaningful(event.operator),
4072
+ mcc: meaningful(event.userLocationInfoMCC),
4073
+ requestType: str(event.requestType) ?? "",
4074
+ bytes: gyUsedBytes(event)
4075
+ });
4076
+ }
4077
+ rows.sort((a, b) => {
4078
+ const ta = Date.parse(a.time);
4079
+ const tb = Date.parse(b.time);
4080
+ if (Number.isFinite(ta) && Number.isFinite(tb) && ta !== tb) return ta - tb;
4081
+ return a.time.localeCompare(b.time);
4082
+ });
4083
+ return { rows, skipped };
4084
+ }
4085
+ function runToStay(run2) {
4086
+ const operators = /* @__PURE__ */ new Set();
4087
+ const mccs = /* @__PURE__ */ new Set();
4088
+ let countryName = null;
4089
+ let bytes = 0;
4090
+ for (const row of run2) {
4091
+ if (row.operator) operators.add(row.operator);
4092
+ if (row.mcc) mccs.add(row.mcc);
4093
+ if (!countryName && row.countryName) countryName = row.countryName;
4094
+ bytes += row.bytes;
4095
+ }
4096
+ const first = run2[0];
4097
+ const last = run2[run2.length - 1];
4098
+ return {
4099
+ country: first.country,
4100
+ country_name: countryName,
4101
+ first_seen: first.time,
4102
+ last_seen: last.time,
4103
+ operators: [...operators].sort(),
4104
+ mccs: [...mccs].sort(),
4105
+ event_count: run2.length,
4106
+ used_bytes: bytes
4107
+ };
4108
+ }
4109
+ function collapseRuns(rows) {
4110
+ const runs = [];
4111
+ for (const row of rows) {
4112
+ const current = runs[runs.length - 1];
4113
+ if (current && current[0].country === row.country) current.push(row);
4114
+ else runs.push([row]);
4115
+ }
4116
+ return runs;
4117
+ }
4118
+ function collapseGyStays(events) {
4119
+ const { rows, skipped } = normalise(events);
4120
+ if (rows.length === 0) {
4121
+ return {
4122
+ stays: [],
4123
+ transitions: [],
4124
+ events_considered: 0,
4125
+ events_skipped: skipped,
4126
+ teardown_artifacts_dropped: 0
4127
+ };
4128
+ }
4129
+ let runs = collapseRuns(rows);
4130
+ let teardownDropped = 0;
4131
+ for (let changed = true; changed; ) {
4132
+ changed = false;
4133
+ for (let i = 1; i < runs.length - 1; i++) {
4134
+ const run2 = runs[i];
4135
+ if (!run2.every((r) => r.requestType.toLowerCase() === "term")) continue;
4136
+ if (runs[i - 1][0].country !== runs[i + 1][0].country) continue;
4137
+ teardownDropped += run2.length;
4138
+ runs = collapseRuns(runs.flatMap((r, idx) => idx === i ? [] : r));
4139
+ changed = true;
4140
+ break;
4141
+ }
4142
+ }
4143
+ const stays = runs.map(runToStay);
4144
+ const transitions = stays.slice(1).map((stay, idx) => ({
4145
+ from: stays[idx].country,
4146
+ to: stay.country,
4147
+ at: stay.first_seen
4148
+ }));
4149
+ return {
4150
+ stays,
4151
+ transitions,
4152
+ events_considered: rows.length,
4153
+ events_skipped: skipped,
4154
+ teardown_artifacts_dropped: teardownDropped
4155
+ };
4156
+ }
4157
+ function gyCountryHistoryFromResponse(response) {
4158
+ return collapseGyStays(extractGyEvents(response));
4159
+ }
3494
4160
 
3495
4161
  // src/lib/storefront-logo.ts
3496
4162
  var OPENAI_KEY_NAMES = [
@@ -3635,6 +4301,7 @@ export {
3635
4301
  esimStatusPerAccountParams,
3636
4302
  normalizePackageTemplate,
3637
4303
  normalizePackageTemplateChanges,
4304
+ mccToIso,
3638
4305
  buildListSubscriberParams,
3639
4306
  extractSubscriberStatus,
3640
4307
  applySubscriberFilters,
@@ -3651,12 +4318,14 @@ export {
3651
4318
  subscriberSimId,
3652
4319
  prepaidPackageRows,
3653
4320
  isActivePackage,
4321
+ staleActivePackages,
3654
4322
  packageDataUsed,
3655
4323
  packageDataLimit,
3656
4324
  packageExpiry,
3657
4325
  packageName,
3658
4326
  networkEventRows,
3659
4327
  summarizeNetworkEvents,
4328
+ gyCountryHistoryFromResponse,
3660
4329
  generateStorefrontLogo,
3661
4330
  run,
3662
4331
  which,
@@ -3695,4 +4364,4 @@ export {
3695
4364
  storefrontScreen,
3696
4365
  CARRIER_VERSION
3697
4366
  };
3698
- //# sourceMappingURL=chunk-KYS5GHJV.js.map
4367
+ //# sourceMappingURL=chunk-R62KED76.js.map