koishi-plugin-warframe 1.8.7 → 1.9.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/lib/index.js CHANGED
@@ -1286,6 +1286,7 @@ var messages = {
1286
1286
  "relic.notFound": "未找到对应遗物信息",
1287
1287
  "arbitration.invalidDayRange": "天数需小于等于14且大于0",
1288
1288
  "bounty.unavailable": "当前该地点暂无可用赏金",
1289
+ "nightwave.unavailable": "当前没有午夜电波",
1289
1290
  "voidTrader.drifting": "虚空商人仍在未知地带漂流...",
1290
1291
  "voidTrader.arriving": "距离虚空商人到达还有: {time}",
1291
1292
  "riven.imageNotFound": "未检测到图片",
@@ -1609,7 +1610,7 @@ async function getHotRivenWeapons2() {
1609
1610
  __name(getHotRivenWeapons2, "getHotRivenWeapons");
1610
1611
 
1611
1612
  // src/warframe/services/wf-service.ts
1612
- var import_warframe_public_export_plus7 = require("warframe-public-export-plus");
1613
+ var import_warframe_public_export_plus9 = require("warframe-public-export-plus");
1613
1614
 
1614
1615
  // src/warframe/assets/index.ts
1615
1616
  var {
@@ -1634,6 +1635,23 @@ var arbitrationSchedule = arbitrationScheduleText.split("\n").map((line) => line
1634
1635
  };
1635
1636
  });
1636
1637
 
1638
+ // src/warframe/data/wf/archonHunt.ts
1639
+ var import_warframe_public_export_plus = require("warframe-public-export-plus");
1640
+ var MODE_NAME_KEY = "/Lotus/Language/WorldStateWindow/LiteSortieMissionName";
1641
+ var HUNT_ENEMY_LEVELS = [
1642
+ { minLevel: 130, maxLevel: 135 },
1643
+ { minLevel: 135, maxLevel: 140 },
1644
+ { minLevel: 145, maxLevel: 150 }
1645
+ ];
1646
+ function getArchonHuntModeName() {
1647
+ return import_warframe_public_export_plus.dict_zh[MODE_NAME_KEY] ?? dictZhExtra[MODE_NAME_KEY] ?? MODE_NAME_KEY;
1648
+ }
1649
+ __name(getArchonHuntModeName, "getArchonHuntModeName");
1650
+ function getArchonHuntEnemyLevels(index) {
1651
+ return HUNT_ENEMY_LEVELS[index] ?? HUNT_ENEMY_LEVELS[HUNT_ENEMY_LEVELS.length - 1];
1652
+ }
1653
+ __name(getArchonHuntEnemyLevels, "getArchonHuntEnemyLevels");
1654
+
1637
1655
  // src/warframe/infrastructure/wf/wf-api.ts
1638
1656
  var apiBase = "https://api.warframe.com/cdn/";
1639
1657
  var oracleBountyCycleUrl = "https://oracle.browse.wf/bounty-cycle";
@@ -1646,6 +1664,22 @@ function extractSyndicateMissionsRaw(json) {
1646
1664
  }
1647
1665
  }
1648
1666
  __name(extractSyndicateMissionsRaw, "extractSyndicateMissionsRaw");
1667
+ function extractSeasonInfoRaw(json) {
1668
+ try {
1669
+ const data = JSON.parse(json);
1670
+ const info = data.SeasonInfo;
1671
+ if (!info || typeof info !== "object") {
1672
+ return void 0;
1673
+ }
1674
+ return {
1675
+ ...info,
1676
+ ActiveChallenges: Array.isArray(info.ActiveChallenges) ? info.ActiveChallenges : []
1677
+ };
1678
+ } catch {
1679
+ return void 0;
1680
+ }
1681
+ }
1682
+ __name(extractSeasonInfoRaw, "extractSeasonInfoRaw");
1649
1683
  async function fetchWorldStateJson() {
1650
1684
  return fetchAsyncText(`${apiBase}worldState.php`);
1651
1685
  }
@@ -1835,14 +1869,14 @@ var globalOracleBountyCycle = createAsyncCache(
1835
1869
  );
1836
1870
 
1837
1871
  // src/warframe/data/wf/globalWorldState.ts
1838
- var import_warframe_public_export_plus3 = require("warframe-public-export-plus");
1872
+ var import_warframe_public_export_plus4 = require("warframe-public-export-plus");
1839
1873
 
1840
1874
  // src/warframe/infrastructure/wf/wf-export-adapter.ts
1841
- var import_warframe_public_export_plus = require("warframe-public-export-plus");
1875
+ var import_warframe_public_export_plus2 = require("warframe-public-export-plus");
1842
1876
  function regionToShort(region, dict) {
1843
1877
  let faction;
1844
1878
  if (region.faction) {
1845
- const name2 = import_warframe_public_export_plus.ExportFactions[region.faction].name;
1879
+ const name2 = import_warframe_public_export_plus2.ExportFactions[region.faction].name;
1846
1880
  if (name2) {
1847
1881
  faction = dict[name2];
1848
1882
  }
@@ -1871,9 +1905,9 @@ function fixRelicRewardKey(item) {
1871
1905
  __name(fixRelicRewardKey, "fixRelicRewardKey");
1872
1906
 
1873
1907
  // src/warframe/infrastructure/wf/wfcd-adapter.ts
1874
- var import_warframe_public_export_plus2 = require("warframe-public-export-plus");
1908
+ var import_warframe_public_export_plus3 = require("warframe-public-export-plus");
1875
1909
  function relicToFullNameZH(tier, category) {
1876
- return `${import_warframe_public_export_plus2.dict_zh[relicEraToTransKey(tier)] ?? toPascalCase(tier)} ${category} 遗物`;
1910
+ return `${import_warframe_public_export_plus3.dict_zh[relicEraToTransKey(tier)] ?? toPascalCase(tier)} ${category} 遗物`;
1877
1911
  }
1878
1912
  __name(relicToFullNameZH, "relicToFullNameZH");
1879
1913
  var solNodesEnDict;
@@ -1916,52 +1950,52 @@ function fissureTierNumToNumber(a) {
1916
1950
  __name(fissureTierNumToNumber, "fissureTierNumToNumber");
1917
1951
  function getVoidTraderItem(i) {
1918
1952
  const itemNameKey = getVoidTraderItemName(i.uniqueName);
1919
- const itemName = !itemNameKey ? i.item : typeof itemNameKey === "string" ? import_warframe_public_export_plus2.dict_zh[itemNameKey] ?? (itemNameKey.includes("/") ? i.item : itemNameKey) : relicToFullNameZH(itemNameKey.era, itemNameKey.category);
1953
+ const itemName = !itemNameKey ? i.item : typeof itemNameKey === "string" ? import_warframe_public_export_plus3.dict_zh[itemNameKey] ?? (itemNameKey.includes("/") ? i.item : itemNameKey) : relicToFullNameZH(itemNameKey.era, itemNameKey.category);
1920
1954
  return { name: itemName, ducats: i.ducats, credits: i.credits };
1921
1955
  }
1922
1956
  __name(getVoidTraderItem, "getVoidTraderItem");
1923
1957
  function getVoidTraderItemName(sourceKey) {
1924
1958
  const fixedKey = sourceKey.replace("/StoreItems", "");
1925
- const flavour = import_warframe_public_export_plus2.ExportFlavour[fixedKey];
1959
+ const flavour = import_warframe_public_export_plus3.ExportFlavour[fixedKey];
1926
1960
  if (flavour) {
1927
1961
  return flavour.name;
1928
1962
  }
1929
- const weapon = import_warframe_public_export_plus2.ExportWeapons[fixedKey];
1963
+ const weapon = import_warframe_public_export_plus3.ExportWeapons[fixedKey];
1930
1964
  if (weapon) {
1931
1965
  return weapon.name;
1932
1966
  }
1933
- const mod = import_warframe_public_export_plus2.ExportUpgrades[fixedKey];
1967
+ const mod = import_warframe_public_export_plus3.ExportUpgrades[fixedKey];
1934
1968
  if (mod) {
1935
1969
  return mod.name;
1936
1970
  }
1937
- const relic = import_warframe_public_export_plus2.ExportRelics[fixedKey];
1971
+ const relic = import_warframe_public_export_plus3.ExportRelics[fixedKey];
1938
1972
  if (relic) {
1939
1973
  return { era: relic.era, category: relic.category };
1940
1974
  }
1941
- const skin = import_warframe_public_export_plus2.ExportCustoms[fixedKey];
1975
+ const skin = import_warframe_public_export_plus3.ExportCustoms[fixedKey];
1942
1976
  if (skin) {
1943
1977
  return skin.name;
1944
1978
  }
1945
- const recipe = import_warframe_public_export_plus2.ExportRecipes[fixedKey];
1979
+ const recipe = import_warframe_public_export_plus3.ExportRecipes[fixedKey];
1946
1980
  if (recipe) {
1947
- const recipeResult = import_warframe_public_export_plus2.ExportKeys[recipe.resultType];
1981
+ const recipeResult = import_warframe_public_export_plus3.ExportKeys[recipe.resultType];
1948
1982
  if (recipeResult) {
1949
1983
  return recipeResult.name;
1950
1984
  }
1951
1985
  }
1952
- const virtual = import_warframe_public_export_plus2.ExportVirtuals[fixedKey];
1986
+ const virtual = import_warframe_public_export_plus3.ExportVirtuals[fixedKey];
1953
1987
  if (virtual) {
1954
1988
  return virtual.name;
1955
1989
  }
1956
- const resource = import_warframe_public_export_plus2.ExportResources[fixedKey];
1990
+ const resource = import_warframe_public_export_plus3.ExportResources[fixedKey];
1957
1991
  if (resource) {
1958
1992
  return resource.name;
1959
1993
  }
1960
- const booster = import_warframe_public_export_plus2.ExportBundles[sourceKey];
1994
+ const booster = import_warframe_public_export_plus3.ExportBundles[sourceKey];
1961
1995
  if (booster) {
1962
1996
  return booster.name;
1963
1997
  }
1964
- const boosterPack = import_warframe_public_export_plus2.ExportBoosterPacks[fixedKey];
1998
+ const boosterPack = import_warframe_public_export_plus3.ExportBoosterPacks[fixedKey];
1965
1999
  if (boosterPack) {
1966
2000
  return boosterPack.name;
1967
2001
  }
@@ -1971,13 +2005,13 @@ __name(getVoidTraderItemName, "getVoidTraderItemName");
1971
2005
  // src/warframe/data/wf/globalWorldState.ts
1972
2006
  async function adaptFissure(fissure) {
1973
2007
  const nodeKey = await getSolNodeKey(fissure.nodeKey);
1974
- const tierName = fissure.tierNum in fissureTierName ? import_warframe_public_export_plus3.dict_zh[fissureTierName[fissure.tierNum]] : fissure.tierNum;
2008
+ const tierName = fissure.tierNum in fissureTierName ? import_warframe_public_export_plus4.dict_zh[fissureTierName[fissure.tierNum]] : fissure.tierNum;
1975
2009
  return {
1976
2010
  category: fissure.isStorm ? "rj-fissures" : fissure.isHard ? "sp-fissures" : "fissures",
1977
2011
  hard: fissure.isHard,
1978
2012
  activation: fissure.activation?.getTime() ?? 0,
1979
2013
  expiry: fissure.expiry?.getTime() ?? 0,
1980
- node: regionToShort(import_warframe_public_export_plus3.ExportRegions[nodeKey], import_warframe_public_export_plus3.dict_zh),
2014
+ node: regionToShort(import_warframe_public_export_plus4.ExportRegions[nodeKey], import_warframe_public_export_plus4.dict_zh),
1981
2015
  tier: String(tierName),
1982
2016
  tierNum: fissureTierNumToNumber(fissure.tierNum)
1983
2017
  };
@@ -1989,6 +2023,7 @@ var globalWorldState = createAsyncCache(async () => {
1989
2023
  throw new Error("获取游戏信息失败");
1990
2024
  }
1991
2025
  const syndicateMissionsRaw = extractSyndicateMissionsRaw(json);
2026
+ const seasonInfoRaw = extractSeasonInfoRaw(json);
1992
2027
  const worldState = await getWorldState(json);
1993
2028
  const fissures = [];
1994
2029
  const rjFissures = [];
@@ -2009,6 +2044,7 @@ var globalWorldState = createAsyncCache(async () => {
2009
2044
  return {
2010
2045
  raw: worldState,
2011
2046
  syndicateMissionsRaw,
2047
+ seasonInfoRaw,
2012
2048
  fissures,
2013
2049
  spFissures,
2014
2050
  rjFissures
@@ -2016,12 +2052,12 @@ var globalWorldState = createAsyncCache(async () => {
2016
2052
  }, -1);
2017
2053
 
2018
2054
  // src/warframe/data/wf/relics.ts
2019
- var import_warframe_public_export_plus4 = require("warframe-public-export-plus");
2055
+ var import_warframe_public_export_plus5 = require("warframe-public-export-plus");
2020
2056
  var relics = (() => {
2021
2057
  const result = {};
2022
- for (const key in import_warframe_public_export_plus4.ExportRelics) {
2023
- const exportRelic = import_warframe_public_export_plus4.ExportRelics[key];
2024
- const exportRewards = import_warframe_public_export_plus4.ExportRewards[exportRelic.rewardManifest];
2058
+ for (const key in import_warframe_public_export_plus5.ExportRelics) {
2059
+ const exportRelic = import_warframe_public_export_plus5.ExportRelics[key];
2060
+ const exportRewards = import_warframe_public_export_plus5.ExportRewards[exportRelic.rewardManifest];
2025
2061
  const era = `/Lotus/Language/Relics/Era_${exportRelic.era.toUpperCase()}`;
2026
2062
  const relicKey = normalizeName(exportRelic.era + exportRelic.category);
2027
2063
  const rewards = (exportRewards[0] ?? []).map((r) => {
@@ -2059,13 +2095,13 @@ var rivenAttrValueDict = (() => {
2059
2095
  })();
2060
2096
 
2061
2097
  // src/warframe/data/wf/rivenDisposition.ts
2062
- var import_warframe_public_export_plus5 = require("warframe-public-export-plus");
2098
+ var import_warframe_public_export_plus6 = require("warframe-public-export-plus");
2063
2099
  var weaponRivenDispositionDict = (() => {
2064
2100
  const mapped = rivenCalc.weapons.reduce(
2065
2101
  (prev, element) => {
2066
2102
  let mapped2;
2067
- for (const weaponKey in import_warframe_public_export_plus5.ExportWeapons) {
2068
- const weapon = import_warframe_public_export_plus5.ExportWeapons[weaponKey];
2103
+ for (const weaponKey in import_warframe_public_export_plus6.ExportWeapons) {
2104
+ const weapon = import_warframe_public_export_plus6.ExportWeapons[weaponKey];
2069
2105
  const splited = weapon.name.split("/");
2070
2106
  if (splited.length <= 0) {
2071
2107
  continue;
@@ -2076,7 +2112,7 @@ var weaponRivenDispositionDict = (() => {
2076
2112
  mapped2 = weapon;
2077
2113
  break;
2078
2114
  }
2079
- const weaponEN2 = import_warframe_public_export_plus5.dict_en[weapon.name];
2115
+ const weaponEN2 = import_warframe_public_export_plus6.dict_en[weapon.name];
2080
2116
  if (weaponEN2 && normalizeName(weaponEN2) === normalizedCalcName) {
2081
2117
  mapped2 = weapon;
2082
2118
  break;
@@ -2085,8 +2121,8 @@ var weaponRivenDispositionDict = (() => {
2085
2121
  if (!mapped2) {
2086
2122
  return prev;
2087
2123
  }
2088
- const weaponEN = import_warframe_public_export_plus5.dict_en[mapped2.name];
2089
- const weaponZH = import_warframe_public_export_plus5.dict_zh[mapped2.name];
2124
+ const weaponEN = import_warframe_public_export_plus6.dict_en[mapped2.name];
2125
+ const weaponZH = import_warframe_public_export_plus6.dict_zh[mapped2.name];
2090
2126
  const result = {
2091
2127
  name: {
2092
2128
  en: weaponEN,
@@ -2320,7 +2356,7 @@ async function extractTextFromImage(image, secret) {
2320
2356
  __name(extractTextFromImage, "extractTextFromImage");
2321
2357
 
2322
2358
  // src/warframe/infrastructure/wf/bounty-adapter.ts
2323
- var import_warframe_public_export_plus6 = require("warframe-public-export-plus");
2359
+ var import_warframe_public_export_plus7 = require("warframe-public-export-plus");
2324
2360
  var bountyLocationTag = {
2325
2361
  cetus: "CetusSyndicate",
2326
2362
  fortuna: "SolarisSyndicate",
@@ -2485,13 +2521,13 @@ function resolveBlueprintNameViaDictZh(pathLeaf) {
2485
2521
  }
2486
2522
  const needle = `${base}Name`.toLowerCase();
2487
2523
  let translated;
2488
- for (const key of Object.keys(import_warframe_public_export_plus6.dict_zh)) {
2524
+ for (const key of Object.keys(import_warframe_public_export_plus7.dict_zh)) {
2489
2525
  if (!key.toLowerCase().endsWith(needle)) {
2490
2526
  continue;
2491
2527
  }
2492
2528
  const boundary = key.length - needle.length;
2493
2529
  if (boundary === 0 || key[boundary - 1] === "/" || key[boundary - 1] === "_") {
2494
- translated = import_warframe_public_export_plus6.dict_zh[key];
2530
+ translated = import_warframe_public_export_plus7.dict_zh[key];
2495
2531
  break;
2496
2532
  }
2497
2533
  }
@@ -2510,69 +2546,69 @@ function resolveExportItemNameZh(sourceKey) {
2510
2546
  return `${creditMatch[1]} 现金`;
2511
2547
  }
2512
2548
  const fixedKey = sourceKey.replace("/StoreItems", "");
2513
- const flavour = import_warframe_public_export_plus6.ExportFlavour[fixedKey];
2549
+ const flavour = import_warframe_public_export_plus7.ExportFlavour[fixedKey];
2514
2550
  if (flavour?.name) {
2515
- return import_warframe_public_export_plus6.dict_zh[flavour.name] ?? flavour.name;
2551
+ return import_warframe_public_export_plus7.dict_zh[flavour.name] ?? flavour.name;
2516
2552
  }
2517
- const weapon = import_warframe_public_export_plus6.ExportWeapons[fixedKey];
2553
+ const weapon = import_warframe_public_export_plus7.ExportWeapons[fixedKey];
2518
2554
  if (weapon?.name) {
2519
- return import_warframe_public_export_plus6.dict_zh[weapon.name] ?? weapon.name;
2555
+ return import_warframe_public_export_plus7.dict_zh[weapon.name] ?? weapon.name;
2520
2556
  }
2521
- const mod = import_warframe_public_export_plus6.ExportUpgrades[fixedKey];
2557
+ const mod = import_warframe_public_export_plus7.ExportUpgrades[fixedKey];
2522
2558
  if (mod?.name) {
2523
- return import_warframe_public_export_plus6.dict_zh[mod.name] ?? mod.name;
2559
+ return import_warframe_public_export_plus7.dict_zh[mod.name] ?? mod.name;
2524
2560
  }
2525
- const arcane = import_warframe_public_export_plus6.ExportArcanes[fixedKey];
2561
+ const arcane = import_warframe_public_export_plus7.ExportArcanes[fixedKey];
2526
2562
  if (arcane?.name) {
2527
- return import_warframe_public_export_plus6.dict_zh[arcane.name] ?? arcane.name;
2563
+ return import_warframe_public_export_plus7.dict_zh[arcane.name] ?? arcane.name;
2528
2564
  }
2529
- const fusion = import_warframe_public_export_plus6.ExportFusionBundles[fixedKey];
2565
+ const fusion = import_warframe_public_export_plus7.ExportFusionBundles[fixedKey];
2530
2566
  if (fusion?.name) {
2531
- return import_warframe_public_export_plus6.dict_zh[fusion.name] ?? fusion.name;
2567
+ return import_warframe_public_export_plus7.dict_zh[fusion.name] ?? fusion.name;
2532
2568
  }
2533
- const relic = import_warframe_public_export_plus6.ExportRelics[fixedKey];
2569
+ const relic = import_warframe_public_export_plus7.ExportRelics[fixedKey];
2534
2570
  if (relic) {
2535
- const era = import_warframe_public_export_plus6.dict_zh[relicEraToTransKey(relic.era)] ?? toPascalCase(relic.era);
2571
+ const era = import_warframe_public_export_plus7.dict_zh[relicEraToTransKey(relic.era)] ?? toPascalCase(relic.era);
2536
2572
  return `${era} ${relic.category} 遗物`;
2537
2573
  }
2538
- const skin = import_warframe_public_export_plus6.ExportCustoms[fixedKey];
2574
+ const skin = import_warframe_public_export_plus7.ExportCustoms[fixedKey];
2539
2575
  if (skin?.name) {
2540
- return import_warframe_public_export_plus6.dict_zh[skin.name] ?? skin.name;
2576
+ return import_warframe_public_export_plus7.dict_zh[skin.name] ?? skin.name;
2541
2577
  }
2542
- const recipe = import_warframe_public_export_plus6.ExportRecipes[fixedKey];
2578
+ const recipe = import_warframe_public_export_plus7.ExportRecipes[fixedKey];
2543
2579
  if (recipe?.resultType) {
2544
- const recipeResult = import_warframe_public_export_plus6.ExportKeys[recipe.resultType] ?? import_warframe_public_export_plus6.ExportResources[recipe.resultType] ?? import_warframe_public_export_plus6.ExportWeapons[recipe.resultType] ?? import_warframe_public_export_plus6.ExportWarframes[recipe.resultType];
2580
+ const recipeResult = import_warframe_public_export_plus7.ExportKeys[recipe.resultType] ?? import_warframe_public_export_plus7.ExportResources[recipe.resultType] ?? import_warframe_public_export_plus7.ExportWeapons[recipe.resultType] ?? import_warframe_public_export_plus7.ExportWarframes[recipe.resultType];
2545
2581
  if (recipeResult?.name) {
2546
- const translated = import_warframe_public_export_plus6.dict_zh[recipeResult.name] ?? recipeResult.name;
2582
+ const translated = import_warframe_public_export_plus7.dict_zh[recipeResult.name] ?? recipeResult.name;
2547
2583
  return translated.includes("蓝图") ? translated : `${translated} 蓝图`;
2548
2584
  }
2549
2585
  }
2550
- const virtual = import_warframe_public_export_plus6.ExportVirtuals[fixedKey];
2586
+ const virtual = import_warframe_public_export_plus7.ExportVirtuals[fixedKey];
2551
2587
  if (virtual?.name) {
2552
- return import_warframe_public_export_plus6.dict_zh[virtual.name] ?? virtual.name;
2588
+ return import_warframe_public_export_plus7.dict_zh[virtual.name] ?? virtual.name;
2553
2589
  }
2554
- const resource = import_warframe_public_export_plus6.ExportResources[fixedKey];
2590
+ const resource = import_warframe_public_export_plus7.ExportResources[fixedKey];
2555
2591
  if (resource?.name) {
2556
- return import_warframe_public_export_plus6.dict_zh[resource.name] ?? resource.name;
2592
+ return import_warframe_public_export_plus7.dict_zh[resource.name] ?? resource.name;
2557
2593
  }
2558
- const gear = import_warframe_public_export_plus6.ExportGear[fixedKey];
2594
+ const gear = import_warframe_public_export_plus7.ExportGear[fixedKey];
2559
2595
  if (gear?.name) {
2560
- return import_warframe_public_export_plus6.dict_zh[gear.name] ?? gear.name;
2596
+ return import_warframe_public_export_plus7.dict_zh[gear.name] ?? gear.name;
2561
2597
  }
2562
- const bundle = import_warframe_public_export_plus6.ExportBundles[sourceKey] ?? import_warframe_public_export_plus6.ExportBundles[fixedKey];
2598
+ const bundle = import_warframe_public_export_plus7.ExportBundles[sourceKey] ?? import_warframe_public_export_plus7.ExportBundles[fixedKey];
2563
2599
  if (bundle?.name) {
2564
- return import_warframe_public_export_plus6.dict_zh[bundle.name] ?? bundle.name;
2600
+ return import_warframe_public_export_plus7.dict_zh[bundle.name] ?? bundle.name;
2565
2601
  }
2566
- const boosterPack = import_warframe_public_export_plus6.ExportBoosterPacks[fixedKey];
2602
+ const boosterPack = import_warframe_public_export_plus7.ExportBoosterPacks[fixedKey];
2567
2603
  if (boosterPack?.name) {
2568
- return import_warframe_public_export_plus6.dict_zh[boosterPack.name] ?? boosterPack.name;
2604
+ return import_warframe_public_export_plus7.dict_zh[boosterPack.name] ?? boosterPack.name;
2569
2605
  }
2570
2606
  const pathLeaf = fixedKey.split("/").pop() ?? sourceKey;
2571
2607
  return resolveBlueprintNameViaDictZh(pathLeaf) ?? pathLeaf;
2572
2608
  }
2573
2609
  __name(resolveExportItemNameZh, "resolveExportItemNameZh");
2574
2610
  function rewardsFromDeck(rewardsKey) {
2575
- const deck = import_warframe_public_export_plus6.ExportRewards[rewardsKey];
2611
+ const deck = import_warframe_public_export_plus7.ExportRewards[rewardsKey];
2576
2612
  if (!deck?.length) {
2577
2613
  return [];
2578
2614
  }
@@ -2605,9 +2641,9 @@ function jobName(job) {
2605
2641
  return chamber ? `隔离库 ${chamber}` : "隔离库";
2606
2642
  }
2607
2643
  if (job.jobType) {
2608
- const bounty = import_warframe_public_export_plus6.ExportBounties[job.jobType];
2644
+ const bounty = import_warframe_public_export_plus7.ExportBounties[job.jobType];
2609
2645
  if (bounty?.name) {
2610
- return import_warframe_public_export_plus6.dict_zh[bounty.name] ?? bounty.name;
2646
+ return import_warframe_public_export_plus7.dict_zh[bounty.name] ?? bounty.name;
2611
2647
  }
2612
2648
  return job.jobType.split("/").pop() ?? "未知赏金";
2613
2649
  }
@@ -2615,9 +2651,9 @@ function jobName(job) {
2615
2651
  }
2616
2652
  __name(jobName, "jobName");
2617
2653
  function boardTitle(location, tag) {
2618
- const syndicate = import_warframe_public_export_plus6.ExportSyndicates[tag];
2654
+ const syndicate = import_warframe_public_export_plus7.ExportSyndicates[tag];
2619
2655
  if (syndicate?.name) {
2620
- const name2 = import_warframe_public_export_plus6.dict_zh[syndicate.name] ?? syndicate.name;
2656
+ const name2 = import_warframe_public_export_plus7.dict_zh[syndicate.name] ?? syndicate.name;
2621
2657
  return name2.endsWith("赏金") ? name2 : `${name2}赏金`;
2622
2658
  }
2623
2659
  return locationFallbackTitle[location];
@@ -2654,15 +2690,15 @@ function findRawSyndicateMission(missions, location) {
2654
2690
  }
2655
2691
  __name(findRawSyndicateMission, "findRawSyndicateMission");
2656
2692
  function formatOracleMission(nodeKey) {
2657
- const region = import_warframe_public_export_plus6.ExportRegions[nodeKey];
2693
+ const region = import_warframe_public_export_plus7.ExportRegions[nodeKey];
2658
2694
  if (!region?.name) {
2659
2695
  return nodeKey;
2660
2696
  }
2661
- const name2 = import_warframe_public_export_plus6.dict_zh[region.name] ?? region.name;
2697
+ const name2 = import_warframe_public_export_plus7.dict_zh[region.name] ?? region.name;
2662
2698
  if (hexNodesWithoutMissionSuffix.has(nodeKey) || !region.missionName) {
2663
2699
  return name2;
2664
2700
  }
2665
- const mission = import_warframe_public_export_plus6.dict_zh[region.missionName] ?? region.missionName;
2701
+ const mission = import_warframe_public_export_plus7.dict_zh[region.missionName] ?? region.missionName;
2666
2702
  if (!mission || mission === name2) {
2667
2703
  return name2;
2668
2704
  }
@@ -2670,21 +2706,21 @@ function formatOracleMission(nodeKey) {
2670
2706
  }
2671
2707
  __name(formatOracleMission, "formatOracleMission");
2672
2708
  function formatOracleChallenge(challengePath) {
2673
- const challenge = import_warframe_public_export_plus6.ExportChallenges[challengePath];
2709
+ const challenge = import_warframe_public_export_plus7.ExportChallenges[challengePath];
2674
2710
  if (!challenge?.description) {
2675
2711
  return challengePath.split("/").pop() ?? challengePath;
2676
2712
  }
2677
- const raw = import_warframe_public_export_plus6.dict_zh[challenge.description] ?? challenge.description;
2713
+ const raw = import_warframe_public_export_plus7.dict_zh[challenge.description] ?? challenge.description;
2678
2714
  const lastLine = raw.split(/\r?\n/).pop() ?? raw;
2679
2715
  return lastLine.split("|COUNT|").join(String(challenge.requiredCount ?? 0));
2680
2716
  }
2681
2717
  __name(formatOracleChallenge, "formatOracleChallenge");
2682
2718
  function zarimanFactionZh(faction) {
2683
2719
  if (faction === "FC_GRINEER") {
2684
- return import_warframe_public_export_plus6.dict_zh["/Lotus/Language/Game/Faction_GrineerUC"] ?? "Grineer";
2720
+ return import_warframe_public_export_plus7.dict_zh["/Lotus/Language/Game/Faction_GrineerUC"] ?? "Grineer";
2685
2721
  }
2686
2722
  if (faction === "FC_CORPUS") {
2687
- return import_warframe_public_export_plus6.dict_zh["/Lotus/Language/Game/Faction_CorpusUC"] ?? "Corpus";
2723
+ return import_warframe_public_export_plus7.dict_zh["/Lotus/Language/Game/Faction_CorpusUC"] ?? "Corpus";
2688
2724
  }
2689
2725
  return void 0;
2690
2726
  }
@@ -2727,6 +2763,101 @@ function adaptOracleBountyBoard(location, cycle) {
2727
2763
  }
2728
2764
  __name(adaptOracleBountyBoard, "adaptOracleBountyBoard");
2729
2765
 
2766
+ // src/warframe/infrastructure/wf/nightwave-adapter.ts
2767
+ var import_warframe_public_export_plus8 = require("warframe-public-export-plus");
2768
+ var RADIO_LEGION_TITLE_KEY = "/Lotus/Language/Syndicates/RadioLegionTitle";
2769
+ function timestampMs(value) {
2770
+ const raw = value?.$date?.$numberLong;
2771
+ if (raw === void 0 || raw === "") {
2772
+ return 0;
2773
+ }
2774
+ const ms = Number(raw);
2775
+ return Number.isFinite(ms) ? ms : 0;
2776
+ }
2777
+ __name(timestampMs, "timestampMs");
2778
+ function remainingLabel(expiry, now) {
2779
+ return msToHumanReadable(Math.max(expiry - now, 0));
2780
+ }
2781
+ __name(remainingLabel, "remainingLabel");
2782
+ function translate(key) {
2783
+ return import_warframe_public_export_plus8.dict_zh[key] ?? dictZhExtra[key] ?? key;
2784
+ }
2785
+ __name(translate, "translate");
2786
+ function seasonTitle(affiliationTag) {
2787
+ const syndicate = import_warframe_public_export_plus8.ExportSyndicates[affiliationTag];
2788
+ if (syndicate?.name) {
2789
+ return translate(syndicate.name);
2790
+ }
2791
+ return translate(RADIO_LEGION_TITLE_KEY);
2792
+ }
2793
+ __name(seasonTitle, "seasonTitle");
2794
+ function classifyChallenge(path, raw) {
2795
+ if (raw.Daily || path.includes("/Daily/")) {
2796
+ return "daily";
2797
+ }
2798
+ if (raw.Permanent || /permanent/i.test(path)) {
2799
+ return "permanent";
2800
+ }
2801
+ if (/hard/i.test(path)) {
2802
+ return "elite";
2803
+ }
2804
+ return "weekly";
2805
+ }
2806
+ __name(classifyChallenge, "classifyChallenge");
2807
+ function challengeFallbackName(path) {
2808
+ return path.split("/").pop() ?? path;
2809
+ }
2810
+ __name(challengeFallbackName, "challengeFallbackName");
2811
+ function adaptChallenge(raw, now) {
2812
+ const path = raw.Challenge;
2813
+ if (!path) {
2814
+ return void 0;
2815
+ }
2816
+ const expiry = timestampMs(raw.Expiry);
2817
+ if (expiry <= now) {
2818
+ return void 0;
2819
+ }
2820
+ const kind = classifyChallenge(path, raw);
2821
+ const remaining = remainingLabel(expiry, now);
2822
+ const exported = import_warframe_public_export_plus8.ExportNightwave.challenges[path];
2823
+ if (!exported) {
2824
+ return {
2825
+ name: challengeFallbackName(path),
2826
+ description: "",
2827
+ kind,
2828
+ remaining
2829
+ };
2830
+ }
2831
+ const description = translate(exported.description).split("|COUNT|").join(String(exported.required));
2832
+ return {
2833
+ name: translate(exported.name),
2834
+ description,
2835
+ kind,
2836
+ remaining,
2837
+ standing: exported.standing
2838
+ };
2839
+ }
2840
+ __name(adaptChallenge, "adaptChallenge");
2841
+ function adaptNightwave(raw, now = Date.now()) {
2842
+ const expiry = timestampMs(raw.Expiry);
2843
+ const challenges = [];
2844
+ for (const entry of raw.ActiveChallenges) {
2845
+ const adapted = adaptChallenge(entry, now);
2846
+ if (adapted) {
2847
+ challenges.push(adapted);
2848
+ }
2849
+ }
2850
+ return {
2851
+ title: seasonTitle(raw.AffiliationTag),
2852
+ season: raw.Season,
2853
+ phase: raw.Phase,
2854
+ expiry,
2855
+ remaining: remainingLabel(expiry, now),
2856
+ challenges
2857
+ };
2858
+ }
2859
+ __name(adaptNightwave, "adaptNightwave");
2860
+
2730
2861
  // src/warframe/services/wf-service.ts
2731
2862
  async function getRelic(input) {
2732
2863
  if (!input) {
@@ -2788,7 +2919,7 @@ function getArbitrations(day = 3) {
2788
2919
  return {
2789
2920
  ok: true,
2790
2921
  data: weekArbys.filter((a) => arbyRewards[a.node]).map((a) => {
2791
- const obj = regionToShort(import_warframe_public_export_plus7.ExportRegions[a.node], import_warframe_public_export_plus7.dict_zh);
2922
+ const obj = regionToShort(import_warframe_public_export_plus9.ExportRegions[a.node], import_warframe_public_export_plus9.dict_zh);
2792
2923
  return {
2793
2924
  ...obj,
2794
2925
  time: new Date(a.time * 1e3).toLocaleString("zh-cn", {
@@ -2809,15 +2940,46 @@ function getArbitrations(day = 3) {
2809
2940
  };
2810
2941
  }
2811
2942
  __name(getArbitrations, "getArbitrations");
2943
+ async function adaptArchonHunt(source) {
2944
+ const name2 = import_warframe_public_export_plus9.dict_zh[`/Lotus/Language/Narmer/${removeSpace(source.boss)}`] ?? source.boss;
2945
+ const missions = await Promise.all(
2946
+ (source.missions ?? []).map(async (mission, index) => {
2947
+ const receivedType = await getMissionTypeKey(mission.type);
2948
+ const type = import_warframe_public_export_plus9.dict_zh[import_warframe_public_export_plus9.ExportMissionTypes[receivedType]?.name ?? ""] ?? mission.type;
2949
+ const solNodeKey = await getSolNodeKey(mission.nodeKey);
2950
+ const region = solNodeKey ? import_warframe_public_export_plus9.ExportRegions[solNodeKey] : void 0;
2951
+ const levels = getArchonHuntEnemyLevels(index);
2952
+ const node = region ? regionToShort(region, import_warframe_public_export_plus9.dict_zh) : {
2953
+ name: mission.node ?? mission.nodeKey,
2954
+ system: "",
2955
+ type: "",
2956
+ faction: "",
2957
+ minLevel: 0,
2958
+ maxLevel: 0
2959
+ };
2960
+ return {
2961
+ type,
2962
+ node: {
2963
+ ...node,
2964
+ minLevel: levels.minLevel,
2965
+ maxLevel: levels.maxLevel
2966
+ }
2967
+ };
2968
+ })
2969
+ );
2970
+ return {
2971
+ modeName: getArchonHuntModeName(),
2972
+ name: name2,
2973
+ missions
2974
+ };
2975
+ }
2976
+ __name(adaptArchonHunt, "adaptArchonHunt");
2812
2977
  async function getWeekly() {
2813
2978
  const { raw: worldState } = await globalWorldState.get();
2814
2979
  if (!worldState) {
2815
2980
  return failure("common.fetchFailed", true);
2816
2981
  }
2817
- const archon = {
2818
- name: import_warframe_public_export_plus7.dict_zh[`/Lotus/Language/Narmer/${removeSpace(worldState.archonHunt.boss)}`],
2819
- missions: []
2820
- };
2982
+ const archon = await adaptArchonHunt(worldState.archonHunt);
2821
2983
  const stringToDebuff = /* @__PURE__ */ __name((key, name2, prefix) => {
2822
2984
  const keyToName = dictZhExtra[`${prefix}${key}`];
2823
2985
  if (!keyToName) {
@@ -2840,7 +3002,7 @@ async function getWeekly() {
2840
3002
  const deepArchimMissions = await Promise.all(
2841
3003
  deepArchim.missions.map(async (m) => {
2842
3004
  const receivedType = await getMissionTypeKey(m.missionType);
2843
- const type = import_warframe_public_export_plus7.dict_zh[import_warframe_public_export_plus7.ExportMissionTypes[receivedType]?.name ?? ""] ?? m.missionType;
3005
+ const type = import_warframe_public_export_plus9.dict_zh[import_warframe_public_export_plus9.ExportMissionTypes[receivedType]?.name ?? ""] ?? m.missionType;
2844
3006
  const deviation = stringToDebuff(
2845
3007
  m.deviation.key,
2846
3008
  m.deviation.name,
@@ -2868,7 +3030,7 @@ async function getWeekly() {
2868
3030
  const temporalArchimMissions = await Promise.all(
2869
3031
  temporalArchim.missions.map(async (m) => {
2870
3032
  const receivedType = await getMissionTypeKey(m.missionType);
2871
- const type = import_warframe_public_export_plus7.dict_zh[import_warframe_public_export_plus7.ExportMissionTypes[receivedType]?.name ?? ""] ?? receivedType;
3033
+ const type = import_warframe_public_export_plus9.dict_zh[import_warframe_public_export_plus9.ExportMissionTypes[receivedType]?.name ?? ""] ?? receivedType;
2872
3034
  const deviation = stringToDebuff(
2873
3035
  m.deviation.key,
2874
3036
  m.deviation.name,
@@ -2902,6 +3064,22 @@ async function getWeekly() {
2902
3064
  };
2903
3065
  }
2904
3066
  __name(getWeekly, "getWeekly");
3067
+ function resolveNightwave(raw, now = Date.now()) {
3068
+ if (!raw) {
3069
+ return failure("nightwave.unavailable");
3070
+ }
3071
+ return { ok: true, data: adaptNightwave(raw, now) };
3072
+ }
3073
+ __name(resolveNightwave, "resolveNightwave");
3074
+ async function getNightwave() {
3075
+ try {
3076
+ const { seasonInfoRaw } = await globalWorldState.get();
3077
+ return resolveNightwave(seasonInfoRaw);
3078
+ } catch {
3079
+ return failure("common.fetchFailed", true);
3080
+ }
3081
+ }
3082
+ __name(getNightwave, "getNightwave");
2905
3083
  async function getEnvironment() {
2906
3084
  const { raw: worldState } = await globalWorldState.get();
2907
3085
  if (!worldState) {
@@ -2967,8 +3145,8 @@ function getCircuitWeek() {
2967
3145
  const week = Math.trunc((Date.now() - EPOCH) / 6048e5);
2968
3146
  const index1 = (week + 1) % incarnons.length;
2969
3147
  const index2 = (week + 8) % warframes.length;
2970
- const incarnons2 = incarnons.map((v) => v.map((i) => import_warframe_public_export_plus7.dict_zh[i]));
2971
- const warframes2 = warframes.map((v) => v.map((i) => import_warframe_public_export_plus7.dict_zh[i]));
3148
+ const incarnons2 = incarnons.map((v) => v.map((i) => import_warframe_public_export_plus9.dict_zh[i]));
3149
+ const warframes2 = warframes.map((v) => v.map((i) => import_warframe_public_export_plus9.dict_zh[i]));
2972
3150
  return {
2973
3151
  currentIncarnons: index1,
2974
3152
  currentWarframes: index2,
@@ -3355,7 +3533,7 @@ function analyzeRivenStat(parseResult) {
3355
3533
  __name(analyzeRivenStat, "analyzeRivenStat");
3356
3534
 
3357
3535
  // src/warframe/services/wfm-service/index.ts
3358
- var import_warframe_public_export_plus8 = require("warframe-public-export-plus");
3536
+ var import_warframe_public_export_plus10 = require("warframe-public-export-plus");
3359
3537
 
3360
3538
  // src/warframe/data/wfm/globalDucatnator.ts
3361
3539
  var globalDucatnatorIDDict = createAsyncCache(async () => {
@@ -4179,7 +4357,7 @@ async function getRivenOrders(input) {
4179
4357
  }
4180
4358
  __name(getRivenOrders, "getRivenOrders");
4181
4359
  async function applyRelicData(relic) {
4182
- const tier = import_warframe_public_export_plus8.dict_zh[relic.tierKey] ?? relic.tier;
4360
+ const tier = import_warframe_public_export_plus10.dict_zh[relic.tierKey] ?? relic.tier;
4183
4361
  const { globalItemGameRefDict } = await globalItemData.get();
4184
4362
  const wfmDict = await globalDucatnatorIDDict.get();
4185
4363
  const loadedItems = relic.items.map((element) => {
@@ -4268,7 +4446,7 @@ var primedModHistory = createAsyncCache(async () => {
4268
4446
  }, 432e5);
4269
4447
 
4270
4448
  // src/warframe/services/world-state-refresh.ts
4271
- var import_warframe_public_export_plus9 = require("warframe-public-export-plus");
4449
+ var import_warframe_public_export_plus11 = require("warframe-public-export-plus");
4272
4450
  var ALLOWED_FISSURE_MISSION_TYPES = /* @__PURE__ */ new Set(["MT_EXTERMINATION", "MT_DEFENSE", "MT_ARTIFACT"]);
4273
4451
  function time(value) {
4274
4452
  return value?.getTime() ?? 0;
@@ -4287,7 +4465,7 @@ function fissureId(value) {
4287
4465
  __name(fissureId, "fissureId");
4288
4466
  async function fissureMissionType(fissure) {
4289
4467
  const nodeKey = await getSolNodeKey(fissure.nodeKey);
4290
- return import_warframe_public_export_plus9.ExportRegions[nodeKey]?.missionType;
4468
+ return import_warframe_public_export_plus11.ExportRegions[nodeKey]?.missionType;
4291
4469
  }
4292
4470
  __name(fissureMissionType, "fissureMissionType");
4293
4471
  function dailyDealId(value) {
@@ -5167,7 +5345,15 @@ function WeeklyComponent(archon, deepArchimedea, temporalArchimedea) {
5167
5345
  `;
5168
5346
  const archonHuntSection = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { style: sectionStyle, children: [
5169
5347
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:12px;color:var(--wf-text-muted);margin-bottom:6px;", children: "Archon Hunt" }),
5170
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:16px;font-weight:600;color:var(--wf-text-primary);", children: `执行官刺杀: ${archon.name}` })
5348
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:16px;font-weight:600;color:var(--wf-text-primary);margin-bottom:8px;", children: `${archon.modeName}: ${archon.name}` }),
5349
+ archon.missions.map((mission) => {
5350
+ const location = [mission.node.system, mission.node.name, mission.node.faction].filter(Boolean).join(" · ");
5351
+ const levels = mission.node.minLevel && mission.node.maxLevel ? `Lv.${mission.node.minLevel}-${mission.node.maxLevel}` : "";
5352
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: missionCardStyle, children: [
5353
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:13px;font-weight:600;margin-bottom:4px;color:var(--wf-text-body);", children: mission.type }),
5354
+ location || levels ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:12px;color:var(--wf-text-secondary);", children: [location, levels].filter(Boolean).join(" · ") }) : null
5355
+ ] });
5356
+ })
5171
5357
  ] });
5172
5358
  const deepArchimedeaSection = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { style: sectionStyle, children: [
5173
5359
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:12px;color:var(--wf-success);margin-bottom:6px;", children: "Deep Archimedea" }),
@@ -5239,6 +5425,44 @@ function WeeklyComponent(archon, deepArchimedea, temporalArchimedea) {
5239
5425
  );
5240
5426
  }
5241
5427
  __name(WeeklyComponent, "WeeklyComponent");
5428
+ function NightwaveComponent(board) {
5429
+ const kindLabel = {
5430
+ daily: "每日",
5431
+ weekly: "每周",
5432
+ elite: "精英",
5433
+ permanent: "精选"
5434
+ };
5435
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5436
+ "div",
5437
+ {
5438
+ style: "width:560px;background-color:var(--wf-bg-card);border-radius:var(--wf-radius);padding:10px 12px;box-shadow:var(--wf-shadow-card);border:1px solid var(--wf-border);font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;color:var(--wf-text-body);",
5439
+ children: [
5440
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { style: "font-size:18px;font-weight:bold;color:var(--wf-text-primary);margin:0 0 2px 0;text-align:center;", children: board.title }),
5441
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "text-align:center;font-size:12px;color:var(--wf-text-secondary);margin-bottom:2px;", children: `第${board.season + 1}季 · 剩余${board.remaining}` }),
5442
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "text-align:center;font-size:10px;color:var(--wf-text-muted);margin-bottom:8px;", children: "剩余时间不准确,最多可能偏差数月" }),
5443
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "display:flex;flex-direction:column;gap:4px;", children: board.challenges.map((challenge) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5444
+ "div",
5445
+ {
5446
+ style: "padding:6px 8px;background-color:var(--wf-bg-subtle);border-radius:var(--wf-radius-sm);",
5447
+ children: [
5448
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: "display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;", children: [
5449
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: "font-size:11px;color:var(--wf-accent);", children: kindLabel[challenge.kind] }),
5450
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: "font-size:13px;font-weight:700;color:var(--wf-text-primary);flex:1;", children: challenge.name }),
5451
+ challenge.standing === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: "font-size:11px;color:var(--wf-accent);", children: `${challenge.standing} 声望` }),
5452
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: "font-size:11px;color:var(--wf-text-muted);", children: [
5453
+ "剩余",
5454
+ challenge.remaining
5455
+ ] })
5456
+ ] }),
5457
+ challenge.description ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: "font-size:11px;line-height:1.35;color:var(--wf-text-body);margin-top:2px;", children: challenge.description }) : null
5458
+ ]
5459
+ }
5460
+ )) })
5461
+ ]
5462
+ }
5463
+ );
5464
+ }
5465
+ __name(NightwaveComponent, "NightwaveComponent");
5242
5466
  function RelicComponent(relic) {
5243
5467
  const gold = relic.items.filter((i) => i.rarity === "RARE");
5244
5468
  const silver = relic.items.filter((i) => i.rarity === "UNCOMMON");
@@ -6196,6 +6420,13 @@ function createWfCommands(deps) {
6196
6420
  )
6197
6421
  );
6198
6422
  }, "weeklyCommand"),
6423
+ nightwaveCommand: /* @__PURE__ */ __name(async (_action) => {
6424
+ const result = await getNightwave();
6425
+ if (!result.ok) {
6426
+ return t(result);
6427
+ }
6428
+ return render(NightwaveComponent(result.data));
6429
+ }, "nightwaveCommand"),
6199
6430
  weeklyRivenCommand: /* @__PURE__ */ __name(async (_action, minPrice) => {
6200
6431
  const threshold = minPrice && minPrice > 0 ? minPrice : 100;
6201
6432
  const result = await getWeeklyRivens(threshold);
@@ -6965,6 +7196,7 @@ function setupCommands(ctx, deps) {
6965
7196
  ctx.command("bounty-cavia", "科维兽赏金").alias("科维兽").alias("科维兽赏金").alias("赏金科维兽").alias("cavia").action(wf.bountyCaviaCommand);
6966
7197
  ctx.command("bounty-hex", "六人组赏金").alias("六人组").alias("六人组赏金").alias("赏金六人组").alias("1999赏金").alias("hex").action(wf.bountyHexCommand);
6967
7198
  ctx.command("weekly", "周常任务").alias("周常").alias("科研").alias("时光科研").alias("深层科研").alias("执行官").action(wf.weeklyCommand);
7199
+ ctx.command("nightwave", "当前午夜电波").alias("电波").alias("午夜电波").action(wf.nightwaveCommand);
6968
7200
  ctx.command("circuit", "本周回廊战甲及灵化之源").alias("灵化之源").alias("灵化").action(wf.circuitCommand);
6969
7201
  ctx.command("riven <img:image>", "分析紫卡截图").action(wf.rivenCommand);
6970
7202
  ctx.command(