Compare commits

...

31 Commits

Author SHA1 Message Date
Adam Hathcock f4cc4bc77e Merge pull request #272 from specklesystems/adam/add-2026
.NET Build and Publish / build (push) Has been cancelled
fix: Update HostAppVersion.cs for 2026
2025-04-07 10:55:25 +01:00
Jonathon Broughton d395f03219 fix: Update HostAppVersion.cs
Adding v2026 for next autodesk releases support.
2025-04-07 10:10:18 +01:00
Oğuzhan Koral 3cad57ceb3 Update object instead save (#266)
.NET Build and Publish / build (push) Has been cancelled
2025-03-24 20:24:15 +03:00
Oğuzhan Koral 11937ad7c9 Handle refresh token on catch (#265)
.NET Build and Publish / build (push) Has been cancelled
2025-03-24 13:39:23 +03:00
Adam Hathcock 8210fde69a Merge pull request #264 from specklesystems/oguzhan/parameter-for-app-id-secret
.NET Build and Publish / build (push) Has been cancelled
Chore(accounts): Extract hard coded app as parameter into function
2025-03-20 15:29:50 +00:00
oguzhankoral fa6f90621e Extract hard coded app as parameter into function 2025-03-20 18:18:23 +03:00
Adam Hathcock b3f4190614 Merge pull request #260 from specklesystems/adam/fix-cancel-check
.NET Build and Publish / build (push) Has been cancelled
Cancellation check for sending needs to not be wrapped
2025-03-17 12:21:44 +00:00
Adam Hathcock 2fc0024cd2 Cancellation check for sending needs to not be wrapped 2025-03-17 12:08:42 +00:00
Adam Hathcock 300a5627fd Merge pull request #259 from specklesystems/revit-levels
.NET Build and Publish / build (push) Has been cancelled
feat(objects): adds level to revitobject
2025-03-17 11:06:13 +00:00
Claire Kuang 22f029fe33 Update RevitObject.cs 2025-03-17 10:32:47 +00:00
Claire Kuang c728266c88 Update RevitObject.cs 2025-03-17 10:31:43 +00:00
Claire Kuang 7f2d57cdad adds level 2025-03-17 10:05:41 +00:00
Adam Hathcock 4e84766be9 Merge pull request #253 from specklesystems/regions-PR-to-main
.NET Build and Publish / build (push) Has been cancelled
2025-03-12 17:55:01 +00:00
KatKatKateryna 73a95aded0 Regions class (#241)
* region class

* comments

* adjusted constructor

* todos

* comment

* change displayValur to curves

* small refactor

* assign correct property

* generalize display value

* some minor xml changes

* transform meshes; bbox not required

* remove comment

* Update Region.cs

---------

Co-Authored-By: Claire Kuang <kuang.claire@gmail.com>
Co-Authored-By: Adam Hathcock <adamhathcock@users.noreply.github.com>
2025-03-12 17:38:28 +00:00
Adam Hathcock ac0ab3904c Merge pull request #250 from specklesystems/fix-main
.NET Build and Publish / build (push) Has been cancelled
Fix main again: version the nuget correctly
2025-03-10 09:03:53 +00:00
Adam Hathcock 5c9d672a2b Really fix publish version 2025-03-10 08:50:52 +00:00
Adam Hathcock 18d6653282 Merge pull request #247 from specklesystems/fix-main
.NET Build and Publish / build (push) Has been cancelled
Fix main
2025-03-07 14:54:53 +00:00
Adam Hathcock d58a656c8a make private 2025-03-07 14:43:48 +00:00
Adam Hathcock 720d049145 format 2025-03-07 14:35:37 +00:00
Adam Hathcock 129688a646 Fix restore tools and comment out integration test for now 2025-03-07 14:34:24 +00:00
Adam Hathcock fa66258b23 Merge pull request #246 from specklesystems/release-to-main
Release to main
2025-03-07 14:27:19 +00:00
Adam Hathcock 9f0c572993 also on tags 2025-03-07 14:01:19 +00:00
Adam Hathcock 158baff5b0 Merge branch 'update-build-stamp' into release-to-main 2025-03-07 14:01:10 +00:00
Adam Hathcock f20064c9f0 update usage to read shell instead of file 2025-02-19 15:42:08 +00:00
Adam Hathcock 6f1b22d13a Merge remote-tracking branch 'origin/dev' into update-build-stamp 2025-02-19 15:33:31 +00:00
Adam Hathcock ef19bfa69d fix dependencies 2025-02-10 13:41:39 +00:00
Adam Hathcock 45601f1a2f modify build to have correct version 2025-02-10 13:35:59 +00:00
Adam Hathcock adf3298baf release branch is main 2025-02-10 10:38:58 +00:00
Adam Hathcock 8f5e5f675b fmt 2025-02-10 10:36:50 +00:00
Adam Hathcock 9217e67a9d Merge remote-tracking branch 'origin/dev' into update-build-stamp 2025-02-10 10:27:26 +00:00
Adam Hathcock ebccf6ff79 update build stamp and tooling 2025-01-03 16:22:58 +00:00
23 changed files with 178 additions and 120 deletions
+1 -1
View File
@@ -10,7 +10,7 @@
"rollForward": false
},
"gitversion.tool": {
"version": "5.12.0",
"version": "6.1.0",
"commands": [
"dotnet-gitversion"
],
+1
View File
@@ -3,6 +3,7 @@ name: .NET Build and Publish
on:
push:
branches: ["main", "dev"]
tags: ["3.*"]
jobs:
build:
-1
View File
@@ -32,7 +32,6 @@
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
<GlobalPackageReference Include="PolySharp" Version="1.15.0" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<GlobalPackageReference Include="GitVersion.MsBuild" Version="5.12.0" />
<GlobalPackageReference Include="Speckle.InterfaceGenerator" Version="0.9.6" />
</ItemGroup>
</Project>
+3 -8
View File
@@ -1,11 +1,6 @@
workflow: GitFlow/v1
next-version: 3.0.0
mode: ContinuousDeployment
assembly-informational-format: "{Major}.{Minor}.{Patch}-{PreReleaseTag}"
branches:
main:
regex: ^main$
tag: rc
develop:
tag: dev
pull-request:
tag: pr
prevent-increment:
when-current-commit-tagged: true
+1
View File
@@ -24,6 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{DA2AED
docker-compose.yml = docker-compose.yml
CodeMetricsConfig.txt = CodeMetricsConfig.txt
Directory.Build.Targets = Directory.Build.Targets
.config\dotnet-tools.json = .config\dotnet-tools.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{58D37DA9-F948-48CA-9A73-F5BBBD533DBF}"
+32 -7
View File
@@ -1,3 +1,4 @@
using System.Text.Json;
using GlobExpressions;
using static Bullseye.Targets;
using static SimpleExec.Command;
@@ -11,11 +12,20 @@ const string BUILD = "build";
const string TEST = "test";
const string INTEGRATION = "integration";
const string PACK = "pack";
const string PACK_LOCAL = "pack-local";
const string CLEAN_LOCKS = "clean-locks";
const string PERF = "perf";
const string DEEP_CLEAN = "deep-clean";
static async Task<(string, string)> GetVersions()
{
var (output, _) = await ReadAsync("dotnet", "dotnet-gitversion /output json").ConfigureAwait(false);
output = output.Trim();
var jDoc = JsonDocument.Parse(output);
var version = jDoc.RootElement.GetProperty("FullSemVer").GetString() ?? "3.0.0-localBuild";
var fileVersion = jDoc.RootElement.GetProperty("AssemblySemFileVer").GetString() ?? "3.0.0.0";
return (version, fileVersion);
}
Target(
CLEAN_LOCKS,
() =>
@@ -60,14 +70,20 @@ Target(RESTORE_TOOLS, () => RunAsync("dotnet", "tool restore"));
Target(FORMAT, DependsOn(RESTORE_TOOLS), () => RunAsync("dotnet", "csharpier --check ."));
Target(RESTORE, () => RunAsync("dotnet", "restore Speckle.Sdk.sln --locked-mode"));
Target(RESTORE, DependsOn(FORMAT), () => RunAsync("dotnet", "restore Speckle.Sdk.sln --locked-mode"));
Target(
BUILD,
DependsOn(RESTORE),
async () =>
{
await RunAsync("dotnet", $"build Speckle.Sdk.sln -c Release --no-restore -warnaserror").ConfigureAwait(false);
var (version, fileVersion) = await GetVersions().ConfigureAwait(false);
Console.WriteLine($"Version: {version} & {fileVersion}");
await RunAsync(
"dotnet",
$"build Speckle.Sdk.sln -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion}"
)
.ConfigureAwait(false);
}
);
@@ -152,10 +168,19 @@ Target(
}
);
static Task RunPack() => RunAsync("dotnet", "pack Speckle.Sdk.sln -c Release -o output --no-build");
Target(PACK, DependsOn(TEST), RunPack);
Target(PACK_LOCAL, DependsOn(BUILD), RunPack);
Target(
PACK,
DependsOn(BUILD),
async () =>
{
{
var (version, fileVersion) = await GetVersions().ConfigureAwait(false);
Console.WriteLine($"Version: {version} & {fileVersion}");
await RunAsync("dotnet", $"pack Speckle.Sdk.sln -c Release -o output --no-build -p:Version={version}")
.ConfigureAwait(false);
}
}
);
Target("default", DependsOn(FORMAT, TEST, INTEGRATION), () => Console.WriteLine("Done!"));
-6
View File
@@ -8,12 +8,6 @@
"resolved": "5.0.0",
"contentHash": "bqyt+m17ym+5aN45C5oZRAjuLDt8jKiCm/ys1XfymIXSkrTFwvI/QsbY3ucPSHDz7SF7uON7B57kXFv5H2k1ew=="
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Glob": {
"type": "Direct",
"requested": "[1.1.9, )",
+7
View File
@@ -12,6 +12,13 @@ public class RevitObject : DataObject, IRevitObject
public required string family { get; set; }
public required string category { get; set; }
/// <summary>
/// The level constraint of the object.
/// For objects constrained by multiple levels, this represents the base constraint.
/// For objects with no level constraint, this should be null.
/// </summary>
public required string? level { get; set; }
/// <summary>
/// A Curve or Point object representing the location of a Revit element.
/// </summary>
+97
View File
@@ -0,0 +1,97 @@
using Speckle.Objects.Other;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models;
namespace Speckle.Objects.Geometry;
/// <summary>
/// Flat polygon, defined by an outer boundary and inner loops.
/// </summary>
[SpeckleType("Objects.Geometry.Region")]
public class Region : Base, IHasArea, IHasBoundingBox, ITransformable, IDisplayValue<List<Mesh>>
{
/// <summary>
/// Boundary of a region.
/// Should be a planar, closed, non-self-intersecting ICurve.
/// </summary>
public required ICurve boundary { get; set; }
/// <summary>
/// Loops (voids) in the region.
/// Each loop should be planar, closed, non-self-intersecting ICurve, located inside the boundary.
/// The loops should not intersect or touch each other.
/// </summary>
public required List<ICurve> innerLoops { get; set; } = new();
/// <summary>
/// The units of object's coordinates.
/// This should be one of <see cref="Units"/>
/// </summary>
public required string units { get; set; }
/// <summary>
/// Indication whether the region is just a geometry (false) or has a hatch pattern (true).
/// It's a distinction for receiving in apps that support both Region and Hatch (aka region with hatch pattern)
/// </summary>
public required bool hasHatchPattern { get; set; }
/// <inheritdoc/>
public double area { get; set; }
/// <inheritdoc/>
public Box? bbox { get; set; }
/// <inheritdoc/>
[DetachProperty]
public List<Mesh> displayValue { get; set; } = new();
/// <inheritdoc/>
public bool TransformTo(Transform transform, out ITransformable transformed)
{
// assign self to the returned object, in case transformation fails
transformed = this;
// transform boundary
if (boundary is ITransformable boundaryTransformable)
{
boundaryTransformable.TransformTo(transform, out ITransformable transformedBoundaryResult);
var transformedBoundary = (ICurve)transformedBoundaryResult;
// transform inner loops
var transformedLoops = new List<ICurve>();
foreach (var loop in innerLoops)
{
if (loop is ITransformable loopTransformable)
{
loopTransformable.TransformTo(transform, out ITransformable transformedLoop);
transformedLoops.Add((ICurve)transformedLoop);
}
else
{
return false;
}
}
// transform display meshes
var transformedMeshes = new List<Mesh>();
foreach (var mesh in displayValue)
{
mesh.TransformTo(transform, out ITransformable transformedMesh);
transformedMeshes.Add((Mesh)transformedMesh);
}
// if boundary and loops transformations succeeded
transformed = new Region
{
boundary = transformedBoundary,
innerLoops = transformedLoops,
hasHatchPattern = hasHatchPattern,
displayValue = transformedMeshes,
units = units,
};
return true;
}
return false;
}
}
-12
View File
@@ -2,12 +2,6 @@
"version": 2,
"dependencies": {
".NETStandard,Version=v2.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -315,12 +309,6 @@
}
},
"net8.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -2,12 +2,6 @@
"version": 2,
"dependencies": {
".NETStandard,Version=v2.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"ILRepack.FullAuto": {
"type": "Direct",
"requested": "[1.6.0, )",
@@ -169,12 +163,6 @@
}
},
"net8.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"ILRepack.FullAuto": {
"type": "Direct",
"requested": "[1.6.0, )",
+31 -16
View File
@@ -399,8 +399,9 @@ public sealed class AccountManager(
/// <summary>
/// Refetches user and server info for each account
/// </summary>
/// <param name="app"> It is defaultAppId in the server. By default it is "sca" to not break existing parts that this function involves.</param>
/// <returns></returns>
public async Task UpdateAccounts(CancellationToken ct = default)
public async Task UpdateAccounts(CancellationToken ct = default, string app = "sca")
{
// need to ToList() the GetAccounts call or the UpdateObject call at the end of this method
// will not work because sqlite does not support concurrent db calls
@@ -415,16 +416,9 @@ public sealed class AccountManager(
//TODO: once we get a token expired exception from the server use that instead
if (userServerInfo?.activeUser == null || userServerInfo.serverInfo == null)
{
var tokenResponse = await GetRefreshedToken(account.refreshToken, url).ConfigureAwait(false);
userServerInfo = await GetUserServerInfo(tokenResponse.token, url, ct).ConfigureAwait(false);
if (userServerInfo?.activeUser == null || userServerInfo.serverInfo == null)
{
throw new SpeckleException("Could not refresh token");
}
account.token = tokenResponse.token;
account.refreshToken = tokenResponse.refreshToken;
// We were initially was handling refresh token here bc quite a while ago server was returning null
// for activeUser and serverInfo instead of throwing exception. In short, our logic moved into catch block to cover both.
throw new SpeckleException("Token is expired");
}
account.isOnline = true;
@@ -437,11 +431,32 @@ public sealed class AccountManager(
}
catch (Exception ex) when (!ex.IsFatal())
{
account.isOnline = false;
await RefreshAndSetAccountToken(account, app).ConfigureAwait(false);
}
ct.ThrowIfCancellationRequested();
_accountStorage.SaveObject(account.id, JsonConvert.SerializeObject(account));
_accountStorage.UpdateObject(account.id, JsonConvert.SerializeObject(account));
}
}
/// <summary>
/// Mutates the account with new tokens.
/// </summary>
/// <param name="account"></param>
/// <param name="app"></param>
private async Task RefreshAndSetAccountToken(Account account, string app)
{
try
{
Uri url = new(account.serverInfo.url);
var tokenResponse = await GetRefreshedToken(account.refreshToken, url, app).ConfigureAwait(false);
account.token = tokenResponse.token;
account.refreshToken = tokenResponse.refreshToken;
account.isOnline = true;
}
catch (Exception ex) when (!ex.IsFatal())
{
account.isOnline = false;
}
}
@@ -766,7 +781,7 @@ public sealed class AccountManager(
}
}
private async Task<TokenExchangeResponse> GetRefreshedToken(string refreshToken, Uri server)
private async Task<TokenExchangeResponse> GetRefreshedToken(string refreshToken, Uri server, string app = "sca")
{
try
{
@@ -774,8 +789,8 @@ public sealed class AccountManager(
var body = new
{
appId = "sca",
appSecret = "sca",
appId = app,
appSecret = app,
refreshToken,
};
+1
View File
@@ -13,6 +13,7 @@ public enum HostAppVersion
v2023,
v2024,
v2025,
v2026,
v21,
v22,
v25,
@@ -89,11 +89,12 @@ public sealed class SerializeProcess(
public void ThrowIfFailed()
{
//always check for cancellation first
cancellationToken.ThrowIfCancellationRequested();
if (Exception is not null)
{
throw new SpeckleException("Error while sending", Exception);
}
cancellationToken.ThrowIfCancellationRequested();
}
private async Task WaitForSchedulerCompletion()
-12
View File
@@ -2,12 +2,6 @@
"version": 2,
"dependencies": {
".NETStandard,Version=v2.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"GraphQL.Client": {
"type": "Direct",
"requested": "[6.0.0, )",
@@ -301,12 +295,6 @@
}
},
"net8.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"GraphQL.Client": {
"type": "Direct",
"requested": "[6.0.0, )",
@@ -14,12 +14,6 @@
"resolved": "8.0.0",
"contentHash": "6fWiV7mGZUzZXzeiW3hWF0nJokuuNm4hnzuqbM3IXHqGYkWnHl65+wNpuQ73xfJXClX0fmfKcTdQ2Ula719IDg=="
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
"requested": "[17.13.0, )",
@@ -2,12 +2,6 @@
"version": 2,
"dependencies": {
"net8.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Direct",
"requested": "[2.2.0, )",
@@ -14,12 +14,6 @@
"resolved": "8.0.0",
"contentHash": "6fWiV7mGZUzZXzeiW3hWF0nJokuuNm4hnzuqbM3IXHqGYkWnHl65+wNpuQ73xfJXClX0fmfKcTdQ2Ula719IDg=="
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
"requested": "[17.13.0, )",
@@ -2,12 +2,6 @@
"version": 2,
"dependencies": {
"net8.0": {
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
"requested": "[17.13.0, )",
@@ -65,8 +65,8 @@ public class ProjectResourceTests
result.createdAt.Should().Be(_testProject.createdAt);
}
[Fact]
public async Task ProjectUpdate_Should_UpdateProjectSuccessfully()
//[Fact]
private async Task ProjectUpdate_Should_UpdateProjectSuccessfully()
{
// Arrange
const string NEW_NAME = "MY new name";
@@ -8,12 +8,6 @@
"resolved": "9.0.1",
"contentHash": "aadciFNDT5bnylaYUkKal+s5hF7yU/lmZxImQWAlk1438iPqK1Uf79H5ylELpyLIU49HL5ql+tnWBihp3WVLCA=="
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
"requested": "[17.13.0, )",
@@ -20,12 +20,6 @@
"System.Management": "5.0.0"
}
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Direct",
"requested": "[2.2.0, )",
@@ -14,12 +14,6 @@
"resolved": "8.0.0",
"contentHash": "6fWiV7mGZUzZXzeiW3hWF0nJokuuNm4hnzuqbM3IXHqGYkWnHl65+wNpuQ73xfJXClX0fmfKcTdQ2Ula719IDg=="
},
"GitVersion.MsBuild": {
"type": "Direct",
"requested": "[5.12.0, )",
"resolved": "5.12.0",
"contentHash": "dJuigXycpJNOiLT9or7mkHSkGFHgGW3/p6cNNYEKZBa7Hhp1FdX/cvqYWWYhRLpfoZOedeA7aRbYiOB3vW/dvA=="
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Direct",
"requested": "[2.2.0, )",