feat(recipedata): add catalog + load result, wire csharpier
Two concerns bundled into one commit because the csharpier tool restore reformatted four earlier files as soon as the manifest landed: - .config/dotnet-tools.json: csharpier 1.2.6 as local tool, follows the standard .config layout (dotnet tool restore will find it). - Anvil/packages.lock.json: produced by dotnet restore, pinned alongside the csproj's RestorePackagesWithLockFile=true. - Anvil/RecipeData/RecipeDataLoadResult.cs: public record carrying the adapter's load-pass summary (counts + duration + warnings). Surfaced to the SelfTest step and future UI status surfaces. - Anvil/RecipeData/RecipeDataCatalog.cs: public DI singleton with all seven dictionary lookups, the two helper methods (ActionsForClassJob, TryResolveActionRowId), and the four meta properties from spec §2.7. Backed by a private CatalogState record that the adapter swaps in via a volatile reference - readers either see the empty initial state or the fully populated post-load snapshot, never a partial mid-build. TryResolveActionRowId carries the Cosmic-sentinel logic so hook code does not need to know about the CosmicOnly flag itself. - Reformatting in AnvilAction.cs, ActionMechanicsTable.cs, ConditionMechanicsTable.cs, and Anvil.csproj: csharpier-mandated line-wrap / blank-line tweaks. No semantic changes.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/dotnet-tools.json",
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"csharpier": {
|
||||
"version": "1.2.6",
|
||||
"commands": ["csharpier"],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-12
@@ -24,18 +24,9 @@
|
||||
Include="Microsoft.Extensions.DependencyInjection"
|
||||
Version="[10.0.7, 11.0.0)"
|
||||
/>
|
||||
<PackageReference
|
||||
Include="Microsoft.Extensions.Hosting"
|
||||
Version="[10.0.7, 11.0.0)"
|
||||
/>
|
||||
<PackageReference
|
||||
Include="Microsoft.Extensions.Logging"
|
||||
Version="[10.0.7, 11.0.0)"
|
||||
/>
|
||||
<PackageReference
|
||||
Include="Microsoft.Extensions.Options"
|
||||
Version="[10.0.7, 11.0.0)"
|
||||
/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="[10.0.7, 11.0.0)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="[10.0.7, 11.0.0)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="[10.0.7, 11.0.0)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -103,6 +103,7 @@ public enum AnvilActionFlags : ushort
|
||||
None = 0,
|
||||
RequiresGoodOrExcellent = 1 << 0,
|
||||
RequiresFirstStep = 1 << 1,
|
||||
|
||||
// 1 << 2 reserved (see comment above)
|
||||
SpecialistOnly = 1 << 3,
|
||||
NoBuffTick = 1 << 4,
|
||||
|
||||
@@ -265,7 +265,8 @@ internal static class ActionMechanicsTable
|
||||
IqStackBonus = 0,
|
||||
ChargesPerCraft = 1,
|
||||
GrantsBuff = null,
|
||||
Flags = AnvilActionFlags.RequiresFirstStep | AnvilActionFlags.RequiresLowLevelRecipe,
|
||||
Flags =
|
||||
AnvilActionFlags.RequiresFirstStep | AnvilActionFlags.RequiresLowLevelRecipe,
|
||||
},
|
||||
[AnvilActionKind.TrainedFinesse] = new ActionMechanicsEntry
|
||||
{
|
||||
|
||||
@@ -20,7 +20,10 @@ namespace Anvil.RecipeData.Mechanics;
|
||||
|
||||
internal static class ConditionMechanicsTable
|
||||
{
|
||||
public static IReadOnlyDictionary<AnvilConditionKind, ConditionMechanicsEntry> Entries { get; } =
|
||||
public static IReadOnlyDictionary<
|
||||
AnvilConditionKind,
|
||||
ConditionMechanicsEntry
|
||||
> Entries { get; } =
|
||||
new Dictionary<AnvilConditionKind, ConditionMechanicsEntry>
|
||||
{
|
||||
[AnvilConditionKind.Normal] = new ConditionMechanicsEntry
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
// Public read-only catalog of all Anvil RecipeData. Registered as a DI
|
||||
// singleton; consumers (simulator, solver, macro engine, IPC, UI) inject
|
||||
// the instance and pull whichever dictionary they need.
|
||||
//
|
||||
// IsLoaded gates everything: the catalog starts empty (no NREs, just empty
|
||||
// collections) and the LuminaRecipeAdapter swaps in a fully populated state
|
||||
// snapshot once the sheet walk finishes. UI windows render a spinner until
|
||||
// IsLoaded flips to true (200-800 ms after plugin start). The swap goes
|
||||
// through a volatile reference so cross-thread readers see the new state
|
||||
// atomically without an explicit lock.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Anvil.RecipeData;
|
||||
|
||||
public sealed class RecipeDataCatalog
|
||||
{
|
||||
private volatile CatalogState _state = CatalogState.Empty;
|
||||
|
||||
// Recipe lookups
|
||||
public IReadOnlyDictionary<uint, AnvilRecipe> RecipesById => _state.RecipesById;
|
||||
public IReadOnlyDictionary<uint, IReadOnlyList<AnvilRecipe>> RecipesByOutputItemId =>
|
||||
_state.RecipesByOutputItemId;
|
||||
public IReadOnlyDictionary<uint, IReadOnlyList<AnvilRecipe>> RecipesByClassJobId =>
|
||||
_state.RecipesByClassJobId;
|
||||
|
||||
// Item lookups
|
||||
public IReadOnlyDictionary<uint, AnvilItem> ItemsById => _state.ItemsById;
|
||||
|
||||
// Action lookups - two complementary paths.
|
||||
// ActionsByKind is the simulator's path ("Basic Synthesis" is one entity).
|
||||
// ActionsByLuminaRowId is the hook's path (UseAction / IsActionHighlighted
|
||||
// see the per-job RowId from the game). Cosmic actions appear once in
|
||||
// ActionsByLuminaRowId (their single sentinel RowId from the Action sheet);
|
||||
// non-Cosmic actions appear eight times (one per crafter job), each
|
||||
// pointing at the same AnvilAction record.
|
||||
public IReadOnlyDictionary<AnvilActionKind, AnvilAction> ActionsByKind => _state.ActionsByKind;
|
||||
public IReadOnlyDictionary<uint, AnvilAction> ActionsByLuminaRowId =>
|
||||
_state.ActionsByLuminaRowId;
|
||||
|
||||
// Buff / Condition catalogs
|
||||
public IReadOnlyDictionary<AnvilBuffKind, AnvilBuff> BuffsByKind => _state.BuffsByKind;
|
||||
public IReadOnlyDictionary<AnvilConditionKind, AnvilCondition> ConditionsByKind =>
|
||||
_state.ConditionsByKind;
|
||||
|
||||
// Food / Medicine catalogs (split into two lists because the UI treats
|
||||
// them as two separate equip slots).
|
||||
public IReadOnlyList<AnvilFood> Foods => _state.Foods;
|
||||
public IReadOnlyList<AnvilFood> Medicines => _state.Medicines;
|
||||
|
||||
// Meta
|
||||
public bool IsLoaded => _state.IsLoaded;
|
||||
public DateTime? LoadedAt => _state.LoadedAt;
|
||||
public int RecipeCount => _state.RecipesById.Count;
|
||||
public int ActionCount => _state.ActionsByKind.Count;
|
||||
|
||||
// Returns every action a given crafter job has unlocked at the given
|
||||
// level. Cosmic-only actions (sentinel-keyed under ClassJobId 0) are
|
||||
// excluded - this helper has no recipe argument and therefore no way
|
||||
// to gate the Cosmic surface correctly. Consumers that need Cosmic
|
||||
// actions must combine AnvilRecipe.IsCosmic with
|
||||
// AnvilActionFlags.CosmicOnly themselves.
|
||||
public IReadOnlyList<AnvilAction> ActionsForClassJob(uint classJobId, byte characterLevel)
|
||||
{
|
||||
if (classJobId == 0)
|
||||
return Array.Empty<AnvilAction>();
|
||||
|
||||
var result = new List<AnvilAction>();
|
||||
foreach (var action in _state.ActionsByKind.Values)
|
||||
{
|
||||
if (!action.RowIdByClassJob.ContainsKey(classJobId))
|
||||
continue;
|
||||
if (action.LevelRequired > characterLevel)
|
||||
continue;
|
||||
result.Add(action);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Resolves the in-game RowId an UseAction / IsActionHighlighted hook
|
||||
// needs for a given action + job pairing. Cosmic actions resolve via
|
||||
// the sentinel RowIdByClassJob[0] (one RowId covers every crafter job);
|
||||
// every other action resolves via RowIdByClassJob[classJobId]. Returns
|
||||
// false when the action is not available to the job (e.g. a Cosmic
|
||||
// action queried on a non-Cosmic recipe, or a per-job action queried
|
||||
// for a job that is missing the per-job row).
|
||||
public bool TryResolveActionRowId(AnvilAction action, uint classJobId, out uint rowId)
|
||||
{
|
||||
if (action.Flags.HasFlag(AnvilActionFlags.CosmicOnly))
|
||||
{
|
||||
if (action.RowIdByClassJob.TryGetValue(0u, out rowId))
|
||||
return true;
|
||||
rowId = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (action.RowIdByClassJob.TryGetValue(classJobId, out rowId))
|
||||
return true;
|
||||
rowId = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adapter-only entry point. Internal so the LuminaRecipeAdapter (same
|
||||
// assembly) and the Anvil.Tests build-suite project (via
|
||||
// InternalsVisibleTo) can populate the catalog. Single atomic write to
|
||||
// a volatile reference - readers either see the old empty state or the
|
||||
// fully built new state, never a partial one.
|
||||
internal void ApplyLoad(CatalogState newState)
|
||||
{
|
||||
_state = newState;
|
||||
}
|
||||
}
|
||||
|
||||
// Immutable snapshot of every catalog bucket. The adapter builds one of
|
||||
// these and hands it to ApplyLoad. Records' value-semantics plus
|
||||
// ImmutableDictionary defaults keep the public surface allocation-free
|
||||
// before the first load.
|
||||
internal sealed record CatalogState
|
||||
{
|
||||
public required bool IsLoaded { get; init; }
|
||||
public required DateTime? LoadedAt { get; init; }
|
||||
public required IReadOnlyDictionary<uint, AnvilRecipe> RecipesById { get; init; }
|
||||
public required IReadOnlyDictionary<
|
||||
uint,
|
||||
IReadOnlyList<AnvilRecipe>
|
||||
> RecipesByOutputItemId { get; init; }
|
||||
public required IReadOnlyDictionary<
|
||||
uint,
|
||||
IReadOnlyList<AnvilRecipe>
|
||||
> RecipesByClassJobId { get; init; }
|
||||
public required IReadOnlyDictionary<uint, AnvilItem> ItemsById { get; init; }
|
||||
public required IReadOnlyDictionary<AnvilActionKind, AnvilAction> ActionsByKind { get; init; }
|
||||
public required IReadOnlyDictionary<uint, AnvilAction> ActionsByLuminaRowId { get; init; }
|
||||
public required IReadOnlyDictionary<AnvilBuffKind, AnvilBuff> BuffsByKind { get; init; }
|
||||
public required IReadOnlyDictionary<
|
||||
AnvilConditionKind,
|
||||
AnvilCondition
|
||||
> ConditionsByKind { get; init; }
|
||||
public required IReadOnlyList<AnvilFood> Foods { get; init; }
|
||||
public required IReadOnlyList<AnvilFood> Medicines { get; init; }
|
||||
|
||||
public static CatalogState Empty { get; } =
|
||||
new()
|
||||
{
|
||||
IsLoaded = false,
|
||||
LoadedAt = null,
|
||||
RecipesById = ImmutableDictionary<uint, AnvilRecipe>.Empty,
|
||||
RecipesByOutputItemId = ImmutableDictionary<uint, IReadOnlyList<AnvilRecipe>>.Empty,
|
||||
RecipesByClassJobId = ImmutableDictionary<uint, IReadOnlyList<AnvilRecipe>>.Empty,
|
||||
ItemsById = ImmutableDictionary<uint, AnvilItem>.Empty,
|
||||
ActionsByKind = ImmutableDictionary<AnvilActionKind, AnvilAction>.Empty,
|
||||
ActionsByLuminaRowId = ImmutableDictionary<uint, AnvilAction>.Empty,
|
||||
BuffsByKind = ImmutableDictionary<AnvilBuffKind, AnvilBuff>.Empty,
|
||||
ConditionsByKind = ImmutableDictionary<AnvilConditionKind, AnvilCondition>.Empty,
|
||||
Foods = Array.Empty<AnvilFood>(),
|
||||
Medicines = Array.Empty<AnvilFood>(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Result of one LuminaRecipeAdapter load pass. Surfaced to the SelfTest step
|
||||
// for /xlperf reporting and (later) to any UI status surface that wants to
|
||||
// show "X recipes / Y actions" after init. Warnings carries non-fatal
|
||||
// problems the adapter saw while walking the sheets (unknown action names,
|
||||
// inconsistent per-job rows, etc.) - the load still succeeds and the
|
||||
// catalog stays usable.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Anvil.RecipeData;
|
||||
|
||||
public sealed record RecipeDataLoadResult(
|
||||
int RecipesLoaded,
|
||||
int ItemsLoaded,
|
||||
int ActionsLoaded,
|
||||
int FoodsLoaded,
|
||||
TimeSpan Duration,
|
||||
IReadOnlyList<string> Warnings
|
||||
);
|
||||
@@ -0,0 +1,307 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net10.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[15.0.0, )",
|
||||
"resolved": "15.0.0",
|
||||
"contentHash": "411vwC8/X8Z/sQ2TI6v3SvOn66xFPeOjFn3Zn+h0d3Ox2t1kFm66AhDvmx/qcMwVrR+Hidxj0dadpQ2dgyXMBQ=="
|
||||
},
|
||||
"DotNet.ReproducibleBuilds": {
|
||||
"type": "Direct",
|
||||
"requested": "[1.2.39, )",
|
||||
"resolved": "1.2.39",
|
||||
"contentHash": "fcFN01tDTIQqDuTwr1jUQK/geofiwjG5DycJQOnC72i1SsLAk1ELe+apBOuZ11UMQG8YKFZG1FgvjZPbqHyatg=="
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.7, 11.0.0)",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "91F/o3emPV/+xY/ip3s2LqDNF14kjttlVtq0BXgg6p4MnCzeSZxnUJm+t6WRrtD3JdGo88/oX+z7OwK4y8PZuw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Hosting": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.7, 11.0.0)",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "M/vBpfWcschvS2EUeq7cHfscsxabiGTptXwV7GeSueovGiSoNjyo1j5PMcWuOAAQrRW3nRqxZk8NeumrmpzUBg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.CommandLine": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Json": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.UserSecrets": "10.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection": "10.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Diagnostics": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.7",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Console": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Debug": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.EventLog": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.EventSource": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.7, 11.0.0)",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "hOeRIQ63GkgiYCB/MIFp+LQs8aXpJXpB55t6Aj37ab7t2/6WeFcPXxYM9hdy/o5tffzwf8mhqzLJP6mjGYCxjw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.7, 11.0.0)",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "00SHUGTh2jSMvIr6x9Xwd2nE+B5/qFCO/9hDwUDhJsjYRDlADmaBZ7tqehXzBDsfjHSXJzuRHJzPYPPjphBQ7Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "wZbGh7J8R1vXN525O6d8dlcDTxhRTnd5MyW4LdfP5S0tSnTwTCseYSrq6g0Mxh7W9xn8P/2xPuf0D/m6k2dy2w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "t56nEgvECcyLPojZIUFWJknQQDAbgfTf9J+QMYJE1YYvVgz69vN6B/AKL8Grvj3Lcnp8kTpNqwmwFhb3YLJmtQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "8bS1qIaRivny+WX+49pmeJ6iAylbtX8C0DLEcCQWZjdxQvLqaMssXiGD9P/6pYElrHbK5/nAHmjbQ8STqdMYeg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.CommandLine": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "3lNjglxfFxOzI9zG+3HSg/YSGqo//8Fqw6u6iuIamZb4JCorbA3JLaeWOpfKTAPi2UJwaispOXWx14dUqcGz4A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "TWto3imA+mJMLZI+5sbgLiFFoOFNFkizQYNaC5jTuiHKn3diwm1RN7mWDOEZN9kG2bixw7IvgpvtUG5/teSRzA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "qbZLvLsoTdArSloEnSxs21P781YUmwVmHc5NJPQD/ezAreQ7884z+6QfAZVKi86WAZtzx83jK2uC4itxOM44gQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "64dimvyyKk0dbUbrLg/YCv4ugJ4sVz2aXLwfvZwR1EC4tJqW9ru/oVRcXwoJRa2lQGXtYtlpk4maWOeIb48tQw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.UserSecrets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "YqVIICoIdl0016wkeO2WQS+uEbEXbUhMLKdC5rZNl1X3nu59F+nwaAHdHjq/4OK+Cx31DYmNUSFh+MUot8qSDw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Json": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "Z6mfFEaFcwCfSboxJwOLfu7/31npCY9q70WUamHW/vRQhDvBKOT4Vf9YkZj5J6hLvJpb0oDEYfHunQZj0xxvKw=="
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "l+smp1qPlU0OUXD0OGfdp7OUFrbdq7ZaP5T7m2WpfZ4RFKD7iG73BAT7tjSMxNmbSXkhAn1jYHOAqzYG1r9sNg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "uJ9JP677y+uy+C0vtaSfi7XXgFAdz8DhU3M9lwwIXDfQKcyQ0yxM9DVYa0NXDtdVTYA2eBUtVFZ8LY0GCdeE/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "teioDgVpi8L186wUfrXQV1YuBt6lCSPmFZiMZo53+FZxHFjOV+f4GXo4LXgJ273Mku9//AdXWVjk9J7eJP6inw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Physical": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "zhgWg/i0ECj5v0jLFBSZHplvc5ygCI91DR4nne+BP4XAKF5ycz0pEKnFiTw8C1jCABJEZsnBZh6pXAvn71kFmw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileSystemGlobbing": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileSystemGlobbing": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "NTUspqB+vH9g4wAD6KPOBx01xqYuKXR/cHXm449zpbq1GqfjdAxBmg7eJXrNsPw7SKwIdT2cJ05GxYVvc+lvsA=="
|
||||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "5s8d6qC6EA8UOI4wR/+zlsq7SXttJMRb9d7zvVZ7+bE3CQEfVtC9ITUDCommm87R1zzj6WJBbCnztuIJXnP3DA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "tIEcQ2gvERrH2KiCjdsVcHGhXt9lIsuDStfOIeZWr7/fP8IXhGiYfx0/80PNI7WPO2IYuFtlZLSlnTS8+/Mchw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "7BBnoGF37USiu7j434put9mDp7EjdlNDIZsR4vHfC1FbLZeLqiWjgJbeEtF0p59Ryqt8AtraHawf0ZKbe5jibg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Console": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "DA++Es6v6W0HfrOrw+K8WyN6jNnZHp640PDdEvl8yfeVmgflKdn6vSSFvufNUSOuY+M2ZaSUgfY+jUKtNpXcCw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Configuration": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "Y6DSt/JZApunYWKqTtqbdsR6iqAvHx3D0tavbNJ1rnC24MUpF+3XO/VKgFi+9PFqMyvQ2GHBBGb8H3cLSw7rDg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.EventLog": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "1C8eTuxF6BLncNSJ1HCfmaBcjpUSqQDPlBVdYTlet9oldHTPpNh9iatxSJLs8TOqdp/FOpH+nSLdBve7fu9mTQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7",
|
||||
"System.Diagnostics.EventLog": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.EventSource": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "YWfndnDX1jVMGCN8d5T+rO+BO8sDw6BkYlUk0BYui+WP7+HhlWx8QLdA4yUDjrkGVb3AQxIWWEPVKw5Nnfj5GQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Logging": "10.0.7",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "IT7f+EMXZtkjatEcF+o6aOw/7OE4etRrMiDGEWH/iiTu2R3uhC4NEQJCfHiibtX45U3sIQ5Fh6tbb1qaOz3YAg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.7",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.7",
|
||||
"Microsoft.Extensions.Options": "10.0.7",
|
||||
"Microsoft.Extensions.Primitives": "10.0.7"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "D5M0Jr551iTgwkZMN9rm0pSkgNLj5quUWQUmQPMZh7k/bnvZTnXRGfE2KuvXf1EEjt/ofD9yw9IumpgdP9QCnw=="
|
||||
},
|
||||
"System.Diagnostics.EventLog": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.7",
|
||||
"contentHash": "WbmDLeTPYhEzXhvYVioTVn/D1XX6bovyny9n5p8Zxtf03+eY385RB818teZm6n+fA63iZNvng0/Np4tLuhkMhQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user