From 856e1b4d8bc9f96524e522d06132a518348b4aed Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 10:48:59 -0700 Subject: [PATCH 01/39] Breaking change docs: minimum Android API level raised from 21 to 24 in .NET 11 (#53543) * Initial plan * Add breaking change article: minimum Android API level raised to 24 in .NET 11 Agent-Logs-Url: https://github.com/dotnet/docs/sessions/41a292af-77ac-4383-ba90-42d89250723d Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> * Apply suggestions from code review * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/core/compatibility/11.md | 6 +++ .../maui/11/android-minimum-api-level.md | 42 +++++++++++++++++++ docs/core/compatibility/toc.yml | 4 ++ 3 files changed, 52 insertions(+) create mode 100644 docs/core/compatibility/maui/11/android-minimum-api-level.md diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 089c8e7daf3f4..78415ceab75f9 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -77,6 +77,12 @@ See [Breaking changes in EF Core 11](/ef/core/what-is-new/ef-core-11.0/breaking- |-------------------------------------------------------------------|-------------------| | [SslStream server-side AIA certificate downloads disabled by default](networking/11/sslstream-aia-downloads-disabled.md) | Behavioral change | +## .NET MAUI + +| Title | Type of change | +|-------------------------------------------------------------------|-------------------| +| [Minimum Android API level raised to 24](maui/11/android-minimum-api-level.md) | Behavioral change | + ## SDK and MSBuild | Title | Type of change | diff --git a/docs/core/compatibility/maui/11/android-minimum-api-level.md b/docs/core/compatibility/maui/11/android-minimum-api-level.md new file mode 100644 index 0000000000000..2171a72617406 --- /dev/null +++ b/docs/core/compatibility/maui/11/android-minimum-api-level.md @@ -0,0 +1,42 @@ +--- +title: "Breaking change: Minimum Android API level raised to 24" +description: "Learn about the breaking change in .NET 11 where the minimum supported Android API level has been raised from 21 to 24." +ms.date: 05/04/2026 +ai-usage: ai-assisted +--- + +# Minimum Android API level raised to 24 + +The minimum supported Android API level for .NET 11 has been raised from 21 (Android 5.0) to 24 (Android 7.0). + +## Version introduced + +.NET 11 Preview 4 + +## Previous behavior + +Previously, you could target devices running Android API 21 (Android 5.0 Lollipop) or newer. + +## New behavior + +Starting in .NET 11, devices running Android API 24 (Android 7.0 Nougat) or newer are supported. Apps built with .NET 11 can't be installed or run on devices running Android API 21, 22, or 23. + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +Migrating the Android runtime from Mono to CoreCLR requires Android API 24 or later. + +## Recommended action + +Set `SupportedOSPlatformVersion` to `24` in your project file so your app declares the correct minimum supported Android version to build analyzers and assembly metadata. + +If you set `android:minSdkVersion` manually in your Android manifest, raise that value to `24` too so it matches the project setting. + +Notify users on devices that run Android 5.x or 6.x that they won't be able to install new updates of your app. + +## Affected APIs + +None. diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index ed732eb84f966..a80919a03092a 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -54,6 +54,10 @@ items: items: - name: SslStream server-side AIA certificate downloads disabled by default href: networking/11/sslstream-aia-downloads-disabled.md + - name: .NET MAUI + items: + - name: Minimum Android API level raised to 24 + href: maui/11/android-minimum-api-level.md - name: SDK and MSBuild items: - name: mono launch target not set for .NET Framework apps From c7918eb1a577158ac1a03ea8094e051853265c40 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 10:49:26 -0700 Subject: [PATCH 02/39] Breaking change doc: VSTest/Microsoft.NET.Test.SDK removes Newtonsoft.Json dependency (.NET 11) (#53545) * Initial plan * Add breaking change article: VSTest removes Newtonsoft.Json dependency in .NET 11 Agent-Logs-Url: https://github.com/dotnet/docs/sessions/339e02d8-bbe0-4dec-99bf-af7f8430dd0b Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> * Update docs/core/compatibility/sdk/11/vstest-removes-newtonsoft-json.md * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/core/compatibility/11.md | 1 + .../sdk/11/vstest-removes-newtonsoft-json.md | 89 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + 3 files changed, 92 insertions(+) create mode 100644 docs/core/compatibility/sdk/11/vstest-removes-newtonsoft-json.md diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 78415ceab75f9..ca571c2399bf6 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -88,3 +88,4 @@ See [Breaking changes in EF Core 11](/ef/core/what-is-new/ef-core-11.0/breaking- | Title | Type of change | |-------------------------------------------------------------------|-------------------| | [mono launch target not set for .NET Framework apps](sdk/11/mono-launch-target-removed.md) | Behavioral change | +| [VSTest removes dependency on Newtonsoft.Json](sdk/11/vstest-removes-newtonsoft-json.md) | Binary/source incompatible | diff --git a/docs/core/compatibility/sdk/11/vstest-removes-newtonsoft-json.md b/docs/core/compatibility/sdk/11/vstest-removes-newtonsoft-json.md new file mode 100644 index 0000000000000..8d07e00581751 --- /dev/null +++ b/docs/core/compatibility/sdk/11/vstest-removes-newtonsoft-json.md @@ -0,0 +1,89 @@ +--- +title: "Breaking change: VSTest removes dependency on Newtonsoft.Json" +description: "Learn about the breaking change in .NET 11 where the VSTest platform and Microsoft.NET.Test.SDK no longer depend on Newtonsoft.Json." +ms.date: 05/04/2026 +ai-usage: ai-assisted +--- + +# VSTest removes dependency on Newtonsoft.Json + +The VSTest platform and `Microsoft.NET.Test.SDK` NuGet package no longer depend on `Newtonsoft.Json`. On .NET, `System.Text.Json` is used instead. On .NET Framework, JSONite is used. + +## Version introduced + +.NET 11 Preview 4 + +## Previous behavior + +Previously, `Microsoft.NET.Test.SDK` brought a transitive dependency on `Newtonsoft.Json` into test projects. `Newtonsoft.Json` was available for compilation and at runtime without an explicit package reference. Projects that used `Newtonsoft.Json` types without declaring a direct dependency on the package compiled and ran successfully. + +Additionally, VSTest's internal communication utilities exposed `Newtonsoft.Json` types (such as `Newtonsoft.Json.Linq.JToken`) in its public API. + +## New behavior + +Starting in .NET 11, `Newtonsoft.Json` is no longer a transitive dependency of `Microsoft.NET.Test.SDK`. Projects that used `Newtonsoft.Json` types without a direct package reference fail to compile. Projects that excluded `Newtonsoft.Json` runtime assets and relied on the copy shipped with VSTest now fail at runtime with: + +``` +FileNotFoundException: Could not load 'Newtonsoft.Json' +``` + +Test extensions (such as data collectors or test adapters) that depended on `Newtonsoft.Json` being provided by VSTest also fail with: + +``` +Data collector 'SampleDataCollector' threw an exception during type loading, construction, or initialization: +System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, +Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. +``` + +The `Newtonsoft.Json`-based types in `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities` have been removed from the public API. + +## Type of breaking change + +This change can affect [source compatibility](../../categories.md#source-compatibility) and [binary compatibility](../../categories.md#binary-compatibility). + +## Reason for change + +To align the VSTest platform's dependencies with the .NET SDK and the broader .NET ecosystem, `Newtonsoft.Json` was removed as a dependency. To minimize unintended side effects on the code under test, the number of assemblies that VSTest adds to the test output folder is reduced. Test projects can bring exactly the dependencies they need at the versions they require. + +## Recommended action + +In all cases, the fix is to add an explicit `Newtonsoft.Json` package reference to any project that uses it: + +```xml + +``` + +### Test projects that fail to compile + +If your test project uses `Newtonsoft.Json` types (for example, `JsonConvert`, `JToken`, or `JObject`) without a direct package reference, add a `PackageReference` to `Newtonsoft.Json` in your test project file. + +### Tests that fail with FileNotFoundException at runtime + +If your project has a `PackageReference` for `Newtonsoft.Json` with `runtime` and previously relied on the copy shipped with VSTest, remove the `ExcludeAssets` restriction or add a separate direct reference: + +```xml + + + runtime + + + + +``` + +### Test extensions that fail with FileNotFoundException + +If you maintain or use a test extension (data collector or test adapter) that depended on `Newtonsoft.Json` being provided by VSTest, add `Newtonsoft.Json` as a direct dependency to the extension's project. + +## Affected APIs + +The following `Newtonsoft.Json`-based APIs were removed from `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities`: + +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Message.Payload` property (type `Newtonsoft.Json.Linq.JToken?`) +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.DefaultTestPlatformContractResolver` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.TestCaseConverter` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.TestObjectConverter` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.TestPlatformContractResolver` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.TestResultConverter` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Serialization.TestRunStatisticsConverter` +- `Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.VersionedMessage` diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index a80919a03092a..327c0135cd2f8 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -62,6 +62,8 @@ items: items: - name: mono launch target not set for .NET Framework apps href: sdk/11/mono-launch-target-removed.md + - name: VSTest removes dependency on Newtonsoft.Json + href: sdk/11/vstest-removes-newtonsoft-json.md - name: .NET 10 items: - name: Overview From c1a69013e6437131eb1a95e59840a4d68dd94b1e Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 5 May 2026 14:11:50 -0400 Subject: [PATCH 03/39] Add C# 9 diagnostics for record types (#53507) * Add record declaration errors * Copy edit * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * respond to feedback. Rework one corrective recommendations. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../record-declaration-errors.md | 86 ++++++++++++------- docs/csharp/language-reference/toc.yml | 5 +- ...n-t-have-specifics-on-this-csharp-error.md | 5 -- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/docs/csharp/language-reference/compiler-messages/record-declaration-errors.md b/docs/csharp/language-reference/compiler-messages/record-declaration-errors.md index e17705f656691..ea70a53eda165 100644 --- a/docs/csharp/language-reference/compiler-messages/record-declaration-errors.md +++ b/docs/csharp/language-reference/compiler-messages/record-declaration-errors.md @@ -3,41 +3,51 @@ title: Resolve errors and warnings related to record declarations description: Learn how to diagnose and correct C# compiler errors and warnings when you declare record types, either record struct types or record class types. f1_keywords: - "CS8851" + - "CS8857" - "CS8858" - "CS8859" - "CS8860" - "CS8864" - "CS8865" - "CS8866" + - "CS8869" - "CS8870" + - "CS8871" - "CS8872" - "CS8873" - "CS8874" - "CS8875" + - "CS8876" - "CS8877" - "CS8879" + - "CS8906" - "CS8907" - "CS8908" - "CS8913" helpviewer_keywords: - "CS8851" + - "CS8857" - "CS8858" - "CS8859" - "CS8860" - "CS8864" - "CS8865" - "CS8866" + - "CS8869" - "CS8870" + - "CS8871" - "CS8872" - "CS8873" - "CS8874" - "CS8875" + - "CS8876" - "CS8877" - "CS8879" + - "CS8906" - "CS8907" - "CS8908" - "CS8913" -ms.date: 03/06/2026 +ms.date: 04/29/2026 ai-usage: ai-assisted --- # Resolve errors and warnings for record declarations @@ -47,76 +57,90 @@ The C# compiler generates errors and warnings when you misuse [record types](../ -- [**CS8851**](#equality-members): *'Type' defines 'Equals' but not 'GetHashCode'* -- [**CS8858**](#equality-members): *The receiver type is not a valid record type and is not a struct type.* +- [**CS8851**](#equality-members): *'type' defines 'Equals' but not 'GetHashCode'* +- [**CS8857**](#equality-members): *The receiver of a `with` expression must have a non-void type.* +- [**CS8858**](#equality-members): *The receiver type 'type' is not a valid record type and is not a struct type.* - [**CS8859**](#reserved-member-names): *Members named 'Clone' are disallowed in records.* - [**CS8860**](#reserved-member-names): *Types and aliases should not be named 'record'.* - [**CS8864**](#record-inheritance): *Records may only inherit from object or another record.* - [**CS8865**](#record-inheritance): *Only records may inherit from records.* -- [**CS8866**](#positional-members): *Record member must be a readable instance property or field of the type to match the positional parameter.* -- [**CS8870**](#synthesized-member-signatures): *Member cannot be sealed because containing record is not sealed.* -- [**CS8872**](#synthesized-member-signatures): *Member must allow overriding because the containing record is not sealed.* -- [**CS8873**](#synthesized-member-signatures): *Record member must be public.* -- [**CS8874**](#synthesized-member-signatures): *Record member must return type.* -- [**CS8875**](#synthesized-member-signatures): *Record member must be protected.* -- [**CS8877**](#synthesized-member-signatures): *Record member may not be static.* -- [**CS8879**](#synthesized-member-signatures): *Record member must be private.* -- [**CS8908**](#positional-members): *The type may not be used for a field of a record.* -- [**CS8913**](#positional-members): *The positional member found corresponding to this parameter is hidden.* +- [**CS8866**](#positional-members): *Record member 'member' must be a readable instance property or field of type 'type' to match positional parameter 'parameter'.* +- [**CS8869**](#synthesized-member-signatures): *'member' does not override expected method from 'object'.* +- [**CS8870**](#synthesized-member-signatures): *'member' cannot be sealed because containing record is not sealed.* +- [**CS8871**](#synthesized-member-signatures): *'member' does not override expected method from 'type'.* +- [**CS8872**](#synthesized-member-signatures): *'member' must allow overriding because the containing record is not sealed.* +- [**CS8873**](#synthesized-member-signatures): *Record member 'member' must be public.* +- [**CS8874**](#synthesized-member-signatures): *Record member 'member' must return 'type'.* +- [**CS8875**](#synthesized-member-signatures): *Record member 'member' must be protected.* +- [**CS8876**](#synthesized-member-signatures): *'member' does not override expected property from 'type'.* +- [**CS8877**](#synthesized-member-signatures): *Record member 'member' may not be static.* +- [**CS8879**](#synthesized-member-signatures): *Record member 'member' must be private.* +- [**CS8906**](#synthesized-member-signatures): *Record equality contract property 'member' must have a get accessor.* +- [**CS8908**](#positional-members): *The type 'type' may not be used for a field of a record.* +- [**CS8913**](#positional-members): *The positional member 'member' found corresponding to this parameter is hidden.* In addition, this article covers the following warning: -- [**CS8907**](#positional-members): *Parameter is unread. Did you forget to use it to initialize the property with that name?* +- [**CS8907**](#positional-members): *Parameter 'name' is unread. Did you forget to use it to initialize the property with that name?* ## Synthesized member signatures -- **CS8870**: *Member cannot be sealed because containing record is not sealed.* -- **CS8872**: *Member must allow overriding because the containing record is not sealed.* -- **CS8873**: *Record member must be public.* -- **CS8874**: *Record member must return type.* -- **CS8875**: *Record member must be protected.* -- **CS8877**: *Record member may not be static.* -- **CS8879**: *Record member must be private.* +- **CS8869**: *'member' does not override expected method from 'object'.* +- **CS8870**: *'member' cannot be sealed because containing record is not sealed.* +- **CS8871**: *'member' does not override expected method from 'type'.* +- **CS8872**: *'member' must allow overriding because the containing record is not sealed.* +- **CS8873**: *Record member 'member' must be public.* +- **CS8874**: *Record member 'member' must return 'type'.* +- **CS8875**: *Record member 'member' must be protected.* +- **CS8876**: *'member' does not override expected property from 'type'.* +- **CS8877**: *Record member 'member' may not be static.* +- **CS8879**: *Record member 'member' must be private.* +- **CS8906**: *Record equality contract property 'member' must have a get accessor.* When you explicitly declare a member that the compiler would otherwise synthesize for a [record type](../builtin-types/record.md), your declaration must match the expected signature, accessibility, and modifiers. For the complete rules, see the [records specification](~/_csharpstandard/standard/classes.md#1516-synthesized-record-class-members) in the C# language specification. To correct these errors, apply the following changes to your explicitly declared record members: - Change the accessibility of the `Equals` method, `GetHashCode`, `ToString`, the deconstruct method, and the `EqualityContract` property or `op_Equality` and `op_Inequality` operators to `public`. The compiler requires these members to be publicly accessible so that value-based [equality](../builtin-types/record.md#value-equality) works correctly across all calling contexts (**CS8873**). -1-- Change the accessibility of the `PrintMembers` method to `protected` when you declare it in a non-sealed record class. The method must be `protected` because derived records override it to include their own properties in the [formatted output](../builtin-types/record.md#built-in-formatting-for-display) (**CS8875**). +- Change the accessibility of the `PrintMembers` method to `protected` when you declare it in a non-sealed record class. The method must be `protected` because derived records override it to include their own properties in the [formatted output](../builtin-types/record.md#built-in-formatting-for-display) (**CS8875**). - Change the accessibility of the `PrintMembers` method to `private` when you declare it in a sealed record class or a record struct. Because no derived type can exist, the method doesn't need to be accessible outside the type (**CS8879**). - Remove the `static` modifier from any explicitly declared synthesized member. Synthesized members operate on specific record instances to implement behaviors like equality comparison, formatting, and copying, so they must be instance members (**CS8877**). - Change the return type of the member to match the type the compiler expects. For example, the `EqualityContract` property must return `System.Type`, and the `Equals` method must return `bool`. The compiler relies on these exact return types to generate correct code for [equality](../builtin-types/record.md#equality-in-inheritance-hierarchies) and other synthesized behaviors (**CS8874**). - Remove the `sealed` modifier from any explicitly declared synthesized member in a non-sealed record. Derived records must be able to override these members to provide their own value-based equality and formatting logic (**CS8870**). - Declare explicitly provided synthesized members as `virtual` or `override` in a non-sealed record. The compiler requires these members to allow overriding so that derived records in the [inheritance hierarchy](../builtin-types/record.md#equality-in-inheritance-hierarchies) can customize their behavior (**CS8872**). +- Ensure that your explicitly declared member overrides the expected method from `object` or from the base record type. For example, the `Equals` method must override `object.Equals`, and `GetHashCode` must override `object.GetHashCode`. The compiler checks that these members participate in the correct override chain so that [value-based equality](../builtin-types/record.md#value-equality) and other synthesized behaviors work correctly across the type hierarchy (**CS8869**, **CS8871**). +- Ensure that your explicitly declared `EqualityContract` property overrides the base record's `EqualityContract` property. The compiler relies on the override chain for the equality contract to distinguish record types at run time within the [inheritance hierarchy](../builtin-types/record.md#equality-in-inheritance-hierarchies) (**CS8876**). +- Add a `get` accessor to the `EqualityContract` property. The compiler reads the equality contract at run time to determine whether two record instances are of the same type, so the property must be readable (**CS8906**). ## Positional members -- **CS8866**: *Record member must be a readable instance property or field of the type to match the positional parameter.* -- **CS8907**: *Parameter is unread. Did you forget to use it to initialize the property with that name?* -- **CS8908**: *The type may not be used for a field of a record.* -- **CS8913**: *The positional member found corresponding to this parameter is hidden.* +- **CS8866**: *Record member 'member' must be a readable instance property or field of type 'type' to match positional parameter 'parameter'.* +- **CS8907**: *Parameter 'name' is unread. Did you forget to use it to initialize the property with that name?* +- **CS8908**: *The type 'type' may not be used for a field of a record.* +- **CS8913**: *The positional member 'member' found corresponding to this parameter is hidden.* When you declare a [positional record](../builtin-types/record.md#positional-syntax-for-property-and-field-definition), the compiler synthesizes properties that correspond to each positional parameter. These diagnostics indicate that your explicit declarations conflict with those synthesized properties. For the complete rules, see the [records specification](~/_csharpstandard/standard/classes.md#1516-synthesized-record-class-members) in the C# language specification. To correct these errors, apply the following changes to your positional record declarations: -- Change any explicitly declared member that corresponds to a positional parameter so that it's a readable instance property or field with the same type as the parameter. The compiler needs the member to be readable and type-compatible so that the synthesized `Deconstruct` method and [positional pattern matching](../../fundamentals/functional/pattern-matching.md) can access the value correctly (**CS8866**). -- Ensure that each positional parameter is used to initialize its corresponding property in the constructor body when you provide an explicit constructor. The compiler raises a warning when a parameter goes unused because it typically indicates a typo or a mismatch between the parameter name and the property name, which would leave the property uninitialized (**CS8907**). +- Change any explicitly declared member that corresponds to a positional parameter so it's a readable instance property or field with the same type as the parameter. The compiler needs the member to be readable and type-compatible so that the synthesized `Deconstruct` method and [positional pattern matching](../../fundamentals/functional/pattern-matching.md) can access the value correctly (**CS8866**). +- Ensure that each positional parameter initializes its corresponding property in the constructor body when you provide an explicit constructor. The compiler raises a warning when a parameter goes unused because it typically indicates a typo or a mismatch between the parameter name and the property name, which would leave the property uninitialized (**CS8907**). - Change the type of a field declared in a record to a type that's valid in that context. Certain types, such as `Span` or other `ref struct` types, can't be used as fields in a record because record types require all fields to be compatible with heap allocation and value-based equality (**CS8908**). - Remove the `new` modifier from a member in a derived record that hides a positional member from the base record. When a positional member is hidden, the compiler can't match the positional parameter to its corresponding property, which breaks the synthesized `Deconstruct` method and positional [pattern matching](../../fundamentals/functional/pattern-matching.md) (**CS8913**). ## Equality members -- **CS8851**: *Type defines 'Equals' but not 'GetHashCode'* -- **CS8858**: *The receiver type is not a valid record type and is not a struct type.* +- **CS8851**: *'type' defines 'Equals' but not 'GetHashCode'* +- **CS8857**: *The receiver of a `with` expression must have a non-void type.* +- **CS8858**: *The receiver type 'type' is not a valid record type and is not a struct type.* [Record types](../builtin-types/record.md) provide built-in [value-based equality](../builtin-types/record.md#value-equality). These diagnostics arise when your declarations conflict with the equality contract. For the complete rules on equality, see [equality comparisons](../../programming-guide/statements-expressions-operators/equality-comparisons.md). To correct these errors, apply the following changes: - Add a `GetHashCode` method whenever you define an `Equals` method. The [equality contract](../../programming-guide/statements-expressions-operators/equality-comparisons.md) requires that objects considered equal produce the same hash code, so the compiler enforces that these two methods are always defined together (**CS8851**). -- Change the receiver of a `with` expression so that it's a [record type](../builtin-types/record.md) or a [struct type](../builtin-types/struct.md). The `with` expression creates a modified copy by using the type's copy constructor, which is only available on record types and struct types (**CS8858**). +- Change the receiver of a `with` expression so that it's a [record type](../builtin-types/record.md) or a [struct type](../builtin-types/struct.md). The `with` expression creates a modified copy by using the `record` copy constructor, or value copy semantics for `struct` types (**CS8858**). +- Ensure the receiver of a [`with` expression](../operators/with-expression.md) has a non-void type. The `with` expression produces a new copy of the receiver, so the receiver must evaluate to a value that can be copied (**CS8857**). ## Record inheritance diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 8221b7ef8e7bc..95360816b6483 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -500,8 +500,9 @@ items: href: ./compiler-messages/record-declaration-errors.md displayName: > record, record struct, record class, positional record, - CS8851, CS8858, CS8859, CS8860, CS8864, CS8865, CS8866, CS8870, CS8872, CS8873, - CS8874, CS8875, CS8877, CS8879, CS8907, CS8908, CS8913 + CS8851, CS8857, CS8858, CS8859, CS8860, CS8864, CS8865, CS8866, CS8869, CS8870, + CS8871, CS8872, CS8873, CS8874, CS8875, CS8876, CS8877, CS8879, CS8906, CS8907, + CS8908, CS8913 - name: Union type declarations href: ./compiler-messages/union-declaration-errors.md displayName: > diff --git a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md index 2376d982022a1..bd3a161703253 100644 --- a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md +++ b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md @@ -305,10 +305,6 @@ f1_keywords: - "CS8853" - "CS8855" - "CS8856" - - "CS8857" # records - - "CS8869" - - "CS8871" - - "CS8876" - "CS8888" # feature / version - "CS8889" - "CS8890" @@ -318,7 +314,6 @@ f1_keywords: - "CS8895" - "CS8896" - "CS8903" # init only property - - "CS8906" # record # Coming in C# 15 - "CS9343" # misc - "CS9346" From 15e0a2f40653332823fab695cbe671a54c5ecd23 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 5 May 2026 14:19:56 -0400 Subject: [PATCH 04/39] Add diagnostics for init only properties (#53520) * Additional consolidation * Reorganize themes * Proofread all error messages Make sure the error messages in the doc match the roslyn source. * Final Copyedit Review and do a final copyedit. * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Respond to feedback Reword one recommendation. * fix warning * Apply suggestions from code review Co-authored-by: Bill Wagner --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .openpublishing.redirection.csharp.json | 44 +++ .../property-declaration-errors.md | 261 ++++++++++++------ docs/csharp/language-reference/toc.yml | 34 +-- docs/csharp/misc/cs0273.md | 40 --- docs/csharp/misc/cs0274.md | 29 -- docs/csharp/misc/cs0275.md | 31 --- docs/csharp/misc/cs0276.md | 34 --- docs/csharp/misc/cs0442.md | 33 --- docs/csharp/misc/cs0544.md | 38 --- docs/csharp/misc/cs0546.md | 69 ----- docs/csharp/misc/cs0547.md | 42 --- docs/csharp/misc/cs0548.md | 39 --- docs/csharp/misc/cs0610.md | 32 --- docs/csharp/misc/cs1715.md | 49 ---- ...n-t-have-specifics-on-this-csharp-error.md | 6 - 15 files changed, 220 insertions(+), 561 deletions(-) delete mode 100644 docs/csharp/misc/cs0273.md delete mode 100644 docs/csharp/misc/cs0274.md delete mode 100644 docs/csharp/misc/cs0275.md delete mode 100644 docs/csharp/misc/cs0276.md delete mode 100644 docs/csharp/misc/cs0442.md delete mode 100644 docs/csharp/misc/cs0544.md delete mode 100644 docs/csharp/misc/cs0546.md delete mode 100644 docs/csharp/misc/cs0547.md delete mode 100644 docs/csharp/misc/cs0548.md delete mode 100644 docs/csharp/misc/cs0610.md delete mode 100644 docs/csharp/misc/cs1715.md diff --git a/.openpublishing.redirection.csharp.json b/.openpublishing.redirection.csharp.json index aa121a7e60ef0..7a7f642051219 100644 --- a/.openpublishing.redirection.csharp.json +++ b/.openpublishing.redirection.csharp.json @@ -40,10 +40,30 @@ "source_path_from_root": "/docs/csharp/misc/cs0221.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0273.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0274.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0275.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0276.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0410.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0442.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0463.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" @@ -52,10 +72,30 @@ "source_path_from_root": "/docs/csharp/misc/cs0543.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0544.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0546.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0547.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, + { + "source_path_from_root": "/docs/csharp/misc/cs0548.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0594.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/overloaded-operator-errors" }, + { + "source_path_from_root": "/docs/csharp/misc/cs0610.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs0644.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" @@ -228,6 +268,10 @@ "source_path_from_root": "/docs/csharp/misc/cs1599.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" }, + { + "source_path_from_root": "/docs/csharp/misc/cs1715.md", + "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors" + }, { "source_path_from_root": "/docs/csharp/misc/cs1958.md", "redirect_url": "/dotnet/csharp/language-reference/compiler-messages/delegate-function-pointer-diagnostics" diff --git a/docs/csharp/language-reference/compiler-messages/property-declaration-errors.md b/docs/csharp/language-reference/compiler-messages/property-declaration-errors.md index a01e476b2c69f..e7437efc66830 100644 --- a/docs/csharp/language-reference/compiler-messages/property-declaration-errors.md +++ b/docs/csharp/language-reference/compiler-messages/property-declaration-errors.md @@ -3,14 +3,26 @@ title: Compiler Errors on property declarations description: Use this article to diagnose and correct compiler errors and warnings when you define properties in your types. f1_keywords: - "CS0200" + - "CS0273" + - "CS0274" + - "CS0275" + - "CS0276" + - "CS0442" + - "CS0544" - "CS0545" + - "CS0546" + - "CS0547" + - "CS0548" - "CS0571" + - "CS0610" - "CS0840" - "CS1014" - "CS1043" + - "CS1715" - "CS8050" - "CS8051" - "CS8053" + - "CS8080" - "CS8145" - "CS8147" - "CS8341" @@ -20,6 +32,11 @@ f1_keywords: - "CS8660" - "CS8661" - "CS8664" + - "CS8852" + - "CS8853" + - "CS8855" + - "CS8856" + - "CS8903" - "CS9029" - "CS9030" - "CS9031" @@ -41,14 +58,26 @@ f1_keywords: - "CS9273" helpviewer_keywords: - "CS0200" + - "CS0273" + - "CS0274" + - "CS0275" + - "CS0276" + - "CS0442" + - "CS0544" - "CS0545" + - "CS0546" + - "CS0547" + - "CS0548" - "CS0571" + - "CS0610" - "CS0840" - "CS1014" - "CS1043" + - "CS1715" - "CS8050" - "CS8051" - "CS8053" + - "CS8080" - "CS8145" - "CS8147" - "CS8341" @@ -58,6 +87,11 @@ helpviewer_keywords: - "CS8660" - "CS8661" - "CS8664" + - "CS8852" + - "CS8853" + - "CS8855" + - "CS8856" + - "CS8903" - "CS9029" - "CS9030" - "CS9031" @@ -77,7 +111,7 @@ helpviewer_keywords: - "CS9264" - "CS9266" - "CS9273" -ms.date: 12/11/2025 +ms.date: 04/30/2026 ai-usage: ai-assisted --- # Errors and warnings related to property declarations @@ -88,33 +122,50 @@ You can encounter the following errors related to property declarations: That's by design. The text closely matches the text of the compiler error / warning for SEO purposes. --> - [**CS0200**](#readonly-properties): *Property or indexer 'property' cannot be assigned to -- it is read only* -- [**CS0545**](#property-accessor-syntax): *'function' : cannot override because 'property' does not have an overridable get accessor* -- [**CS0571**](#property-accessor-syntax): *'function' : cannot explicitly call operator or accessor* -- [**CS0840**](#auto-implemented-properties): *'Property name' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.* -- [**CS1014**](#auto-implemented-properties): *A get or set accessor expected* -- [**CS1043**](#property-accessor-syntax): *{ or ; expected* -- [**CS8050**](#property-initializers): *Only auto-implemented properties, or properties that use the 'field' keyword, can have initializers* -- [**CS8051**](#property-initializers): *Auto-implemented properties must have get accessors* -- [**CS8053**](#property-initializers): *Instance properties in interfaces cannot have initializers* +- [**CS0273**](#accessor-accessibility): *The accessibility modifier of the 'accessor' accessor must be more restrictive than the property or indexer 'property'* +- [**CS0274**](#accessor-accessibility): *Cannot specify accessibility modifiers for both accessors of the property or indexer 'property'* +- [**CS0275**](#accessor-accessibility): *'accessor': accessibility modifiers may not be used on accessors in an interface* +- [**CS0276**](#accessor-accessibility): *'property': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor* +- [**CS0442**](#accessor-accessibility): *'property': abstract properties cannot have private accessors* +- [**CS0544**](#property-overrides): *'property': cannot override because 'member' is not a property* +- [**CS0545**](#property-overrides): *'function' : cannot override because 'property' does not have an overridable get accessor* +- [**CS0546**](#property-overrides): *'accessor': cannot override because 'property' does not have an overridable set accessor* +- [**CS0547**](#property-declaration-syntax): *'property': property or indexer cannot have void type* +- [**CS0548**](#property-declaration-syntax): *'property': property or indexer must have at least one accessor* +- [**CS0571**](#property-declaration-syntax): *'function' : cannot explicitly call operator or accessor* +- [**CS0610**](#property-declaration-syntax): *Field or property cannot be of type 'type'* +- [**CS0840**](#property-declaration-syntax): *'Property name' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.* +- [**CS1014**](#property-declaration-syntax): *A get or set accessor expected* +- [**CS1043**](#property-declaration-syntax): *{ or ; expected* +- [**CS1715**](#property-overrides): *'type': type must be 'type' to match overridden member 'member'* +- [**CS8050**](#property-initializers): *Only auto-implemented properties, or properties that use the 'field' keyword, can have initializers.* +- [**CS8051**](#property-initializers): *Auto-implemented properties must have get accessors.* +- [**CS8053**](#property-initializers): *Instance properties in interfaces cannot have initializers.* +- [**CS8080**](#property-overrides): *Auto-implemented properties must override all accessors of the overridden property.* - [**CS8145**](#ref-returning-properties): *Auto-implemented properties cannot return by reference* - [**CS8147**](#ref-returning-properties): *Properties which return by reference cannot have set accessors* -- [**CS8341**](#readonly-properties): *Auto-implemented instance properties in readonly structs must be readonly* -- [**CS8657**](#readonly-properties): *Static member cannot be marked 'readonly'* -- [**CS8658**](#readonly-properties): *Auto-implemented 'set' accessor cannot be marked 'readonly'* -- [**CS8659**](#readonly-properties): *Auto-implemented property cannot be marked 'readonly' because it has a 'set' accessor* -- [**CS8660**](#readonly-properties): *Cannot specify 'readonly' modifiers on both property and its accessor* -- [**CS8661**](#readonly-properties): *Cannot specify 'readonly' modifiers on both accessors of property* -- [**CS8664**](#readonly-properties): *'readonly' can only be used on accessors if property has both get and set* +- [**CS8341**](#readonly-properties): *Auto-implemented instance properties in readonly structs must be readonly.* +- [**CS8657**](#readonly-properties): *Static member 'member' cannot be marked 'readonly'.* +- [**CS8658**](#readonly-properties): *Auto-implemented 'set' accessor 'accessor' cannot be marked 'readonly'.* +- [**CS8659**](#readonly-properties): *Auto-implemented property 'property' cannot be marked 'readonly' because it has a 'set' accessor.* +- [**CS8660**](#readonly-properties): *Cannot specify 'readonly' modifiers on both property or indexer 'property' and its accessor. Remove one of them.* +- [**CS8661**](#readonly-properties): *Cannot specify 'readonly' modifiers on both accessors of property or indexer 'property'. Instead, put a 'readonly' modifier on the property itself.* +- [**CS8664**](#readonly-properties): *'property': 'readonly' can only be used on accessors if the property or indexer has both a get and a set accessor* +- [**CS8852**](#init-only-properties): *Init-only property or indexer 'property' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.* +- [**CS8853**](#init-only-properties): *'member' must match by init-only of overridden member 'member'* +- [**CS8855**](#init-only-properties): *Accessors 'accessor' and 'accessor' should both be init-only or neither* +- [**CS8856**](#init-only-properties): *The 'init' accessor is not valid on static members* +- [**CS8903**](#init-only-properties): *'init' accessors cannot be marked 'readonly'. Mark 'property' readonly instead.* - [**CS9029**](#required-members): *Types and aliases cannot be named 'required'.* -- [**CS9030**](#required-members): *Member must be required because it overrides required member.* -- [**CS9031**](#required-members): *Required member cannot be hidden by derived member.* +- [**CS9030**](#required-members): *'member' must be required because it overrides required member 'member'* +- [**CS9031**](#required-members): *Required member 'member' cannot be hidden by 'member'.* - [**CS9032**](#required-members): *Required member cannot be less visible or have a setter less visible than the containing type.* - [**CS9033**](#required-members): *Do not use '`System.Runtime.CompilerServices.RequiredMemberAttribute'`. Use the 'required' keyword on required fields and properties instead.* - [**CS9034**](#required-members): *Required member must be settable.* - [**CS9035**](#required-members): *Required member must be set in the object initializer or attribute constructor.* - [**CS9036**](#required-members): *Required member 'memberName' must be assigned a value, it cannot use a nested member or collection initializer.* -- [**CS9037**](#required-members): *The required members list is malformed and cannot be interpreted.* -- [**CS9038**](#required-members): *The required members list for the base type is malformed and cannot be interpreted. To use this constructor, apply the '`SetsRequiredMembers`' attribute*. +- [**CS9037**](#required-members): *The required members list for 'type' is malformed and cannot be interpreted.* +- [**CS9038**](#required-members): *The required members list for the base type 'type' is malformed and cannot be interpreted. To use this constructor, apply the '`SetsRequiredMembers`' attribute.* - [**CS9039**](#required-members): *This constructor must add '`SetsRequiredMembers`' because it chains to a constructor that has that attribute.* - [**CS9040**](#required-members): *Type cannot satisfy the '`new()`' constraint on parameter in the generic type or method because it has required members.* - [**CS9042**](#required-members): *Required member should not be attributed with '`ObsoleteAttribute`' unless the containing type is obsolete or all constructors are obsolete.* @@ -124,118 +175,153 @@ That's by design. The text closely matches the text of the compiler error / warn The following warnings can be generated for field-backed properties: -- [**CS9264**](#field-backed-properties): *Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or adding '`[field: MaybeNull, AllowNull]`' attributes.* -- [**CS9266**](#field-backed-properties): *One accessor of property should use '`field`' because the other accessor is using it.* +- [**CS9264**](#field-backed-properties): *Non-nullable property 'property' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where '`field`' is null in the '`get`' accessor.* +- [**CS9266**](#field-backed-properties): *The 'accessor' accessor of property 'property' should use '`field`' because the other accessor is using it.* - [**CS9273**](#field-backed-properties): *In this language version, '`field`' is a keyword within a property accessor. Rename the variable or use the identifier '`@field`' instead.* The following sections explain the cause and fixes for these errors and warnings. -## Property accessor syntax +## Accessor accessibility -- **CS0545**: *'function' : cannot override because 'property' does not have an overridable get accessor* -- **CS0571**: *'function' : cannot explicitly call operator or accessor* -- **CS1043**: *{ or ; expected* - -To correct property accessor syntax errors, apply one of the following changes based on the specific diagnostic: +- **CS0273**: *The accessibility modifier of the 'accessor' accessor must be more restrictive than the property or indexer 'property'* +- **CS0274**: *Cannot specify accessibility modifiers for both accessors of the property or indexer 'property'* +- **CS0275**: *'accessor': accessibility modifiers may not be used on accessors in an interface* +- **CS0276**: *'property': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor* +- **CS0442**: *'property': abstract properties cannot have private accessors* -Override only the accessors that exist in the base class property declaration (**CS0545**). You can't override a property accessor that isn't present or accessible in the base class because there's no virtual method to override in the compiled IL. If the base class property has only a `get` accessor, remove the `set` accessor from your override, or add the missing accessor to the base class and mark it `virtual`. Alternatively, use the `new` keyword instead of `override` to hide the base class property with a completely new property definition that has different accessors. +These errors enforce the rules for access modifiers on property and indexer accessors. For the full rules, see [Restricting Accessor Accessibility](../../programming-guide/classes-and-structs/restricting-accessor-accessibility.md) and [Accessors](~/_csharpstandard/standard/classes.md#1573-accessors) in the C# specification. To correct these errors, apply one of the following changes based on the specific diagnostic: -Access properties using property syntax rather than calling accessor methods directly (**CS0571**). Property accessors compile to special methods with names like `get_PropertyName` and `set_PropertyName`, but you should invoke these methods through property syntax (`obj.Property` and `obj.Property = value`). This approach maintains proper semantics and allows the compiler to perform necessary checks. The same principle applies to operators, which compile to methods like `op_Increment` but should be invoked using operator syntax (`++obj`) rather than method calls. +- Use an access modifier that's more restrictive than the property's declared accessibility (**CS0273**). For example, an `internal` property can have a `private` set accessor, but not a `public` one. The accessor's accessibility must be a proper subset of the property's accessibility. +- Apply an access modifier to only one of the two accessors (**CS0274**). The property declaration itself establishes the default accessibility for both accessors, and only one accessor can differ from that default. Place the access modifier on whichever accessor needs restricted access. +- Remove access modifiers from accessors in interface property declarations (**CS0275**). Interface members define a public contract, and access modifiers on individual accessors aren't permitted. If you need to restrict access, apply the restriction in the implementing class instead. +- Add both a `get` and a `set` accessor to the property before applying an access modifier to either one (**CS0276**). Access modifiers on accessors distinguish one accessor's visibility from the other, which requires both accessors to be present. If the property has only one accessor, remove the access modifier from it. +- Change the access modifier on abstract property accessors from `private` to a less restrictive modifier (**CS0442**). Abstract members must be accessible to derived classes so those classes can provide implementations. Use `protected`, `internal`, or `protected internal` instead of `private`. -Use proper property accessor syntax with braces or expression bodies (**CS1043**). Property accessors must follow C# syntax rules: accessor bodies must be enclosed in curly braces `{ }`, expression-bodied accessors must use the `=>` syntax, and auto-implemented properties must end with a semicolon after the accessor list. The compiler expects either a complete accessor implementation or the semicolon that indicates an auto-implemented accessor. +For more information, see [Restricting Accessor Accessibility](../../programming-guide/classes-and-structs/restricting-accessor-accessibility.md) and [Properties](../../programming-guide/classes-and-structs/properties.md). -For more information, see [Properties](../../programming-guide/classes-and-structs/properties.md), [Inheritance](../../fundamentals/object-oriented/inheritance.md), and [Using Properties](../../programming-guide/classes-and-structs/using-properties.md). - -## Auto-implemented properties +## Property declaration syntax +- **CS0547**: *'property': property or indexer cannot have void type* +- **CS0548**: *'property': property or indexer must have at least one accessor* +- **CS0571**: *'function' : cannot explicitly call operator or accessor* +- **CS0610**: *Field or property cannot be of type 'type'* - **CS0840**: *'Property name' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.* - **CS1014**: *A get or set accessor expected* +- **CS1043**: *{ or ; expected* -To correct auto-implemented property errors, apply one of the following changes based on the specific diagnostic: +These errors enforce the structural requirements of property and indexer declarations. For the full rules, see [Properties](../../programming-guide/classes-and-structs/properties.md) and the [Properties](~/_csharpstandard/standard/classes.md#157-properties) section of the C# specification. To correct these errors, apply one of the following changes based on the specific diagnostic: -Add both `get` and `set` accessors to the property declaration (**CS0840**). Auto-implemented properties require the compiler to generate a backing field, and the compiler can only do this when both accessors are present to ensure the storage can be both read and written. If you need a read-only auto-implemented property, include a `set` accessor and make it `private` to restrict write access while still allowing the compiler to generate the backing field. Alternatively, if the property is declared as `abstract` or `extern`, remove the accessor bodies entirely since these modifiers indicate the implementation is provided elsewhere. For `partial` properties, you can split the declaration and implementation across partial type declarations. +- Change the property type from `void` to a valid type (**CS0547**). Properties and indexers represent expressions, and [`void`](../builtin-types/void.md) isn't a valid expression type. Choose the appropriate type for the data the property represents. +- Add at least one accessor (`get`, `set`, or `init`) to the property declaration (**CS0548**). A property without any accessors has no way to read or write its value. Include a `get` accessor, a `set` or `init` accessor, or both. +- Access properties using property syntax rather than calling accessor methods directly (**CS0571**). Property accessors compile to methods named `get_PropertyName` and `set_PropertyName`, but invoke these methods through property syntax (`obj.Property` and `obj.Property = value`). The same principle applies to operators. Use operator syntax (`++obj`) rather than calling methods like `op_Increment`. +- Change the field or property type from a restricted type to an allowed type (**CS0610**). Certain types like and can't be used as fields or properties. These types can still be used as method parameters or local variables. +- For a read-only property, declare a `get`-only auto-implemented property. Otherwise, add both `get` and `set` accessors to auto-implemented property declarations, or provide explicit accessor bodies (**CS0840**). For a property that needs custom logic, use the `field` keyword, added in C# 13 to access the compiler-synthesized backing field in your accessor body. For `abstract` or `extern` properties, remove the accessor bodies because the implementation is provided elsewhere. For `partial` properties, split the declaration and implementation across partial type declarations. +- Ensure the property body contains only valid accessor keywords—`get`, `set`, or `init` (**CS1014**). Property bodies can't contain arbitrary statements or member declarations. Move fields and methods outside the property to the class or struct body. +- Use proper property accessor syntax with braces or expression bodies (**CS1043**). Accessor bodies must use curly braces `{ }`, expression-bodied accessors must use `=>` syntax, and auto-implemented properties must end with a semicolon after the accessor token. -Ensure the property declaration contains only valid accessor keywords `get` and `set` (**CS1014**). Property syntax only allows accessor declarations, not arbitrary statements or member declarations within the property body. If you need additional logic, implement the property with explicit accessor bodies that contain your code. If you're attempting to declare fields or methods, move those declarations outside the property to the class or struct body where member declarations are allowed. +For more information, see [Properties](../../programming-guide/classes-and-structs/properties.md), [Auto-Implemented Properties](../../programming-guide/classes-and-structs/auto-implemented-properties.md), and [Using Properties](../../programming-guide/classes-and-structs/using-properties.md). -For more information, see [Properties](../../programming-guide/classes-and-structs/properties.md) and [Auto-Implemented Properties](../../programming-guide/classes-and-structs/auto-implemented-properties.md). +## Property overrides + +- **CS0544**: *'property': cannot override because 'member' is not a property* +- **CS0545**: *'function' : cannot override because 'property' does not have an overridable get accessor* +- **CS0546**: *'accessor': cannot override because 'property' does not have an overridable set accessor* +- **CS1715**: *'type': type must be 'type' to match overridden member 'member'* +- **CS8080**: *Auto-implemented properties must override all accessors of the overridden property.* + +These errors enforce the rules for overriding properties in derived classes. For the full rules, see [Inheritance](../../fundamentals/object-oriented/inheritance.md) and the [Virtual, sealed, override, and abstract accessors](~/_csharpstandard/standard/classes.md#1576-virtual-sealed-override-and-abstract-accessors) section of the C# specification. To correct these errors, apply one of the following changes based on the specific diagnostic: + +- Ensure the member you're overriding is a property, not a field or method (**CS0544**). The `override` keyword on a property can only target a `virtual`, `abstract`, or `override` property in a base class. To shadow a non-property member with a property, use the `new` keyword instead of `override`. +- Override only the accessors that exist in the base class property declaration (**CS0545**, **CS0546**). You can't override a property accessor that isn't present or accessible in the base class because there's no virtual method to override. If the base class property has only a `get` accessor, you can't add a `set` accessor through an override. Either add the missing accessor to the base class and mark it `virtual`, or use `new` to hide the base class property with a new property definition. +- Match the type of the overriding property to the type of the overridden member (**CS1715**). Read-only (`get`-only) properties support covariant return types beginning with C# 9, so the override can return a more derived type. However, properties that have a `set` or `init` accessor require an exact type match because the setter accepts values of the declared type. If you need a different type on a property with a setter, change the property type in the derived class to match the base class declaration, or remove the setter and use a covariant return type instead. +- Include all accessors from the base property when overriding with an auto-implemented property (**CS8080**). Auto-implemented properties generate both storage and accessor implementations, so they must override all accessors present in the base class. If the base property has both `get` and `set`, the auto-implemented override must also have both. To override only specific accessors, implement the property with explicit accessor bodies and an explicit backing field instead of using auto-implementation. + +For more information, see [Inheritance](../../fundamentals/object-oriented/inheritance.md), [Properties](../../programming-guide/classes-and-structs/properties.md), and [Using Properties](../../programming-guide/classes-and-structs/using-properties.md). ## Field-backed properties - **CS9258**: *In this language version, the '`field`' keyword binds to a synthesized backing field for the property. To avoid generating a synthesized backing field, and to refer to the existing member, use '`this.field`' or '`@field`' instead.* - **CS9263**: *A partial property cannot have an initializer on both the definition and implementation.* -- **CS9264**: *Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or adding '`[field: MaybeNull, AllowNull]`' attributes.* -- **CS9266**: *One accessor of property should use '`field`' because the other accessor is using it.* +- **CS9264**: *Non-nullable property 'property' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where '`field`' is null in the '`get`' accessor.* +- **CS9266**: *The 'accessor' accessor of property 'property' should use '`field`' because the other accessor is using it.* - **CS9273**: *In this language version, '`field`' is a keyword within a property accessor. Rename the variable or use the identifier '`@field`' instead.* To correct field-backed property errors, apply one of the following changes based on the specific diagnostic: -Rename any variable named `field` to a different identifier, or use the `@field` escape syntax to refer to your variable (**CS9258**, **CS9273**). This correction is necessary because `field` is a contextual keyword within property accessors in C# 13 and later, where it refers to the compiler-synthesized backing field. If you want to access an existing member named `field` instead of the synthesized backing field, qualify it with `this.field` to disambiguate the reference. - -Remove the initializer from either the partial property definition or the implementation, keeping only one (**CS9263**). This correction is required because allowing initializers in both locations would create ambiguity about which value should be used and could lead to the backing field being initialized twice with potentially different values. - -Add the `[field: MaybeNull, AllowNull]` attributes to the property declaration to indicate that the backing field should be treated as nullable (**CS9264**). This correction aligns the nullability expectations between the property type and the compiler-synthesized backing field, resolving the mismatch where the property is declared as non-nullable but the `field` keyword usage suggests it could be null. Alternatively, change the property type to nullable, add the `required` modifier to ensure initialization, or initialize the property in the constructor. - -Consistently use either the `field` keyword in both accessors or use an explicit backing field in both accessors (**CS9266**). This correction prevents potential bugs where one accessor modifies the compiler-synthesized backing field while the other accessor modifies a different storage location, leading to inconsistent property behavior. +- Rename any variable named `field` to a different identifier, or use the `@field` escape syntax to refer to your variable (**CS9258**, **CS9273**). This correction is necessary because `field` is a contextual keyword within property accessors in C# 13 and later, where it refers to the compiler-synthesized backing field. If you want to access an existing member named `field` instead of the synthesized backing field, qualify it with `this.field` to disambiguate the reference. +- Remove the initializer from either the partial property definition or the implementation, keeping only one (**CS9263**). This correction is required because allowing initializers in both locations would create ambiguity about which value should be used and could lead to the backing field being initialized twice with potentially different values. +- Add the `[field: MaybeNull, AllowNull]` attributes to the property declaration to indicate that the backing field should be treated as nullable (**CS9264**). This correction aligns the nullability expectations between the property type and the compiler-synthesized backing field, resolving the mismatch where the property is declared as non-nullable but the `field` keyword usage suggests it could be null. Alternatively, change the property type to nullable, add the `required` modifier to ensure initialization, or initialize the property in the constructor. +- Consistently use either the `field` keyword in both accessors or use an explicit backing field in both accessors (**CS9266**). This correction prevents potential bugs where one accessor modifies the compiler-synthesized backing field while the other accessor modifies a different storage location, leading to inconsistent property behavior. For more information, see [field keyword](../../programming-guide/classes-and-structs/properties.md#field-backed-properties) and [Partial properties](../../programming-guide/classes-and-structs/partial-classes-and-methods.md#partial-members). ## Readonly properties - **CS0200**: *Property or indexer 'property' cannot be assigned to -- it is read only* -- **CS8341**: *Auto-implemented instance properties in readonly structs must be readonly* -- **CS8657**: *Static member cannot be marked 'readonly'* -- **CS8658**: *Auto-implemented 'set' accessor cannot be marked 'readonly'* -- **CS8659**: *Auto-implemented property cannot be marked 'readonly' because it has a 'set' accessor* -- **CS8660**: *Cannot specify 'readonly' modifiers on both property and its accessor* -- **CS8661**: *Cannot specify 'readonly' modifiers on both accessors of property* -- **CS8664**: *'readonly' can only be used on accessors if property has both get and set* +- **CS8341**: *Auto-implemented instance properties in readonly structs must be readonly.* +- **CS8657**: *Static member 'member' cannot be marked 'readonly'.* +- **CS8658**: *Auto-implemented 'set' accessor 'accessor' cannot be marked 'readonly'.* +- **CS8659**: *Auto-implemented property 'property' cannot be marked 'readonly' because it has a 'set' accessor.* +- **CS8660**: *Cannot specify 'readonly' modifiers on both property or indexer 'property' and its accessor. Remove one of them.* +- **CS8661**: *Cannot specify 'readonly' modifiers on both accessors of property or indexer 'property'. Instead, put a 'readonly' modifier on the property itself.* +- **CS8664**: *'property': 'readonly' can only be used on accessors if the property or indexer has both a get and a set accessor* To correct readonly property errors, apply one of the following changes based on the specific diagnostic: -Add a `set` or `init` accessor to the property to make it writable (**CS0200**). This correction is necessary because properties without set accessors are read-only and can only be assigned in the declaring type's constructor or field initializer. If you need the property to be set during object initialization but immutable afterward, use an `init` accessor instead of a `set` accessor. If the property should remain read-only, move the assignment into the constructor where initialization is permitted, or reconsider whether the assignment is necessary at all. - -Mark auto-implemented instance properties as `readonly` when you declare them within a `readonly struct` (**CS8341**). This correction enforces the immutability contract of the containing struct, ensuring that all instance members respect the `readonly` guarantee. If the property needs to be mutable, either remove the `readonly` modifier from the struct declaration or implement the property with an explicit backing field and accessor bodies that don't modify instance state. +- Add a `set` or `init` accessor to the property to make it writable (**CS0200**). This correction is necessary because properties without set accessors are read-only and can only be assigned in the declaring type's constructor or field initializer. If you need the property to be set during object initialization but immutable afterward, use an `init` accessor instead of a `set` accessor. If the property should remain read-only, move the assignment into the constructor where initialization is permitted, or reconsider whether the assignment is necessary at all. +- Mark auto-implemented instance properties as `readonly` when you declare them within a `readonly struct` (**CS8341**). This correction enforces the immutability contract of the containing struct, ensuring that all instance members respect the `readonly` guarantee. If the property needs to be mutable, either remove the `readonly` modifier from the struct declaration or implement the property with an explicit backing field and accessor bodies that don't modify instance state. +- Remove the `readonly` modifier from static property or accessor declarations (**CS8657**). This correction is required because the `readonly` modifier only applies to instance members of structs to indicate they don't modify instance state, and static members don't have instance state to protect. If you need a read-only static property, simply omit the `set` accessor rather than using the `readonly` modifier. +- Remove the `readonly` modifier from auto-implemented `set` accessors, or apply it to the `get` accessor only (**CS8658**). This correction is necessary because `set` accessors inherently modify state, which contradicts the purpose of the `readonly` modifier that guarantees no modification of instance state. If you need a property that can be set during initialization but is read-only afterward, use an `init` accessor instead of a `set` accessor. +- Remove the `readonly` modifier from the property declaration when the property has a `set` accessor (**CS8659**). This correction is required because properties with `set` accessors can modify instance state, which violates the `readonly` guarantee. If you need initialization-time setting only, replace the `set` accessor with an `init` accessor, or remove the `set` accessor entirely to make the property truly read-only. +- Place the `readonly` modifier either on the property declaration or on individual accessors, but not both (**CS8660**, **CS8661**). This correction prevents redundant modifier declarations that could create confusion about which modifier takes precedence. If you want to mark specific accessors as `readonly`, remove the modifier from the property declaration and place it only on the accessors. Alternatively, if all accessors should be `readonly`, mark the property itself rather than individual accessors. +- Ensure both `get` and `set` accessors are present when marking individual accessors as `readonly` (**CS8664**). This correction is necessary because the `readonly` modifier on individual accessors distinguishes between accessors that modify state and those that don't, which only makes sense when both accessor types exist. If the property has only a `get` accessor, mark the entire property as `readonly` instead of the individual accessor. -Remove the `readonly` modifier from static property or accessor declarations (**CS8657**). This correction is required because the `readonly` modifier only applies to instance members of structs to indicate they don't modify instance state, and static members don't have instance state to protect. If you need a read-only static property, simply omit the `set` accessor rather than using the `readonly` modifier. +For more information, see [readonly instance members](../builtin-types/struct.md#readonly-instance-members), [init keyword](../keywords/init.md), and [Properties](../../programming-guide/classes-and-structs/properties.md). -Remove the `readonly` modifier from auto-implemented `set` accessors, or apply it to the `get` accessor only (**CS8658**). This correction is necessary because `set` accessors inherently modify state, which contradicts the purpose of the `readonly` modifier that guarantees no modification of instance state. If you need a property that can be set during initialization but is read-only afterward, use an `init` accessor instead of a `set` accessor. +## Init-only properties -Remove the `readonly` modifier from the property declaration when the property has a `set` accessor (**CS8659**). This correction is required because properties with `set` accessors can modify instance state, which violates the `readonly` guarantee. If you need initialization-time setting only, replace the `set` accessor with an `init` accessor, or remove the `set` accessor entirely to make the property truly read-only. +- **CS8852**: *Init-only property or indexer 'property' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor.* +- **CS8853**: *'member' must match by init-only of overridden member 'member'* +- **CS8855**: *Accessors 'accessor' and 'accessor' should both be init-only or neither* +- **CS8856**: *The 'init' accessor is not valid on static members* +- **CS8903**: *'init' accessors cannot be marked 'readonly'. Mark 'property' readonly instead.* -Place the `readonly` modifier either on the property declaration or on individual accessors, but not both (**CS8660**, **CS8661**). This correction prevents redundant modifier declarations that could create confusion about which modifier takes precedence. If you want to mark specific accessors as `readonly`, remove the modifier from the property declaration and place it only on the accessors. Alternatively, if all accessors should be `readonly`, mark the property itself rather than individual accessors. +These errors enforce the rules for the `init` accessor, which enables immutable object initialization. For the full rules, see [init keyword](../keywords/init.md). To correct these errors, apply one of the following changes based on the specific diagnostic: -Ensure both `get` and `set` accessors are present when marking individual accessors as `readonly` (**CS8664**). This correction is necessary because the `readonly` modifier on individual accessors distinguishes between accessors that modify state and those that don't, which only makes sense when both accessor types exist. If the property has only a `get` accessor, mark the entire property as `readonly` instead of the individual accessor. +- Move assignments to init-only properties into an object initializer, a constructor, or an `init` accessor (**CS8852**). Init-only properties can't be assigned after object construction completes. Assign the value in the constructor body, an `init` accessor, or an object initializer expression (`new MyType { Property = value }`). If you need to assign the property after construction, change the `init` accessor to a `set` accessor. +- Match the `init` or `set` accessor kind when overriding a property (**CS8853**). If the base class property uses an `init` accessor, the overriding property must also use `init`. Similarly, if the base uses `set`, the override must use `set`. This consistency ensures that the immutability contract established by the base type is preserved in derived types. +- Use the same accessor kind (`init` or `set`) on both accessors in an explicit interface implementation (**CS8855**). When a type explicitly implements two interfaces that declare the same property, both accessor implementations must agree: either both use `init` or both use `set`. +- Remove the `init` accessor from static property declarations, or change it to a `set` accessor (**CS8856**). The `init` accessor is designed for instance initialization patterns tied to object construction, and static members don't participate in object initialization. Use a `set` accessor for mutable static properties, or remove the setter entirely for read-only static properties. +- Remove the `readonly` modifier from the `init` accessor (**CS8903**). The `readonly` modifier on a struct member guarantees that the member doesn't mutate the struct instance. Because an `init` accessor assigns to instance state, it inherently mutates the struct and can't be marked `readonly`. To make the `get` accessor `readonly`, apply the `readonly` modifier to the `get` accessor only. -For more information, see [readonly instance members](../builtin-types/struct.md#readonly-instance-members), [init keyword](../keywords/init.md), and [Properties](../../programming-guide/classes-and-structs/properties.md). +For more information, see [init keyword](../keywords/init.md) and [Object and Collection Initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md). ## Property initializers -- **CS8050**: *Only auto-implemented properties, or properties that use the 'field' keyword, can have initializers* -- **CS8051**: *Auto-implemented properties must have get accessors* -- **CS8053**: *Instance properties in interfaces cannot have initializers* +- **CS8050**: *Only auto-implemented properties, or properties that use the 'field' keyword, can have initializers.* +- **CS8051**: *Auto-implemented properties must have get accessors.* +- **CS8053**: *Instance properties in interfaces cannot have initializers.* To correct property initializer errors, apply one of the following changes based on the specific diagnostic: -Convert the property to use auto-implemented syntax by removing the accessor bodies and letting the compiler generate the backing field (**CS8050**). This correction is needed because only properties with compiler-managed storage can have initializers, ensuring the initialization occurs before any accessor logic executes. Alternatively, modify the accessor implementations to use the `field` keyword to access the compiler-synthesized backing field. This approach enables the initializer while maintaining custom accessor logic. If neither approach is suitable, remove the initializer and assign the value in a constructor instead, where you have full control over the initialization sequence. - -Add a `get` accessor to the auto-implemented property to enable reading the initialized value (**CS8051**). This correction is required because initializers set a value that must be retrievable, and a write-only property violates this fundamental expectation of property initialization. If you truly need a write-only property, implement the accessors explicitly with a backing field and assign the field directly in a constructor rather than using a property initializer. - -Remove the initializer from interface property declarations (**CS8053**). This correction is necessary because interfaces define contracts for implementing types rather than providing concrete implementations with initial values. If you need to provide default values, implement the property in a class that implements the interface, or use default interface methods (available in C# 8.0 and later) to supply a default implementation. +- Convert the property to use auto-implemented syntax by removing the accessor bodies and letting the compiler generate the backing field (**CS8050**). This correction is needed because only properties with compiler-managed storage can have initializers, ensuring the initialization occurs before any accessor logic executes. Alternatively, modify the accessor implementations to use the `field` keyword to access the compiler-synthesized backing field. This approach enables the initializer while maintaining custom accessor logic. If neither approach is suitable, remove the initializer and assign the value in a constructor instead, where you have full control over the initialization sequence. +- Add a `get` accessor to the auto-implemented property to enable reading the initialized value (**CS8051**). This correction is required because initializers set a value that must be retrievable, and a write-only property violates this fundamental expectation of property initialization. If you truly need a write-only property, implement the accessors explicitly with a backing field and assign the field directly in a constructor rather than using a property initializer. +- Remove the initializer from interface property declarations (**CS8053**). This correction is necessary because interfaces define contracts for implementing types rather than providing concrete implementations with initial values. If you need to provide default values, implement the property in a class that implements the interface, or use default interface methods (available in C# 8.0 and later) to supply a default implementation. For more information, see [Properties](../../programming-guide/classes-and-structs/properties.md), [Auto-Implemented Properties](../../programming-guide/classes-and-structs/auto-implemented-properties.md), and [field keyword](../../programming-guide/classes-and-structs/properties.md#field-backed-properties). ## Required members - **CS9029**: *Types and aliases cannot be named 'required'.* -- **CS9030**: *Member must be required because it overrides required member.* -- **CS9031**: *Required member cannot be hidden by derived member.* +- **CS9030**: *'member' must be required because it overrides required member 'member'* +- **CS9031**: *Required member 'member' cannot be hidden by 'member'.* - **CS9032**: *Required member cannot be less visible or have a setter less visible than the containing type.* - **CS9033**: *Do not use '`System.Runtime.CompilerServices.RequiredMemberAttribute'`. Use the 'required' keyword on required fields and properties instead.* - **CS9034**: *Required member must be settable.* - **CS9035**: *Required member must be set in the object initializer or attribute constructor.* - **CS9036**: *Required member 'memberName' must be assigned a value, it cannot use a nested member or collection initializer.* -- **CS9037**: *The required members list is malformed and cannot be interpreted.* -- **CS9038**: *The required members list for the base type is malformed and cannot be interpreted. To use this constructor, apply the '`SetsRequiredMembers`' attribute*. +- **CS9037**: *The required members list for 'type' is malformed and cannot be interpreted.* +- **CS9038**: *The required members list for the base type 'type' is malformed and cannot be interpreted. To use this constructor, apply the '`SetsRequiredMembers`' attribute.* - **CS9039**: *This constructor must add '`SetsRequiredMembers`' because it chains to a constructor that has that attribute.* - **CS9040**: *Type cannot satisfy the '`new()`' constraint on parameter in the generic type or method because it has required members.* - **CS9042**: *Required member should not be attributed with '`ObsoleteAttribute`' unless the containing type is obsolete or all constructors are obsolete.* @@ -243,19 +329,13 @@ For more information, see [Properties](../../programming-guide/classes-and-struc To correct required member errors, apply one of the following changes based on the specific diagnostic: -Avoid using `required` as a type or alias name (**CS9029**). This correction is necessary because `required` is a contextual keyword in C# 11 and later, and using it as a type name creates ambiguity in code where the keyword might appear. - -Ensure derived members maintain the `required` modifier when overriding required members (**CS9030**). This correction enforces the contract established by the base class, guaranteeing that all derived types maintain the same initialization requirements. Avoid hiding required members with non-required members in derived classes (**CS9031**), as this action breaks the initialization contract that consumers expect from the base type. - -Make required members at least as visible as their containing type, and ensure property setters are also sufficiently visible (**CS9032**). This correction prevents situations where a type is publicly accessible but its required members can't be initialized from all contexts where the type is constructed. - -Use the `required` keyword instead of manually applying `RequiredMemberAttribute` (**CS9033**). This correction ensures the compiler generates the correct metadata and enforces all required member rules, which manual attribute application might not do correctly. - -Ensure required members have set accessors or are otherwise settable (**CS9034**). This correction is necessary because required members must be initialized during object creation, which requires write access. When creating instances, initialize required members directly in object initializers (**CS9035**, **CS9036**). You must assign a value to each required member rather than using nested member initializers or collection initializers, because the required member itself must be set before accessing its properties. - -Apply the `SetsRequiredMembers` attribute to constructors that initialize all required members in their bodies (**CS9038**, **CS9039**). This correction informs the compiler that the constructor fulfills the required member contract, allowing object creation without object initializers. If a constructor chains to another constructor with `SetsRequiredMembers`, it must also have the attribute. - -Avoid using required members in types that must satisfy the `new()` constraint (**CS9040**), as the parameterless constructor can't guarantee required member initialization without an object initializer. Don't mark required members as obsolete unless the containing type or all constructors are obsolete (**CS9042**), to prevent situations where members are required but their use is discouraged. Required members aren't allowed in top-level statements or script contexts (**CS9045**) because these contexts don't support the object initialization syntax needed to set required members. +- Avoid using `required` as a type or alias name (**CS9029**). This correction is necessary because `required` is a contextual keyword in C# 11 and later, and using it as a type name creates ambiguity in code where the keyword might appear. +- Ensure derived members maintain the `required` modifier when overriding required members (**CS9030**). This correction enforces the contract established by the base class, guaranteeing that all derived types maintain the same initialization requirements. Avoid hiding required members with non-required members in derived classes (**CS9031**), as this action breaks the initialization contract that consumers expect from the base type. +- Make required members at least as visible as their containing type, and ensure property setters are also sufficiently visible (**CS9032**). This correction prevents situations where a type is publicly accessible but its required members can't be initialized from all contexts where the type is constructed. +- Use the `required` keyword instead of manually applying (**CS9033**). This correction ensures the compiler generates the correct metadata and enforces all required member rules, which manual attribute application might not do correctly. +- Ensure required members have set accessors or are otherwise settable (**CS9034**). This correction is necessary because required members must be initialized during object creation, which requires write access. When creating instances, initialize required members directly in object initializers (**CS9035**, **CS9036**). You must assign a value to each required member rather than using nested member initializers or collection initializers, because the required member itself must be set before accessing its properties. +- Apply the `SetsRequiredMembers` attribute to constructors that initialize all required members in their bodies (**CS9038**, **CS9039**). This correction informs the compiler that the constructor fulfills the required member contract, allowing object creation without object initializers. If a constructor chains to another constructor with `SetsRequiredMembers`, it must also have the attribute. +- Avoid using required members in types that must satisfy the `new()` constraint (**CS9040**), as the parameterless constructor can't guarantee required member initialization without an object initializer. Don't mark required members as obsolete unless the containing type or all constructors are obsolete (**CS9042**), to prevent situations where members are required but their use is discouraged. Required members aren't allowed in top-level statements or script contexts (**CS9045**) because these contexts don't support the object initialization syntax needed to set required members. For more information, see the [required modifier](../keywords/required.md) reference article and [Object and Collection Initializers](../../programming-guide/classes-and-structs/object-and-collection-initializers.md) guide. @@ -266,8 +346,7 @@ For more information, see the [required modifier](../keywords/required.md) refer To correct ref-returning property errors, apply one of the following changes based on the specific diagnostic: -Implement the property explicitly with a backing field and use the `ref` keyword in the `get` accessor's return expression (**CS8145**). This correction is necessary because auto-implemented properties generate a private backing field that the compiler manages internally. Returning a reference to a private field would expose internal storage that callers shouldn't access directly. To create a ref-returning property, declare an explicit field and return it with `=> ref backingField` syntax. Alternatively, if you don't need to return a reference to allow direct modification of the storage, remove the `ref` modifier from the property declaration. - -Remove the `set` accessor from ref-returning properties (**CS8147**). This correction is required because a ref-returning property already provides both read and write access through the returned reference itself. Callers can directly modify the value through the reference without needing a separate setter method. Including a `set` accessor would create two different mechanisms for modifying the same storage, which is redundant and could lead to confusion about which modification path should be used. +- Implement the property explicitly with a backing field and use the `ref` keyword in the `get` accessor's return expression (**CS8145**). This correction is necessary because auto-implemented properties generate a private backing field that the compiler manages internally. Returning a reference to a private field would expose internal storage that callers shouldn't access directly. To create a ref-returning property, declare an explicit field and return it with `=> ref backingField` syntax. Alternatively, if you don't need to return a reference to allow direct modification of the storage, remove the `ref` modifier from the property declaration. +- Remove the `set` accessor from ref-returning properties (**CS8147**). This correction is required because a ref-returning property already provides both read and write access through the returned reference itself. Callers can directly modify the value through the reference without needing a separate setter method. Including a `set` accessor would create two different mechanisms for modifying the same storage, which is redundant and could lead to confusion about which modification path should be used. For more information, see [ref returns and ref locals](../statements/jump-statements.md#ref-returns) and [Properties](../../programming-guide/classes-and-structs/properties.md). diff --git a/docs/csharp/language-reference/toc.yml b/docs/csharp/language-reference/toc.yml index 95360816b6483..e0408b3069312 100644 --- a/docs/csharp/language-reference/toc.yml +++ b/docs/csharp/language-reference/toc.yml @@ -522,10 +522,12 @@ items: href: ./compiler-messages/property-declaration-errors.md displayName: > property, auto-implemented, init-only, field-backed, - CS0200, CS0545, CS0571, CS0840, CS1014, CS1043, CS8050, CS8051, CS8053, CS8145, - CS8147, CS8341, CS8657, CS8658, CS8659, CS8660, CS8661, CS8664, CS9029, CS9030, - CS9031, CS9032, CS9033, CS9034, CS9035, CS9036, CS9037, CS9038, CS9039, CS9040, - CS9042, CS9045, CS9258, CS9263, CS9264, CS9266, CS9273 + CS0200, CS0273, CS0274, CS0275, CS0276, CS0442, CS0544, CS0545, CS0546, CS0547, + CS0548, CS0571, CS0610, CS0840, CS1014, CS1043, CS1715, CS8050, CS8051, CS8053, + CS8080, CS8145, CS8147, CS8341, CS8657, CS8658, CS8659, CS8660, CS8661, CS8664, + CS8852, CS8853, CS8855, CS8856, CS8903, CS9029, CS9030, CS9031, CS9032, CS9033, + CS9034, CS9035, CS9036, CS9037, CS9038, CS9039, CS9040, CS9042, CS9045, CS9258, + CS9263, CS9264, CS9266, CS9273 - name: Operator declarations href: ./compiler-messages/overloaded-operator-errors.md displayName: > @@ -1000,14 +1002,6 @@ items: href: ../misc/cs0271.md - name: CS0272 href: ../misc/cs0272.md - - name: CS0273 - href: ../misc/cs0273.md - - name: CS0274 - href: ../misc/cs0274.md - - name: CS0275 - href: ../misc/cs0275.md - - name: CS0276 - href: ../misc/cs0276.md - name: CS0281 href: ../misc/cs0281.md - name: CS0283 @@ -1032,8 +1026,6 @@ items: href: ./compiler-messages/cs0433.md - name: CS0441 href: ../misc/cs0441.md - - name: CS0442 - href: ../misc/cs0442.md - name: CS0443 href: ../misc/cs0443.md - name: CS0445 @@ -1102,16 +1094,8 @@ items: href: ./compiler-messages/interface-implementation-errors.md - name: CS0542 href: ../misc/cs0542.md - - name: CS0544 - href: ../misc/cs0544.md - name: CS0545 href: ./compiler-messages/property-declaration-errors.md - - name: CS0546 - href: ../misc/cs0546.md - - name: CS0547 - href: ../misc/cs0547.md - - name: CS0548 - href: ../misc/cs0548.md - name: CS0549 href: ../misc/cs0549.md - name: CS0551 @@ -1146,8 +1130,6 @@ items: href: ../misc/cs0596.md - name: CS0601 href: ../misc/cs0601.md - - name: CS0610 - href: ../misc/cs0610.md - name: CS0619 href: ../misc/cs0619.md - name: CS0620 @@ -1482,8 +1464,6 @@ items: href: ./compiler-messages/cs1705.md - name: CS1713 href: ../misc/cs1713.md - - name: CS1715 - href: ../misc/cs1715.md - name: CS1719 href: ../misc/cs1719.md - name: CS1721 @@ -1640,8 +1620,6 @@ items: href: ./compiler-messages/cs8140.md - name: CS8141 href: ./compiler-messages/cs8141.md - - name: CS8145 - href: ./compiler-messages/property-declaration-errors.md - name: CS8146 href: ./compiler-messages/cs8146.md - name: CS8147 diff --git a/docs/csharp/misc/cs0273.md b/docs/csharp/misc/cs0273.md deleted file mode 100644 index c386adf6f060b..0000000000000 --- a/docs/csharp/misc/cs0273.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: "Compiler error CS0273" -title: "Compiler error CS0273" -ms.date: 02/11/2019 -f1_keywords: - - "CS0273" -helpviewer_keywords: - - "CS0273" -ms.assetid: 851ad056-feee-48fd-834c-578a1a13e926 ---- -# Compiler error CS0273 - -The accessibility modifier of the 'property_accessor' accessor must be more restrictive than the property or indexer 'property' - -The accessibility modifier of the set/get accessor must be more restrictive than the property or indexer 'property/indexer' - -This error occurs when the accessibility of the accessor you declared isn't less restrictive than the accessibility of the property or indexer. - -## To correct this error - -Use the appropriate access modifier on either the property or the accessor. For more information, see [Restricting Accessor Accessibility](../programming-guide/classes-and-structs/restricting-accessor-accessibility.md) and [Accessors](/dotnet/csharp/language-reference/language-specification/classes#accessors). - -## Example - -This sample contains an internal property with an internal set method. The following sample generates CS0273. - -```csharp -// CS0273.cs -// compile with: /target:library -public class MyClass -{ - internal int Property - { - get { return 0; } - internal set {} // CS0273 - // try the following line instead - // private set {} - } -} -``` diff --git a/docs/csharp/misc/cs0274.md b/docs/csharp/misc/cs0274.md deleted file mode 100644 index 678aedb73b751..0000000000000 --- a/docs/csharp/misc/cs0274.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: "Compiler Error CS0274" -title: "Compiler Error CS0274" -ms.date: 07/20/2015 -f1_keywords: - - "CS0274" -helpviewer_keywords: - - "CS0274" -ms.assetid: bbd2d64e-a756-4713-b9ed-711d50b65e00 ---- -# Compiler Error CS0274 - -Cannot specify accessibility modifiers for both accessors of the property or indexer 'property/indexer' - - This error occurs when you declare a property or indexer with access modifiers on both its accessors. To resolve this error, use an access modifier on only one of the two accessors. For more information, see [Accessor Accessibility](../programming-guide/classes-and-structs/restricting-accessor-accessibility.md). - - The following example generates CS0274: - -```csharp -// CS0274.cs -public class MyClass -{ - public int Property // CS0274 - { - public get { return 0; } - protected set { } - } -} -``` diff --git a/docs/csharp/misc/cs0275.md b/docs/csharp/misc/cs0275.md deleted file mode 100644 index ff85e824b38bf..0000000000000 --- a/docs/csharp/misc/cs0275.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -description: "Compiler Error CS0275" -title: "Compiler Error CS0275" -ms.date: 07/20/2015 -f1_keywords: - - "CS0275" -helpviewer_keywords: - - "CS0275" -ms.assetid: 4d59f11c-b0ea-4c91-b2cb-cbe3be9a9ba2 ---- -# Compiler Error CS0275 - -'accessor': accessibility modifiers may not be used on accessors in an interface - - This error occurs when you use an access modifier on any one of the accessors of a property or indexer in an interface. To resolve, remove the access modifier. - -## Example - - The following example generates CS0275: - -```csharp -// CS0275.cs -public interface MyInterface -{ - int Property - { - get; - internal set; // CS0275 - } -} -``` diff --git a/docs/csharp/misc/cs0276.md b/docs/csharp/misc/cs0276.md deleted file mode 100644 index e92af4a8027eb..0000000000000 --- a/docs/csharp/misc/cs0276.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -description: "Compiler Error CS0276" -title: "Compiler Error CS0276" -ms.date: 07/20/2015 -f1_keywords: - - "CS0276" -helpviewer_keywords: - - "CS0276" -ms.assetid: 0c49017f-c7a9-42a5-9d0a-6f1d82142bd7 ---- -# Compiler Error CS0276 - -'property/indexer': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor - - This error occurs when you declare a property or indexer with one accessor only, and use an access modifier on the accessor. To resolve, remove the access modifier or add another accessor. - -## Example - - The following example generates CS0276: - -```csharp -// CS0276.cs -public class MyClass -{ - public int Property - { - protected set { } // CS0276 - } - public int Property2 - { - internal get { } // CS0276 - } -} -``` diff --git a/docs/csharp/misc/cs0442.md b/docs/csharp/misc/cs0442.md deleted file mode 100644 index 866f11fbd0f51..0000000000000 --- a/docs/csharp/misc/cs0442.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -description: "Compiler Error CS0442" -title: "Compiler Error CS0442" -ms.date: 07/20/2015 -f1_keywords: - - "CS0442" -helpviewer_keywords: - - "CS0442" -ms.assetid: a411660d-0db6-4b63-b19e-f4538fc201e5 ---- -# Compiler Error CS0442 - -'Property': abstract properties cannot have private accessors - - This error occurs when you use the access modifier "private" to modify an abstract accessor. To resolve, use a different access modifier, or make the property non-abstract. - -## Example - - The following sample generates CS0442: - -```csharp -// CS0442.cs -public abstract class MyClass -{ - public abstract int AbstractProperty - { - get; - private set; // CS0442 - // Try this instead: - // set; - } -} -``` diff --git a/docs/csharp/misc/cs0544.md b/docs/csharp/misc/cs0544.md deleted file mode 100644 index 72d92d0227e98..0000000000000 --- a/docs/csharp/misc/cs0544.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -description: "Compiler Error CS0544" -title: "Compiler Error CS0544" -ms.date: 07/20/2015 -f1_keywords: - - "CS0544" -helpviewer_keywords: - - "CS0544" -ms.assetid: f8230a02-a666-4a1a-94cb-46f87463206a ---- -# Compiler Error CS0544 - -'property override': cannot override because 'non-property' is not a property - - An attempt was made to override a nonproperty data type as a [property](../programming-guide/classes-and-structs/properties.md), which is not allowed. - - The following sample generates CS0544: - -```csharp -// CS0544.cs -// compile with: /target:library -public class a -{ - public int i; -} - -public class b : a -{ - public override int i { // CS0544 - // try the following line instead - // public new int i { - get - { - return 0; - } - } -} -``` diff --git a/docs/csharp/misc/cs0546.md b/docs/csharp/misc/cs0546.md deleted file mode 100644 index ac30260b1e775..0000000000000 --- a/docs/csharp/misc/cs0546.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -description: "Compiler Error CS0546" -title: "Compiler Error CS0546" -ms.date: 07/20/2015 -f1_keywords: - - "CS0546" -helpviewer_keywords: - - "CS0546" -ms.assetid: d259c86f-ee29-4e2d-b381-6ba7252af87e ---- -# Compiler Error CS0546 - -'accessor' : cannot override because 'property' does not have an overridable set accessor - - An attempt to override one of the accessor methods for a property failed because the accessor cannot be overridden. This error can occur if: - -- the base class property is not declared as [virtual](../language-reference/keywords/virtual.md). - -- the base class property does not declare the [get](../language-reference/keywords/get.md) or [set](../language-reference/keywords/set.md) accessor you are trying to override. - - If you do not want to override the base class property, you can use the [new](../language-reference/keywords/new-modifier.md) keyword before the property in derived class. - - For more information, see [Using Properties](../programming-guide/classes-and-structs/using-properties.md). - -## Example - - The following sample generates CS0546 because the base class does not declare a set accessor for the property. - -```csharp -// CS0546.cs -// compile with: /target:library -public class a -{ - public virtual int i - { - get - { - return 0; - } - } - - public virtual int i2 - { - get - { - return 0; - } - - set {} - } -} - -public class b : a -{ - public override int i - { - set {} // CS0546 error no set - } - - public override int i2 - { - set {} // OK - } -} -``` - -## See also - -- [Properties](../programming-guide/classes-and-structs/properties.md) diff --git a/docs/csharp/misc/cs0547.md b/docs/csharp/misc/cs0547.md deleted file mode 100644 index cb112225dab7c..0000000000000 --- a/docs/csharp/misc/cs0547.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -description: "Compiler Error CS0547" -title: "Compiler Error CS0547" -ms.date: 07/20/2015 -f1_keywords: - - "CS0547" -helpviewer_keywords: - - "CS0547" -ms.assetid: aa80873f-deb0-4ff2-8435-92a626bb5b80 ---- -# Compiler Error CS0547 - -'property' : property or indexer cannot have void type - - [void](../language-reference/builtin-types/void.md) is invalid as a return value for a property. - - For more information, see [Properties](../programming-guide/classes-and-structs/properties.md). - - The following sample generates CS0547: - -```csharp -// CS0547.cs -public class a -{ - public void i // CS0547 - // Try the following declaration instead: - // public int i - { - get - { - return 0; - } - } -} - -public class b : a -{ - public static void Main() - { - } -} -``` diff --git a/docs/csharp/misc/cs0548.md b/docs/csharp/misc/cs0548.md deleted file mode 100644 index cfc2e69627615..0000000000000 --- a/docs/csharp/misc/cs0548.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -description: "Compiler Error CS0548" -title: "Compiler Error CS0548" -ms.date: 07/20/2015 -f1_keywords: - - "CS0548" -helpviewer_keywords: - - "CS0548" -ms.assetid: c4d34da7-0b4a-4312-ac7f-46db100e43c7 ---- -# Compiler Error CS0548 - -'property' : property or indexer must have at least one accessor - - A property must have at least one accessor (get or set) method. - - For more information, see and [Using Properties](../programming-guide/classes-and-structs/using-properties.md). - -## Example - - The following sample generates CS0548. - -```csharp -// CS0548.cs -// compile with: /target:library -public class b -{ - public int MyProp {} // CS0548 - - public int MyProp2 // OK - { - get - { - return 0; - } - set {} - } -} -``` diff --git a/docs/csharp/misc/cs0610.md b/docs/csharp/misc/cs0610.md deleted file mode 100644 index f3b121546fd4d..0000000000000 --- a/docs/csharp/misc/cs0610.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -description: "Compiler Error CS0610" -title: "Compiler Error CS0610" -ms.date: 07/20/2015 -f1_keywords: - - "CS0610" -helpviewer_keywords: - - "CS0610" -ms.assetid: 6cdce74c-5c00-4539-9df1-32be70e9912d ---- -# Compiler Error CS0610 - -Field or property cannot be of type 'type' - - There are some types that cannot be used as fields or properties. These types include **System.ArgIterator** and **System.TypedReference**. - - The following sample generates CS0610 as a result of using **System.TypedReference** as a field: - -```csharp -// CS0610.cs -public class MainClass -{ - System.TypedReference i; // CS0610 - public static void Main () - { - } - - public static void Test(System.TypedReference i) // OK - { - } -} -``` diff --git a/docs/csharp/misc/cs1715.md b/docs/csharp/misc/cs1715.md deleted file mode 100644 index c9e145c0abc1c..0000000000000 --- a/docs/csharp/misc/cs1715.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -description: "Learn more about: Compiler Error CS1715" -title: "Compiler Error CS1715" -ms.date: 07/20/2015 -f1_keywords: - - "CS1715" -helpviewer_keywords: - - "CS1715" -ms.assetid: 740044d1-a61c-4156-bc6a-adf26c7499ec ---- -# Compiler Error CS1715 - -'Type1': type must be 'Type2' to match overridden member 'MemberName' - - This error is the same as [Compiler Error CS0508](./cs0508.md), except that CS0508 now only applies to methods that have return types, while CS1715 applies to properties and indexers that only have 'types' instead of 'return types'. - -## Example - - The following code generates CS1715. - -```csharp -// CS1715.cs -abstract public class Base -{ - abstract public int myProperty - { - get; - set; - } -} - -public class Derived : Base -{ - int myField; - public override double myProperty // CS1715 - // try the following line instead - // public override int myProperty - { - get { return myField; } - set { myField;= value; } - } - - public static void Main() - { - Derived d = new Derived(); - d.myProperty = 5; - } -} -``` diff --git a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md index bd3a161703253..f2e9492617f92 100644 --- a/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md +++ b/docs/csharp/misc/sorry-we-don-t-have-specifics-on-this-csharp-error.md @@ -156,7 +156,6 @@ f1_keywords: - "CS8077" - "CS8078" # build only diagnostic - "CS8079" - - "CS8080" - "CS8081" - "CS8082" - "CS8084" @@ -301,10 +300,6 @@ f1_keywords: - "CS8823" - "CS8830" # feature / version - "CS8831" - - "CS8852" # init only properties - - "CS8853" - - "CS8855" - - "CS8856" - "CS8888" # feature / version - "CS8889" - "CS8890" @@ -313,7 +308,6 @@ f1_keywords: - "CS8894" - "CS8895" - "CS8896" - - "CS8903" # init only property # Coming in C# 15 - "CS9343" # misc - "CS9346" From 32e7426e36b5b8305d03b00cae8fc03da5585585 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 5 May 2026 15:18:39 -0400 Subject: [PATCH 05/39] Async coordination primitives (#53171) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Async coordination primitives Fixes #17714 (final PR) 1. Create `async-coordination-primitives.md` — from "Building Async Coordination Primitives" parts 1-4 (AsyncManualResetEvent, AsyncAutoResetEvent, AsyncCountdownEvent, AsyncBarrier). 1. Create `async-coordination-primitives-advanced.md` — from parts 5-7 (AsyncSemaphore, AsyncLock, AsyncReaderWriterLock). **Note BCL equivalents** (`SemaphoreSlim.WaitAsync`, `System.Threading.Channels`). 1. **Heavy modernization needed:** update all code for current .NET idioms, call out which primitives now have framework equivalents. 1. Add both to TOC under a "Coordination primitives" sub-section. * Edit pass and address feedback. * fix build issues * Final content edits * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * respond to feedback. * Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> * Respond to feedback. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/navigate/advanced-programming/toc.yml | 6 + .../async-coordination-primitives-advanced.md | 97 +++++ .../async-coordination-primitives.md | 104 +++++ ...AsyncCoordinationPrimitivesAdvanced.csproj | 10 + .../csharp/Program.cs | 378 ++++++++++++++++++ ...AsyncCoordinationPrimitivesAdvanced.vbproj | 9 + .../vb/Program.vb | 334 ++++++++++++++++ .../csharp/AsyncCoordinationPrimitives.csproj | 10 + .../csharp/Program.cs | 260 ++++++++++++ .../vb/AsyncCoordinationPrimitives.vbproj | 9 + .../vb/Program.vb | 231 +++++++++++ 11 files changed, 1448 insertions(+) create mode 100644 docs/standard/asynchronous-programming-patterns/async-coordination-primitives-advanced.md create mode 100644 docs/standard/asynchronous-programming-patterns/async-coordination-primitives.md create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/AsyncCoordinationPrimitivesAdvanced.csproj create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/Program.cs create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/AsyncCoordinationPrimitivesAdvanced.vbproj create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/Program.vb create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/AsyncCoordinationPrimitives.csproj create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/Program.cs create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/AsyncCoordinationPrimitives.vbproj create mode 100644 docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/Program.vb diff --git a/docs/navigate/advanced-programming/toc.yml b/docs/navigate/advanced-programming/toc.yml index 93439663390e4..fc1397e62a59b 100644 --- a/docs/navigate/advanced-programming/toc.yml +++ b/docs/navigate/advanced-programming/toc.yml @@ -40,6 +40,12 @@ items: href: ../../standard/asynchronous-programming-patterns/complete-your-tasks.md - name: Keep async methods alive href: ../../standard/asynchronous-programming-patterns/keep-async-methods-alive.md + - name: Coordination primitives + items: + - name: Build async coordination primitives + href: ../../standard/asynchronous-programming-patterns/async-coordination-primitives.md + - name: Async semaphores, locks, and reader/writer coordination + href: ../../standard/asynchronous-programming-patterns/async-coordination-primitives-advanced.md - name: Event-based asynchronous pattern (EAP) items: - name: Documentation overview diff --git a/docs/standard/asynchronous-programming-patterns/async-coordination-primitives-advanced.md b/docs/standard/asynchronous-programming-patterns/async-coordination-primitives-advanced.md new file mode 100644 index 0000000000000..b57ee3ea88b9d --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/async-coordination-primitives-advanced.md @@ -0,0 +1,97 @@ +--- +title: "Async semaphores, locks, and reader/writer coordination" +description: Learn to use SemaphoreSlim.WaitAsync for async throttling, build async locks for mutual exclusion, and coordinate readers and writers in async code. +ms.date: 04/16/2026 +ai-usage: ai-assisted +dev_langs: + - "csharp" + - "vb" +--- + +# Async semaphores, locks, and reader/writer coordination + +When async code needs throttling, mutual exclusion, or reader/writer coordination, use the built-in .NET types rather than building your own. This article shows how to apply those types, and then walks through custom implementations to explain how they work internally. + +## Async semaphore — throttle concurrent access + +A semaphore limits how many callers can access a resource concurrently. provides a method that lets you await entry without blocking a thread: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="SemaphoreSlimUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="SemaphoreSlimUsage"::: + +Always pair `WaitAsync` with `Release` in a `try`/`finally` block. If you forget to release, the semaphore count never increases, and other callers wait indefinitely. + +### How an async semaphore works + +Internally, an async semaphore maintains a count and a queue of waiters. When the count is above zero, `WaitAsync` decrements the count and returns immediately. When the count is zero, `WaitAsync` enqueues a and returns its task. `Release` either dequeues a waiter and completes it, or increments the count: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="AsyncSemaphore"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="AsyncSemaphore"::: + +The `Release` method completes the `TaskCompletionSource` outside the lock, just like the `AsyncAutoResetEvent` in [Build async coordination primitives](async-coordination-primitives.md). This approach prevents synchronous continuations from running while the lock is held. + +> [!NOTE] +> `AsyncSemaphore` is an educational implementation. Use instead—it supports cancellation tokens, timeouts, and has been thoroughly tested. + +## Async lock: mutual exclusion across awaits + +A lock with a count of 1 provides mutual exclusion. The C# `lock` statement and (.NET 9+) don't work across `await` boundaries because they're thread-affine. A *thread-affine* lock the same thread that acquires the lock must be the one that releases it. Across an `await`, the thread that resumes the continuation might not be the thread that acquired the lock, which violates that requirement. Use with a count of 1 instead: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="SemaphoreSlimAsLock"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="SemaphoreSlimAsLock"::: + +### How an async lock works + +You can wrap the semaphore pattern in a type that supports `using` for automatic release. The `LockAsync` method returns a disposable `Releaser`; when the `Releaser` is disposed, it releases the semaphore: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="AsyncLock"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="AsyncLock"::: + +Usage is concise and safe: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="AsyncLockUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="AsyncLockUsage"::: + +> [!NOTE] +> `AsyncLock` is an educational implementation. Use initialized to `1` with `try`/`finally` directly—the `AsyncLock` type shown here illustrates the disposable-releaser pattern but adds no capabilities beyond what `SemaphoreSlim` provides. + +## Async reader/writer coordination + +A reader/writer lock allows multiple concurrent readers but only one exclusive writer. .NET provides , which offers reader/writer scheduling for tasks through two instances: + +- — runs tasks concurrently (like readers), as long as no exclusive task is active. +- — runs tasks exclusively (like writers), with no other tasks running. + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="ConcurrentExclusiveUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="ConcurrentExclusiveUsage"::: + +> [!IMPORTANT] +> `ConcurrentExclusiveSchedulerPair` protects at the task level, not across `await` boundaries. If a task queued to the `ExclusiveScheduler` contains an `await` on an incomplete operation, the exclusive lock releases when the `await` yields and reacquires when the continuation runs. Another exclusive or concurrent task can run during that gap. This behavior works well when you protect in-memory data structures and ensure no `await` interrupts the critical section. For scenarios that require holding the lock across awaits, use a custom `AsyncReaderWriterLock` like the one shown in the following section. + +### Custom async reader/writer lock + +The following implementation gives writers priority over readers. When a writer is waiting, new readers queue behind it. When a writer finishes and no other writers are waiting, all queued readers run together: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="AsyncReaderWriterLock"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="AsyncReaderWriterLock"::: + +Usage follows the same disposable-releaser pattern as `AsyncLock`: + +:::code language="csharp" source="./snippets/async-coordination-primitives-advanced/csharp/Program.cs" id="AsyncReaderWriterLockUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives-advanced/vb/Program.vb" id="AsyncReaderWriterLockUsage"::: + +> [!TIP] +> A production reader/writer lock requires thorough testing for edge cases: reentrancy, error paths, cancellation, and fairness policies. Consider established libraries (such as [Nito.AsyncEx](https://github.com/StephenCleary/AsyncEx)) before building your own. + +## Channels as an alternative coordination pattern + + provides a thread-safe producer-consumer queue that supports `async` reads and writes. Bounded channels () provide natural back-pressure, replacing some scenarios where you'd otherwise use a semaphore for throttling. + +For more information, see [System.Threading.Channels](/dotnet/core/extensions/channels). + +## See also + +- [Build async coordination primitives](async-coordination-primitives.md) +- [Keep async methods alive](keep-async-methods-alive.md) +- [Complete your tasks](complete-your-tasks.md) +- [Consuming the Task-based Asynchronous Pattern](consuming-the-task-based-asynchronous-pattern.md) diff --git a/docs/standard/asynchronous-programming-patterns/async-coordination-primitives.md b/docs/standard/asynchronous-programming-patterns/async-coordination-primitives.md new file mode 100644 index 0000000000000..1e08c80d4f33a --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/async-coordination-primitives.md @@ -0,0 +1,104 @@ +--- +title: "Build async coordination primitives" +description: Learn how to build async coordination primitives using TaskCompletionSource, including manual-reset events, auto-reset events, countdown events, and barriers. +ms.date: 04/16/2026 +ai-usage: ai-assisted +dev_langs: + - "csharp" + - "vb" +helpviewer_keywords: + - "async coordination" + - "TaskCompletionSource" + - "AsyncManualResetEvent" + - "AsyncAutoResetEvent" + - "AsyncCountdownEvent" + - "AsyncBarrier" + - "coordination primitives" +--- + +# Build async coordination primitives + +Synchronous coordination primitives like , , and block the calling thread while waiting. In async code, blocking a thread wastes a resource that could be doing other work. Use to build async equivalents that let callers `await` instead of blocking. + +A `TaskCompletionSource` produces a that you complete manually by calling , , or . Code that awaits that task suspends without blocking a thread and resumes when you complete the source. This pattern forms the building block for every primitive in this article. + +> [!NOTE] +> The primitives in this article are educational implementations. For production throttling and mutual exclusion, use the built-in types covered in [Async semaphores, locks, and reader/writer coordination](async-coordination-primitives-advanced.md). Always complete every `TaskCompletionSource` you create; see [Complete your tasks](complete-your-tasks.md) for guidance. + +## Async manual-reset event + +A manual-reset event starts in a non-signaled state. Callers wait for the event, and all waiters resume when another party signals (sets) the event. The event stays signaled until you explicitly reset it. The synchronous equivalent is . The .NET runtime provides directly for one-shot broadcast signaling. Create a new instance each cycle rather than building a reset wrapper around it. + +`TaskCompletionSource` is itself a one-shot manual-reset event: its `Task` is incomplete until you call a `Set*` method, and then all awaiters resume. Add a `Reset` method that swaps in a new `TaskCompletionSource`, and you have a reusable async manual-reset event. + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncManualResetEvent"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncManualResetEvent"::: + +Key implementation details: + +- The constructor passes to prevent `Set` from running waiter continuations synchronously on the calling thread. Without this flag, `Set` could block for an unpredictable amount of time. +- `Reset` uses to swap in a new `TaskCompletionSource` only when the current one is already completed. This atomic swap prevents orphaning a task that a waiter already received. + +The following example shows how two tasks coordinate through the event: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncManualResetEventUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncManualResetEventUsage"::: + +## Async auto-reset event + +An auto-reset event is similar to a manual-reset event, but it automatically returns to the non-signaled state after releasing exactly one waiter. If multiple callers are waiting when the event is signaled, only one waiter resumes. The synchronous equivalent is . The .NET runtime includes for single-waiter async signaling. Initialize it to `0` with a maximum count of `1` and call `WaitAsync` to wait and `Release` to signal. + +Because each signal releases only one waiter, you need a collection of `TaskCompletionSource` instances—one per waiter—so you can complete them individually: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncAutoResetEvent"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncAutoResetEvent"::: + +Key implementation details: + +- The `Set` method completes the `TaskCompletionSource` (TCS) *outside* the lock. Completing a TCS inside the lock runs synchronous continuations while the lock is held, which could cause deadlocks or unexpected reentrancy. +- When `Set` is called and no waiter is queued, the signal is stored so the next `WaitAsync` call completes immediately. + +The following example shows a producer signaling a consumer through the event: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncAutoResetEventUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncAutoResetEventUsage"::: + +## Async countdown event + +A countdown event waits for a specified number of signals before it allows waiters to proceed. This pattern is useful for fork/join scenarios where you start N operations and want to await all N completions. The synchronous equivalent is . The .NET runtime provides for fork/join coordination with a fixed set of tasks. Use it instead. + +Build the async version by composing the `AsyncManualResetEvent` from the previous section with an atomic counter: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncCountdownEvent"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncCountdownEvent"::: + +The `Signal` method decrements the count atomically with . When the count reaches zero, it sets the inner event, and all waiters resume. + +The following example uses a countdown event to await three concurrent operations: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncCountdownEventUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncCountdownEventUsage"::: + +## Async barrier + +A barrier coordinates a fixed set of participants across multiple rounds. Each participant signals when it finishes its work for the current round and then waits for all other participants to finish. When the last participant signals, all participants resume, and the barrier resets for the next round. The synchronous equivalent is . The .NET runtime provides for multi-round async synchronization. Combine it with a loop, one `WhenAll` call per round. + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncBarrier"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncBarrier"::: + +Key implementation details: + +- Before completing the shared `TaskCompletionSource`, the method resets the count and swaps in a new `TaskCompletionSource` for the next round. This ordering ensures that when waiters resume, the barrier is already ready for the next round. +- All participants share the same `Task`. Because the sample creates the `TaskCompletionSource` with `RunContinuationsAsynchronously`, continuations resume asynchronously instead of running inline on the thread that completes the barrier. + +The following example runs three participants through two rounds of a barrier: + +:::code language="csharp" source="./snippets/async-coordination-primitives/csharp/Program.cs" id="AsyncBarrierUsage"::: +:::code language="vb" source="./snippets/async-coordination-primitives/vb/Program.vb" id="AsyncBarrierUsage"::: + +## See also + +- [Async semaphores, locks, and reader/writer coordination](async-coordination-primitives-advanced.md) +- [Task-based asynchronous pattern (TAP)](task-based-asynchronous-pattern-tap.md) +- [Complete your tasks](complete-your-tasks.md) +- [Keep async methods alive](keep-async-methods-alive.md) diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/AsyncCoordinationPrimitivesAdvanced.csproj b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/AsyncCoordinationPrimitivesAdvanced.csproj new file mode 100644 index 0000000000000..dfb40caafcf9a --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/AsyncCoordinationPrimitivesAdvanced.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/Program.cs b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/Program.cs new file mode 100644 index 0000000000000..e47b477c2a01e --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/csharp/Program.cs @@ -0,0 +1,378 @@ +using System.Collections.Concurrent; + +// +public static class SemaphoreSlimDemo +{ + public static async Task RunAsync() + { + using var semaphore = new SemaphoreSlim(3); + + Task[] tasks = Enumerable.Range(1, 6).Select(id => Task.Run(async () => + { + await semaphore.WaitAsync(); + try + { + Console.WriteLine($"Task {id}: entered (count = {semaphore.CurrentCount})"); + await Task.Delay(100); + } + finally + { + semaphore.Release(); + Console.WriteLine($"Task {id}: released"); + } + })).ToArray(); + + await Task.WhenAll(tasks); + } +} +// + +// +// Educational only — use SemaphoreSlim instead of this sample implementation. +public class AsyncSemaphore +{ + private readonly Queue _waiters = new(); + private int _currentCount; + + public AsyncSemaphore(int initialCount) + { + ArgumentOutOfRangeException.ThrowIfNegative(initialCount, nameof(initialCount)); + _currentCount = initialCount; + } + + public Task WaitAsync() + { + lock (_waiters) + { + if (_currentCount > 0) + { + _currentCount--; + return Task.CompletedTask; + } + else + { + var waiter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + _waiters.Enqueue(waiter); + return waiter.Task; + } + } + } + + public void Release() + { + TaskCompletionSource? toRelease = null; + + lock (_waiters) + { + if (_waiters.Count > 0) + toRelease = _waiters.Dequeue(); + else + _currentCount++; + } + + toRelease?.TrySetResult(); + } +} +// + +// +public static class SemaphoreSlimAsLockDemo +{ + private static readonly SemaphoreSlim s_lock = new(1, 1); + private static int s_sharedCounter; + + public static async Task RunAsync() + { + Task[] tasks = Enumerable.Range(1, 5).Select(_ => Task.Run(async () => + { + await s_lock.WaitAsync(); + try + { + int before = s_sharedCounter; + await Task.Delay(10); + s_sharedCounter = before + 1; + } + finally + { + s_lock.Release(); + } + })).ToArray(); + + await Task.WhenAll(tasks); + Console.WriteLine($"Counter = {s_sharedCounter} (expected 5)"); + } +} +// + +// +// Educational only — use SemaphoreSlim(1, 1) with try/finally instead of this sample implementation. +public class AsyncLock : IDisposable +{ + private readonly SemaphoreSlim _semaphore = new(1, 1); + private readonly Task _releaser; + + public AsyncLock() + { + _releaser = Task.FromResult(new Releaser(this)); + } + + public Task LockAsync() + { + Task wait = _semaphore.WaitAsync(); + return wait.IsCompleted + ? _releaser + : wait.ContinueWith( + (_, state) => new Releaser((AsyncLock)state!), + this, + CancellationToken.None, + TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default); + } + + public struct Releaser : IDisposable + { + private readonly AsyncLock? _toRelease; + + internal Releaser(AsyncLock toRelease) => _toRelease = toRelease; + + public void Dispose() => _toRelease?._semaphore.Release(); + } + + public void Dispose() => _semaphore.Dispose(); +} +// + +// +public static class AsyncLockDemo +{ + private static readonly AsyncLock s_lock = new(); + private static int s_sharedValue; + + public static async Task RunAsync() + { + Task[] tasks = Enumerable.Range(1, 5).Select(id => Task.Run(async () => + { + using (await s_lock.LockAsync()) + { + int before = s_sharedValue; + await Task.Delay(10); + s_sharedValue = before + 1; + Console.WriteLine($"Task {id}: incremented to {s_sharedValue}"); + } + })).ToArray(); + + await Task.WhenAll(tasks); + Console.WriteLine($"Final value = {s_sharedValue} (expected 5)"); + } +} +// + +// +public static class ConcurrentExclusiveDemo +{ + public static async Task RunAsync() + { + var pair = new ConcurrentExclusiveSchedulerPair(); + var factory = new TaskFactory(pair.ExclusiveScheduler); + + int sharedValue = 0; + + Task writerTask = factory.StartNew(() => + { + sharedValue = 42; + Console.WriteLine($"Writer: set value to {sharedValue}"); + }); + + var readerFactory = new TaskFactory(pair.ConcurrentScheduler); + + Task[] readerTasks = Enumerable.Range(1, 3).Select(id => + readerFactory.StartNew(() => + { + Console.WriteLine($"Reader {id}: value = {sharedValue}"); + })).ToArray(); + + await writerTask; + await Task.WhenAll(readerTasks); + } +} +// + +// +public class AsyncReaderWriterLock +{ + private readonly Queue> _waitingWriters = new(); + private TaskCompletionSource _waitingReader = + new(TaskCreationOptions.RunContinuationsAsynchronously); + private int _readersWaiting; + private int _status; // 0 = free, -1 = writer active, >0 = reader count + + private readonly Task _readerReleaser; + private readonly Task _writerReleaser; + + public AsyncReaderWriterLock() + { + _readerReleaser = Task.FromResult(new Releaser(this, isWriter: false)); + _writerReleaser = Task.FromResult(new Releaser(this, isWriter: true)); + } + + public Task ReaderLockAsync() + { + lock (_waitingWriters) + { + if (_status >= 0 && _waitingWriters.Count == 0) + { + _status++; + return _readerReleaser; + } + else + { + _readersWaiting++; + return _waitingReader.Task; + } + } + } + + public Task WriterLockAsync() + { + lock (_waitingWriters) + { + if (_status == 0) + { + _status = -1; + return _writerReleaser; + } + else + { + var waiter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + _waitingWriters.Enqueue(waiter); + return waiter.Task; + } + } + } + + private void ReaderRelease() + { + TaskCompletionSource? toWake = null; + + lock (_waitingWriters) + { + _status--; + if (_status == 0 && _waitingWriters.Count > 0) + { + _status = -1; + toWake = _waitingWriters.Dequeue(); + } + } + + toWake?.SetResult(new Releaser(this, isWriter: true)); + } + + private void WriterRelease() + { + TaskCompletionSource? toWake = null; + bool toWakeIsWriter = false; + + lock (_waitingWriters) + { + if (_waitingWriters.Count > 0) + { + toWake = _waitingWriters.Dequeue(); + toWakeIsWriter = true; + } + else if (_readersWaiting > 0) + { + toWake = _waitingReader; + _status = _readersWaiting; + _readersWaiting = 0; + _waitingReader = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + } + else + { + _status = 0; + } + } + + toWake?.SetResult(new Releaser(this, toWakeIsWriter)); + } + + public struct Releaser : IDisposable + { + private readonly AsyncReaderWriterLock? _lock; + private readonly bool _isWriter; + + internal Releaser(AsyncReaderWriterLock lockObj, bool isWriter) + { + _lock = lockObj; + _isWriter = isWriter; + } + + public void Dispose() + { + if (_lock is not null) + { + if (_isWriter) _lock.WriterRelease(); + else _lock.ReaderRelease(); + } + } + } +} +// + +// +public static class AsyncReaderWriterLockDemo +{ + private static readonly AsyncReaderWriterLock s_rwLock = new(); + private static string s_data = "initial"; + + public static async Task RunAsync() + { + Task writer = Task.Run(async () => + { + using (await s_rwLock.WriterLockAsync()) + { + Console.WriteLine("Writer: acquired exclusive lock"); + await Task.Delay(50); + s_data = "updated"; + Console.WriteLine("Writer: data updated"); + } + }); + + Task[] readers = Enumerable.Range(1, 3).Select(id => Task.Run(async () => + { + await Task.Delay(10); + using (await s_rwLock.ReaderLockAsync()) + { + Console.WriteLine($"Reader {id}: data = {s_data}"); + } + })).ToArray(); + + await writer; + await Task.WhenAll(readers); + } +} +// + +public static class Program +{ + public static async Task Main() + { + Console.WriteLine("--- SemaphoreSlim ---"); + await SemaphoreSlimDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- SemaphoreSlim as lock ---"); + await SemaphoreSlimAsLockDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- AsyncLock ---"); + await AsyncLockDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- ConcurrentExclusiveSchedulerPair ---"); + await ConcurrentExclusiveDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- AsyncReaderWriterLock ---"); + await AsyncReaderWriterLockDemo.RunAsync(); + } +} diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/AsyncCoordinationPrimitivesAdvanced.vbproj b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/AsyncCoordinationPrimitivesAdvanced.vbproj new file mode 100644 index 0000000000000..219b1b9e39ace --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/AsyncCoordinationPrimitivesAdvanced.vbproj @@ -0,0 +1,9 @@ + + + + Exe + AsyncCoordinationPrimitivesAdvanced + net10.0 + + + diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/Program.vb b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/Program.vb new file mode 100644 index 0000000000000..1b992c570203c --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives-advanced/vb/Program.vb @@ -0,0 +1,334 @@ +Imports System.Collections.Concurrent +Imports System.Threading + +' +Public Module SemaphoreSlimDemo + Public Async Function RunAsync() As Task + Using semaphore As New SemaphoreSlim(3) + Dim tasks As Task() = Enumerable.Range(1, 6).Select( + Function(id) Task.Run(Async Function() + Await semaphore.WaitAsync() + Try + Console.WriteLine($"Task {id}: entered (count = {semaphore.CurrentCount})") + Await Task.Delay(100) + Finally + semaphore.Release() + Console.WriteLine($"Task {id}: released") + End Try + End Function)).ToArray() + + Await Task.WhenAll(tasks) + End Using + End Function +End Module +' + +' +' Educational only — use SemaphoreSlim instead of this sample implementation. +Public Class AsyncSemaphore + Private ReadOnly _waiters As New Queue(Of TaskCompletionSource)() + Private _currentCount As Integer + + Public Sub New(initialCount As Integer) + If initialCount < 0 Then Throw New ArgumentOutOfRangeException(NameOf(initialCount)) + _currentCount = initialCount + End Sub + + Public Function WaitAsync() As Task + SyncLock _waiters + If _currentCount > 0 Then + _currentCount -= 1 + Return Task.CompletedTask + Else + Dim waiter As New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously) + _waiters.Enqueue(waiter) + Return waiter.Task + End If + End SyncLock + End Function + + Public Sub Release() + Dim toRelease As TaskCompletionSource = Nothing + + SyncLock _waiters + If _waiters.Count > 0 Then + toRelease = _waiters.Dequeue() + Else + _currentCount += 1 + End If + End SyncLock + + toRelease?.TrySetResult() + End Sub +End Class +' + +' +Public Module SemaphoreSlimAsLockDemo + Private ReadOnly s_lock As New SemaphoreSlim(1, 1) + Private s_sharedCounter As Integer + + Public Async Function RunAsync() As Task + Dim tasks As Task() = Enumerable.Range(1, 5).Select( + Function(unused) Task.Run(Async Function() + Await s_lock.WaitAsync() + Try + Dim before As Integer = s_sharedCounter + Await Task.Delay(10) + s_sharedCounter = before + 1 + Finally + s_lock.Release() + End Try + End Function)).ToArray() + + Await Task.WhenAll(tasks) + Console.WriteLine($"Counter = {s_sharedCounter} (expected 5)") + End Function +End Module +' + +' +' Educational only — use SemaphoreSlim(1, 1) with Try/Finally instead of this sample implementation. +Public Class AsyncLock + Implements IDisposable + + Private ReadOnly _semaphore As New SemaphoreSlim(1, 1) + Private ReadOnly _releaser As Task(Of Releaser) + + Public Sub New() + _releaser = Task.FromResult(New Releaser(Me)) + End Sub + + Public Function LockAsync() As Task(Of Releaser) + Dim wait As Task = _semaphore.WaitAsync() + If wait.IsCompleted Then + Return _releaser + Else + Return wait.ContinueWith( + Function(unused, state) New Releaser(DirectCast(state, AsyncLock)), + Me, + CancellationToken.None, + TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default) + End If + End Function + + Public Structure Releaser + Implements IDisposable + + Private ReadOnly _toRelease As AsyncLock + + Friend Sub New(toRelease As AsyncLock) + _toRelease = toRelease + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + _toRelease?._semaphore.Release() + End Sub + End Structure + + Public Sub Dispose() Implements IDisposable.Dispose + _semaphore.Dispose() + End Sub +End Class +' + +' +Public Module AsyncLockDemo + Private ReadOnly s_lock As New AsyncLock() + Private s_sharedValue As Integer + + Public Async Function RunAsync() As Task + Dim tasks As Task() = Enumerable.Range(1, 5).Select( + Function(id) Task.Run(Async Function() + Using Await s_lock.LockAsync() + Dim before As Integer = s_sharedValue + Await Task.Delay(10) + s_sharedValue = before + 1 + Console.WriteLine($"Task {id}: incremented to {s_sharedValue}") + End Using + End Function)).ToArray() + + Await Task.WhenAll(tasks) + Console.WriteLine($"Final value = {s_sharedValue} (expected 5)") + End Function +End Module +' + +' +Public Module ConcurrentExclusiveDemo + Public Async Function RunAsync() As Task + Dim pair As New ConcurrentExclusiveSchedulerPair() + Dim exclusiveFactory As New TaskFactory(pair.ExclusiveScheduler) + + Dim sharedValue As Integer = 0 + + Dim writerTask As Task = exclusiveFactory.StartNew(Sub() + sharedValue = 42 + Console.WriteLine($"Writer: set value to {sharedValue}") + End Sub) + + Dim readerFactory As New TaskFactory(pair.ConcurrentScheduler) + + Dim readerTasks As Task() = Enumerable.Range(1, 3).Select( + Function(id) readerFactory.StartNew(Sub() + Console.WriteLine($"Reader {id}: value = {sharedValue}") + End Sub)).ToArray() + + Await writerTask + Await Task.WhenAll(readerTasks) + End Function +End Module +' + +' +Public Class AsyncReaderWriterLock + Private ReadOnly _waitingWriters As New Queue(Of TaskCompletionSource(Of Releaser))() + Private _waitingReader As New TaskCompletionSource(Of Releaser)(TaskCreationOptions.RunContinuationsAsynchronously) + Private _readersWaiting As Integer + Private _status As Integer ' 0 = free, -1 = writer active, >0 = reader count + + Private ReadOnly _readerReleaser As Task(Of Releaser) + Private ReadOnly _writerReleaser As Task(Of Releaser) + + Public Sub New() + _readerReleaser = Task.FromResult(New Releaser(Me, isWriter:=False)) + _writerReleaser = Task.FromResult(New Releaser(Me, isWriter:=True)) + End Sub + + Public Function ReaderLockAsync() As Task(Of Releaser) + SyncLock _waitingWriters + If _status >= 0 AndAlso _waitingWriters.Count = 0 Then + _status += 1 + Return _readerReleaser + Else + _readersWaiting += 1 + Return _waitingReader.Task + End If + End SyncLock + End Function + + Public Function WriterLockAsync() As Task(Of Releaser) + SyncLock _waitingWriters + If _status = 0 Then + _status = -1 + Return _writerReleaser + Else + Dim waiter As New TaskCompletionSource(Of Releaser)( + System.Threading.Tasks.TaskCreationOptions.RunContinuationsAsynchronously) + _waitingWriters.Enqueue(waiter) + Return waiter.Task + End If + End SyncLock + End Function + + Private Sub ReaderRelease() + Dim toWake As TaskCompletionSource(Of Releaser) = Nothing + + SyncLock _waitingWriters + _status -= 1 + If _status = 0 AndAlso _waitingWriters.Count > 0 Then + _status = -1 + toWake = _waitingWriters.Dequeue() + End If + End SyncLock + + toWake?.SetResult(New Releaser(Me, isWriter:=True)) + End Sub + + Private Sub WriterRelease() + Dim toWake As TaskCompletionSource(Of Releaser) = Nothing + Dim toWakeIsWriter As Boolean = False + + SyncLock _waitingWriters + If _waitingWriters.Count > 0 Then + toWake = _waitingWriters.Dequeue() + toWakeIsWriter = True + ElseIf _readersWaiting > 0 Then + toWake = _waitingReader + _status = _readersWaiting + _readersWaiting = 0 + _waitingReader = New TaskCompletionSource(Of Releaser)(TaskCreationOptions.RunContinuationsAsynchronously) + Else + _status = 0 + End If + End SyncLock + + toWake?.SetResult(New Releaser(Me, toWakeIsWriter)) + End Sub + + Public Structure Releaser + Implements IDisposable + + Private ReadOnly _lock As AsyncReaderWriterLock + Private ReadOnly _isWriter As Boolean + + Friend Sub New(lockObj As AsyncReaderWriterLock, isWriter As Boolean) + _lock = lockObj + _isWriter = isWriter + End Sub + + Public Sub Dispose() Implements IDisposable.Dispose + If _lock IsNot Nothing Then + If _isWriter Then + _lock.WriterRelease() + Else + _lock.ReaderRelease() + End If + End If + End Sub + End Structure +End Class +' + +' +Public Module AsyncReaderWriterLockDemo + Private ReadOnly s_rwLock As New AsyncReaderWriterLock() + Private s_data As String = "initial" + + Public Async Function RunAsync() As Task + Dim writer As Task = Task.Run(Async Function() + Using Await s_rwLock.WriterLockAsync() + Console.WriteLine("Writer: acquired exclusive lock") + Await Task.Delay(50) + s_data = "updated" + Console.WriteLine("Writer: data updated") + End Using + End Function) + + Dim readers As Task() = Enumerable.Range(1, 3).Select( + Function(id) Task.Run(Async Function() + Await Task.Delay(10) + Using Await s_rwLock.ReaderLockAsync() + Console.WriteLine($"Reader {id}: data = {s_data}") + End Using + End Function)).ToArray() + + Await writer + Await Task.WhenAll(readers) + End Function +End Module +' + +Module Program + Sub Main() + Console.WriteLine("--- SemaphoreSlim ---") + SemaphoreSlimDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- SemaphoreSlim as lock ---") + SemaphoreSlimAsLockDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- AsyncLock ---") + AsyncLockDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- ConcurrentExclusiveSchedulerPair ---") + ConcurrentExclusiveDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- AsyncReaderWriterLock ---") + AsyncReaderWriterLockDemo.RunAsync().Wait() + End Sub +End Module diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/AsyncCoordinationPrimitives.csproj b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/AsyncCoordinationPrimitives.csproj new file mode 100644 index 0000000000000..dfb40caafcf9a --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/AsyncCoordinationPrimitives.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/Program.cs b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/Program.cs new file mode 100644 index 0000000000000..d1991b8f719a6 --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/csharp/Program.cs @@ -0,0 +1,260 @@ +// +// Educational only — use TaskCompletionSource directly instead of this sample implementation; create a new instance each cycle. +public class AsyncManualResetEvent +{ + private volatile TaskCompletionSource _tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); + + public Task WaitAsync() => _tcs.Task; + + public void Set() => _tcs.TrySetResult(); + + public void Reset() + { + while (true) + { + TaskCompletionSource tcs = _tcs; + if (!tcs.Task.IsCompleted || + Interlocked.CompareExchange( + ref _tcs, + new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously), + tcs) == tcs) + { + return; + } + } + } +} +// + +// +public static class AsyncManualResetEventDemo +{ + public static async Task RunAsync() + { + var gate = new AsyncManualResetEvent(); + + Task waiter = Task.Run(async () => + { + Console.WriteLine("Waiter: waiting for signal..."); + await gate.WaitAsync(); + Console.WriteLine("Waiter: signal received!"); + }); + + await Task.Delay(100); + Console.WriteLine("Signaler: setting the event."); + gate.Set(); + + await waiter; + } +} +// + +// +// Educational only — use SemaphoreSlim(0, 1) instead of this sample implementation: call WaitAsync() to wait and Release() to signal. +public class AsyncAutoResetEvent +{ + private readonly Queue _waiters = new(); + private bool _signaled; + + public Task WaitAsync() + { + lock (_waiters) + { + if (_signaled) + { + _signaled = false; + return Task.CompletedTask; + } + else + { + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + _waiters.Enqueue(tcs); + return tcs.Task; + } + } + } + + public void Set() + { + TaskCompletionSource? toRelease = null; + + lock (_waiters) + { + if (_waiters.Count > 0) + { + toRelease = _waiters.Dequeue(); + } + else if (!_signaled) + { + _signaled = true; + } + } + + toRelease?.TrySetResult(); + } +} +// + +// +public static class AsyncAutoResetEventDemo +{ + public static async Task RunAsync() + { + var autoEvent = new AsyncAutoResetEvent(); + + Task consumer = Task.Run(async () => + { + for (int i = 0; i < 3; i++) + { + await autoEvent.WaitAsync(); + Console.WriteLine($"Consumer: received signal {i + 1}"); + } + }); + + for (int i = 0; i < 3; i++) + { + await Task.Delay(50); + Console.WriteLine($"Producer: sending signal {i + 1}"); + autoEvent.Set(); + } + + await consumer; + } +} +// + +// +// Educational only — use Task.WhenAll() instead of this sample implementation to coordinate a fixed set of tasks. +public class AsyncCountdownEvent +{ + private readonly AsyncManualResetEvent _event = new(); + private int _count; + + public AsyncCountdownEvent(int initialCount) + { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(initialCount, nameof(initialCount)); + _count = initialCount; + } + + public Task WaitAsync() => _event.WaitAsync(); + + public void Signal() + { + if (_count <= 0) + throw new InvalidOperationException("The event is already signaled."); + + int newCount = Interlocked.Decrement(ref _count); + + if (newCount == 0) + _event.Set(); + else if (newCount < 0) + throw new InvalidOperationException("Too many signals."); + } + + public Task SignalAndWait() + { + Signal(); + return WaitAsync(); + } +} +// + +// +public static class AsyncCountdownEventDemo +{ + public static async Task RunAsync() + { + var countdown = new AsyncCountdownEvent(3); + + for (int i = 1; i <= 3; i++) + { + int id = i; + _ = Task.Run(async () => + { + await Task.Delay(id * 30); + Console.WriteLine($"Worker {id}: done."); + countdown.Signal(); + }); + } + + await countdown.WaitAsync(); + Console.WriteLine("All workers finished."); + } +} +// + +// +// Educational only — use Task.WhenAll() in a loop instead of this sample implementation, one call per round. +public class AsyncBarrier +{ + private readonly int _participantCount; + private int _remainingParticipants; + private TaskCompletionSource _tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); + + public AsyncBarrier(int participantCount) + { + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(participantCount, nameof(participantCount)); + _remainingParticipants = _participantCount = participantCount; + } + + public Task SignalAndWait() + { + TaskCompletionSource tcs = _tcs; + + if (Interlocked.Decrement(ref _remainingParticipants) == 0) + { + _remainingParticipants = _participantCount; + _tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + tcs.SetResult(); + } + + return tcs.Task; + } +} +// + +// +public static class AsyncBarrierDemo +{ + public static async Task RunAsync() + { + var barrier = new AsyncBarrier(3); + int rounds = 2; + + Task[] participants = Enumerable.Range(1, 3).Select(id => Task.Run(async () => + { + for (int round = 1; round <= rounds; round++) + { + Console.WriteLine($"Participant {id}: working on round {round}"); + await Task.Delay(id * 20); + Console.WriteLine($"Participant {id}: finished round {round}, waiting at barrier"); + await barrier.SignalAndWait(); + } + })).ToArray(); + + await Task.WhenAll(participants); + Console.WriteLine("All rounds complete."); + } +} +// + +public static class Program +{ + public static async Task Main() + { + Console.WriteLine("--- AsyncManualResetEvent ---"); + await AsyncManualResetEventDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- AsyncAutoResetEvent ---"); + await AsyncAutoResetEventDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- AsyncCountdownEvent ---"); + await AsyncCountdownEventDemo.RunAsync(); + + Console.WriteLine(); + Console.WriteLine("--- AsyncBarrier ---"); + await AsyncBarrierDemo.RunAsync(); + } +} diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/AsyncCoordinationPrimitives.vbproj b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/AsyncCoordinationPrimitives.vbproj new file mode 100644 index 0000000000000..d91391285e5e7 --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/AsyncCoordinationPrimitives.vbproj @@ -0,0 +1,9 @@ + + + + Exe + AsyncCoordinationPrimitives + net10.0 + + + diff --git a/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/Program.vb b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/Program.vb new file mode 100644 index 0000000000000..d4c61713f4e68 --- /dev/null +++ b/docs/standard/asynchronous-programming-patterns/snippets/async-coordination-primitives/vb/Program.vb @@ -0,0 +1,231 @@ +Imports System.Threading + +' +' Educational only — use TaskCompletionSource(Of T) directly instead of this sample implementation; create a new instance each cycle. +Public Class AsyncManualResetEvent + Private _tcs As TaskCompletionSource = New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously) + + Public Function WaitAsync() As Task + Return _tcs.Task + End Function + + Public Sub [Set]() + _tcs.TrySetResult() + End Sub + + Public Sub Reset() + Do + Dim tcs As TaskCompletionSource = _tcs + If Not tcs.Task.IsCompleted OrElse + Interlocked.CompareExchange( + _tcs, + New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously), + tcs) Is tcs Then + Return + End If + Loop + End Sub +End Class +' + +' +Public Module AsyncManualResetEventDemo + Public Async Function RunAsync() As Task + Dim gate As New AsyncManualResetEvent() + + Dim waiter As Task = Task.Run(Async Function() + Console.WriteLine("Waiter: waiting for signal...") + Await gate.WaitAsync() + Console.WriteLine("Waiter: signal received!") + End Function) + + Await Task.Delay(100) + Console.WriteLine("Signaler: setting the event.") + gate.Set() + + Await waiter + End Function +End Module +' + +' +' Educational only — use SemaphoreSlim(0, 1) instead of this sample implementation: call WaitAsync() to wait and Release() to signal. +Public Class AsyncAutoResetEvent + Private ReadOnly _waiters As New Queue(Of TaskCompletionSource)() + Private _signaled As Boolean + + Public Function WaitAsync() As Task + SyncLock _waiters + If _signaled Then + _signaled = False + Return Task.CompletedTask + Else + Dim tcs As New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously) + _waiters.Enqueue(tcs) + Return tcs.Task + End If + End SyncLock + End Function + + Public Sub [Set]() + Dim toRelease As TaskCompletionSource = Nothing + + SyncLock _waiters + If _waiters.Count > 0 Then + toRelease = _waiters.Dequeue() + ElseIf Not _signaled Then + _signaled = True + End If + End SyncLock + + toRelease?.TrySetResult() + End Sub +End Class +' + +' +Public Module AsyncAutoResetEventDemo + Public Async Function RunAsync() As Task + Dim autoEvent As New AsyncAutoResetEvent() + + Dim consumer As Task = Task.Run(Async Function() + For i As Integer = 0 To 2 + Await autoEvent.WaitAsync() + Console.WriteLine($"Consumer: received signal {i + 1}") + Next + End Function) + + For i As Integer = 0 To 2 + Await Task.Delay(50) + Console.WriteLine($"Producer: sending signal {i + 1}") + autoEvent.Set() + Next + + Await consumer + End Function +End Module +' + +' +' Educational only — use Task.WhenAll() instead of this sample implementation to coordinate a fixed set of tasks. +Public Class AsyncCountdownEvent + Private ReadOnly _event As New AsyncManualResetEvent() + Private _count As Integer + + Public Sub New(initialCount As Integer) + If initialCount <= 0 Then Throw New ArgumentOutOfRangeException(NameOf(initialCount)) + _count = initialCount + End Sub + + Public Function WaitAsync() As Task + Return _event.WaitAsync() + End Function + + Public Sub Signal() + If _count <= 0 Then + Throw New InvalidOperationException("The event is already signaled.") + End If + + Dim newCount As Integer = Interlocked.Decrement(_count) + + If newCount = 0 Then + _event.Set() + ElseIf newCount < 0 Then + Throw New InvalidOperationException("Too many signals.") + End If + End Sub + + Public Function SignalAndWait() As Task + Signal() + Return WaitAsync() + End Function +End Class +' + +' +Public Module AsyncCountdownEventDemo + Public Async Function RunAsync() As Task + Dim countdown As New AsyncCountdownEvent(3) + + For i As Integer = 1 To 3 + Dim id As Integer = i + Dim backgroundTask As Task = Task.Run(Async Function() + Await Task.Delay(id * 30) + Console.WriteLine($"Worker {id}: done.") + countdown.Signal() + End Function) + Next + + Await countdown.WaitAsync() + Console.WriteLine("All workers finished.") + End Function +End Module +' + +' +' Educational only — use Task.WhenAll() in a loop instead of this sample implementation, one call per round. +Public Class AsyncBarrier + Private ReadOnly _participantCount As Integer + Private _remainingParticipants As Integer + Private _tcs As TaskCompletionSource = New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously) + + Public Sub New(participantCount As Integer) + If participantCount <= 0 Then Throw New ArgumentOutOfRangeException(NameOf(participantCount)) + _participantCount = participantCount + _remainingParticipants = participantCount + End Sub + + Public Function SignalAndWait() As Task + Dim tcs As TaskCompletionSource = _tcs + + If Interlocked.Decrement(_remainingParticipants) = 0 Then + _remainingParticipants = _participantCount + _tcs = New TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously) + tcs.SetResult() + End If + + Return tcs.Task + End Function +End Class +' + +' +Public Module AsyncBarrierDemo + Public Async Function RunAsync() As Task + Dim barrier As New AsyncBarrier(3) + Dim rounds As Integer = 2 + + Dim participants As Task() = Enumerable.Range(1, 3).Select( + Function(id) Task.Run(Async Function() + For round As Integer = 1 To rounds + Console.WriteLine($"Participant {id}: working on round {round}") + Await Task.Delay(id * 20) + Console.WriteLine($"Participant {id}: finished round {round}, waiting at barrier") + Await barrier.SignalAndWait() + Next + End Function)).ToArray() + + Await Task.WhenAll(participants) + Console.WriteLine("All rounds complete.") + End Function +End Module +' + +Module Program + Sub Main() + Console.WriteLine("--- AsyncManualResetEvent ---") + AsyncManualResetEventDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- AsyncAutoResetEvent ---") + AsyncAutoResetEventDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- AsyncCountdownEvent ---") + AsyncCountdownEventDemo.RunAsync().Wait() + + Console.WriteLine() + Console.WriteLine("--- AsyncBarrier ---") + AsyncBarrierDemo.RunAsync().Wait() + End Sub +End Module From 5ac198b939e804c8a6140081a7aa6bb8fd486451 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:26:06 +0000 Subject: [PATCH 06/39] Bump github/codeql-action from 4.35.2 to 4.35.3 (#53572) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...e46ed2cbd01164d986452f91f178727624ae40d7) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 3f915b49da0b1..3c620e9dcea32 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v3.29.5 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v3.29.5 with: sarif_file: results.sarif From 058b157155a4d7bcd882275af429bd8a16a525e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:27:30 +0000 Subject: [PATCH 07/39] Bump DavidAnson/markdownlint-cli2-action from 23.1.0 to 23.2.0 (#53575) Bumps [DavidAnson/markdownlint-cli2-action](https://github.com/davidanson/markdownlint-cli2-action) from 23.1.0 to 23.2.0. - [Release notes](https://github.com/davidanson/markdownlint-cli2-action/releases) - [Commits](https://github.com/davidanson/markdownlint-cli2-action/compare/6b51ade7a9e4a75a7ad929842dd298a3804ebe8b...ded1f9488f68a970bc66ea5619e13e9b52e601cd) --- updated-dependencies: - dependency-name: DavidAnson/markdownlint-cli2-action dependency-version: 23.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/markdownlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 5d41f4484c8b4..accd912af466b 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -27,7 +27,7 @@ jobs: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: DavidAnson/markdownlint-cli2-action@6b51ade7a9e4a75a7ad929842dd298a3804ebe8b # v23.1.0 + - uses: DavidAnson/markdownlint-cli2-action@ded1f9488f68a970bc66ea5619e13e9b52e601cd # v23.2.0 with: config: ".markdownlint-cli2.jsonc" globs: "**/*.md" From 2967faf054a16ca0c38e133535028fe49d917867 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:27:33 +0000 Subject: [PATCH 08/39] Bump the dotnet group with 1 update (#53582) Bumps Microsoft.Extensions.DependencyInjection from 10.0.6 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.Extensions.DependencyInjection dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/exception-summary/exception-summary.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj b/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj index fed7bf57041ad..3aaf59e22c5ec 100644 --- a/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj +++ b/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj @@ -8,7 +8,7 @@ - + From 18f181209b5db9f25f9dad3d335c8c8f10b2bc22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:30:57 +0000 Subject: [PATCH 09/39] Bump the dotnet group with 2 updates (#53589) Bumps Microsoft.Extensions.Logging from 10.0.5 to 10.0.7 Bumps Microsoft.Extensions.Logging.Console from 10.0.5 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.Extensions.Logging dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Console dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../getting-started-logger-message.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/extensions/snippets/logging/getting-started-logger-message/getting-started-logger-message.csproj b/docs/core/extensions/snippets/logging/getting-started-logger-message/getting-started-logger-message.csproj index 2e9c86c2ed99b..2e111ab6604fe 100644 --- a/docs/core/extensions/snippets/logging/getting-started-logger-message/getting-started-logger-message.csproj +++ b/docs/core/extensions/snippets/logging/getting-started-logger-message/getting-started-logger-message.csproj @@ -8,8 +8,8 @@ - - + + From d21d908dce1bcd39e1abeee57b106d53955781e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:32:12 +0000 Subject: [PATCH 10/39] Bump the dotnet group with 5 updates (#53610) Bumps Microsoft.NET.Test.Sdk from 18.5.0 to 18.5.1 Bumps MSTest.TestAdapter from 4.2.1 to 4.2.2 Bumps MSTest.TestFramework from 4.2.1 to 4.2.2 Bumps NUnit from 4.5.1 to 4.6.0 Bumps NUnit.Analyzers from 4.12.0 to 4.13.0 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: MSTest.TestAdapter dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: MSTest.TestFramework dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: NUnit dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: NUnit.Analyzers dependency-version: 4.13.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../csharp/MSTest.Project/MSTest.Project.csproj | 6 +++--- .../csharp/NUnit.TestProject/NUnit.Project.csproj | 6 +++--- .../csharp/XUnit.TestProject/XUnit.Project.csproj | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj b/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj index f82c098ab1c39..eb506827d0ef3 100644 --- a/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj +++ b/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj @@ -8,9 +8,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj b/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj index f89c6d9a72388..6338464b50011 100644 --- a/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj +++ b/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj @@ -8,10 +8,10 @@ - + - - + + all runtime; build; native; contentfiles; analyzers diff --git a/docs/core/testing/snippets/order-unit-tests/csharp/XUnit.TestProject/XUnit.Project.csproj b/docs/core/testing/snippets/order-unit-tests/csharp/XUnit.TestProject/XUnit.Project.csproj index ce0425af52565..df393bc2d8c18 100644 --- a/docs/core/testing/snippets/order-unit-tests/csharp/XUnit.TestProject/XUnit.Project.csproj +++ b/docs/core/testing/snippets/order-unit-tests/csharp/XUnit.TestProject/XUnit.Project.csproj @@ -8,7 +8,7 @@ - + all From d96b630a08d2aaaced482c0e54db59d47c8ad1e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:33:31 +0000 Subject: [PATCH 11/39] Bump the dotnet group with 2 updates (#53615) Bumps Azure.Security.KeyVault.Secrets from 4.10.0 to 4.11.0 Bumps Microsoft.Extensions.Azure from 1.13.1 to 1.14.0 --- updated-dependencies: - dependency-name: Azure.Security.KeyVault.Secrets dependency-version: 4.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.Azure dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../sdk/snippets/authentication/Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/azure/sdk/snippets/authentication/Directory.Packages.props b/docs/azure/sdk/snippets/authentication/Directory.Packages.props index dedf6b3adbb28..9428a290864a9 100644 --- a/docs/azure/sdk/snippets/authentication/Directory.Packages.props +++ b/docs/azure/sdk/snippets/authentication/Directory.Packages.props @@ -7,10 +7,10 @@ - + - + From 904e5b034ebb20bda39e8e040726c4cea14f7ea4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:33:56 +0000 Subject: [PATCH 12/39] Bump the dotnet group with 2 updates (#53619) Bumps Microsoft.Extensions.AI from 10.5.0 to 10.5.2 Bumps OllamaSharp from 5.4.8 to 5.4.25 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: OllamaSharp dependency-version: 5.4.25 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/microsoft-extensions-ai/AI.Shared/AI.Shared.csproj | 2 +- .../ConsoleAI.ToolCalling/ConsoleAI.ToolCalling.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ai/snippets/microsoft-extensions-ai/AI.Shared/AI.Shared.csproj b/docs/ai/snippets/microsoft-extensions-ai/AI.Shared/AI.Shared.csproj index c90f45c97df35..2d59d5b9df902 100644 --- a/docs/ai/snippets/microsoft-extensions-ai/AI.Shared/AI.Shared.csproj +++ b/docs/ai/snippets/microsoft-extensions-ai/AI.Shared/AI.Shared.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ToolCalling/ConsoleAI.ToolCalling.csproj b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ToolCalling/ConsoleAI.ToolCalling.csproj index 69e1dda850abc..bb845dfd3498c 100644 --- a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ToolCalling/ConsoleAI.ToolCalling.csproj +++ b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.ToolCalling/ConsoleAI.ToolCalling.csproj @@ -8,7 +8,7 @@ - + From e761dc7f205140b4fe5e950f2df4da84f841bc98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:34:25 +0000 Subject: [PATCH 13/39] Bump the dotnet group with 4 updates (#53618) Bumps Azure.Identity from 1.19.0 to 1.21.0 Bumps Microsoft.Extensions.AI.OpenAI from 10.4.1 to 10.5.2 Bumps Microsoft.Extensions.Configuration from 10.0.5 to 10.0.7 Bumps Microsoft.Extensions.Configuration.UserSecrets from 10.0.5 to 10.0.7 --- updated-dependencies: - dependency-name: Azure.Identity dependency-version: 1.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI.OpenAI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration.UserSecrets dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../azure-openai/ExtensionsAzureOpenAI.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/ai/quickstarts/snippets/prompt-completion/azure-openai/ExtensionsAzureOpenAI.csproj b/docs/ai/quickstarts/snippets/prompt-completion/azure-openai/ExtensionsAzureOpenAI.csproj index fa0271c61d218..d15bd0545bd0f 100644 --- a/docs/ai/quickstarts/snippets/prompt-completion/azure-openai/ExtensionsAzureOpenAI.csproj +++ b/docs/ai/quickstarts/snippets/prompt-completion/azure-openai/ExtensionsAzureOpenAI.csproj @@ -8,11 +8,11 @@ - + - - - + + + From 411edfcd0e14f16a82b1db55aea57c07f2d15b6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:34:44 +0000 Subject: [PATCH 14/39] Bump the dotnet group with 2 updates (#53622) Bumps Microsoft.Extensions.AI from 10.5.0 to 10.5.2 Bumps Microsoft.Extensions.AI.Abstractions from 10.5.0 to 10.5.2 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI.Abstractions dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../ConsoleAI.StatelessStateful.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.StatelessStateful/ConsoleAI.StatelessStateful.csproj b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.StatelessStateful/ConsoleAI.StatelessStateful.csproj index c831db999fdab..9bd560e7cc7d7 100644 --- a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.StatelessStateful/ConsoleAI.StatelessStateful.csproj +++ b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.StatelessStateful/ConsoleAI.StatelessStateful.csproj @@ -8,7 +8,7 @@ - + From 819c4bef4cdcb27bc2044b8b7ac6b1ad69bbfcfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:35:06 +0000 Subject: [PATCH 15/39] Bump the dotnet group with 4 updates (#53621) Bumps coverlet.collector from 8.0.1 to 10.0.0 Bumps Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1 Bumps MSTest.TestAdapter from 4.2.1 to 4.2.2 Bumps MSTest.TestFramework from 4.2.1 to 4.2.2 --- updated-dependencies: - dependency-name: coverlet.collector dependency-version: 10.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: dotnet - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: MSTest.TestAdapter dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: MSTest.TestFramework dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../csharp/PrimeService.Tests/PrimeService.Tests.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj b/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj index 6855aec7a4e3b..e450c791a1b40 100644 --- a/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj +++ b/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj @@ -7,10 +7,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive From d00e17d7fae6a9ba386e4297243e891a89af460c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:35:10 +0000 Subject: [PATCH 16/39] Bump the dotnet group with 2 updates (#53624) Bumps Microsoft.Extensions.Hosting from 10.0.5 to 10.0.7 Bumps Microsoft.Extensions.Logging.Console from 10.0.5 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.Extensions.Hosting dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Console dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/orleans/Directory.Build.props | 2 +- .../BroadcastChannel.Silo/BroadcastChannel.Silo.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/orleans/Directory.Build.props b/docs/orleans/Directory.Build.props index 4c687b6fd6730..c7e18ffa1975e 100644 --- a/docs/orleans/Directory.Build.props +++ b/docs/orleans/Directory.Build.props @@ -16,7 +16,7 @@ - + diff --git a/docs/orleans/streaming/snippets/broadcastchannel/BroadcastChannel.Silo/BroadcastChannel.Silo.csproj b/docs/orleans/streaming/snippets/broadcastchannel/BroadcastChannel.Silo/BroadcastChannel.Silo.csproj index abaefd9fbcdeb..fb9399c7dbf19 100644 --- a/docs/orleans/streaming/snippets/broadcastchannel/BroadcastChannel.Silo/BroadcastChannel.Silo.csproj +++ b/docs/orleans/streaming/snippets/broadcastchannel/BroadcastChannel.Silo/BroadcastChannel.Silo.csproj @@ -6,7 +6,7 @@ - + From e35c63d114e8c947128af83ccf6887203eb53d54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:35:36 +0000 Subject: [PATCH 17/39] Bump the dotnet group with 2 updates (#53626) Bumps Microsoft.Extensions.AI from 10.5.0 to 10.5.2 Bumps OpenTelemetry.Exporter.Console from 1.15.1 to 1.15.3 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: OpenTelemetry.Exporter.Console dependency-version: 1.15.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../ConsoleAI.UseTelemetry/ConsoleAI.UseTelemetry.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.UseTelemetry/ConsoleAI.UseTelemetry.csproj b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.UseTelemetry/ConsoleAI.UseTelemetry.csproj index 44faa47bdf8d5..ddf701516d4ce 100644 --- a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.UseTelemetry/ConsoleAI.UseTelemetry.csproj +++ b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.UseTelemetry/ConsoleAI.UseTelemetry.csproj @@ -9,7 +9,7 @@ - + From c23ab984e15966ca6b5581bfea3cf94aabe23e4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:36:02 +0000 Subject: [PATCH 18/39] Bump the dotnet group with 2 updates (#53625) Bumps Microsoft.Extensions.AI from 10.5.0 to 10.5.2 Bumps Microsoft.Extensions.Caching.Memory from 10.0.5 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Caching.Memory dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj index d3fbfebce33c3..1527dd026aea3 100644 --- a/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj +++ b/docs/ai/snippets/microsoft-extensions-ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj @@ -9,7 +9,7 @@ - + From 95eb09f2911420493886a5489262dbc347a6bcc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:36:36 +0000 Subject: [PATCH 19/39] Bump the dotnet group with 3 updates (#53627) Bumps Azure.Identity from 1.19.0 to 1.21.0 Bumps Microsoft.Extensions.AI from 10.4.1 to 10.5.2 Bumps Microsoft.Extensions.AI.OpenAI from 10.4.1 to 10.5.2 --- updated-dependencies: - dependency-name: Azure.Identity dependency-version: 1.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI.OpenAI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../quickstarts/snippets/mcp-client/MinimalMCPClient.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/ai/quickstarts/snippets/mcp-client/MinimalMCPClient.csproj b/docs/ai/quickstarts/snippets/mcp-client/MinimalMCPClient.csproj index 71a6eb7346cc2..b1954a6311556 100644 --- a/docs/ai/quickstarts/snippets/mcp-client/MinimalMCPClient.csproj +++ b/docs/ai/quickstarts/snippets/mcp-client/MinimalMCPClient.csproj @@ -9,9 +9,9 @@ - - - + + + From e77670612ddbe65f167524a2f9aa2aa9fb964e8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:36:39 +0000 Subject: [PATCH 20/39] Bump the dotnet group with 2 updates (#53630) Bumps Microsoft.Extensions.Logging.Abstractions from 10.0.6 to 10.0.7 Bumps Microsoft.Extensions.Logging.Console from 10.0.6 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.Extensions.Logging.Abstractions dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Abstractions dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Abstractions dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Console dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Logging.Console dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/minimal/Client/Client.csproj | 2 +- .../snippets/minimal/GrainInterfaces/GrainInterfaces.csproj | 4 ++-- .../snippets/minimal/Grains/Grains.csproj | 2 +- .../tutorials-and-samples/snippets/minimal/Silo/Silo.csproj | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/orleans/tutorials-and-samples/snippets/minimal/Client/Client.csproj b/docs/orleans/tutorials-and-samples/snippets/minimal/Client/Client.csproj index 345d8e6b7a166..270390b52a796 100644 --- a/docs/orleans/tutorials-and-samples/snippets/minimal/Client/Client.csproj +++ b/docs/orleans/tutorials-and-samples/snippets/minimal/Client/Client.csproj @@ -6,7 +6,7 @@ - + diff --git a/docs/orleans/tutorials-and-samples/snippets/minimal/GrainInterfaces/GrainInterfaces.csproj b/docs/orleans/tutorials-and-samples/snippets/minimal/GrainInterfaces/GrainInterfaces.csproj index 4c6c9efd03fc8..6bd1facbba9e7 100644 --- a/docs/orleans/tutorials-and-samples/snippets/minimal/GrainInterfaces/GrainInterfaces.csproj +++ b/docs/orleans/tutorials-and-samples/snippets/minimal/GrainInterfaces/GrainInterfaces.csproj @@ -2,8 +2,8 @@ - - + + diff --git a/docs/orleans/tutorials-and-samples/snippets/minimal/Grains/Grains.csproj b/docs/orleans/tutorials-and-samples/snippets/minimal/Grains/Grains.csproj index 6573c7d90c21a..9e18e4c2cf74d 100644 --- a/docs/orleans/tutorials-and-samples/snippets/minimal/Grains/Grains.csproj +++ b/docs/orleans/tutorials-and-samples/snippets/minimal/Grains/Grains.csproj @@ -2,7 +2,7 @@ - + diff --git a/docs/orleans/tutorials-and-samples/snippets/minimal/Silo/Silo.csproj b/docs/orleans/tutorials-and-samples/snippets/minimal/Silo/Silo.csproj index b22c71883b4b6..f25ea59515edc 100644 --- a/docs/orleans/tutorials-and-samples/snippets/minimal/Silo/Silo.csproj +++ b/docs/orleans/tutorials-and-samples/snippets/minimal/Silo/Silo.csproj @@ -6,8 +6,8 @@ - - + + From 4f6181f2223c06a68656943aa77e3c9b1bbfb95c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:37:37 +0000 Subject: [PATCH 21/39] Bump the dotnet group with 6 updates (#53632) Bumps Microsoft.Extensions.AI.Abstractions from 10.5.0 to 10.5.2 Bumps Microsoft.Extensions.AI.OpenAI from 10.5.0 to 10.5.2 Bumps Microsoft.Extensions.Configuration from 10.0.6 to 10.0.7 Bumps Microsoft.Extensions.Configuration.UserSecrets from 10.0.6 to 10.0.7 Bumps Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1 Bumps MSTest from 4.2.1 to 4.2.2 --- updated-dependencies: - dependency-name: Microsoft.Extensions.AI.Abstractions dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.AI.OpenAI dependency-version: 10.5.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.Extensions.Configuration.UserSecrets dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: MSTest dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../snippets/evaluate-ai-responses/TestAI.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/ai/evaluation/snippets/evaluate-ai-responses/TestAI.csproj b/docs/ai/evaluation/snippets/evaluate-ai-responses/TestAI.csproj index 19942460ab022..1e6bd8c12e814 100644 --- a/docs/ai/evaluation/snippets/evaluate-ai-responses/TestAI.csproj +++ b/docs/ai/evaluation/snippets/evaluate-ai-responses/TestAI.csproj @@ -11,14 +11,14 @@ - + - - - - - + + + + + From 9a688af05d605ba292e0a6929a016c667c8d90ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 12:38:13 +0000 Subject: [PATCH 22/39] Bump the dotnet group with 1 update (#53636) Bumps Microsoft.Agents.AI.OpenAI from 1.3.0 to 1.4.0 --- updated-dependencies: - dependency-name: Microsoft.Agents.AI.OpenAI dependency-version: 1.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj b/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj index 79767b88e3b56..acf7aec25579f 100644 --- a/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj +++ b/docs/ai/snippets/prompt-engineering/multi-turn-chat.csproj @@ -10,7 +10,7 @@ - + {3k~ zlWht!g?^Ay%j}V{C5W0i=#+R@JvP9Ru*jB)&19s%as(}8K;je^%+pP@c*Ez^Qk5Zt zWsQnDNS%A4A_hos>5h^xH zJNw`9?OcHOg#bmzA2&B9V@+NydB|?@RY!?+P6_kFEVx3IAEg@02n*S?Dp4Gh$ZQ!! zhE%>0(WrE#Wo;rdZk*4ej~fev(6H$%q%`hgaH2x*Qz&MRxNrJ$MZySCb-|C?i@fn9 zH&h-Zg@_K*G)0%p87>cHQ159q2}Co@e{_}%-_mE;`u)d3`@fgH;bTClwtud<40`n# z$A}mo`d9Ulx^UyI#U)0Z+d}6Nz&SnjxpL$uA1s2|ii{JmApaUnwYwnXC23%nZDL4>qSQ+nZ`lzSQ^UCr!f0n%lZ5rGYWvDRCrs);Cr9 zGZ%2=sWyoe5Z%Tm7AX!!b!42{xq6zOWx)LF60x_$jTO6(&(9%P-(Dnk5@N-aJA3vf z&?rs*K{*sDdTsAPSRF|^1OtM)m5)T~2vT?QgT|b{Wx+b~G6l!?=A@-HGvg%wOU0k8 zUY#-gH{(iT#2H^QuCprl(6mxpjf4c6Ln6;t|o+%#BuK`)nc;gPdmjDQ!RW4 zy%7T%J`y%GzP%r1y4Z@d8rAdhV@(q7?RCM!>s^e~v@2p5SVF&4axv{3>ps6yGY$H{ zDq!*zLNY9L9KN~6EK%${0M))QB_npr>&jC2$vQ6o0!Yof8ql~k>D`BEeA^!X13o!` zQ1VQazZjhy+%2?2n{1O)bY0!Bggf+A$G+=XOfP|jpX~Pj;1t%->1oj^7Dqiz-Qrvm z<9U1=`@V;^qc$1vK|STSNbJ-FtQI3RmK z9v=W;3jjh)ha&)30py+lw$KHz1ppy@>Nv1s8(ZW6*aAp5wQV@CVjEkK0c-)Jo7pNH z(6OC|(t$kmAwAB8d{HJ`w!xkKS@E<8A!V2 zd+i|iXPN^E9R5u11u%?AodkB^%i}VLK;Z@()ei#mXaSIf?!R&f;6c@$smkmU6cZZz z!Un$DRfv$pmu|rl>rRZjc|0Vr_2od?gtJY}Y=tJ70X`E9>BpIU!A zt!EvCpX(vRvm>aFI2_j9QLOl_6!r8fLQuYSpr(+Bd*oz2lEG}cFfjC zDQ0iK1W&y`TZUGwoI2h|XA5K^YW9i^KAQIGvPV!-L)xyGftGr<;0dT5G@<|O3XkFH z$B)`_zQJtW7E`gcqsGe~RND}ka4WLh>i=cEddFPLPU7gUXrDal+?%m{?IX0aH~yxA z4pH7yy+^AapL%?)2+mq;DSwzVV>PQn|87@sk<6ZX53CB;I-mM7FF!$*_chAvQox7r z;;5Q9KrZZ6_<`S-f=Cw^#|vk&Ix)`)bS|EGFCa-#p75f4`OZoLNz>*3Ox@- z;cIccI>#^uU?|vIVAW=XlC${W+Mt&}Po^XBbhw{ER)VGWVOVN^yzk7a$!+W(3EZ4q zrJ}RynCa}E;fIbHQd&*p7pe~n8^8*$a<&104>@SYv)?CIn|F-13uXM3NqEth@KGV` zyLelOR|w%9t2foMv!|j?V=O&4DuG)!VEGM1$D^jRf9V0aTHZf^_CdeehZU)X*7AAf z@CG#vbuUBnvt7%)7SgL`GF7jFQJww6EeZT19mL@bS4B5!&YYls?qo5F;#2=6=6>PT z5A4eH=d^@SIG5^ZX@S|x@42Y90;`!y!@D7{2VfKcQN(Ep+@nI5dyk(1FxVfcPh6bk89oB9 zuU3>5-qOi?IPnZjdu*t5Tpcr4H5;T%HPJxD@lQ^gc*l9vddJz+A9NQe9WP!)_;GP7Xxsz4sv$(34siQKGx&IsixN zH+0Tu^CB@4?J0nK3%I>`Tx!DZ2L%JT08rK=0DcqiySP!rM5q!^bGd zOMv)pZUHrvOrqLg5j)>`zbfFdUY!qN`%V1T&outZ2&}4lNSd=hu*H(WXFdW`Tw9nY zJ8(lV;s^6>g*N#r;gp=)nm-|Xaa>`~Bw-e`MRtvpq{Zn?9{&rt^yireUYy8fh%^2s zqR*p&7daaLN%g~#ErxR}9H?GA{^13{%W(JC_2QV#A%Ic zHI+Y2_;_@3@(n7E`@8t9$2o7cn#3QTLUU5lg9#h7&9%I<(QAZ!Cjd-qe#X(n4S92aDX&=FeI+(*}FBxt&3?b-rf8V81PG7TEo zVC#jNC`&Arw&qZx=*PM`+fM5$TK0F(;cY~Yk&d~qQq^Zsh?@glG+d&Ahkx^u>w~uV z?L?K9y8~emu5Is;G(OKZhIJ6EX^umwr1jo#)l z&6O1Y-#|khrL;C1>ZISw^Q(VUNmF3jx;bfjlEcS--Qu{Eqa~~5_HDkRs?y{y@$l*o zy8es(d3&HPW2`-&Ns4hzagA!D!W-)$ul!|VNs~jl396U27~*GfZw+K!yV6j1m|0Gu zmy{2R9_Kj`Yv9yA50jA|+Ndyo^_NfoCo=jEfa-s<4f3DB=H<<)+)TH>L+1H%oI}UK z+tP9hW^Z5meAM0o1T+t80MPieIH_&DW0uEx!g`ZN^&?kdow*ux#pcGUBNE$(=3RPk z+xP$-IQc3S)C~bstCoiCUvwn386lT$KYacm}C3=QBErH)y~ zF67~NLKEq_fj)$DFa<|2c@)+$+GiCKB$cSA1?zEuTlrXQ_YkQp^mz*YfQ2`+XCA+ z8cEi0`!C^R-s((+^4{l{{^cQMZ)QTqS_2rG=R1Gdvo}-IM^}PEm08&2r6Zb;QHyIUS%K7-pVXgd?MKQ zLq8icu3*)|5VOK~$hzi!TgqDZ7(JjOUFOA4GpTqLsLfiV!?96{gYdVu7C!y#`@r9;sQGApiK-k38F?P7^xNBtnGY$VXX&b$-U5LG++=ZZz_(`+YwNb0 z<1XIMjv{pfL?sSHy6liRA({9*4V;+v_27uV{P63QS5!{|4L1Jd>Hc;jp1 zZYRTbz0smiiZ`8(0>Iz*yS2PA{{xTXdpI05w#_1+281)FoF!tst!CS`p2e*O%JcN_ z6GJvp0H`@@u={4gv^blF=7XyC;9!jSy|~zgAJB# zqcdn|jw*=204)bP!EN_-i?-dUPIj3+y$ndT>4ca}=~gtXN)+Lr$Y`@$0>eF>aYn7F zG4?(_kZOxp0O7g683DyYwCTY6Cts=x+ocptkY!F~`qi32Ot9!qBzV_niz>>Q9>w`^ zE{RMP%z^rbZZ1PLwqKT|!{%6>sRPn|wc_fA5;Y(*qDl}y_uV_cL~(RA2u0LEp?iG7CirOPlQfS&2{_#Be z=_Cj)OF7H!F0n8f6*4s!2Zv9PnRvNaQp1T7_L?#}P<9Km*ijXz_;S-#$^q#%LKg=E zxpqu2`-^u_zD^pXxFJ^s3U0Ua0?r>p*+(y7m`blX%NC01@9zt!JLAVFf;!qjZLIly zPCH+>Bn*bzoG_$*a1D$FdOu0y&c2Xj(FWf1H~t>XmFW+9@YCbB-mfPYn%WbzCy0l6 zRscBT;4H#BU6|QxKVlW)8%%gtYO*|HZx2z-QGuXI`MY1l1Ki#%-X#;>zo%}jr^+10 z3$UBDWLD;gd<{_!Z;>UG?5I^! zuMO61VbU_CXfT{R?ZYJlKe|DR<49F!)q6(qH4_mDyEhGEG^*8?$5HOE8ECq&-74=4^j zuO4=}F+(N82-y9s=eFW(tu+=mmWviV`TTVF?YEZbr+YhOt`*D0$pM@?@KI9#lvzcsigZK6YyZWPJI<-XXBg1jCNpO+8Wl#jR1>il>y zzs$Ri^(}R0z152=&+Y2Uzh3P)3hVPYBii)vK%S?1_xI1?ACGSwjQ=%5rD=z;xIr$} zGdw3~q+drscCA-;C?hISi~d?CL>sdCbl!XS-#?z}SsE(!fgT$8_(G1~5&jY{v~Ok^ zQi{L`6vntq5ekJ@71cfJ&*Imjl88?NhJ49wOyB!Oh7UR9n#}h(J?RQp1^v*qY0o&N z@E!;;Ox#|2>?H{^z2JK`VV8^2M5>p1U6_C==;Try*pBxtJ3oF>nkg&p$Zsdu^o+r$ z*k1ftuaQgrpm~!y4uOT}I`hEUG3g%jfx0f$;YygW0VL76Dlgo(m zFCrU*k=l4%%Yt9wO1InlAh{T_x8%3LI!egqI`fh(P%TU^G!f;!hh80|5;NCl>kSg& zPX<IKbdZni>{W7A zS`=Rb@%)Ph5qW_g+Hz3`!6Sq0IqV&~XHxAF<}Iz}O!eb8wD8bXuFW5fA+5BBre$}u zsYWVE^ly#b`E`9q0SV%Fqc|YpE!hOCqn2JiPe)L?jToaKse>HB?Kct!1^<}2-tt)2 zx4n*<6LO-&R1)Wzv$2*W!NjYz$dHSbSRZ~-TS(p)Hoo{WK3@i2gVTF`ynXDnzQ@3i zN6MI&)&`PaR=UTC4gOUChPfDw*-SJj*lZ#F`S!6nKv3eN;a9|(CMDyY<>P1x+De&R zK%-751E#9_(Kb`f(Ii$;&edWkn>$ia-`GZu{84zOLXu!86|%fB+gVRgdMC+8{&8KjNq^HOmq5LINS~K@wlGT2b~vh*L~X;5`TWT zv3Pt#-%%%Rn*krHE8Fg?jeo__f4+B1<;_IT=doPWe*q3vdf0(#3F#U|ni7|TGKgR?( z-WL<`a`=e6Ks{Yg$1=3RU)-5?;+PcRIJRt3qyw-Lf`n31$9a%aNG!eB3u*IJ6=igJs8uyGviw1M| z&eo67hK5XTAuHx(y0r-1Tm#UB14tY33t;b0=9r^9`j)rmlx=XW!&$X79pnqwepnYvJ6Cx5=%g7wEv5R;&XONCnm^vhQ4yTJ~{Z5<6XxyWkDw>!14`8=LByUBrSy;(2v! zC|BV_z!|38JL(>qY8XKZrAIx%d=7RI+;^^Ky-IxqeS4pBM$L$F2Fd$_1Jz~Ss5Fpt zs_Q%|Y6E^uVC|+-Fu5hQ1gKZZVM%p^+XA6}+l|^d3UB}3H2P4GW$6B)$Uee`jR~gO z)}0X--TA34++&ouDPyQ+6TxlsJ5F7}JwK68Iz%q^Fs6?uk-mC6mUx~gN9Eq+xER5X z8s&z}p}NCn9|CQ7d))elnZx)<`XL~OST~u8XFvW2h17l9vXLOxi5sq+I#?HeMT2t~ zb(>!RE&urth^Tu*;?-^9c4nyT_`A|^LJ;@g)ddwQ7sn;x^i%DD$RRgc^hhqQ_>5?z zxTf=B!cw?wZk}D8NQeIRKW^7KX>G@|zlO*sdHcFkay?Af5*_1=rNeDdKU z&tc&s9|DTQMD=%Fk*>RQtBO*)TQ>Z)uub_}%jvJ-BKn`AR4mMteeUS*lKpNV{x)As zTT?b%WKmY2?{h3TOGH0_Sd!vvEXWL!>!?rOF^P}WmIk}Q_j27YRvKgecUM?2t zKi59aUs5U-jMwrX`?{GN;Tm#dNm#g`tuAvS2%_w`LgUo_%ScdZ!g>a@la2LXX(CrD zn6kA)V#>$HO4L8=H5-CaIM-0sMbhj9&FW}d$d`k?gpiXterNW z^vfJyUxdvnj-lv$*7Y^uJk)aoNvln37ZzUCzOOkowkHlxcJ${)YtCruCcpzIn@SDm zJpZmev@kKl*?kI$pCkKos=s~Gv2YAHZK6G_H=5{j?d>aZfo*j<%Vc*r!i^Yyhxm{J zm*ot@2%By|buH7h9x63vlqkgxVPZt8-4^gCbLo8$vMZOV9fC5$b0(UmAhpZ%mR<@u zdYnO7K}AwdH({Oec{vd2@W4}k3$669J0@}!ol@UEJ7QZ2(WJiaI@`6M%9tT6ba~bG@bN{M9@?e3L6e$P=In(2@dR- zM>hvWV%T_$2ZbuN**yg0TX>h_O^MqUVT(~I8j$inwZ;{(n+I8mwZW^`qvvHDA27KC zEq**RtxOieLEN6knW~LA6q6mDJqE(d;S)aeZ}1)hM8J62948!@xqF^<^QL*6^iO+x zeK625^wn-vxBsuK@~5%?!%6(JAjI(*e>iS;y8$czsbGJx@{Ep#hO;MKdJ7~eAc*;8 z90RCSqz{hDV=;FvhtMA47-r@$gpx}wN@k8w2tXwWfI@eGTF`_u<)Fs^`aGJ+ZpD$I z9GG8OFigHApZz4lBNzsMQGlr+pL|GajhX-HWt^bmez_$GNvc|><_i(5n~Pt?UTX2J z5(i^L7?#A_-54w8NHvj<3tH;Wv$vwm6qBS7tnc|noy;LWTD+pao=$X$&Ms8Va^G<| zLdgOHra*|9KlIZWp-@(Pj;^+Jc)J?xN0$N9t1ULPtIjY5(o!GHKRZl?47d>~D>@*J zb_bq6%8)urV)PQ%^!4cyvXU|1M#=gj{^ZaE!>4-4%?3+Obzeqs+Q?0G_$C`8ZHxJz zJmNnb?ed_n)gizaSO1&T*Yt{CJroCHZl%<=#(cd0*+oD>{(Mw9tRC>wz%w4P7hy$h zC(Tc*-oypO+l)7S6X|mVTy!e@n9o;RuQ_i7FYtN(8%3%GS>oW)6#>9IFYq-ARhn>S z5Dv}{QJ7g14&=b1^#8(?F8)^O|3LC zFh5qZ)juEL4GMIj1iS4Z+J}2l`3M^w_TlT{9vf`BVybM9|bcp^QtD?-R%3! zrM``oDWK->*E4`7EH)4{m9x}{@6^Ap7WNBZ#o!~qrkMCV9A%S6K`xaG#=t zBtT5-gH=Tiq0JB0gopWMTQ450Z}r~ODbcqltcWOOFB(|}#5Nb6g8qU;|AGQ#(kQ42 z>L$(j{>gNYn8h7E*+F^Y_p8DxQlN>owmfCbl3WkoY`7DsN;8FL2}S?K|;;4I|?(f)x`A*EOH^ z-~0S(HtPmFMc6xbn5e%-9p3P9K$bdPxjX3Hx4+e9^H{9bc}Z7BmS<;6&(tsZed0IX zUR`^4Kgq7ITT(t2HC0d9Ay7B*h%`CZStYm_r&8^#5uxuYBKXB7hHw8c_@@|RKi2ly z9{@B}aZBvBUeQx(fQhzA@6*1cs>S*M2}>4zv6DlUNt}>JP$ZDHu)}Qml+N>6rP|}} z+LmsyJm#b9TQbK#hg_bnY5ew;!w8c&P=O^1FcYnY#REW`+%KI5<(w6PjBV`hM z>@gq8vVpQ>?U#V8TumW=q(#$c{*2}I=v8vSQlq1%_S^!=?L@4v;p@>aCZJpjl)gsY z+NF2nwx^ABWZ&C73oKPbmuZWWYkB^e*vep86p0dpOmjeO)9+*eTCdM9cxIMNjk$Ie z5w+oooAd7&>5QDB=?v;j+GavKZ@OURQY*n)@k<_+?+4|JCsRF%yj-)NG&U(wq=*@4$ z4Ve<+%su<}u2h902WYq}@c63aTQH!7e>}Fzf-6)w04}5EEY~1=eAy0JLdxG!5}5A# zA;^4SUsS)NGv4ViwE4%5eStHVD~g_B`X}Z1lgelc`FYq7E&h=2)292oVU=I&TjV=e z&Vry7;NeCWL%?NhTgA_!YkToey95irQyqLkLh3Ob=q^m>8u8Kn5AB07#A1v6*V1-A93lM1$^Pl(I zv8VL6oJG3jJv5#&E3sPKZ!;#g6RIsFmujdQ>4Fd3-7+B?bE3jx zqaK>DCCveVunV?$Kl1!=3jlSS!?_7&%spH(Rh|sVIJ_|~WDD}guG_Fp0Nte$H4r;m6Q-W9+nBYm|t!-D-b6k#} zYB$p3@ZIH@LzzmYXRHB~wWHvKO!&H8Xi?JBMh!@3n;s0kVCs}U%AzZ+Teul)n9pA| z1tlbc^(k@|m~nfcMs>}j5KyFu^$y#sI*2p~_EoYmNahA6jOvn_bi>{`7(eHaINf%2 zOWgZ?;3J$7tVUxG%DtS`MQ{Z7+62uqHNvWY<(lE?q+|_bWuj)$?h#F^EKB)qPw3U! zpWoS8pSEvqf1GJlhg>J5?bkypv7_q~Xk^e6yrR&8IET=bi8(JV$|Y8;EvKF1G2#zbrIWl#k^M zYdJ%JdZ$dGB@BW2(RP2YRo<0QBaj&8&3hJ8QcN8oknW*%fm5cBb&D?QdA+@>_{r@x z#-KqFV1ZuJIod}%RXd<63{=1~ARlC_OI|*4)S=ynrx^X91@=>p zpLFdT3UIaIZ(Jo2BrvyfKj*hRml&N=Ke5f|NTV{k->1_T?0KN!nqIvNC6BfHhSN#? zcJo6#!W&-!2l$m^WO zpXXZ1fjD$zB)b*?w=f_ATXR2{oYE`%$N0o*c%NF%hh??YnXYZ@URgBmH`7wnQ>HuV zi(6d)dI7C+u`v>Ic$FE?GtFhx%0awJ^^N;$!7}`0n70q8$ zd4k>ivgC?;e=j}VbIEsM?yaYCE5S0w_bZ1M@liW&HqN;XHKj%+&X!#T`l-Mm_l6EB z;y@+@mz|b&@kW99BWmkKiR*g7cev49-}g610T^n%x)x96wn}>=%hx@Y#mj<=+*k?>4&aX!8V3& z(!XrIE*&D!KwPex{p^M>2RckAO;^erN%kHkC<#-LVRhM&vS&sb8a~=K+jZRB&q!*^ zsOzd?D*=WbUTN7uea6vI;0-&+%7!+&T-%a9J8l>NsmY4bDB08ETOhui*{RK+#8am+ zjPaB;HTv>;&q5f#HP7WD%JQtp=)<53iRH!uU1IXp=C~0T3G3C2-Mk(N-t~R!q7H4x6+WHpCCpniwW>H&=eBEN_LC1^odo?aP^P*d{j2`Q z1TxUk0farC)OeBON&v2(1B(L`_uh2|bGC5EDH_OoE^lRk#k%~C=dnEgywMu4ZkKM<}bgc``MG%>R z@-h`Up}Ap1QW8t^Tg3dub$I}t30Hak&ClJ_{UwG>mMeG`@hOJ0gDGg^ z59Q_sFD*pc-19@D>t6v50e=%M132L)CB?iPS{cLQm7n5PDU4L;3xhf{~U7Q&3QE=Y-;C?`a5ize+pT3I)hHu1Q zi&6oj|3&R?n1tyWcDbqJfB)*|3PydK#6*Yr)wjqeI>DP?>;@mGC6Q)sCDAKF7T>qL z@GWXxu*KsrT$6r=V0cC}=0;QZy{ZnObYLJBXrR2WWzevz1N4<@N7)R6n^hRRNXLC6 z5RFU1E{~_~mpgq607iid%z+4uS?Iu{C|M&=ig40{&C{Yu%EFxXYrkok0nXb1^A@0% zI!sQB$$Q4>ll=^5C|eF*VIA<T?;lnV*N>u zf9d*fSFN{tG+;){{h;edZWf8ALjW7w7od9q{+ef3emK5m$4R6P!lHb6YC&bAuYQAC zkM8O=7eP{POfpa~yGy(IQTLObN15K>ve>AZ`#z(46G9X$z!gO&g zT{Gq8Q6J^H1?z_w{HRRRqY|?gkNWR~)YEy|68+7fdu0;)Awm5k?rq(bTbn1y#rlnZ z?FpU>lit@2Tc0!)>plS31%Q+4!v*oiq1m%4oIrj~G^QvC2&E%azj}F*N1uiXwFdL- zSw3u@!*YJD@V5N4E>WwfZm)PoqE~woTH)OAi)SR26{AFeg_Dv;ci(AN&-9-MFwa- z$^4^xgHV6O(gF~YB+y1Q(-&o&Zh-I+gvCDu}gMQLFY*mc-TOpS?n$9j*9MkG0xk{+G5Q z-h44h5HYC3VyV6FZ~<;3UYf{S&lbu26m0dLfD=wi4Ad^2k5QCWfAwzJt-Y;*EsKSs zfT+1E=^TU-%!*&f&nZv|z=cC;V!9o)nHbxp9HvFm0)z;h3%CXfWeHw?pkaHjWfW{_MZ zOn1Qs!|?6FYmX(=wC$iyz(rSwk-l}>82q?fpnqV_Pzp;+&<}r4g|*6325$2JZ5d19 zv0<;A(Xj*X~sAg!+ZKdyWSA(Ev%c_vS6==!lTWe-fJ1vci5`r`+8}KzGR4tDL zmM9_-thEftiF<-iera~E<;=H_ii|=LloMkH@`@eI9k0YS!VSL{|xxJ=eW;} z$MdrEnSR~pfp)iDfW}zD$ilx3Ft1X!<^KP-yb5F6cHg?2)VsW;@IJ@@uY=G zxlG7h@)Of#Hg538Cr>u4V`#E{|uFE(hfK8Yw8K3AY@^(e~K#YVLH`^muLfWxe_ z8wtVhSP1#XoLyx+>4&(TS-O7xPg>qPdVIQa;bZB^f6~#$>Y~G+oYILkkboKoJQ%K8 zuV_)0X4``Z>TPr;wO5WGs34T$U(2GO#@+K-W8DX?9EPh@vfk5&A2yl|R9DZPdJ-CX zAfG!t2&iQk!xAHOyWMCL)^V9fB&2P~v21K`GRbjb(tfqJS2Ry;l+0^* zW3yn+?uNxiyMmjc5PQX!pYS`7{C;hzGv5q5su&^>u$-JX0Uu}7hMYDRhrglI);Z}^ z+Q&c;&<*}~mmvX1#2p2A-EDV8jFSUpKz{!({0RVG{@4GTgRgu`<@rAzumi%Ieo}<^ zF^;87Fz7R34M!kp6JqkrC~ z{Ifaz_{h&IyFkY|6{z1T_*nnhao(@3@@L2S0hm*{<#e2HHwqd3>_xq^<&*o_$i7+3 z^JgQwkP`Z5f91w>&7Y0z|8?7T)bFE8ZG6(^=hSVX!0fw?v`6&?;niW;PbY5VN+1h3 z*It|Xfm!qK5XO7p)+bP!+5r0KylpQDL-^;HJ9%V7&|xA8%Zt<=SkGg!ozIITTJYqC z_MRn8A%ul`>^3i-`={kttg-KRn1YI22OkUiL1k`=uhjEQ;pcMwrQ6z&r@v{CFe?5N z3laUjsbLVQ)KE(GQ_4iW@?fCLF5}jPn>l@!Uou=#t8Iw|ra3FUVkIiSRDko~md&ZB zWJ07I!bAu`Uk|R$kGmpR#pIAfWD;z6HgCFIRS)&6YC2e-^~|(dS2&i_r{;)GU3gd6 z=`o--8qKHAQ^#eVvP3c~OU>15-=M@`+X>=2RfGGA{6!0Zk^L(2d#0hA#d(|LN zvQf({(X4~kko;xc)dJ;{B1{8+G;d}`_0v}?gC(en0&LAC_mdS)Qb2nL5d2x@y|2$Q z+IweQj#&`~?Q9+ppP%%n8esig+|&>mEy5q|L9M1d64X1V$z-qDlTnDUrzuEqQ@# ziROpN@vaXAdkN3|zaHMSg4G0$oF@(^?ro!rIIQA}p35w;jL8h1ZG-oiBK9R4NnPjcz!gCWjnGG)=P-`*Dl;I}O7+ z>ipg`cOOV0&q2faR}b}N1Xb^)pF&os$5O+UGYo+?=YQfCn)m{X1;4D&uB)5oQG)oJ z-7kb%CU}c$q%g|S3QbAd6x!<4kR5dH&TY2R%460Sa{2iEKgdey@afhx&W8Ok$RmA+ zUj;lLXj`Ki{Aze*O46q_60DiZ!|M|z(n?Qw(DtDVeuod>brM6IXLW?CR;I7^LrtQr zOE4fp`EHNOov!Zsw85QNF>9ho-NxiIRvI=%)AQrpXBm%?R@j-+mxubb*lTGf%%4phVh%qTE!KLn*u{GfQyWo z2XLuFi7UE3);{u;1cTS|URk1IA~!qvd{zQ>!5V%}2>sOoKEhgNXNF=YYC!oQCWX6gc6oJ8xTuxj_pESGRc%@=bU1HQ@L0(K*sxd9PJ-W+-;*Nd zerhU>hu0`6q+a|4zX7ZW*w*Oc!*xiMw5DQW%q!q4FhWF!Q2LZ$@x2e2p?=m;DlH8p zv`uvO3&0Gpl$GJvcy(+M-~%=hp+%q65xY!(D$)1*yq9EwzdwR@X#m{;5!%`RP`m#B z7x9SOA zx?l{&ywcA@RtSwPs3bcQSmFh7;+$bMjsiP`>79`B5&|wB-R}@K0#(m9N$`6J*apj> z?Aw+kQm5?joZ;rALEmBBM3VnKM(QhBOfSN5oY1CBtbFL!&=(a^tSB+f5Z6Ux?Z;7> zaCz07Km8&v4>>1rrr(wtI9tVJ9dOKgBz&2Y15BCp`v4Q7{npWUbP${=mv%zmE#F%N z*D@;w#~fcECb{+%Ag)GBP|Dy^)~g@BJqKZ_ZzmXl4qDGnI^b2NOIkZG z#c@XMIDx9fCd>q#30!yr%7xNPNsWtrR>O~_Qn?Ahrv7VVb}}=}C;dSgj6Tz2FzkH1 zJLa%y$&aIkDRwqc92G=zAHnO8z`ho48m)3N(urkDh>e>u^GAM$5tulpW@|p;sSd2j zvg-mt>fbLaXF@O(ITGhq z5H(|cG*-Ej#=;b2Stl+dZVb_jaoM8Pkvu6%O`It~K-jiAY4DKXyWN-Mja^E(g~L)J zimOHVW;(y}${|n=sshF+)&vkiTuQ*eIGlr1F znZ61A?EKH^o5Inp$pc^%hcmDMHqQp;RQ?=TI04(5zWHCW%u;NQuFa}2O6gVDa6d^a zy>jHODQ7B(??#?#fyMr>Sn>2*rSe-N6Zx#IVVDh7fw1?r3qM+c?gPd%a)c516I$)7goecy>+v_g^nEe~mG@GDX%fT7K82Dcgn=3-UIlZIK#~eX z#|oP4uH#x1L=IYea|VRMZt++v@Prq~%kx|00e7qSqY3yk6jP9cfpit%HugZNE1ODX z_+2zjktKg3yTg6LhPr}tEvjDmUWuu|drq`F7e5;~)n}0uA&4bK%^OFQ{TyxjDGG}< zzvFEu-n2*R)tiFQ59g4HraTj$DSc+%hkx=uCm4UvcQ+NN@_zZ9k79e&CVw~OOCh9s zo#E~{0(j~F!`^#GHMw=`;vx!akg~x9l_EA!0--3qD2i;AV%chF2}MAZBGS9kF$yY5 z5dlR33qmLYQY8>W&jwULdT1gogccwqcfA4kc7OML-`(H&o!=d2+;RTO7=*mC zthwg%%=h=g-tt+GRrZ0s+Z3^C0~RB9C*0f2FX4$`hYmPH@+hudZz^8kc5^9zmXl8d zzpvu$3I2~)350@o1%r<59#+;-yPrFVm){}!uBPX#+S*-nKkVlA)UzK1sY=+71p&Eo z&bIx8P?<%CYxS4(4{B|FI`A~J@N*=z%*-D3nSA^(mWLn8k>L_d+#q+odNDKVZIk@s z6OXUazX?4Hb)oH-?jfm%Yjp-xe2?RxjflV4kI zzU896r+*c2zwBK&g9QwwfGg};RaGAO?o^@meUTYlJ6;5v2^0K&AO2<9!yFioyf4m?v{SVt{UxxirqS|89A%vhX(Ew78$825F^>%WFt-m)R(mXfu-dl2M# z+O{%HBuX7Rax=A>w3f%mi;asN{mnT_Jn+UQX8U=clb`V-Co7o_p}{_yfOWZLG@$qT z-qObJ!tPOTZxsZ~S5s=Dt>580`isydH@jQ>#PZcuc5NC!51h<4WvBSPyUll7)JqUw z8XqZK}-4BnP{KwHO|uK0;^nqW1H+<>F4cJ15hp@`xiw}V&P@T`?0_Mk$%OV zUmVEA`qSC`NJ0E>^)o0guy#cLSK)?ho7vf6IuXsg-Fgp9xSre{B7AiBTg@Bc$2ZCQ zgvcU~Hn<4rd`kS?Kco5yT;ljj_TwuqZq$Io}|0! zth3HS(l4$iAf;Y%?ZeG-vsDz1KeZ=hQhncWKFGT_+PnJkjqppg2twj`+2(G~Qw{du zjVZsbe*7M~FG5uoB((_^Pd$up1#i^8zxweEcADSS3_N~6Xt{g_cw^x1)ejv+?5^P= z@OXo7<>##o!5f*!S3g!e^y;=^mgb&FB29DY({qW#C!zGR8|u>Hu*Kr$T+`U0Wjp;0 zCz=k#%GBA;Cs@zj{?2P@F~hzGN@Y40mFkx~T1{Ilwj4cEGRqgR7@THrW7U=|NE|9H z6(tQG9_bwxY6;g}efQG_RaU_n-}6?B`<()$UZl@GiIrb_)mN-z(*pLRx|Xj&jd@l# z+^^z{ZMLg3?}3S-`kRJL0^bYnkWuTQ-lkK(=2|*ROuS0T-gF>_W}l4CcJRMFTw={s z*NI9+V?I>Vw&xUUMxoi_n5x-8F7sN6HnyqVtNRt`pHi><(V2(?tHbh}ZU?0g61~wW zH-sZ<2I}*x-Xyt_saB(6C}&pdG1eipWN48Qw{nlK^{)mGSS}3Kre}M-K|-A=ZGE7O zZ0RVFOK8H|Pj3ax{&Psa!3lXpcA3iHNR2dL&Ao*y+RK<|S>@K6w4_tb3uEuoZ>e33LBw2LH7kzKi z({WI6TKt|{gr33mhMkMC^0umjuag&7v;KY>Rx>`)BmmpiO6yei`0Yf#1Xyy%rH31i zp)?mQHtnkotB-!V$T8^_A29!!53sRRDm)4OW&=$@qw_I6u_M0J*Y7LU-t(dA2S!I! zcBKp>6wwxohq7~t#DWZEI9wpGJ@)`PgQ)BIV+DD+a3p#jFRUom%$r+6KO~P$f46g~ z{A7>mx<%!6H-2w8z6)apq{>G46NPAgUX|g;9B8J?3K`=1k|}M0^JURJo#(`+jbs^@ zBMd&ji<@}UEl>3729mrlH7|C!FA!9{h~95@t*-1d6yin)XZ7LN770QQWm@o1_4ToB ztz#6zHKKXNGjFTXiz^O-jn-Zu?a$TBXRIpJ-|bxbc<~)g$S_oL@HG~TA2hKYhX)U8 z17TIiT3isK z{)(ud>4+qUoq13?`c(PRY+GsV2Y?VQmT0 zfdV?8d)|KtBH)H1r(t^{hB#~%+f^y|rLzZ6K(_^Z@r2tE;5j39Lt0bM9vRg2s@?=* zh;!9Rr)Lx#TyCku_iH?`@tNZ@9kolioA&N}hszOs|H>9rN-y=XlS^fthFjyb#0#RX zjsTYaKufSi%7@) z2!z*fxZ06OY*bjg`d(&^Tuhngv}Xpx{B%h~XH;BaocV%>O=&?HkY`oWU)>0f-tfr&WXZ)94jo8Iq)J!qtKse zkZ>2g!H?%&8b`K*Z#Ibokm|JyRoUxX&D?C=lWRyB*>p+vrd0p5GL=w2-U@y&o*yeC zTQ|61<8>jYXx(%@F~i*7WRt;`=)*)Co@|!Kr@(p#8yrrhqR_Lr$ik}P^|ty7IrCUa z!-c0#Uu!Gu`loNVQpN&kw3rMTL6j{}3}N}6PCmN2eJKn-SqP@U=(Y=na;9cC&5hn` z4aN)Ap-sk*D=zwPUqQ;=X*9)b@$Iuh`DoLtXCxkt0e$3-bGF5ygtx5el6wjVE`}ZG ziT)MZhUFsz$?I>o2D&ga!QV^C>m+-mWvw-CtOVV&K8JrKBYQKhOu4e9LFqh+gJ{F3 zAHKJ8_2DID9PDQ3-8eX+Rq((6PW^uedgKE&H9?8$D*|9s0)+le5-0BcT6@X!*AV{a ztG@r=L?-H)riHTG5d^ObuiL~KO8`lkyf9zLhBdrb6VSP{>nyh1cak@f-)i=E3L%mW zZel#TgO2GWu>sbS0vj~x;b4-hAm*z(jCZp;8%TYxXQLu<8QCYR=*zxMMrH3OHeh;* zQe=am{G#itDC>oJVc)$o?7yX!H?YxL^Z%z8T0!d7k-|rRi*DSNrDwF(t~=2I#t}`H zj=%CmK}{e6Q35L=OZNkh!{G?S1{eAGsy*MMzvpbPp8IyP#Hmu^nIW!Hxq2O6IjgA@TqLHs)<5}p&I8A{XKszG6qvIa&KGWQ*)|vcIqiy= ziJ6K#iDfR25L~7V4kQ!zezpYtscf z^Mc<7ue6s-?^9ettCbw-!YA>IajD){T>1e<4p!AjW%3k@^-?31H(b&>sYUGo`+4h5 zyE6HZ2ZJwNqYl3CCiPw}Fr6&fhu*)9^tNmKydC%H2M&SmzBfje)Q>rwE6^5+Ym1&@ zxd1>iZ?{x~(0V{5FHd?`KG+K~5+h^%7Zvz4nP+GaLz(tjy5h0SYljp?U9;%q{4u!5 zFWB|?^BB9r#&Lhtw&*ebp_;dszdC& z5tfmGOLD;EsKYf+F3KzhfhbT}2MHgbO%aHDLo*%~D)KU{ zewqVpXA~k=eNVLJ96GsIajMkYSgpEcS>i8EkCMY(Wb8Heo%(o3#c?ru67?dfcwEoh z4=6%N4MIZbp`~JZDc(fK(4t%91i(a>8QQ_|b7#lu3Pw`4?6Gcnpac{MYpoZuHorPa z8$9N@56VwEtu@f|2o{4Vbl`m-GpIav(Qetodu-F2)6E(Ov1aX*TOA)P!$o7mja2$W zbjqDh{y8Eyooftw#BgcycJQdZV*S%ozW_=3<_CPJJ-!U)ST+9pbWixy)=T?q30hlm zhfpb8`rWd!>%{bEKCJswe9vC3aFjf!gsOdfZW_zo*Sud4{>*lPwwTbPvD_G{p?LH! z#v@|c*Of@gziZ^M`M`PmbgTozTq3(|saNAsr=9=eZ41Y4QgOJlBt*B*?W4V#-(p;T z;=|W_!Xjs}wvh8^Qxil9EA_nJJsZE*d*bs%EtIu&qF(LrdS?y)VaSUC-p&4TziibZaMLeg%i0QeS~FNXOxvQzKcdsi0=6K9P}x`$+i5 z7QDm8`}oa`-W@ZcX%{Y5-g~_F^n6#&zHV?#bq|3ibPt$c!0_`JS&s_Hn>GB&k_CD% zQ0njKGoQsV5tk6<-+lOOk^#$6j@BF#18HtWH4`Lgl zDp_`YcIF1!W(!pf!!v!Xz3T$Dj^E7Vt)Wc-F;JwFeT`iOBLq=2L7t~R(8`}nd)slk zFQ9_X;$f9X1?H6eb;$ne|A99Z|7@)oF(#j`gmUu?f+JE*zoVmVZnsWUD6E5Xq^pRB zl$@d;KzBVNWP2uLmCb!cPJx;b;>Z{rPdfv3%zv>3g_w^-uqIroJyD@=cK^jA{neTN zvGZEbHiZhhn(+)%BbLsSd=BNPBW$LK>jVR~Hjv_=6t@(tnO8||U{>vT@3lE*H&@v!x&!=;5db3m*M;S=_`d0`tmRlW?CK;sqQM z{gA_&oak+YZ}ZYPSgy|DpiRHzX5*-pHFHKgmF@1Xo5 z_=4%*L|*{3{AL`T9V&jJ1Mfi#Ox_inEv{d6oocPWr>rP`6j98lJ}&o|7fGfNarQnL z|K^h~M0;YruU;>cL;fME#228(Z$EF-#uvrzZa+U~Wdn52&?5xy3=9Nqgf&=;>Wf#dD^5gGv>` za*1T$#rsoI)hT}8WFJS%$U;>plF2A!1J@V7x$~83Hp(4Z2Ce?{yDZ&DUok?RVhed> zWVv9=AJGt;8#um(o~!#Tdg(9-(41I>dk}a!_&rC^xW@^B;Oj1UGHi{5rA!sTqBno( zK_H+fMy|R7zTj0uxg)p=hlf<|uN@=gRo3wG_O%@om}!`KG}$pguBb~_vWKcu+Daq> z_1JC5^R#G9gTkV9Xpx7by$hWO$acB@9!nj;d$UOK+p%U{{tMl;k&?;nH`;Cu-340w zuDRHVTm`R4-?{If4>_Y&C(7o@8iXfBu0h0z$~BB%vj!1=TAS~Ril7@HSVTOeyPW@I z1YAWwv$4j1vluFo5Y7C0TUB;o!z!#(HT*FrJiKeT@6TcS;T5MmWo^mH-8Vd+joUbf z$%rv0dYO0AIhSiY!G(5sy5}i1^t)}YW*;}N;?x^YeqB3;2#c%%**mLF|Bq9IwLaEU zmKq3$uAR$|L>%2AJ(5!jXeEjU+z{_RIXdk>^U#JPm~Z8MK`P`|lXWn*aKWlnp!jpBSkj z9Lyslm1iZg$HFpdY!`KjQjM@r&Wlaic0mX zZ_3m`Uwo0Er}MImVb`!XQ}!>$Q={btFoT#+!;2pG-`^kV{a%tDP|*YBaM!ksfFy1U z`)w_h74OoXg5J~?w~7=6M?b663IK&2%QU+-)s3d}d;}OWyi2zXq?lh}ngE2cc6982 zCCFrLD-FP3$&M{$@_jCaD!SCdvK}wQN$5Q&U8*b4`P#a(E%f2uWxJ~>7r9To727BY zRs)DvQDgGx?+(NkVpjpAf}tGAJzYKt2-Zn_`tIiJ8OSA=F>#|^w&M#*)~`6O(AP?H z{*(2gG6$Fb83p|U{vC(@w_eJLx=gxDJbXBOi*m@6hfWMNTA+CtWxjD**=Jyf!x_Ri z?>F6KKmy6vuze3Me>PGQYQYQpwq_vU4)4O=Nvy%ks`K28RI3%f*g+4*fyZ$jWev6# z0s@_P_W4c7QTjiBd_mX}*>6Y^7(R zT(ACT>ucHz5wm!FV|bU!_4vY2wfSkHCEdZX4Bm3IgJLyy+BDdGiAa=L=zbux zOW(z(gR&mSWli4bJM2vE6IV`WFIcHYWaWGJ1Kk_$y{M2l% zA_y!$_BHM(w{-l&*ZkIaJFw%hnM^?VdM^pF-gk5$4ro%Bzb97a(DyA6(7w9Zv~kjm z9{62p7X1mbTm9+zvL3Op^1a?wl0El24IDV8oBVqdG*-G=B}gy!JH^+ud=wdu3&KUc9>Of1arfUxrWD$tcPjjda9jx97&=k{`cwSHaJbrs=sM-J&+y&DE{ms#fr7E;B0(+9YgP9bRfgpB>mFQHvR4R zl=`5*aZfN@>{EdT#l}-st@1Js*Y4C}efIg$KesO4%Y1IT>pLf%)`fU=B;gF@Iw-pf z65A z=r$%<8{qq!Ldl%T-m?gaON#>r%p9qb&i-v9ASD6{5W%`ZNNKwy*p~%0mI-;5ptzVf zBT84@IKdEsz~sna%+|H*gYYc6yp;TgNWA{Ds~`U*+pwkna`gFIfBbJ(f?N)9V+?9) z#-q4s-2`S!p>9yc^1!>r1yk6vLJp#`UT9=&`{4`-dhot_-E`I53 zAo~nPgpm3Fc{}@SRPFz~rT!(*6z3AO8Zr}+Tst@I=Hgz9sr@+9Lfr$4i5+mPSE&?X zw=YWY=e3~ou=3Bj{yAp%Hz31bqDqjjWe383Moz1dvde!B1g(Z0AshL3h99~u{%;d# zh3?gVj3T%S|2vW0lgrtEG7kQd=?JAoemb*4Vl5g)@`GFekUpjyWGZuXd_ABMKz~r% zQ}p?lYT0{hUn>63m;9-JZxBvIBLWMQrXeXmd#&tn?YX8dvAF2a*&>G9SHGoOi_Gn< zqkw&Yf9{7FR}A!Q(hmQ0V1=!Tr)cH)WJWuq@sh2xq&FW5V#^Prrk28*ClYHc=kOCgojv|EO=-z-_`WY)4YeB;;)M)^&|*K1E?fx%S1 zjosyO3%avNaNRaCbI{aGe?-WqG~G2;6BFoVA=;SNKgCph=j%>O*soHHL82^t0Gs0L z@K`l(vc}YldkSePd{oj>A~`@M1Z1)-)+A1PE~ZJ^{acqQw8B zm$z?;znA86S!7l{eP+Q86q_g&^{=bXcqAi-@t=QXaS{Q?su!F&u}OZ%hC-8|_Km;j z+!5<}PbgdfERA2Rh|V)*ug%OHj9oBNhtmw}ecfj!v?-7PpoG#Z6>aL(xZXE{C8RM> zcunR-Wu&rWnT_u001wHu^CLd3rP1!ceT4WEVItrTTq9|`l}hs{;6r-!eM>BOTXF5H zLRg%3;Pbe#iJ=KJ)e9(QhraDV67 z_R?Z+WZlS|mwR53-1W8~d%(xA59s?msklF^PJ6j~U#P+dT!$EAnPu`gJE?nM zj`4UX%|5BU(rqqWeg8yVHShcBno5>5xYGj{>6cT&;tGvCWzTeJrAt>e^-{lAi)9cA z=J&X@XsmY+P$SUxm@dz#=8g^!l6_ zwT0Wgt`=^&MpgBlofFm|zaDXJ|L3d*w-G+I3w~u~4Poj6>7!YXroyL_q$R4q39L2Y ztTXl7$1md92ir?siDKE*sOVR9#EsQG);G@&Z_D7!&Lz+0s&5rzN%0J}f`pg8eda){ zwBEr>L^9wq7s2{c>_})zChr$oTyz=4%<1aMVuFl5OB=DJYSTQ#?Sc80Ny7&j-7eL@ zh&r?=p$do0xA$F8VU>K@aBZQjvwkFSiL$X$?Lf+KGesxD_K#*^OJ^oTcTbr;(kv0x z*2WeTNyYTW^?#nAq$Yh`v5G=0>u2X8Zrt*G+CQGqT|cr=eKig~1}g9slxAY)@A~n; zPho7GN6dohL*qsI3B~?=PZK=`KTl{;7IqbD20mQ4J+spWdObHpI*_nAmwET9i^TD~ zO>4%&_Kx4~^j$p7Uvh-)Ms*^Z{^KtrrmHH@X8WcUzp2Qw?Cg=z-^9&~BGMZ7o)P>W zWsdrF;#|b^-Zh__y4a5Erw<)qozG;7zwl>Tau|#}b$^hNb)>s|uO?4?UKby~y3xzc zyecJ_GlES9o0>I$Ec8Y$T18Yf9@{&u#Q1)9h45(r`><`R|kD3M#h)U2+mItU738 zzuFw>Ia)PBtSA_m>C3Qm5uwMF(iQ!TL(UFEVxLANau#JoH*e-wGHIMkI-2#;qJqhJ z9cg1vci#;dwb48w#uz_dxEI;1T&^U*#b?Cnt^9Btek7zhX~mcR)`o zF}J8*pyC@FXB84B5duA0 z-R_fxV)c_|N9d#Gc{xg#wMV{pKK^{4m0%TvJ+hdRc6jH9_ti=#lpU)^f*FUm>D=M_ zW3bc4h(ymgAqpMdJ|bVzz4_JvcV#8+R(s(Gu`6mB2!irx&v0wQ;$<66`j<|Yi)hF| z{%kI7K1Ha9%RBr%kCaF8#AEM7ZlCd)l&AJwvt3(HzbcCZ0jN*b;Kbx95U1gM~-S?jT7%oG5XYw^jtiFa^$47{kBP7>xU;jwDU@_bCtCu?~w-Ypa%Jn*3Cq3 zwT)LtW=)cTx+tpM?<-VQ25xJ^@#L&+c)IJZt;k~J)`OV(#5 z#izN&)6x5YHy_gwoI`^(rQYP_a`qxg?4?8Cbn5FEqOP_hrxj^;$Q7+WMq-4IkG0!1 z3?K19apHO@)p2gV*RgJVJmu{(Ly=>hh5pCxl1@<#H(Z89VeB5Nx~Mp5WQ7Et3ESGF zdC1&&T?WDjEO28HoWS`Ekc+VK>l?C`u6W78st`H&Hrv7hQtHOG`cA)cgQ-k@Tz|7K!hF{%Iz4Xp$6P{xaQj26$m8r zY#Xmuj;MnKdHZCb%$a+Sui6`w_-TD$*Hh{ps-eQ$o-;QO74S(zQoWBn=^35=m@?A( zAuSGL@_5*C`I}9zRv=HyfWHq^Y|Kwv9!n=6ws;$h-5i^kS!6Vb1rLl33pWOUn>xg} z*2Ie#!>cEQ8(TC%wV(8PVUg#oJBC^ni8EK@+O$kJH9P#k){nzIy<`D@MrX$pR|n_P z>5n>E6=zg{N~^0n9A>+q1T)=HG+8{R&*-%ctQ*@kv z&sOEGdvOW1#EtPzy;|8FplW?jPgWPi63Fk!v$N}jE(2)vv4ShjsXAW)>joRa=`nHF zDXN*0BrD6S&7gLb_XaF)qdm`ZF(`Z6?Xv##n1@Rx&D+-)Koa^7NCKkZ$ExFHdx7?B z=L4r{pj5kuPdtz@EibKw@bM|PR z2hr<{?sAz)N3r4jCE~FX^^>5EkNjQI;yU>CUgmruY&01}x@|~T3Jjn4A{82yKna2e zDe~Wlx*gt&rA3L991Q>i1lQ0>GqPct1KAxfD=w0)(oGpYZYt9IRotaoz?h!c%dnN$ z+9XWL;k3hX_zg_XEaQpw4#{+{gsLLIQMl~lH>@u!`@wCw!0V3r=?WtwKS=^!eH+~@ zFDYPY)LS*BjoS7Si3MJXPyNK{D$&T?L#~r6dyMFJRJ5PBf^4~z-bT z9=@gHGam?{Fjw`{(Uyxo9m;v$?OM|^rG*;6#s#y2yDAj ziDv=Tue8G$qhcMQn9-pA-b-Fpc5G%xl9;o)IFb!MjMyn)^hTlR*y^YTrI|88LpezE$%*$BFgFq$JDbrnn11O*xcBWnG}|v6DWVYLZd!Wbv2oH9lWnM+`mow;$Cp^>?=m< z7J!+mHj90c^u0Axab_;OF zd)Cn&2>`u$hF0d*WsM}OWrE06rLMb{-ooKxK362NQ3DIxgBP2pNaKKv=_w)p!Ea|L z9zQcwC)c~K+B#$eQZug4!RI*CKG^526_^>&n~@UWW2tSk%cw*R19Bk5NbQ&BtWvZc z&?&R4>p-EMxa}=^ASJ8WRE+0DgVRt#OyIy><>7)i+2zG)nFdr)dO3u@QwCE|6c4Il z4@f!3%ZUBnnS|g9#i7cJ?#X_w`Y|;Uf@ zY3sC4?&)cyP{MXPNzIy9H4!Pj^pDCkg&wDscJZBKQ{_B26?1?1*_}cuIPilH; zL=KJFx>zdZ6WfPpth5_IUU4kATWqq=Su8D}7OIrX;R~Fb95f2IXC(Vv#YCl?Uagw~q+kl0A6kCnNWV+_t7h96;_M#}CY(bu5+ zx@Qe|OaGSD9i+wraVbCOR@Dv`U;#EiaO&MK?yt#*Z@Hm7kZ8CvR@-T<8T* zd9>@I*Y;S_d=<5jY+QUL^v7y&w7TIC=j7s7kLW}?MMV{Y`%}5Zj_Hj$C4OIe8y77N zZzr8LO92^+bw$e^w=;AiJBzJhDvgc$M zyoA`1gVqY1jFsFk%US%^niD5mAFL}{uXyDz)-XgT-LyiI1@uIYwl+`8klkP#Y!ykB zaYP*wVO^n$afe5=Zhs;S>_Qs^!QEBB^Vdf$g)IG{#jY#x<>J=Z^6UKs4Uwr}gBqr( z*?h#Yak+J-D#Fa1V`EcnmG5Zr;LPZy+Ab|{L-E#GA!QU-nAd6zu_PaNX^;-$YEbP$f;5z91! zJoQUHul$;&Ox6R-bc>3?0nua?g9eRN?=I||DgFk<2YkWW!J5azMYpV(lB$Z=f?Rm2 zTB)K%U$`K;Ct;nZP=_5QBhNTMerB~-R;APakJE4o!E+~#RzYj9xtT=ubqn^$h4NPg zvyC3E!^8da^T8LlR*gxAhwlptazdNrMgB5j>|d;Yp~1EqXZB-%vSRixfH{FLsH<+7 z{n-D?hWxS$$p0SZX2+7*X#EGJY>!+24@%jSFJkYH0dAQlAR)z9K`gFkFr!FSB;bt= zREt1)&wx>8#S2ljLS!}e4dX#PK3dQf4Y9}EELZ1OJtayk-H+b+;hPSro z=*X63+iELsp8c_WBL2B+oZ zILr8pY`kH~QhqGsY24Uky#}D;g|fBJ?qK0dMJ3)zjgJ_F2PVeaXBd!6f2}u=ERo#}GVGC74@^fU zL`+&<6gZ$eAJ~CXksy@qqE@u>qA>K+fgHb^kwct?4US2k${5dsjj$z6-qtsP?T;CQ z4?W*Ke9vatom|XEYc&oKTZlq{c-Ub1>H!+i+iLO`>&EqK&bNhz)=u@#MCNG;+|VB# z>s?lBgvEO#=P5RptbCpTqv2zWHghL|2=oDI=MN_rih-gyY?QT<$I^VEUzg#2gGYrA zo8EfkjB$dOr2tks1(0SC$-lUwH|+aD7@JH{!X_lypMl}rqcsF?#7WDxItf^r;3++^ zH!&k)gGJCVJ=cQU33A<(MX*q84x`65CihdnpU+iZy56RTSYGw*0S&o(St=xe- zPJxzkRIr4nZaVqen4UJq_Kf%gT4YRBg}c`cz;}s}O!nW6mV8IaklvDFS&E+sz4u%y z79j`8#YfG=${@ccN!EE8dk5EMu*N)@htV;Y=ZZhS7lk#Ti^2+>i!`g#L&gRdI_lj~ zrf3U^k-3a;rhT%K!`euM+LOp;U%^PML~*C+LmK|K3Ps#)Vo?RYMEd~Now?}3o>x_= zmWvZRW4Keiw9vOnweW4%0;W4J*W*y(?GLrwKHd$@#gMQbo(iB8zysYkfgu0spmghG zal|IcVSL1H%=O_$=J>HfuCc*FdifpFY~7a(9jTMaMXvUprI_qASBsL;KtIRt^%)*8 z*!e=z^tY{c`^QiTF^<;#S&@%MZ7n(ad2f>iM{upj@3XzrZ<|}K$r@jju#)p0`XfAr z&l@;w^6Pi1zt?J%5)^A3-5>abFPb0Z5+KvnjZj^; zpSC&TmoXRv(@w~kyU}f&Ko@vPHuO^>V>hlk(I7(p%4h8YaG5kUZ0d!I#e8&vm5ZM; zxH=GHYG0njXPg{9f-zwbE;ApEZSg*unVU}+DT5@wMIQ+`UI(62ibnM`` zke%zybU{?j_FZs=2%don6u(0MfU5!2Xlu~SCDkavE|oU$?YnJ#!?zFys~L%$A=;<@ zx@tPr_1ZUrNH^vsZfO2sfrZ;{Y?Z zTS%LtCleyO^;Pr)2r6>!6 z@{A2wcU5RKa5+|`O3vPq!-JC+o_>qk_|=gDMRb^Zm>Io?dnV^x)dp%$LDLAGj^b@RYM+Q zgSx_*{btfHiY5Yol|8w{G=dG7mcOM zG?csVqwXY*K+n3~P_q~XUsRhW2JN*{_?&4f;e27uZ{J2xyaGSuyLZmF_%$>Q&iIs~ z)i|dDymB<;)kWQmYcvnUlBk4|9Su<%N!5*fHlA9g)NAK$maS;sp;e&EK?A)8a^3!4 zmhCarv8g7$_YVdE!>@J%qosX%CRc;5yI*ip$-&phI$}Chw}Ld?fVyPoX@u!2)dJ*~ zUdL~?mM%cHKBWCc9WC+(8y1|~hiM2yWY^P(9{W?;URqgJZjkJq>b$wff#yx!T@bmF z{|2=A67e!jAV&2Irc4$|S=q(Zj$(;R#9oH2iydL?B=hCaNYC$)#^t33Z00dpC8&Yy zoreJJJAW`c==abJ0BDX*D zZi@Dry8-yB2z;?IdR@ht#m2{>X^R_v%(0Eq{MMqlA>0IgE=3r0v7WGg>MY%VC+7O^ zE~S0hhV(ZUNxzlch*)->oxXNTi%-npcKt&c!|YoKL`%UVOo?zr@{^~v;HtOFsa3T9Y1JxERuU~qaK^;6AO zNURNb_PU#3wLdDjmbK&IEq@=tMON_j%hXD_vX2c1FHnXin5MoOrv{)qP+xW1tCsTJ zCEQ5oQWa{2?S?+Q=Rp-}c_t!n5gTkZY6HW8yD55Hqjg3X&7#?cM*2lNR){5nH=60o zx*ONw`+hR>PMl`>g?(!d6?%HyLx%F=J@UxmanRM7T%^&RwpVS8C&L^V@s&35GbKsZ z4DB7Uh34CvIUqdxmL8WfO)H2CywzdBl0Um2+XR+T_R$2_UMEX=L6YSZnjX4oa3&Z7 zhqo8jVy$aN1m6Pot$cXesnV}$-j9Z+=RJOVk6*_W*i{o3nKa}IyAo5T zKT+>Jmxo`spB0k@*!Je9iU(xqR^rsR3n zwoRh6q4e@G)fCb-VHk`dly#{jF6S=2;vhQtf_A6SIf(7fQ1$7rIH-1D&C6^GxL*q^ z7!AmMw{zvHm9|Nf19K)Na4?Ji@hRs*{I?S}q<(DAJS#zsRw;eYL@Teu*&Gn@J^6n+Fh%eYP*&W zhhwJqoYx{}MhlBQyB!z>r`dp+v9Y0)pyr#5wynC9JE{;9d@w6K#jwe2 z5f{{5-+7dgn_oLJz2hT+V$Sk&1Q`X}JXiJyk~v1{2#1=wK5ZE*(cHm#+`t*BfuWI6E4m_u4PuOn9g+ z;|j0HMKc7TUJrx@zO%pJTt@X?dfMJ> zQ1s``KBLU`k9ESBf?ZUa_e#m8dq&cbQ*;%XChRsOne(+T8KZA{O;^*{suxgCsK4?| zYPDwzZ1;NBM)lwmDarNgY5Ji2NlW{t;`f>A(TSTgjzf&~kll?UV7Lne^NUs=qS)iCl5R ze7+q~f9+`lC`5G%0=E~3#o;~2XSOrZ9jLSYE(cR2Wvjl;l2<B~qSUdHNVNRn| z9?9*o(G|=4IQ9wrzv`s;Kd1NqZgGgO-pnS5Xbz!g$t=!;0bRzcm zEy=TAtp~&HTJ6YJ|95!))XhZ!4eZ7?6Lv?iTNUGhl|hDFS)V1Y$ZmB$e$#3{UUXjq zSpko4j*-~?6#swd6>Hr6vw-dKq0L(VtG_xH4JrlcxbZ^lV)hV`H>UjZ9O4QiR|lk0 zL{xqUV2$0%CdKD3U$vCr;{4-(`CLs_Y1g4}_|XPS`S|C1PH+O2B6UufJ-XEv5WSzb zEjpo!VrjTa@6Y?4Jpo*zIa!hohg-=(B>He@ zE~n)(R!Q{6S1bj9Y};p{y8Nzap5bp1%@+6Oyr3dUqlYHCmn%xn z40laENj%bt?Z&iwW_R7_mFZyaiq(4kcUviZS<}aRxpTqC7jIaX0rAW&lJcGX?XN{N zHs~CI;e>|q!VTVQRK9=Sf#6J1HfHg29|4g>PrDY&1^BLyH^a8%B`tK%JWwVFxJqEN z!G1u1#wMDbv@I<1ueumPygB+blzV6%J=2uf_P~R%QF5@rFy5)(aAQTC&3 zJ@i%_(mTi_m7>4u|Lqa{eeOyzs1WpWs}E(tDF21=6PXSAUVNNW7%yWn>PKT|o-YSL zBtp#hdyYj?i>EWoDcNahXir6hBQvkjW2$Pw)dQlrv zxZov9+ObIz)MGv1W364{V7u`dga>a4EVhZIQ*tUSs zZuzYMPyb-2&7XPR!}sC$*?L2A0sr`Zjqe*ex`l6+?3(u7BG0wBKf#}IHqY!&G4QvdRB1vl3AsvdS0}-taJ+h7Estev6<#STJ1Rw@US06R**;bg1YUhKhHrP;A;mUA~ zzb|w9UAC;r49_3dy_-0 zO00m_WxJxt_LA5FfuH^NyC|gQpv*JRy|rJ7t}m197v-l8j+0PQR*S0&5Aa8_NJGuJ zPY%u0ciH|jg$DZiLU19p8@fGiBGe6ka2wk_f8y{R7Nzl~vSN1-X6UhS){LTDrE0Yz z4dS_hh|x&!^GK2nPX+zu&Z^gX*&g=HERJt>mbd)9EnO<-xgix0;Bt)X$p;5HFt&LM zppuImjRaz0Psl$Owk|ge)NczELk{7%YcdkX4a2bLaSy`2T8tgWT#EI{6$P)0*7$kH zd#ea(8}Kjq%uZhDNF4yG9o+RVGVfqRpc+OuYHvB$jZ1MZu6z*%Dlo>s72{Qa3})`e zD!`O>O_bTq(Agce02re`rYmT(w!~E>-^;`&`o0}sMo9HVIa_fX@)qNQ2jYDF%Zn8c z&b9M(Gjm&W33&*O2W{W{EQV#TpbiaFr z|Il)2uaM2{I{ltICpVStI|)%JLrdENEWd{zPVOm^&Fl8;{;l^eLh3megenf2qs^{Y zZtMu+m^!~JYGatp?&~82TEDzh`9#7-Z;{XIowZ_e(O+Uu>AVpu2C4QHaq;u%34 zEV!eB-KQ4-EGYfiSeSF3I)C;u=@nv5+>epqP{LF;vaz31`__fzHTISPH56UecJwdX z1mOrRUZS`05?@6QHez4Lvapx)9$CeMkS0)SODGX43Xa-q<)>vk_LI46)R46X(WvkV zQ=6EfIVDp$x?bi}74gZaK6&A)ma&?bpPpZdUV}%?LxlA@A}GwUH&Z@%YSzXU_*?qP zh<8|Y-+d73$0_*k`56*jGnXgAaG)qx>jQ*?FZ0zs>#P0!SZWvsRDGL|c!*NovevSV zD)hc!7;FpP4Zikm)g)<_HoZ;rK$ybmRjnKg<(9>QwX?zY_|Mg)>>9PC6suqP{z3y zM&0zVwsU3AZ|UyRO~}Dl>TJ*9XURd`BqSD2zzIF|J^wOh zrI&+wzk}(h8c-R#SzC37cC<4g;Ceeg^w zbFmbNOPCvy){&~ML;G|P)}z8qlTQE&*&k@+OR?2$1RPa?PurJm6pmi1@-*9aPLfFb zv<+GvpR6q9k$}kf8yk|Im!wv3++!J^J?%SnYieuk0U|5P;qhem=9r!w{;H2Z+904E zG|RNk2%S}=R=w5W}kCZ+!S zFIBofByDN^Oq$Y}`6K|f;!ZU|#}oN=29i9IE7h;fAkpl#%wf37RzqY(eD&&kJuIhj zcPn6TB~K1xX+SjuTN6f6n2%^Jh?A^{pn9s08-}KV(D&R>;%n5lz+ZX- zw%4(C3tdLp_xcaLl8M$>Oi7=cFIKFZlS+>mYkvL%kAB*UVl+4y?-*?LD~7{^Gm_8& z@{w$-h?*d*&yNYLAjAWeA#fe)yfjPDDQ=rS?Sy<`53v62Rp4xwkrnS?$w46{Saoa3 zE0b}dx(U>&&RAz5;UOQP^FSVF^;iY%6k%=QTC8U}k6BgfrLO(0H^H@JCAcx&xHj89 zmK+78c$xgy2RdLKKykArAJ5N8oUwEn z47%j*r&ai}JV#KAtn1x;GydxtpQu11B_-`BfMrrIE`_d+$qGS-XVXtdf$<-TB0j)* z^%+qent$KyAm054FaQUnPjAJ_&}vdKEN=I%!wUU@y87j%D_i0ba74~HwtawwlJBs) zxH{zjc!cu!L+0$K)6Vyc(KaTXBGznp}9*PxB-Dq%1EC zDI8U;&EOv@Z`&h1k+!%0*mGAW>a(n7zyimVemrgGJ53Vh zv@Kjfa=pW^qm$g1NggkGQP-FMqa&f+4_%$+))@i?=q<@258eS#2sdokt_}}qwpfO8 z$Z?I7G9bOQiUWU4cQMPp4^X2Yc2Hqw_anJ1c2*N8Ks~MwzAZM2l(P%$Jnd{nqqTMW zXCKHgTrjVilqcQ#x@6F!$Yx+}kBdJ)N1Wznrd>q^BCPpgFczh#4XXDQ_v$}}t$*62 z4+b5dR{{2gE+vo(*5CmNxYJ^v0grLW{f(Z=6xV5Gs$h>p!jMw@#9~u>YpCR|9qz6a~RAwp`;b@*3q*0z(1_5e;R!F)297VNHvb=UvvDg z0H1aDpB?}IeBb#|f>rw;JLtbU+W$OjFkjX)!Hd}#g9UkqKem^D5%Fk>dZ}%YMN*GT ziigU8R<`&KMV*c|iWQ^5AKUVL&#MPM8d#lGx-rP#tWSy>h*FOlo_O@rnmGc5fBxAz zGkP>v#N14QBkmh zO0$DV5$QF{f=HL5AT1OXBTXRmrXnIlh|(e@M1c^H4xyK*l!yp{1nEU;2oP#0p(JMp zTxdAyc>o8=5_sV$oW61=5!xg z!hH0t8vP`{tJF_xB~J|jyrqruO7hL^&wCb2r(rgs_lO& zhC55El?S};>&Xj>_f#=D#P-+If4&c%Vh(CVv(CJ2s-)5}Q9@!pS?6azN>bxg=&hFb z)~H9^Gu>xbO4q&z-AWE}v$GL$;3YJ|sQ~O2?hG8-456`(O`WanRi;m0J=~d!A%}!0 zZftHWE(2^;Z)b(AjE^&fA@_V)>_^)$?B6KS$B!B$7U(RTo+|~?brzk_qng!#{d-!f z#%i^R1y+6@etUEkSJM4*tqxwxffQ^E2a6w9+T4EnY)D9{$2y^RwLU|S=Kyk)@?u*_ zSoK+I4N_7JxY&xJuf{(ob;Lg$+u;5KQTZb?2uLPEs;pRNdm?szK>{RU&v$q!Sle-OlAtKnTc(yLr7Q9$mQbZDgF!(F&iRDN zUyykFp=PFg+Wy!|KOYHxhae$yWd~olEHy9F8a(0;EcocMxR_uEuJOYq<$Jv+}c*Yq#Q|KCsTpMvvdq6sZt_T0(S;T8V$E=$y>F- zgSwws;pNxMDGlY`NaE$H>YjTPwRb+kD|b&p%8}Vwg?G&_R!;d_ku00YM#?X|tE?x+ zi#YaXX{YjV!t{VWJTJFp*06WkqVo6w(*S^@0H_(KXmwTYy>{7jeSWL_$?Xn!l@p$- z1O5Z2Kle*?O2Zjv2riFH^G!>KzaPA$G(Rozs&SUkTX5UjQ%vL_oR_EHpT)(*GUVs| z_e4^sQKiNC8QkA(j-~F%A^@}xK()|#FTj~#oxeQtD-!{1OM2Ru7EbCy5#oEq#d24t z{jP~M2FmV}+enB;#LCula^eVM_^L}qLjYGspn#~ADHM>`Ie@bb2p$IKwhTB9AZN(7 zm9bs|_>q8;HB8h7U_#j65vcM{zyau<(nDv4y)|*JThSURTWs&lM2k>hL03I?{+6)j)wH@$zAR+RtdOiSkFDXX<+VlB71QaaqbY(m=#rB)YJ@7C~b#{+t|hHsA<gb@p?6;I&Q=3xk$~d6!FhnI>iOp$IR1ZxTNGe&$olhhBDPD=PSUHi z305hHoN-b5Z!YWmgaC}S@u(bN<62O-L{?-K8T{9$i@0^=9fKS?bI}y!HV$GjecY8g znZE`wg8=1w^;m$_WY2B~kl=Q)pB4JHsdzDYh*C*lk6RzbK4w!Y`B})Tu?LiwW98J6 z-bY&$Z-D#!ufL^(&Cutw1|@8-6o+0Mc@)puFGz6j_vma>@ibx2r~Psq0IdjD*6$_` z5TX4MTr33tmCgK(`J@4F$3A<5AK2GIw`Iew3jrK!tW%j89PDtFA?H_2&}+aiA>wBL z_8tGu3jWf&n*2EypVxXZYe-OKU=-NfmS4!C?*uU9e_3|+?*Y$M4qz(Q`Cdo~5rB{& zmh#IB|Cddm*woZJ7dTMozOC(<^6>YFgc48b&s)|6)tgT?w(U$kq|J`Axp;tazOf>qg%wu=4gb z0?s!OyTH|@IC`s4J*>On-DUcQhpq9X0dSUMShBr$q7= z?wh%#0+5}BsCd&Fp+LXm7;!*hD#E9$$&r|H~Kh17Pgzcv5O-@3Oh^Ezoe^)V_JM+JAhekt`!}$BQzwQSDtWKF@F@p;?jsoAO;Yx#{cpCdU6q2gk! zcJ{VApFTv2`T^3uJ1DzE%_2yzZ16po)r&#pmn;_o(0=GFbNCI~ zd>jW@z+Ps>-H!}Rnh7ZbcInjL#Jqcg7y-Hh*RyN9E`1VdPkomRFrBl!Mhn377`JP; z!c=zABgSv8bxOx>Z58KVbr2OW>6k$H!+sEh_xZj&vpFarrs>xDC3qh_!uzfD+L|nw zFbp&T^>EX)opJcqFSe_HYbP9_TpmF?9^v^Tj-#chvjmt8>nmrwfXkobe7c$#6vu(L z`J&8q3*~I%I$0=mEMMiNNm9dQn`fVi5lDNc13>-;?vNA%iWPGZQ=NDoi$HCw8p+?^ z6qq+0$$il{bE|HRVe+sz=2Eb#=MM^O_|9j5qZ|f+E|vLILoxl|ZR-N7v1QYh=vJod z4UoXpH+AZG>xfElidz=RlmiE*1FY$RLCM}W1whT^rD;^v&=Hr3H37~hyGJ%s{(nWm zLXNrS3ZU^L3-T*_(+T2w5H8?C8Xt6N=3)1S^tQKX!e`Zf8i*YkuCB6Uof2_89cb@h zD8P9z13}YK)|ye9HEvE17h$2w9WLJ-S?t$CZ!h_k_xC!Y0{#j7Br{nnu>k6@;%V8& zpv}E-DJhSNKj(a1n;s@$^tNioK-j4QKU)#ocn);NKiBei#McdEezLp$P}zZgkA=_= z^r^pk0C~{Em|PyE0@OYELfn4Yd+~n^9S5w^dgy0?%1a)eS|GjH#;<;#Mg=B3xLvsJ z&U8sI+cr;oXvN*Vpd#8%$-5TcjAa$wy-w?7@1J?&Ee0PthLO@SJyig$Jvw+^YN+i> z9nd-;n`4KCKPTLW3D=G;F7N-_OX@lN01VbIH@TwsB`R(S;w6p}GE5&Ooya0=guZdt znh%`X>Kr^S$S(tMN#V-HF56)eiUD=2KW5VE_FGWxh`+DYtn4Bv&LQWR;5&5K>$o+L zUR!tCc{*LhTXS++FTmm{-!5bGkE?A%f57LTXB1$r6yTBjnMaDdcpWc@>CHv>cQ^G& zIob>fNr%r`$HZQ&g`x4l>~8ISuM4*8l5z|Q7(!eu|IuS%7W3ZUiGx|z!-^ID4Z^oV zXui*84nQL*E@vuOJK6-WNy;UZO8nJi08R;=u-(aOf?#!i3&kGkpDOnt_xN-Z2*ZcY zM{o8-n8AI)_9uc>p?26>=ze%ss9(Q^lZ#o0iE>KEuRxPve2@&a7=t`Gu5Ev z>E(jT-Bc0ta~2*`lEEHYq*xo4H)I}Ox8znCh>BF_E=gZ4kRrvK^u^T!j-+lt?;r8~h_GWIE_6u!+}8940LH&cNU1LM!Nei?@drya-aZlD zi90wZH1sSx34kSE2E+34sXgL{ZCU>rf-Ma2_EWYU5_r3cQ+|?sLF{mT*MgUuBlrPO zP)ku7sQ!dH_~qpYobciIuWjm62^r=UI5%)ztO*7*^J2=q#=gWM3c4k=pIuU0PkwV& zGqA|n!x@+Xo%(~-!g^ekKk>)kS?cy1K4m5YTU>?~;-FRBHec*+F$6+Q87A+lfY9r$ z@(nxcr+uXt>Lpb5Jv~Id`k!~}@|aQofImlb{=+dnXqC7C_`HI-#mu`c?SSJO#xYNg zCag`fddN{Rh;EMR{5d^P^cXDYamS0PhpeIeQ&ws5*!&4Drm$DRhVsFZeCwWk&y;+9 zVAghB`2z4{%#U5HX2jOS%N78W{=ClR11>RTV{p%?#Bm)2rVm$9oEtr)@Ne;^3OQdQEGH_Hk>(z&e)RT|IK zcUVa@lrEyyf=puLy2mm&&4?A?heLoWu9Pm%vCYcG(y*e`R_S4QCUT3FG-XAZu z^wue4aA+5zQtKr(3RD^jYX{@RPkkx|dk1M(pr0w^aBZ0!kE9DX?7x)7{>wDezscqP zWkl)UBpm-Tcl7Vl_J0{B`Zp;5KMVeq()~xmf0eKPAFBjwa`X3U8*A_F)>t2F)^ls} z@5Yg>(K2A7bGx(nS0V5f6IIRJk&O8`>(A`}=y+%OZj_r*cVC*bp?pU}&*)vZrfSei zoL^q$gO7dRz%B=k5AGQbx_$Ne(}QnL{c-+%VDQ1WZ1e>ogE_uGc3eI6>eil9pFvFv zk{Rza-k-|IupXDsqbExPXTeUuTZ4mLKn_sA!vx_w`E0GGFg`R^VneF9vuweJo6Q76vNy7c&BBkRh^y7kZh z-1>i@1oCCk^ftt7iPJerzkj%Me5ED|#=f>wvc ztNj?gxOhmCJ<1!q5)r+OI&PmJGczw@skauiW@?mNvo5!uEQ6-4x%*h~#V-p6Q8P?l z7c*Pxd%v7jj#lGA)5jZw9`~|!C2cF)r;Zr%=Kv%vMaPf9)L+-!Mw6N-Kd->!;vFu@(!cRBo4${TfCHvxUq^JFi||u< zyk381{L(tJvm4)N74$f6%yLnXJf)i;oLBv5TB_M3fhGm`4TbCr&O>Zn2^Q(amkxA3 zGtzSsR9aoZzucS~P_8`=tn&he<_>`#OrI>{Y86u3cu*~*HW%{wNpa$eqR>Y4AeXpb zHEQE$<{Zvywg$Aia>PlU^mQ@Eh#UC`kxr{07S>l)TV0QL0Udt%T4OOx4@}Pp8H-WCmA$95uztt5Hdu=8chCxlPwQXjvRZ@UUU z+1XIO;>EN)Zf9?i7+~mbuoH9(0h}gW-sPEO$RRL91eS z>g^U#;pHV!7X)&Bw4>GHE(k~{iL^wQx)RIqsp(@e7X%o^prAX)E2JrQ5aN(-9_W}+ zQI!K(m8of)prPkoYyB>;Bldz5x3$BbZNFk}bdhq^Wgz#VcXS6>%xa;?<~6c0sDpUF zgRC>cXhCyC4A#u0&EXmcLS%};Vks*05r~JCs=^?S+B0Y3a{C0KS398xPfV*#owab& z0<>1ES|t-uxs2tXDgunT50VG2dtC?+(^c~CvAZ(0;GD36_0l2-r@_anB~J4Ak&iC< zr%`t}9vI3`C<|e?cF=NXHU-LVxY%p41O-{IzqT-8-BR4typTlk;a7r~)e_54D`^}N zO06V9ye*L(CsPzy@Rhr35l@xdaf6C1^xjs7a{P;Z}6%u6)@SwU38+xSr-*j9}<-2M%8?b|Am3Omj;0 zsWF{M+J_KQg@Q+p`9Jh&p_NX}Yw0L~&om(aL`syds-MwyL_F+}Zc<{`FOzloz|}O{(*xKS5xfWC*;RngpM(MitKqVubkg zhh>0J=B;NFXF;d-cl(^Udq7)yiWeq{n*oLL05%hsoFo_&isB9$92PNO_FESRDu{sv`M#Y3lcQT39HvnP30Q7>RW@%qp_W%hSq6j}hFR zJ3J(u_?iK8CeHR)TJ-jiH7_lkQa*X0H?MRWrR&uH(Z0{SVMophH?`%T-oEs0Tp z!XnB3C(t9KBV!jW14JYIEQm2Jv$xP&61k|$pPn27*Ud^4#szv(Ok-(j? zhTOI%RS^yxziBP-^{yR>=wa`HdPl1V6uer{c6+?$lh{Mf)?HiV)#N@&lH^(Qxtl<< z7gIXuF+%3}ZjeBGUz*7wtZ(&9|41krw9B2N6S9Cmhe8pXcN#(ZMhr-9fbI~4{QU6{ zPj7xX>QbrYfb+oO(iKbLB$*jkHgk=?Wg(*)m)?FsU?7dk3rlBjmzlXgltBJ2Iix5~ zDWhDq8!$?xyRtkYV@yKznFR-~xDkU)m$3j*L{;Os5F4R3SGL!>z#Ng{INAj`z1f{94kidpiKGfLAxbSMaE5cJZ&kdahM{9HfX!@XCQ1tV ziN!Xka#>IPawLf+R_b~|$-rI0#O8{HG`PNY?*O}SV8J6T3g^{k_jFDDue#_J(c3R; zql0g*)PGre8B=2_qmC%h#bikeLWp=n2-L(?Ud0IoiVKX-)D295Mnl4yu**NIVm2_k zfIFkx%`cI`h6}DKGOj-I&3=K-Hz{fJ|MJaLU8pfVs%NE(*BpcRiV+HNre*W@d)y~~ zO6oGajVnU`^lhD}F})Qi6n+o*6D9p(|1k@q6*rQ6C={dF+XR|rRLy;Dd30iYq)exh zmM1L^TeW>#O29V?x#xkJvzsa*0~{mwy-Wx~h<|x*9~3RT*^b|QEus~QfwEaVMsRr% zgUPpkbYXQFt1@dBVKw;^qKa$uh#4m->Ytv#l9EEw@kWr!RU;JCfAhsfAz>}NF5yHY z3Y4&Hl!A52{3ecGX+5BghU4Yvm)q82;mVxy&Bhk#6gMq`^hMoND1Au8Ntrs|x3wzu zsq0FS>+yHiycx%z=A8dugC9TnKCT!YFPtD2(LFXj2(M^|Gjb1%W6Jzu#fYNSURo7Z zrjpN=j&Ws$nJch$1kVV+8Q8d_>#IS2;KpGeK67%QefOdfk$p@eo9Ks0Yl1BuHU-}X55j7J zH)jiq;Cv2?b3>AR-wBZ#PYFv$Bc8FxVS+*@S@qrM$|*EyJspMwekV*o_5#p_0^ zr9VnKF7T&5AJ}J-q}RoeM~Yc28O>A|sFBe|&a-oi2bedW_;S zl2H-p7!QDkjMnTIYs$df!IMetwzFo&B*&D2xs={kejs)9is7@x?n5xKC;d-B7B z&ha}51lzs+pBzH*=kQyb&IF+1oW$Wj77@d(m)4voh5#bK}oU=+Cr$Zb}wyJDhrM_I4@f$OrCqsmViym+1=lPObuTz;d`K{DaEnl6O328b0~cFixC*%Jea^=Q1b zh-SxZoVwjseqxZ>cff9#pha|bpHYnIVOQ966baCw&-@@q6o=8y|49nx_$CG6tB=S_ zYr33V8dc(|wU|3WR-r#>D>Uk}Gk{bq1{Ro(u6N0(fJ58Qri>EAwN${i9i2IkPSWQr zs1A5=K}|>e&XGocV~oBBb2L~3mwZK^0FB$u=gjKJEzR|&AszCT{9#52x;dP$)M;; zM+tU~d2(@=bX^7{d7L^TewXkPrDliJN2{ri8cNUP?iR*w2=4pA5i)e+p=GRwi8ArB zCE`jVjd!PpQn>Q9R0T1w6_ zffsK>^A(#Ec?@3rWuLRUa;K5I)lTxNPV<9j_2Q+sz$Zx)51;2&N8vh3W>d>L?}=VHUsV(xUKcB}An*(LuV2W(K!~p!)Z{{tnk&5pQ5IsCuHk2lA@d30KKvICX6R=w?%0l3Wg z1zdp3$?Yr?xO%Fz9XNo?_y7G{O}Ujlr}Jyw5#Ydbftq_x#q|FDCEu=8F84V21nqGA z_1V@Q0st>}wI#p{{3R2UtkmHQ>@h5+N>t5#Dezo#i&A5JG^u_(Jul*P7Cof&Lo26?2}v@y6h+;W_olxgS7cL-p1JvU%$wukC{92e_t*O#fa zLoGLfJeT-jRuFE>$Ch>J7a&ZQucqkMvLgZVdB15Xfm8MD-M}t1_pX_VRJdSC`E+5^ z%i8lmO#$yytQPper^$TaisKO>SP-WAFs01I!nNMI3z!>J^H(NnNlWmf5~otF-pt`%a;)#Z2H<@kxl z6CvfS)t=#srg5hDPh1x|xo&Q2E{|FS)?KUBG*G-NU+tHeCc`*XmEJ?)8U;u$p!Pu& zEe*VxYD4)v?_jl<@EMoqU4N;e0S2G?Q<(t@5>w5u1P0Gu!iAoE+7WC+amRqghVy&q z5kVO6eTlN4&xaITy8xu|7}LKD3#r-DU?Yt3UoiCxgQKaDisQ$7FO+Btx!d;kNb)!f z+NuoO(+>53W6bv#c~q(&nD#QXG8~h9@!cfJYyfXXFImRn^~6b^#H1VLgyipl*)x6Xf!X6+2xz==fhCofQyvae$VXi$nVp2GL%K0eODb)2G78ke z_381x?XpQ$y?~6OEOmIKKsWFSKNA=xJIss(LBba(lyZ+K*ER1AMWg8lVetCx1%Nr2 zl)-gs>0s9&fO>8*C3KaMdJ?E~5-s|CfNSgEW1x1RdNqpiT1;s&BekLD#=NWeBGFDy z3GT!_y%Zwj)O#*+WZWGHQ04yJm2yO^;0{xPztCYChw=RTKFz$tX~Djo7t{pv7%@Wk z@hAz(H$})gjX6IHHB~wIItU!F^dp$vZ4<ah?^ts7m& zJ(sN6B&L=e81|}`b|eQ|oq^Dtz2kV6QZ8!X?-(b^Lsw~Ww?>sX9q#p_*MAXTr@1ag zssr@<(>Ki7vVJufvg0o0Rk?Y$y8nE}(Ie;9cpkC8x18OfA9PABu+J5L;N=)cH^sf4 zz1;gxzEJI?ha1X*dm4f*?zCt-EhVj0Hg7cGMn2;vn6BPfK-q~hR3g-n;=QK48Ft4? z){79U-HXu@uGDZ{#RAosN*TCrUMU4*mm8qzI6Lk>Kz1=(_AzIh`jxF_C(}L&<0>L2 zIIj-qfxue5X|Ys=?*iHNI6J>PMAA@HX#~e}3jNe!KQ&^BZ;SuC_U|qm%BrjSp&Edl zzvY6D(`^k-#&JuAsVb8`&YA^pH~-)C1}%@*&&1$8!%-c>K(QyJ@yqg0k?psQkw ze4%6xW|UyQ!~!g&41!3H4u_MSh*?K6dCzQKi7kN*+s)6@W-Zj5dujla2VAs`nLI57 zsNN_|ybo?@fLrutw3pE8ZR5!LLfWB~ov|g&=#ibKx__xMUT+_CEr}jv`R9`sU!`63>m#{qM)^Mly&=7i5KY z&uvc)T>ii6*PZb~TCp{alr+ipVRwjy_Fm|9BXQ*OJ14&0`g~zG&SRez%BY10 zhDsVs`e<9XrEckVSl_i>`6|wpj; zrel+?5bL%pTPm0IRowVLkN#gRa04>1)qsi&V$iDvls&uf^1)4#xT?}#=gK86wbh?P z`7EUNvmby^rsj_OOD#)=(hpcG_Q`d}B{C{{Y68}+gFL1S@IClv>h8Vwk8Y(hZ_P6v zr3cfzpCtFZ=9mPw3lN?#hVz?Ma8qBM5Kd(fyBkw}HR5cr;Vu0@obJErrXk=FBVgZ_ z3rwUJ;7C5VLhYu$4URN7I7J(5Vb&YYA5t7UExiQR-)lQHuzM_-R!!c?o2=f7zrEiV zDA3x9r*m9WZoMq* zMWnl1+d0Lqbp5u@FEG9rABAV;jW;YGX~iP2y8OA^?wf%!j2!nfv{m5PbOru&a=W5{ zv&EgaM9+cvuk$G%<4s?F`6qBg5$x%h?_Y{PrmFu;*o0NF1bJrkXFhE+v2$6FT=ZJ=OI#+eMgFt@h?UKoc%#06Hj{V72BDL7czUyJAZE zhRBIj94>1bFKPVSA4pNMi&{?R&QTg>%7UXsRCkDTHE~azS3UL06UZCFT*33Zq3)8Me1n@ottN#l&pzUu+$-M`6`y&&Zy-gJvMN4)KdcEb(Ay?tH_c> zs4uC;G_4n`N_^=woFCPt$8o^bltKT1C$XP%BFrzIisU9ZMLU&KB!hcz5|`%L z0X%PQnh1cJXQ_1o5H*!=LQNRTG7{MJI$M`d8$M4_ppqTt6B73NFNyH~{02rZn`(%rpw4RQS`g?m$eNd0}Ozr%s(M3A@9wnS~=!9tFy{ zd`wA?ZB~$Y_>b147~8ZjqZs0@>pEGfbZ<&NJC}mBf+Nr)oZJz?b;??=iXBx7>ZsLC>_+6tcGSsL<`=|B1>^~dS-80`%ec8ZTy@oz&10rLz#Latae!H#)dg~azU=B z3h$%ec=LDreHSw`UHrB}E-LU;S}h56wJsR3TFTX8SE-;geA(;Iqf9-Z)P(2GNRZ^2 zcL})VP>Wc7a9xY^c7rSkd9cUhm+Jr!+9PG%&Lt5+5p?aa!pB?VwZnr2UlO@dOE7i* zWWg6{PDCprGznXA0$An>aFWc>vLJU7b~7CuGYXtJ&6jvVV?Mc+Y8uW{h5Gf3gP4;A;#ZoWNxGB zX`NicO*Jtm1ZhFH7aIU4kt1k|h?093N_B5;LBS*CA^RjPDN8nQK)I4akkZF%Mf>jD z9iCGV+kS6|@|HG$Zg@mN_;Y9O9Y_S)qDnayBwm)PxE}akqPN6p3JDz6REt|8y-=uD5bL+W17a`dUdJNUR+m&L`CYl=Fm>NkM?g^8 zj<;6oDYW`)wIeQaq)8r7*vDTEGs;<`oc11E&2EMuA(ykkVno5+0^Sq$djV-E|D-Km zM;)Qqhh*sbE~J&n0_}5`=)ktta>F&^8&us%vbbuSjG)Lzk@u*36y{pg5x+a6@JE5k z91XwX%aiq!VYS4ed6yhXGkGHW7dhbbH{bYjj_A)>^sbgBJ|yvSTK0=Da!@-bIip@? zl5vzz_nbz&*W5l(wHJ9;KFmuwt@PX^NnWOuUvzy}X9J8~9Hh>YBxN8rXH>mA30Rpt ziu%a~3Z}Nt{@$A6Vb~#rgj|~u?u{Z_oo>kJ;?wIqU5Q9h{}_CnQMp=%~(Ng$!WH~!%F9^ zwO!JIJAM#$ja=5$Kj#eC3TTJ2S{xI}+T`s4;)$DBtJbUes2}Y5L>t ziBD#+!5b%+QzA?UTYqrAcUh&6B)m-Hv*W+u`c9A#S|6b=*DnU#Li-6?-$+i|>wDu09U8S>?j3%+4+BO?XRQISV5 zSz6|5Vnn&jWbOd9H1HXsoRY|^>c};7Y99@&`U=cG7;H7(X1?g6 zb5nxJ=BQb(6X|p5_?>lkBzwHR`7n)yPf%;30SsLGt7|s;S`_pE?U{{Fw=~QB7o1W+ zujfAD^nS+GQD8g0;k(YkNzccIzXNrIV83M#hdKn;10l=YdCkNzionI+W(awjvOSD9Ya0@LlpXiD6f;9oG2+*A^~!+7D#*W~tp8+P|NG>c z|6fekzIeSL9kd{=3bX*K^QXk^3GTjZY}T45-D(-kkH8FX+}Y{Cy(j9A-C<+L92fa@;c{?>^6_4D_SnivBg1LO6q9xHpkkBx2O=5>p!!2Qtw zJof)bA?K53aqBC7vy86F97OV*p|W1IR}zy;Ifpr-&*bi{q0k-bAr!^F5m-JROqG%w zEHWK+aFp&(l~k)(StD729_2ltB?X}DFr5udpRY^^O4_$uQ?h78*J!aPvU;@ZZr)f> z&?3_rgIFINpy9gbdFg?S(o|+*fWseSH_Pfgm9^L%o8Vg7yB@61;A6yk)s!E_ht@sbgJGb~GKG|#)A0S? zSr?{#n*c4d)+2z17Y3vdjOgOoP&GR|q_Al{uarbwEL+wkfTtAmaE}yJS60tp@9`7| zju-RN7!zqzzLhBAe$=Y-d|&6(wHe(Cfp zRh{d4vgQ>;4f{-6+DPDThV$Vxsq5bD8Z-Q2O}s)YjRSd13f>pAIk`xsY4KFoutl64 z-Y5D=rc{8rF%WFRZ^T+~xq0N8ta6RYoL6YCtJX~U6Ogh%yoZ?^=`*2#^zBDYM;}v# zx#a1asa#s!6=`ml8W%cI-0$&ic8M`xHhA(iIlVKDQjTr;uGF%L5VXZZQXb5vFNJVZ zZF|{^|FS~m%r_k|Su<7NB27|uqG9`<Zz59|23AIWicO zQjt$p*`S8j#(aYqW#j}n*$+M`5x_MrfvePB_a_-@^rj3F@X7vS`;p(7YcH7|**Wgx z9`-Lg)YchGHJ(-N^2w_=AE^pf-|bW*Vzoy)Zj5wzMoKsYNUFlsdM(x`^3>){K8)S3 zS)r|jPmx6TRSviTmj5n#-&b9OtA24`7MA&Dx$Pn`#x&IOhAh3f)KV$Q%EZ6`gq-!s zF#1#A4}!|Nq|IcJhI)`ZwH-F#ac8#1Mdd`pJ5_iPQ{x9x7UnI4V$2s+8>#tt&0-j% z7VG?l6HB`uwX z*?0ID-eF;y8rufL-M%vGDr?}IM<7l#%?1yg@8lHA2WWc_~YoaI~JXJwEk5^CGl^8 zBX4k1s%xX%wMWU?Mwt3DaS%b|ho8xp%xLa2uHPb%s@zDPjE*fa^}7yp)(S`IQ^fu_ zmaI)5cjE1K)uQnix8*VWWs>fN(?shkAqq-oe+q*Fm0ouz$su_XZG75Chxqgg2xl#! zW_1}w%@L?n(oW00e+dFRF+7)|B%Z$cvHZZX586JY!K%i{qCJ+?4RZBAV9qrn*o5!c zVNWf@psV82q){!iL3--MA#`VY)BZ67SIfL+UEw96!DXS^G;r&g1afId>F;%J8e(_iD!SSp@0 zZ`fouXzwHF;h(`?H%4I~-ZIx;G5u_lJPvNhq|2Cl;h#wRIt#z*!6d?)D)^&dyT$S10>CcoRWl&0IKYN%>ynaWVf+^0XbL>Vu_=f+H4^vyWel)h& zT8aa!Og-#aF~~ERGP>v+L02f8UfSi5dm4zT--pM&Hi$n>rqQDUycJb?7mKVK$g_hB zM%6+AD{n6^iwu@6RSm#VzA_uK;p2-Wj?LG|ySc`H1PwD1zc3q8i-h~2ZiD6PJ(n9q z(2$lMNWr0|>lZ!FO;k%DbyG7)O%a_BFd>Gd#v7Pj6^A`>FJ2Fai*{uizc>2a{GjIq z2YUDtk|#QTMYaU#oOvs!-QvqQsA>t+bQQJ`$|KZ5gPS= z^2nH}xz@aO?RyU~>LmY|xZWVp3@(%>bwc$?o)M77YuP`ZDAe^a?^jNxmA`Kv2)+&t zf*C^T67nsD9VQc1iu_7{BltcTu-d?|lyR;#n8 z(@p|d^2347F3$?|`fZubZ>nSA!&+5dA(zrGiF$YTrC!y_)15M)Oz%W)4yB(DqI(6M zFpEeT_9iJ6eAnZ=DBfv!h$%F?j&HR++H9WrjXRVBfo@Sj8bs;4_rKUiXWui8|LDk@@gUjrdORuvPjMo7M!1+y=sM-_ zfwc$9dVIo`^Yxd1H1b1dKs~MrG9DMoD8&IlHKFf1U@Z!yor%|280=9KQvH3#pBwtZ zxN{q_$@YPBtL?V95hb=58gPVSWX!snZ)+De$?%Yc`V_JIjPIti*+Tc(!1LIX@Ry)K z!hxZ@`R_zXfkD%C$Ru`kAr>EUH@YpNqF(_vjrCqD;P5N0nUW7j@}ihOg}NzikY~9s z`Xx`NmZj|T6g@T}V*!`9WYk$6u?kT|+*1~(B_(vo6!nGL6an_tIc+9En&6!&(lKc| z?~>KD$R9A@R=;8x(x0F$Mj?VEL<2EYE%{K1V?W&iw=wpC4n>F%9o$!}4D7X%yY7-M zJzzPE&Ta&fR(KiRIEpwyym!E-{bJgK)TMfLBtJ!_PF%yQJ1yM_1LeWX%*fW2Nms-b z*T}2FJJ3WKkDH;114@5IEI?)XXNTrEUDlq=tL=ADUGE5^0J?Gwan?}ydh|Wcg_C%6 zmL80F;?lP>E%~ps+M2PJ>yY+~cfu=i_-y1}zo5DFVPEuv&^wEjG>D$MD}Ar*gJNU=LCog`tYI(TS3z^JdF{>Ux*Otw=+T2kSO|ts z-D-`OM(Y)++&It17TTzJYoS?*0=mBQ<6psHy(n)EO@) zIuk2FkLJy~)8%g9s^G*Mn~VcS=#&z3NGWob;>zms_d4SbIj@xiaFKYq!@Dnl*I1?l zYuQ(Q*bUvugHVT9LE+*4W;2N8`Rv!~o@VXo5Ttm&-C10GQE!WJ8XS&jd4C&!%h9Mp zGOY5u5y_1hptG014o;lh|4Je}NDEz_qU+rIZ_%7b^M$dv$NXzdDu`D0LDN4fYP zhdVU@8$79&^DQ2;YA*V6$}zGkr$y#To6JHBQjBg&fs$siMmOZy z2+;#B?=z3%4k3Ba+76kff`t9vz00K`9{}H~i%D&IQohr#=fqFvaLbDOQ7v2-$380O z6^`hPv^))SU3p>Jv1a8f=y8;C*c?6Kqc!#YANT5n37Pil5NEBgb3^Iub*BmJamb`j z*}8*%mut@|T0ZEUj>i?S_k^pmUW6eO99`uE_*nZpI#U_902|%*v5Sw^WP=2cz3G=p zh-n#ZZBDoJ+x#-n|H4dD5*d?4!L~jKwV=TmT{i`e`#>{O61f6ffEFK;hp$@YaY|(P zy_O6LU?14X3ceQ(?*xtbkh?~%VRnrl`z}}Jukf*{+HoG8-oH>c;vd*IHrGTFG zEa@8w$=91yQR9CLkR*oWNx8ORq`yv(?Pni(JvDnEC<3F438~C(t%~c0oJK!DSN+Vm zG_Bwi(-MAL3t{$nA<7E@2M@S+^IqtYuZH_2xsCix@0p~DiU*;`RZW-Ip38Q!uvU*~ z|Ma~OyZ*UuG)3)TIkEcOc%vm|BRL>9L65VXNxc5$>_|EJ%jRx)&V zQL=@&L`3JZq_4{NOZ20zx1BE}7M;+ln86-w)_{~ds7mz9B0Y*;l@0p~oHqABPJ@<&$y|X>vnfRq79GVvob}ZDKD#-F znf5Lss-Dqm^IJ&j1mDNICkNGy1#1KQ6Tk2Al8n4Jpy81c({V(XDbGc(ELgs%B%W`~ zsxG{bFf1^$KQ`gWj=c9i(YbPCq7wcZ>GN~qVLv+YA|cv7Xf;MWt<%%&RppLyt7s+R zg)-?=Jy0{pxUmnT0((y~*WrBvg2?Z@%<(Zhs(aG}_LY|X$B9k%52T%o{{VW?R!Erx z>al3g*awpBmBpHddzdV66GAER=!zg^cPo0LbKExy@u~$!2pP zp?G*tP%HE72PkttI&&2V;F>nw&komrv+yjfPG>KKYdHf3FmJKoQ{{4bI#>r2U;L+n zb_ZK4gJ~v-BX+$7A!QC@xyrf z4*A8U)~SKrXg-Zg^MzWO#OCN@UPY8B;#k&E%VA)Tlr|=$-Qr`WOdgu+g&`nDGnN>y z_H|#7^6hsPxaSGzj1G!etwsdUu20A|TKe|!vFPoJFa9i(_UVmcu9h$rMD*lB^k9vS z#=vV>PHG@d8_t_H6~_>pOSKc6E3*9*MzQAPO%^;YXo)HzNK?N{_rDv6C=LITTgnf3 zuq*PL1ecdN_E#|e3o~KMi-0x;Zszf6%RlH>7QbQ78#6qSS^5Wz z-suFMKoT7;oWZtAt|nfg3LgEx*n97|CbO+=7-x<;V`Ch|0s^BB zqSR3kG_`YPqzWcC6HO`Kqh{*$T%B?)_CI={t!TxP<;9u+5j>&fYxH zYNXUw9_<8Bw!aE#?pzMi@)qvO0UHs$&du%ir08k%oe#6}Tk(G=+y4;M|5_Fx)vKGI zS$GrxvIMwcA2vuQ+*8V8Q$l(``9bT}kI)aK9%erp6OdeRu6iR}s>XkUJEA^c-H;p0&UKhv=B1IGZ83z>Yz1!OV)oyYQ~ zaH`DdOA9wf^UXK|eJd`4;D?LrNGrS}MD{%(thD&~nZg!VO{(1jcvsI3SZT)6deg$u z2r%f2vrAPrRy%ijzE6Z~2H*RT^awSG6z?HOfE7CW_AiiwA^I;Myf;`@QcwvNP z!Q<8ArgRW0^Jiq$wQsw2_=g{;XGDGv3^ACyM}*5-3xfHUO&>Bh3qDnt-wuy`_yJeD z-5+LW9csHwe#p5V$cO0zqc0D;yXV6XxN}FIf5_rc(H2H4q4~WZ(>yEWBDttdmG84P z;iMhwKTPHE+=hrL36t^|nSB0S)0y7zOIMmd{J>!CQTGpT3XwB2;XTSne#{AlJagW- z@8pLc7+!4ne%uE)NpRw8ndwX zlXIR9ge(@@pKboG-~Y=@-WMsl_5CANSJf!%00FWG=~DEkWy}tjQTp!r-U|Hgi>4pe zyxjVd@b4;v%0FDB1DyG3Rh=sKZn-v7@%M&M)bWErHd}+JhldJa#J?;d80m-r zHHNfhU!VBzK7-yCnV8hCqQ8@;8 zu4WQ0)7}5Q&8{M3GtxZ1mRt866Y{R}=E;o`HX{cmCIxxZg7ul1)?VBrLJVa^h#Y3i zzqh4>%RJU{2pYk}Q&r198)5?q_CrCk%jJp^m9zVVMroU()ckU9HFD=vYSkQyeVC?X zZIpt)8pEWL=gekPDpyeUgadwzGsO%WKl*+9VjbvB>ZYI6HJo!B6lNA9Lp_i`7PtjY zih?#am6PcK>+q)7O?_LT;)iA-NW;y2W`q_Jc8gSW+B5FB`SRRbk9OuCx#Im*3o}+y z@;wV}W%y0F=FS!EE|{yCt7<{#Cr{Ds9;Pi|@i%tT_XQi?yOrz&nS$@A;iPqITmYT^ z$#I<;an13(Nu7FlKCde@Zr`~k#UY&;HtYC`J5_V ztItj;P%WRf%^lvoCnIAC9S`{d(Ws+8=v845>4V}Hy>$#qeMb?hnPjl4hm{bqvAMx- zO?(mCkg{3$?7p#kb~(CC8x3CR_b2cvKKbz(F);{i%6-xn=lM^r>4 zynOG+^2Rqj5x@>(jtf|UjMOJjb-rHMLx68|?>g7*qV3@NZP8%786IV>GzZjopp4dE z52yDn`QfS-tA~B1VW*y^(}G^iBAiK6V8)-e3#BwEK~jFz$SE_P zqk7uT&c;{G_c@GV>P0@eMKHCFf4ipTo_6ec{s$lGRQXc+nrj98r{}#Vzj(=Rcdgy; zE&mwNO+(zY@U0XRLvQ0N_zV8gmbXhTZ>@M0aVh~CS4FBbtG+ur8G<8;;83O z`(4(F8pSoAo>XA&JeTaMS4%on6=s(CICLL8&gXg-6hf^eJU+QkpXd?qgQGf3&6YCE z-2_iIWlnZI)lVES8~!)PYnE+Cej<>n&3<~ii7>F4lbzXpES;;L)j1$Q3)*%bt|~XD zd^cjouj{*N)v~PaHG4US&vi|DqeS!xgz5^arzKFk{ZR=~owx8mBZU;HZ1u@2JIIXc zy0Fh<>8`xuxV+ANZKe%@KA`tcSW3s?a8Xw(DtL)j1Fpv@@&R`)Ebwo5q{N7+`ac^A zu7cNX{fNMhSZ`g=_gFhC7gO%bWK{*2EickT0xnzowCqE=X2Gy`Sx;5v2CqIz#zna& z2A@qMp(@j3q7WhnZ8k{9suK1wtviQk7ldgwI&3!@&kj%0v`7B;RLvwXT=6IyKqfG}$?h z9TOl%9s2}~56pBv1K>nJY z7;u*9bvF&3KAEu72PR*WhE4a^utx04Q-g>$m6QLnqWwy)74#P+-m#u-oDersj`(up zX!^ndZY`4;9$U8%8VB_{sBrX6R4FYhm}bh{Sh%0%T&yt=vrkncz{l~(YokeP%|Pp7 zXzw8B`Mw$(3Uaoeby3Lk+v7LkHDIK$As}{kaP_XeO8|#d6XNjpU2LsNr6!VdhG)S^ z6~(Y|e(ehVv}|0!io#}yfsz4Sp2yljf?WbK-@lbC6d-dOxZw7}(k(aZ1vLjTRbZ3( z7Y8w%n}`Npvkl;ja=IU&Egu&>((9Y>F)HmUH}{yk%~aoNsh^{iS~U@5E8s$C`6=^d zzWjPc<~+~=p!o19SdpN>NV!*RpZDH>C%36St0Tk+$yE_f%v;XsN>@Ivmy}y=s+jZ^ z`%pq+1_G=c54|283c#|BLwpBI^ivEXl@xf9u`%jW%3Htn zC6|L$9%9{?Rk4FA{cdV2W0^I0yHdEj!%2z(^qAV}+bd8m;EQ%oJ!sCA6C6Uq9gkR1 z(I5SfGa2U5cBm-|spK+LOU8JC+)n0+#2a0s&nW)ROgT5d*8b6enaasmh=jZkQ3>DH zcj!T7#yWTHEQ049*y%+lKO@c#7MHO0=F7aE;&drzw6ZGf$|s@z-3Edz0HlFA^_FgY z!jd+h`sFmO5y$ZrnIPtL=iQBE-#ck{*em69*lIQ0zwTE2hFPbOrW&735nKrUIO!hb zmyzre2S3-&8dW8Io4wMEo#%8y!?Ovg+F~LcFJ1q2O=!%l?apJ!r&F6Y1!-i99kpDS z%#19md(5t4zOzxCaTx#Wq=TIMsy8Pou?AXzQscGf-qi7#NP>p^ys8p`d)3^eI`gt+ zr5ZPPnp9!1v1SGxy*$tJ31lWzNo!5Jk~KI^ElL$e|3)#^wOz->C&4u!x$WsnDDwjX}jqE;thQ)saHzRHv?k zR$OWep%R;M{vDF(b6HTU>Dg4>mmNlfYWx&9`*vKDOoaT&aiV=_<+ouS%j=A)oON!f zJS*NHvn8o`i3W112o|$no88i(q}#coI5Rk#I+C4T;`_-6g+272$`e9umJDE&Co)Rz z5DYbg3gi-Ro{;mYx3ZC!v~{*k^lTAQV2-%9iQzFFS1->|pB|d^GcJldF1B^{X9aAO zDNSS^JKeT-26i_l_Px>nJ2B{G0u@U*;abIZPH#9s(=V!f`$h%et7FS6^7DC7Jp6|eA=(6Ikcv1l7!l7V(- zm!4ML?G#8~CB1x*8OVrK(L+}))+iKXe|#pdnjPRVHfrzjVSTv<8#!%I4aJHvVc0EVg!h;7s@t?c=z#GwIZcm;SPK%rMB-E{`7A9c{67BCADS zL&D+HQSu6=*d%z0!8+vS>ZKdz3NHSx5XXuCA_!KFZsiT9mas*ycA~a(lD0(vwMCPX zL9$LAccs(=dFHViet@A6P**+#8!k3Fi`rO3xNMoa+Nl^i+a>C6{}(R=wzTDAuRXDl zJzX%pOhw5#y{hW?8L#0~RY8@JnNJ{nC)Tc^U1i8cf+YQwCr1um*or;Qh@>oLyzM){ zxv+W0Wh42yGPBJQs}@JUat?ZX#%>Q5Ry0#)G&SE`N%Qb~+~CDGhu`x<^lwpiO52|FXZ(nU(0{XLI2g^OH|+PygLTDr=X`Qrr(wAATCN~ zm;I)sm-xtY^pW}}F5oBfdJtK$#UP+#2E6Jj?E{CzN5|a(OdX2o78~srri91qA=Krj zb_H_0j|ezwx&E5$uC%hz*BPq20I32(JrKx1!2KCz&8qAE5c#V`!iTVEmzYOWb3_fR z$`og~L{Lvf4O@>Awv4%Fr~`GY@aQ>nSDS&bi&9e1nBJ{g1frTQb-9v;Kk+c{4{R2q zG1T=D3ZsiE^~9J&;YCGmu6rkKa;^Eg1zl0T=!E zs0`V?A7b31ztM5zFHUCe-ag#MG>8Uv@&-=tfEN2^M|2q(ZCq5gFB<3TK1%aEr(ZdR z;ZFO4432Wh$#*d9QH8Y6x@V55ANo#OcVe#mTq5W!4JJ1U3OOjcRY2x-7j z^h3&q-so*sXU7dCtFeqK*^R9IIX5|#@ZZK8*YKI0-VDO!<5cvc)7T%RrxOnsQbX`3 zYY)u6VyBicjK93b7$1oW;tZtyW?v{^2;U`FFiNyP@qobHiT)d73aFr0=)bWXRSihYPCe z1M}*XiM!hx<9`<=J~4@T5ih!)&!t&J8bq#5CtTl4+e`h~fRpW%k<+T$!Ww!PsLE$? zPLMPfnwZO@W~29I{r%s*j}++5<0^Kn6bz#vI5;s)Lhs36Ss z0wUlND{ZY5`zFG?H8&n|gcx;G?)jgW40ok@g+bA@Cru#Ex?>)ptQDx%_X zf$zGc3`G&=T|ySTrhO&(kYF8wa5Yz{y?8K~^Be>l_8q024#|#9@X&)QTljHlNw1}k zW#EKj8jaCkYQKlyM+G9M_c=nMH)rd=u!Y(UE3*i}JbbB-EA$eF5jV!NlV zbn-^C-;DUu+rD9O{|R7G3PXgxl z7S)v!AmbzN+XpwEx^{F_2pUzcTj|k#CVk6&G>YzcuKP?JCN4H)adf!TsLSu&6J4J4 zCb99}DmRp`LDZj*#hQy-2ccU^q~CMt_brR=ytgQNm4FHXyli>J-z65nJP8jW!>_S$ z4Cd~bs=g}r2Ky*afO(_zH7Dik=lOs*a1i;sb;#s`J)ybM!&>J?MMdkSyirL*;-yT* zQ)i)fUh(O?shY*Cz8HNUROO#e>pvKlGO&1?RR%k%-i<^Cgsk+1sJqj$6Bk`8$G4NV zBfs))AER-w*A`Q^7Xk5{xhH&|PhRehY2NkW(W389)OW$g9CkHj1GPhzqRhNCL031Q~LWXLc2F~K;sO>P(fl~XXQ=$;L z1NXiIC1rr9x6_d?Ls%-2Z&`%}kjpX<_Rco0(rFYkpt<7R=hKNbvE=#E7c8+r;)_tO zEp^?fU-C>#sr)~pQJUYI@SH)A5CFrn6zziD-Oj!mtG-CJ0hbTe>z=UjAtP%tV>SFU z$Vt%DV}}a;I$*;fm-Q8sLT?7qLF8$b%HHgBr;O{o;+fee-Vm!o0ExQuW|vhoLR^US z*ZG=MU|_AUScj)7%KX$ht}7L6j_QF+rLPx)(K%h zql{9gzxwANR-O6gfqhIVd!U>g8 zGw2P_If5GnN;djz;8oP-eX(f#g%i19u`>Bz@qm8^sr`d}Q?Dww9o8H39a*Oy87%v< zK68F}Q1J9ait#I^_@96K1PZM5J~dTjGA(5FQKps(QDdRocs;L< zni1&_V*V#$&@$>5y!Vj}{U>GtYHB^-YsVzJPt^+X{XHqTj6>YvMjh{5uEL1Y61)U| z^m?YK8N8H7k-VukgefdFwe{fxv2q|4>ptcVXdCwGQZdi}O_#0$gY4NVhk+*|Di4tD z>roAzW9@FiUQ8^#sEjap;0sXu@2BlPyRw4oigpVGpyX%Ho|{W;6HD9;Z6fJmPRy?I zc|P`ZY}yttmDk@t3+%=eAI}YYb_sBNS&wPIbgb;rn7wV-50j0^DNYHjnoJ9`#ph}) z9OUk9{kPT`C++*TS1f(7MsaB&B$bbj#C*#7&o*$yLKa_AY!Xr3Rg8?xb}PJ^T*9;JtL}b}pA=#9eLycV!N9q=wA~Nyddzp~ zkUYlb35L(`<$C|t)VUzjj0R* zT83?cd^aMQj>wbjJLnE*76UzJTRuZ4m8yf1E-LgIjaJz*p_vvAfmn0D4mAFSjVD7W zUS=0GaX#@$6MWr)J7Fa#fxXM;!0EqAzFWo06u4d;3L2|D zH$mA&cH1L|31OvLz1){+&HJOKDd(=|+WDRO+!iyDODfN!K>USX^JkHilWwoHAm!wNpAg$KRZF> z;=7_7H5X%c+}J)^Id*4~wCK7t+jc)knHK0hi+v^y;uhjtKwDH>qPFsTt10%HskC}C zGWNx)b!kA)XecCyJDb~skj(5wJ;J9<8(*06QIqk0m=PL&Bl79h>Jhl>=So%C zJ*veUTgR&bYm|26t`PF~f7NZ(;&M=QofRLuV0A(+a}XI9^p8f@DIM@ zsp#Jb7XZF3F|8DB`;N~clxloZIS2!3LW!)}3Q>n5GnhjuOOJe2XAcvJCu&2!0lcZTh+2VjC{?R9RTTb_vX8M4} zUyF`8EVAA4Y9gq4?S}yNwMQpb=&;=H#Om(6p7P`tD6=KyF&_(nW~t z(h;SZ0x@C9sd;yNsmn(h)4%vUup=WCYAg61&<3uDv;cEKP<{LS`=)R)ueL+pOJxvN zn_^Q=%6Xkek0vn{s)-Twm1LszVd^h@o3{=n>AJfU$Tlo<{>9n2?TA z18DW+qEH?m`|K95VYz!zIn?QB&|Rq;qu|FS4QU)gX(98`9~EUUmfW>~49J7Dr&s3_ z;qqO<26LCcUGuBNr&xXx>ij7dNXaLRlotoVnJdf?-Xq0JMBhm2wvG$iXi5Ojc>{aC zM9q}SLDCDK5iy^L*nja+x=i%D?p%!?ZkZ;xEJ=QAIp|2XNLijxiQQ~73dC6 z84Tt!gjhueyZXE@d<`QKsP3ONdLNET zp*{&_lu>pVF%$`Ir}xRod;~PVyM5pMAw)>NiF@OYFZ+nj{?#Km4w2i9y6^E~?T&c^ z4bBy=?`E>|XtY~kCga9qB*?(SsqN2<|GkC!8MQq!r|eja>desqWt}NxaRB*I<{00Q z5e82GTR#oRiBFove{p)tfdYJ&Fm~8`$9q8h@Drf<7Y_hPkf!6-`V8c1IR+TN)%wVV z^T#%2h5;Inh1%t41uHyh($D+h{<`G|yBRT$iLEsO;@Dg^AX=%FjznnSNEB#1x|mVw zu@J~n8`D_f7_#NDs~MC4%{dC?MXuOjz>FTkA$D_o*b_A zJQ>7nGhacYv~LrK=2f^0;sI}Q6oR3KNY2qzrsnEtCSMj%1SoxP5y|8ssk((X zH&o@1;V`j9{&AhzqD95 zwt9WEDQ7mNnA85YdD`gs>JA@nLn*Dt(I3}T%e7#dv)`Gj+RlTdGP%P)o>ipomSIEc z%b6YYLPzH$;zobdM=S;n z4Tb4A;C0-Vy86*hN7N_BdG4`dQspbjAsY&HI+a-7aN87!$XR^newD$6H?IQQPl##3 z=lCKE13@qMG?nttoMR}>wTk+}{N5 zOXm0}@oY*ADth9tlX_+uWVn)#3XR~_i~qo%DsgX)^7E}nSz4?D9$j{m zdQJzdbImu~`~YFsW=+4vq!-HfCTDLl#kVaN^PW?_2dx?_9Yqp(oJgr09?0T^f%u31 zG|r!&5C~@=!kd~Xv)7NWZ}yR>EC$LDs@|4FlBQ>yg=*j33`N~8zn2JC(a-F1FP1O@ zqBjN#grPM+{qnvE?7)_&c;e&2#!8?jU?{0XeuZjWwU`jL&G2t-+l1e+Vm4`^*1C$E zhirV5*I{>Fdb$de5fiHh8Lcmu15wC11MWMR_cBP8<`sRH;FG?rOtFQKzdM^FOL4BW8 zQ0I*g{3)?o(NR3RObyW@-4|?TX_(5JAgqV3JTALRiV2}Id|nHOvdvM}t`Fmhw1u1z zY;FiLsW=l?NwIw@)5WSDyTw|EQpBQ@AdO0><^L+l7^2d5{ zM^yz+AcBE1`|V>HHvY8i8r7MKdIPV4ufPYkhbsP~AI7dG=xx7S-RiUYJ4T44th4|c zUSCf~X*ua-ao|h^JLZK~=363WNc=5#Ffx8t*%)bnwt7| zrutE<#`tY5P9LvlY~T(=ac`P-mK`%O!;Yka%D$75UBZ(IaN8)?SO&6ip&E#VN7qty z)-DGwo6evQ*l6fMTPqgJ5fis?hx4K#I3)#FOY99ZapV=gL?W!td%vxdjQ@)@P!oJ8 z?#;}cTIPK+1NPDdYYWS`W zyWXAf{OfHB$E6zTQ-E`cXuRpdw;&Q5mLse(+2euY|h|EpY7qU!6*Z% zY~A1U9%;%+mpo}^=IkjC3qlrDD4yu{%V?Tg)CXm1{(8kSnkgsocfDVMsIYUJ3TiiM zy9M%Fe;Ar~@u3tmzGL$vmJ<1aW!-rns8m+xsPtRtRn$>d|dPP=9ozXXH`eL`Zr|-5B+kmPb+nlXrqdIY?fA zQfysmG|tu?CF+OpnlVhRXzib$%#PVbHmN!|JG~J-`cYr2*rhIyD2@co$J1wgvVF@& zP>W}EUnbvGawhnvkay6Kqn$Y9iE5AuGC=Fna(Wv5O&8&|GJGZb@pvAIplq!kA5cm~h<1mP~G31tufq36Mu- zb}74xOK@<;4T}4^58l&BjP-=G;9Be%cZTwfuV=_q4?BzQyLrS(ZATqL#U&tDDH=`K zdw%`P!bu4Vx09W$`Ys;${#z(*QNh8v&fiQWT(RmBAJqy6I@D!wn!M#HuFWZ|NjE_2 zecV@48kcgbK4$XY<7l$<7PW=v?hjNVAUpYp&9E8Ycn*>92W0;sS`5|W(NDX%z}HG& z+7NdJAN3%+q?lv8zHQ@T$cuh2Tz(GW#G*gj79<4`-+Rgn_Nf0QENb(bpKr&lL9&b8a?W3h<_Ir0QM>)g#y z`Ym^Fko}+l3RAh_;4@b$Bd6-_*CtK4BES@VTfTKHN3(t7(3D^a@?d^{&XbqHaYTcS zeiRLS3iX-?n+58cK>5UVuNTQz~A#QOFgu zY>~rqZ7tw zTlu91>DfRlA36Tl6Srn?Jarp+&|)p+URU%3Ld-g0FVl*?pdZdA#&%`<4+b4Za8PJ+ z25=WTe*_m62keaBzyZm|TexX=HsN%cG$@E&_#L%PUL?4ASKlW2jR_Rz6VS_4hyJNe zr&W(4*4>Cq85;7fw+>-9pr1+^5j4OphjPc98CqV zy!(ybEtV}$w;r>jW}$CAyY$^{PU(HmmGz6_DH!?LEb7Fde&Qu8K=KmkRKL7wJ6(S49Xhlr)%kANN>`FtZqPEi)Ef?w zJH@hnoiPJT*Gt&}h|#I9>Cnrg>nfPeLt6qK7!9gR?k;c5%m|V_|K$15e(ZAm1`^Fn z?rDh~q->vpKb{B{YE_VZqc<*(fqr~D#q9M}ezh^1XhY0XhDlvtWy-57%ZW50wc9{_ zbDdB3T7a^1Y6NvBzuA)QCLQKdTBOIL^}<~HT&48=+tn>hA9fYs^##prt*6fTY$CAhx9|Tae32H9AeN#F)voLr(_g2+< zZE>5kv}988t~TS<-Jl27Mr8BY+8}k_`w-I`4i4C;#zJU|!Ulw;Y{Flm#64Q-&whiT z@Vpzh(xu_;Pc4Xa)?{B>F%1+aYo4sD?NeZ}CbydRyOCh&FUwOE+INUAPrOo?Aba%! zw$n%y=5X&<3`=2I5l$3vW%pz z<7PS}9}do+#f1=x`$Yqve18IZv%({zIA}J!!(XjzkYtbgEX3bo?S9;iFCut#S4SL{ z=Jn4KM4zi$R7Pw+m013Fxyip%(f8kF9sW)!-hZ3_`Ojnjn>6ZwCiy=*`S0a0{x=^W ze&gNG5eev@`~S;|Y<}(k|Cfr_GwYa=H-7p*b{(VxNbHC3kf33~`@d^fH(qrDU7Te= zJAn^>HvjqHKlAZ_+ji(b8oQg9OtFWG*{fGDL!OQ*c@XXfgs_JO_`RS{jyAzy!8R#c zj%BiEXE<)W95%SJoUZP@=uso3QCh=Z!IL|=bDol9i&-*m z%L?8iMx?74)7}=hTHdweq~aCM6MwrPI&*&2k3Bg+lY6NxOYc@OTqRKYV*DE}YKZ%C zz@2i*E{#{G;wOyjZMY)voC_jS>_S4!PIPqZ6eV%F0A+iI!D{2K8WI|o$P3Pdr#=KB z{nqF>LhbWtg`uOc5Y;UL0uSsC7z-VaurdN&MjDMgst-!1R?MC~dr&wuN1cauTs|r% zoQI9bLE+d1CO1|RffmU)MP2%ABMcti=f~3x@tdM^S_D&*D{o0#1)-uk=^=qlum;>+ zOVP>#=ZqL-WKkteCk39A@OhY(x5gKyg<`iv%(^ah?oG{|SaIv>;SW%>jUAi1MNWz} z-nRl(wVhgTS1pMa$14s6XZhfn%T|9GZr;J^<+l{o^>sfWM<>r-=mRxyuEK*8?GAKw z2gE3jxl(WHy}Ta`3t?o0fnV~;Ohm#>9BX)2>xdlItF|&d-LtH`;i8~uWrFqCoXEE2 zjVQIqz|?H*aZ^~Yp?Yepkh&j33lwQkOZY8l()IM454dUp5shdrrX=%a zn$+!mH`Au(Z{5oj-K6=@;!u5jBa8e5FS?vu zg{HK5x?L}rW1oUVX1|9lc9-hB6 znI0Na$L`Mcxlz~1S|Jsc6YibwUC`TTBUH0Z_{F@lrwT<4>yKJmTQYGhHu&o9VijKV zk8b>eKD$3A2{ISLkmt3`SDdi%u*4%o>Q(Z*C6gN(B4MdNaXU8cQq#buR&?Xu3B^8# z6S)UBr2a!Y2ev*5VOx;mwr@3f2A#aOZfFSk#cC>pD zXV&|Ww~6n<`^Zz2dyB4=6~*Z{80bK+#UCyNUHMyyHD*W=>i+(0>R|`Y(M|`8oFm(h zq~$3SWTWFksL2>aNS zYPB$1&%G{KJ3@@lp}U;oE8V4&<=sZ-LKP^7sq^jx=dK3&@ih?`d<9Hw(6XzS?mHU&ei z!SK8;x?WkcX!G|1*9N}bgH6J>vgc(6j$c}l)U;X-gY~T)5lP7=?9H7lI#|-J(z8G+b!X0;r0ApVVh7pt^qxNDg#Ko6fk8b9%hO64@y$vRe(7t4=B`U$34KfC_5$LoG2Uw zQO_%tbD$wwwUyPzT8+d7PwmZK2uLa}%t8!pMJ7}%f=3@ak(7MLXfOhxUS)&45(59x zTamk>i3Ommq-|O7g@;4dn3iV-s(afyuORlBs~ET%6_?S@tKkE=cS~El`474j>QzWjJK3jyuALkF5wYc4oZ?(;V%U#xBEuh;E%SUI9 z7vVt}0x5Wo7%4I&sD%Q8IzjjZyq9g)uo?}l#w;=Cp#Br@G+@NATVHpBPUvRaKp3@i zDcjMwb{Wf4I|OFc*y@*roV|XaT_9t$NNeZ{7?;-XJA@^4Rodh_$F0tGD%7(UpOhFh zIv#VXLg0nqjaLgn14e5?b{it^37YXV5oQ(n057j9M?9sn>Vw|{pOAA3V5Y_-yxuyBQjB;8s`v!Znz_kUT&u>|R?Ot=& z=iIAhYC6~7(3aOpA@~d_Q_;;V1-u4+B_(D%xv{aC5;=$#9J$%paMe0s?fY_&jjePT>J?$QK^> zvjNBoKi`4d@`EtXnlzYb$4*%G{z-p1itr)V>64EQ#RN-$5`M%m)UG1}4Q3jEa6h9l( z!pdM<@l~6iYN={B0fBO)j=%!eoC&gQv?)FQUh3fY6YOY`i>SVk~;k$(DH7|go*(%WaOzW z=c(^o!{93Rt0sI&A}^wot5kTvn!8LJ%5H^@&ts9wu^E1ykZIyEZ1HJ$a<7nFu0-H$ zLPwVl%Z!`s)V7qG1J&#)V7V^AiCI{R_@tjE**R(P*gQZPJ5#jd{OqbyG*K&NL}euJ zVZbV>ZdXh(jtZ^iobyGf`OESBemH!xXM9pSMH$R_`4`Vp5aX7{PCd6uTL=aq4W4p= zCcfoREb}OQWEM@$N(p=-pnl*7aS%@Mcj!8}Nucri)0PP1H6^WM6iDnDAKW z4If8XPFHI-$u_t`jn-n&(Hmj`9GQK=TS(>y2AfH=g~uH`CCtyZ{))=U$@I3AheT?# z<&2ImsP1s1lX+cs;-ZF~+*xoWcgga&t8az`C5)keP>Of9>tLgd%kjm$rpIsmn7YBe z1`79!?0D6aZbW5COTl^UuQg||6Nk3M4tnbMDQXcqvO6wYflEN^0v7zz8*q-*ftF>- z3+iNWtp(y3vQiz#3eG9MYLs^J>EpgsTpHx)He`HuB89M+$K90O85DN8sWq<8RtXbL zXZ=bJUWZ2^5a?{#C9h0$a1Rp$}cG06ew7PG@avedyc`Pt6CU6X1HG_gxjl#5ngaHsaAR96$w1h!w? znSw{x9A?NyAjn?em74of@oB_K_+I3;EZEe}JM-m%+?R1KDOxED|HTVv^_<`1Y9>u> zr1s%Cqp;31_%zK_LblH3d70t)Ln~Od9L$}Et5ZIyqTvep&l5163i&poQbA(a0{tZm zh<=}klFW*T6*E-cC*FJS{Ty{VE0-Wk7O*Wol#^o*O-6|43O^t$6gYr7TGaZo)Lr+I zkx8yVRqik#4rQPpEO<4e?qjI@mB2kXE#cKwc09+%K!Gu4@oMs9i&~nf>q z{c^^qPAgnJ%v3;SqJ1Yebd+sJnYc$A?NJVrW&8q*OCE7J(@wWA5uF5vaHG9`Orn7? z(__g(2)QY~C{!X-m-4E6n}lTGE&w~JmAr%n^sQkHjxdSccbhQzYx6U$plh1KRWZJT~zQmN<*2h zgk1Og^tO(rM=t|umh2;SU9PNTw0z@BhhS~}>h;&e-MpCJOQD)zTCQZ3y$%TmznmG8 zl2h%=X)I_(0GO}bx>x}!-y?$=Ww;^G2-xM-B={G81QYZn5PTw8gTbEnI{34c-2S|4 z*`g%|&gRAlC+Y1|_oNSDujuAo>mK|FJu%Mu+j^p`J7~1J!^N4FeBg?2V_hNePYoO^Vek7i-e1vc8iA z#m47o!o|S|ExeT5(0%t(K#Gpqr$Ju^FsVU1(6tR~4Z`}~9bbHq|2%y`f)W5du$B>p z!*&!8*>F!ckkCi-so@R!YpX6q8W1AFmQ0aR8|w8{3WRI+3%}GwNtZj>HWk3P**Ik9 zQ6Eq`%!=8yn(x>`aHmw2`?ka!TJTnmr2BR}I{?5(#t1L@#fs9p(VLiR!ZItOuOr+|kG zD-V%=2Hf5Ev}zYGOuF$GV#Le7cO0NrOzl^$C3`Os1jkD8Hyk31$acmLP~}t;W7%$n zVV1!Ttwf=&qow^19TY*Z%cHgX36q_Ftq~85ia=%K(vv6KLEEs{1e>M7rL}(kC#U5h za=$WvFzzIjr*yoV2XVO%^&RbmhazOkA3ZB^ab5G!wmJC~N0V@~QRDo2vUz-5*I#&kLM9buN0L-@V z1+x_hu57TX+iC7`8ufF=cTZQ%ww~3pR0&me8+C6Y_jb`w{jiHecbfLp-NxU#S5@X7`cj< zUFXu2)TGvG!b)}(3iV^~G*Jfa^Q5*=qMUs|l+zIYf?aDt+R4Ls=QQN1l40oz8h>lP zTu)UrtM{pfii3?j@QCy;fvP}pqGmSVe*7Q$K!=6a_lgq6QSFOMHP4 zabSOu82IOF3qO6{wgMNoBFcPhhHU#942u_vbx)L6&hO-Zr|0Kyz7rIJJV$M;F(e0a z-qeZ_W+Z`Q5x5xi#V>>Z1pimjm-+wC2mhIm|JmE&|6ro$hduu@AAV)Fat2EW?Z7|$ z$y$8|F&{plTKXbOBMi`@EIgGXgJDo00{x%x{#tz0BbV@R$wpdT68z}RHWYcv}a)VcuW{?wCVakWHI z%`UI(QI|2VNvuV!elfU)&)n88TTJ2nT{Q{Au+x3s$z9cLU1r;l3>{(CWWw;On>#Vb zbW4#$NDgkTN~+iLY!eBlWHftW6nmAFkdT%$(BRoUX+betJ5z0AP^>87MuceMq3|88 z#@N6Wn?g1`H>K7UIBVn=XW^p1v@kPM#dM8S&9LK$2hDfZz)6_R8?2&sR=%o zRC69jDWk7u1{n&YC8C)DLtOuxyFG8ItNyNJI3v5o{PFAD^g86a6B@2lk3zR3@041x znj7iW*6`^bpF+8J?Hg*~_9&5;krO${%YX(iUyzwr z4igi8O`bP7;K|sxA{_`+OQ@ZOYYUQJVmAbFeiP<)&7PNd_k4XLajNUrqQ_4r&o+^o zCliViivxm+Zux?8&KP~o{DZ4~o~*s)@Ez(yWo?EnvV@MsNuohOu~y<_OA}$&@5Cb3 zFc3xkfeNRVR@Zbt)HgY)H5*7gQd}H4-VZwYWN130Fs;VQ8HBxXq4uW~h07^_6A-X6 z|9sq^_hy{H$V}(|z$6+POaGGBF+-e0)CBspY!hA}c+dEmba*C~7^VLvW|*0nRoOezp-&5`IaXuL}fm>@h`mSudnRcTP|jImTGbq9@e6v90o zn-?k_qDMbPYkPEl%>{HIK~awAXmy2o`Iz?wwB0-ueugxD5U|LX6BdHEl71Bs=*NEH znJ@`m#fv0L)_hi+!BaxYxcMvTA}lNmZk;Z@eS-2fTqSCA-;ov5-}IV>LU=1pL~7gm z&4xF%{EHBS(Sb8pW$oBYmxs^OwSr-y!k0%kCtl^>X;-S%?gI<%9yYn>bKrhXI`Tjl zt9C@V_<>{QC4&6sY~0Od&x;}ojCgl37k%hD80WtHp#%u1bA6&fG{Wmq{({FnpY_CeVt!n>E?w0CgKi5A`vS=sF z=zJCB*}#5MusFytwSUEdIaj`Yxe*RDdjupSm-A-5rekjI^%7@hMMjFNK?)diKKi%B zA;l9WcY2DG370rYKhf;(rpjo@i*g2AEox^LDqm)Ah$te1ds^=JO;jmqN-rji)%~QP zf0BO3)rB#0EZyKbzkQ+$B*u!3POVh@eK1ML>51Z zQe#|&;B7stJD0MGJz;A5fUs)|ZB)8@qV9yb)b9|3C5!kSHY#(K+4OO`ZJNw#v>)xtdN*>_^5y#)m=M^`T174wiOt(v;m!jcgxH(uRpn;7hqf#h8Ng#|~sdG@OMJbAyI?xy@dP1u;7F9*5DF{Mat&T!b^UzjIHC4?)Xca{z zl|+I_DJ2p^N;7}^TKBG-l|PbqWxvnf&-;6x{XEak{_V?D2(WeB zlv;HOg|PQz?j^a`Rw3zQb^D(J=pd&R5KqnfyYDJ*F6MgwM`UNio*yE_y25AHSI#sY zPGAN=4j*Djj59c#DF5$xT_Rf6T5#>tg5w?m)$=*Q^cdWw4;s|oT*_p-e?#Kd~gtp^8RfaQ-&bsnabK09u}JzI{0KL_QAm$ zid$-}oCI*;>~o6+up+!-SET8wpo6g98w264+Kz>GScV(9(41S;fdhbn6#3xx<+KvR$}>*=Pxy*bsdfvr5(o@}6^Sd-=n z5FYVe*7^&?n^D>Sx~wZ=jh(~VNFX;}ude@9?Ag5V%=>@zLXkhP`vF+5NFIvxm#ar? z=erE5TOBz4G1i9LKb&(jwlRBug?u-4Mdt!|t80v>%+dhbvKAe}j6Sn*?}(5vn#&~UTcojr0} z($h1nfRbhwRgt{4kZ&$h8?e>w|NBb2&;hVT5cGhkx&xrlXs!8$9Q$8DLD1(`nKeHa zz*@#=`Ydu|at0v!01jaXs3}J8%Y|(QV*>3PnMmrz7$A^+e{sJGzOkoacy+eocnc=r zJAhK#mOpW^Z?Ky1$>;Y5YxrKJeFtYfb0|`to3Gte6aoXC~Ivc0I=S}u(JI}Tc207TzS+=sS}uA?`7r5-ZjHut+yXuvK<9dZm* z=-G$wh`TJ#i@+PPhXFdN{(qN^PF~ao(y7v{*$dA!NLFA5`VF^;7ECSe-{IdTX4}uI z+lX1Ohx2t?H-K`}egY1g_a0(M=)dIO!Y{}{87%g{*=Y>g4{jmy&jX|m+M$^*c-J}O zBkA5{6>-2CXHq?2kN~nj+y>UP0h*VizJLuB`wm8a0aQA*k@76+#Z1@Jv)zc)!yG9# z1!g_n$YU1I`0;g9g7w{mBy!L_L5>LolUsu*N4N>&EKai7$y(2ZFGLrC=w`nMOy=8HAQWlYk}b z+gO~;iZeR_DyQv}P5^d`b)QRN6TAuD*2|*E$-W`XY5dqvMj)HX zCCy<*pq0J&iTzu?pfdHs_4K=owLIy#oNkQp{Y5L8l@Y-Lr*`#W3Dd#)GGugqF&;4^ z0pxJg6>}Naz!FZOpD#P_<`Q{&v+G(nEb*ntu(eRn^?Zx$FFqNI3vA^|Qe%0AafcL; z;gUxr?t>!fQ)X#1z|R z`8T9t!xHJ(#s(jO9I96ck5M3Mh-U{M3=`!z%vCzCGwU&!l9a{7xrVSI+iPom1LK2` zFiSga&L>alrl`SnPowk8j<0%-S#`u+y);40wjTB$<9f}Uu9m(^^T0J+&+l=YIc`n3 z3bH5Z_f&!)>17kP-8M7Tk&_o8Q?If^Kym&*dA4g7dXibUQ&@*Mcd6Cod0Ct{f-?H* zG=;%lv|f`ba7ZxNuUCJf)w%&FgN%%r=(%u1&56YbClFt~h5mSuS1$Eric@!q4^RoF zhSZsk&z9f ziQdJ*<%k~dX}9(D#o0r)FngiguR6r8(`bG7?FNq{d*s88g`7fG?^e#tlJT;>=N0hK zospQ(s;XA?C^q(aOcRFSACYu)Z3Au1EA!pWYlZPz`q(Tikt~3uvE~}{K_|Sqp^rY#Ww1>5zh%4ukR~4eraNBB` zF1|<)BSGHtv)3{x>J~YO1$8U+ET06HXEYmg)#E_M-t`Y5R~LJaCy! zeB5hIo0C!;e^=(7I_P@I!s`&I$ln}4XudDJa<`1jIla=vD{W_gnY|xKH#iuix}9m# zMsE2>d8Mnthu=O6w10ZW4+>?rtp(glbWKH&22|_(PwG!yQ8+nxeA)Jf0~$^idIJ^K z(DeGiYF=L(TjsK&R6H7rwzbaXP%3NVMqr8(h)@gkbFliFhJgwgyl+yb3v@OLFYsbkb7|_k+}0X` zY`PxVS}a6_D8;F%bq=3&cAs*1S6{Vg8%eelQtLNEeaGO7xa{UQU-EY&O>Cw{J0f)V)ZwET^ z+l4txaS1)q+dj5{ZP0<<-hG!Vz0J3Zq=Oz1YFvBX{-lbY3gihT#5VCL zi%Qw46DRFFEDPgYLo;8i(iOTIQMYcPbWuWa2*jXx&4FJgWXswE{5#yz+**vo@{%OV zlbDA96#Gei)qU7#?1Uc6!qL9G0l0kyLDRYdE2ZsyZ%Wd`UsYQ<$dE2J^72grzNBU~ z#f@Br#JYUEf|9JONgw;B97UJ%TGLClT%Ht@A!xvy8tq=v8>mdYkIM-^R_51AU%QV{ zh5nwd;#M#FbY5jiSs-D`Udmu?6)&tY*f|%vB3F(+>4loR@3Py;5%+AWG5fh;b#0&E z&?#t|k?5L_9x_UyxexCK@`8Bva-HLF-RxCdW?%b6 zv#1d}JhRz{m8$L520kwiQ}5*Q@x zWp0ph7bF}+yMuE{FRCfCo|WB<&+8D%O?3|FM)1^OD`MH!hHIJ}ks zO*&diu*Q09k@reVyn1KWz98;?#y9+GMd`o_$bMbb9%iI!dCqilxDS7fU%l=24n8fz zzS{PYzK%xKRO6ZizKw8t~!jVNiGbS)#Y63 zdf?ctR^9eGnRE^e8%r{DodVq%x@kHWPDtDnG;OV%n&mvE9)i}}wt71D^g{~?F8rLF zPYQHRTEn7aPRz>g6%LarbS@#hV`a<^g7Rq#OMU)Cz&9qhG71g(OJ(+1U*+M(X$!|g z$S`_^Z>}n&R?bduQ0XYT;J`gixqwf>QYYl-xT$^pTq%3@vSi2fG}1V%S!a(JOtqXK zvIn)l+_S&o!RKjXr16&JXX(Ga@`86qJax{X<5mcXQg_rDyK-b_W|Y_UE|B@2nz+Y0tBh+dE4Fz<1A`EniNY>~LbtA*jnz7)=%N=KcP`u+sVj^~y_ zL!Ub7B?&wuh?bLmNaK^i##5G$I86C@o7JAf^8@5?GTkT98Fm&_@&_c(J6^Xr2mS%~ z2?CrD{;DTz)h2cY=Rep@^dz)~mL_o?1HK`dxipJG+zB+6`jB_jc6kTmj5o;i%SwCC zW2uxHN4JkX>V^KM+bY=M>|&`$cK4vdI^tTYGuj74o)rXYXt&eNBFvang9N9!Ujv-F zv`8-c2003fvNTPP6ZMO>Pk6;z0_BDiaLI40sIapG+|r6z-C41YeASN1;k3%Zi;jZX zr9{6k;f*1&iEAR)C`yZtd71sy!q)c6-ew|sa#~P^FryFZ2!EC#bbl|`6nTsvB0%<* zhB;vBas;*FYp89%L|}fMoVHMmfu6$bqb8~{QPTFLP}R{z<{MGByaiLdIbzPd2u0YX zBm;kpsk&YKivG(||wevDdsBO`14 zb1zFqTJmDKzo|dtRO3#s>pm$3P(q2UT1G;M3T`S5zBvAV?b!0Iv;$gL+2;imBxpb! z9DT-~nt+R+AAJe~<;lSenW=iiC35hj&R*f$1vs~vNy-Moh?YX}xitbEYED`4WqSyZ zt+HMF!}1PNWQRUlMN4Tlk3DvaspR^P42O6-dyqW!X>S%F^ubuk#}3^jA9G0F59jxu ze0jEoIKQBg8ud7JZGh~3nTxCUq<%MCZND|@vcWUm<0|Fw$#)|k_&Ji5Uu&~*8U8D^ zP97u^Tz|Lo?~3z#FRv<({la)^s$tk|{h%t5w{(d&y`fEknlvY>=BuM|*%9w9btoWJ zK@w}puHHjmp8#PLuF#qrzH-fBN7aJ{EbrJ)K@@nnmmg_Xp0cTig9~}KvU6Q+dzUZK zTx8%@fbFUDStnf8Qj`0Tl=lROm?dk!F!d}vCe->pT#&Yuk?DOglT31H7+}K`S!m6Z+)xQ From a0d1fd4538db72277d7a80376f31115f5b554e6d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 11:04:36 +0200 Subject: [PATCH 37/39] =?UTF-8?q?docs:=20Breaking=20change=20=E2=80=93=20N?= =?UTF-8?q?amedPipeServerStream=20+=20PipeOptions.CurrentUserOnly=20tighte?= =?UTF-8?q?ns=20Unix=20socket=20file=20permissions=20to=200600=20in=20.NET?= =?UTF-8?q?=2011=20(#53544)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/core/compatibility/11.md | 1 + .../namedpipeserverstream-unix-permissions.md | 71 +++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + ...-for-network-interprocess-communication.md | 3 + 4 files changed, 77 insertions(+) create mode 100644 docs/core/compatibility/core-libraries/11/namedpipeserverstream-unix-permissions.md diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index ca571c2399bf6..b618fd15f4bb6 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -29,6 +29,7 @@ See [Breaking changes in ASP.NET Core 10](/aspnet/core/breaking-changes/10/overv | [DeflateStream and GZipStream write headers and footers for empty payload](core-libraries/11/deflatestream-gzipstream-empty-payload.md) | Behavioral change | | [Environment.TickCount made consistent with Windows timeout behavior](core-libraries/11/environment-tickcount-windows-behavior.md) | Behavioral change | | [MemoryStream maximum capacity updated and exception behavior changed](core-libraries/11/memorystream-max-capacity.md) | Behavioral change | +| [NamedPipeServerStream with PipeOptions.CurrentUserOnly tightens Unix socket file permissions](core-libraries/11/namedpipeserverstream-unix-permissions.md) | Behavioral change | | [Nullable.GetUnderlyingType throws for custom Type subclasses](core-libraries/11/nullable-getunderlyingtype-throws.md) | Behavioral change | | [API obsoletions with non-default diagnostic IDs (.NET 11)](core-libraries/11/obsolete-apis.md) | Source incompatible | | [TAR-reading APIs verify header checksums when reading](core-libraries/11/tar-checksum-validation.md) | Behavioral change | diff --git a/docs/core/compatibility/core-libraries/11/namedpipeserverstream-unix-permissions.md b/docs/core/compatibility/core-libraries/11/namedpipeserverstream-unix-permissions.md new file mode 100644 index 0000000000000..9e8e9b1819350 --- /dev/null +++ b/docs/core/compatibility/core-libraries/11/namedpipeserverstream-unix-permissions.md @@ -0,0 +1,71 @@ +--- +title: "Breaking change: NamedPipeServerStream with PipeOptions.CurrentUserOnly tightens Unix socket file permissions" +description: "Learn about the breaking change in .NET 11 where NamedPipeServerStream with PipeOptions.CurrentUserOnly sets the Unix socket file mode to 0600." +ms.date: 05/04/2026 +ai-usage: ai-assisted +--- + +# NamedPipeServerStream with PipeOptions.CurrentUserOnly tightens Unix socket file permissions + +To better align on-disk permissions with the documented intent of and with the Windows implementation, the underlying Unix domain socket file is now created with file permissions `0600` (read/write for the owning user only). Previously, the socket file inherited permissions from the process umask, and `CurrentUserOnly` only rejected cross-user connections at connect time without restricting who could open the socket file itself. + +## Version introduced + +.NET 11 Preview 4 + +## Previous behavior + +Previously, the socket file backing a was created with whatever permissions the process umask allowed (commonly `0644` or `0755`). Specifying didn't change the on-disk file mode. Other local users could `stat` and might be able to attempt a connection to the socket file, depending on the platform and effective permissions. Cross-user connection attempts were rejected at connect time by peer-credential checks, but the socket file itself could still be visible to other users and, on some Unix systems, might also be connectable at the operating system level. + +```csharp +using var server = new NamedPipeServerStream( + "mypipe", PipeDirection.InOut, 1, + PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly); + +// Mode reflected the process umask, for example UserRead | UserWrite | GroupRead | OtherRead. +UnixFileMode mode = File.GetUnixFileMode("/tmp/CoreFxPipe_mypipe"); +``` + +## New behavior + +Starting in .NET 11, when you specify , the socket file is `chmod`'d to `0600` immediately after `bind()`. Other local users (other than root) can no longer open or connect to the socket file at the operating system level. + +```csharp +using var server = new NamedPipeServerStream( + "mypipe", PipeDirection.InOut, 1, + PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly); + +// Always UserRead | UserWrite (0600). +UnixFileMode mode = File.GetUnixFileMode("/tmp/CoreFxPipe_mypipe"); +``` + +For the in-process shared server cache, where multiple `NamedPipeServerStream` instances use the same pipe name, the permission change is one-way (ratcheted): + +- If a `CurrentUserOnly` instance is created for a given pipe name, the socket file is tightened to `0600` at that point and stays `0600` for the remainder of that path's shared lifetime. +- A later instance for the same pipe name that doesn't specify `CurrentUserOnly` doesn't loosen the mode back. + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + + is documented as restricting access to the current user. On Unix, however, the socket file was created with permissions derived from the process umask, so enforcement relied on peer-credential checks at connect time. This left the socket file discoverable by other local users, and on platforms that honor socket-node permission bits for `connect()`, it might also allow other users to attempt or make a connection before peer-credential checks rejected cross-user access. That behavior made Unix behavior inconsistent with the option's documented intent and with the Windows implementation. For more information, see [dotnet/runtime#127239](https://github.com/dotnet/runtime/pull/127239). + +## Recommended action + +Most callers benefit from the tighter permissions and require no action. + +On Linux and macOS, uses Unix domain sockets. If you rely on that socket file being visible or connectable to local users other than the owner, update your guidance and your app assumptions to reflect that now sets the socket file mode to `0600` at bind time. + +Removing doesn't guarantee cross-user access by itself. When you omit that option, the socket file still inherits permissions from the process umask, and other users also need enough access to the directory that contains the socket path. If you intend to allow cross-user access, verify the effective socket file mode and the directory permissions on the target system. + +To let the server accept connections from other local users—for example, from a helper process that runs under a different account, or from external tooling that probes the socket—stop passing . + +Also account for the in-process ratcheting behavior. If any `NamedPipeServerStream` instance for a given pipe name in the process specifies `CurrentUserOnly`, all later instances for that pipe name keep `0600` permissions on the socket file until the shared server entry is released. + +## Affected APIs + +- +- +- diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 327c0135cd2f8..e8efd991e7d09 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -20,6 +20,8 @@ items: href: core-libraries/11/environment-tickcount-windows-behavior.md - name: MemoryStream maximum capacity updated and exception behavior changed href: core-libraries/11/memorystream-max-capacity.md + - name: NamedPipeServerStream with PipeOptions.CurrentUserOnly tightens Unix socket file permissions + href: core-libraries/11/namedpipeserverstream-unix-permissions.md - name: Nullable.GetUnderlyingType throws for custom Type subclasses href: core-libraries/11/nullable-getunderlyingtype-throws.md - name: API obsoletions with non-default diagnostic IDs diff --git a/docs/standard/io/how-to-use-named-pipes-for-network-interprocess-communication.md b/docs/standard/io/how-to-use-named-pipes-for-network-interprocess-communication.md index f360288c50e75..f1e3d33afff30 100644 --- a/docs/standard/io/how-to-use-named-pipes-for-network-interprocess-communication.md +++ b/docs/standard/io/how-to-use-named-pipes-for-network-interprocess-communication.md @@ -21,6 +21,9 @@ Named pipes provide interprocess communication between a pipe server and one or > [!IMPORTANT] > .NET on Linux uses Unix Domain Sockets (UDS) for the implementation of these APIs. +> [!NOTE] +> Starting in .NET 11, when you create a with on Unix, the underlying socket file is set to mode `0600` (owner read/write only) at bind time. Previously, the socket file inherited permissions from the process umask. For more information, see [NamedPipeServerStream with PipeOptions.CurrentUserOnly tightens Unix socket file permissions](../../core/compatibility/core-libraries/11/namedpipeserverstream-unix-permissions.md). + To implement name pipes, use the and classes. ## Example 1 From fdf046fd3b226914038bf91eaba6ac5ae8fee01e Mon Sep 17 00:00:00 2001 From: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com> Date: Thu, 7 May 2026 10:24:22 -0400 Subject: [PATCH 38/39] Update package index with latest published versions (#53656) --- docs/azure/includes/dotnet-all.md | 26 +++++++++++++------------- docs/azure/includes/dotnet-new.md | 10 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index c50cca83018a7..4cd12b9744141 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -32,7 +32,7 @@ | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.5/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Conversations Authoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.AI.Language.Conversations.Authoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations.Authoring_1.0.0-beta.3/sdk/cognitivelanguage/Azure.AI.Language.Conversations.Authoring/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.54.0](https://www.nuget.org/packages/Azure.Core/1.54.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.54.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.54.0/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.55.0](https://www.nuget.org/packages/Azure.Core/1.55.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.55.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.55.0/sdk/core/Azure.Core/) | | Core - Client - Core | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | @@ -60,9 +60,9 @@ | Identity | NuGet [1.21.0](https://www.nuget.org/packages/Azure.Identity/1.21.0) | [docs](/dotnet/api/overview/azure/Identity-readme) | GitHub [1.21.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Identity_1.21.0/sdk/identity/Azure.Identity/) | | Identity Broker | NuGet [1.6.0](https://www.nuget.org/packages/Azure.Identity.Broker/1.6.0) | [docs](/dotnet/api/overview/azure/Identity.Broker-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Identity.Broker_1.6.0/sdk/identity/Azure.Identity.Broker/) | | Image Analysis | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.Vision.ImageAnalysis/1.0.0) | [docs](/dotnet/api/overview/azure/AI.Vision.ImageAnalysis-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Vision.ImageAnalysis_1.0.0/sdk/vision/Azure.AI.Vision.ImageAnalysis/) | -| Key Vault - Administration | NuGet [4.7.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Administration/4.7.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Administration-readme) | GitHub [4.7.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Administration_4.7.0/sdk/keyvault/Azure.Security.KeyVault.Administration/) | +| Key Vault - Administration | NuGet [4.8.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Administration/4.8.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Administration-readme) | GitHub [4.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Administration_4.8.0/sdk/keyvault/Azure.Security.KeyVault.Administration/) | | Key Vault - Certificates | NuGet [4.8.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Certificates/4.8.0)
NuGet [4.9.0-beta.1](https://www.nuget.org/packages/Azure.Security.KeyVault.Certificates/4.9.0-beta.1) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Certificates-readme) | GitHub [4.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Certificates_4.8.0/sdk/keyvault/Azure.Security.KeyVault.Certificates/)
GitHub [4.9.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Certificates_4.9.0-beta.1/sdk/keyvault/Azure.Security.KeyVault.Certificates/) | -| Key Vault - Keys | NuGet [4.9.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys/4.9.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Keys-readme) | GitHub [4.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Keys_4.9.0/sdk/keyvault/Azure.Security.KeyVault.Keys/) | +| Key Vault - Keys | NuGet [4.10.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys/4.10.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Keys-readme) | GitHub [4.10.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Keys_4.10.0/sdk/keyvault/Azure.Security.KeyVault.Keys/) | | Key Vault - Secrets | NuGet [4.11.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Secrets/4.11.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Secrets-readme) | GitHub [4.11.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Secrets_4.11.0/sdk/keyvault/Azure.Security.KeyVault.Secrets/) | | Language Text | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.AI.Language.Text/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/AI.Language.Text-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Text_1.0.0-beta.4/sdk/cognitivelanguage/Azure.AI.Language.Text/) | | Load Testing | NuGet [1.0.2](https://www.nuget.org/packages/Azure.Developer.LoadTesting/1.0.2)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.Developer.LoadTesting/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/Developer.LoadTesting-readme) | GitHub [1.0.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.LoadTesting_1.0.2/sdk/loadtestservice/Azure.Developer.LoadTesting/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.LoadTesting_1.3.0-beta.1/sdk/loadtestservice/Azure.Developer.LoadTesting/) | @@ -115,7 +115,7 @@ | Synapse - Monitoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Analytics.Synapse.Monitoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Monitoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Monitoring_1.0.0-beta.3/sdk/synapse/Azure.Analytics.Synapse.Monitoring/) | | Synapse - Spark | NuGet [1.0.0-preview.8](https://www.nuget.org/packages/Azure.Analytics.Synapse.Spark/1.0.0-preview.8) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Spark-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-preview.8](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Spark_1.0.0-preview.8/sdk/synapse/Azure.Analytics.Synapse.Spark/) | | System Events | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid.SystemEvents/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.SystemEvents-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.SystemEvents_1.0.0/sdk/eventgrid/Azure.Messaging.EventGrid.SystemEvents/) | -| System.ClientModel | NuGet [1.10.0](https://www.nuget.org/packages/System.ClientModel/1.10.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.10.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.10.0/sdk/core/System.ClientModel/) | +| System.ClientModel | NuGet [1.11.0](https://www.nuget.org/packages/System.ClientModel/1.11.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.11.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.11.0/sdk/core/System.ClientModel/) | | Tables | NuGet [12.11.0](https://www.nuget.org/packages/Azure.Data.Tables/12.11.0) | [docs](/dotnet/api/overview/azure/Data.Tables-readme) | GitHub [12.11.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.Tables_12.11.0/sdk/tables/Azure.Data.Tables/) | | Text Analytics | NuGet [5.3.0](https://www.nuget.org/packages/Azure.AI.TextAnalytics/5.3.0) | [docs](/dotnet/api/overview/azure/AI.TextAnalytics-readme) | GitHub [5.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.TextAnalytics_5.3.0/sdk/textanalytics/Azure.AI.TextAnalytics/) | | Text Authoring | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Language.Text.Authoring/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Language.Text.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Text.Authoring_1.0.0-beta.2/sdk/cognitivelanguage/Azure.AI.Language.Text.Authoring/) | @@ -227,7 +227,7 @@ | Resource Management - Communication | NuGet [1.3.1](https://www.nuget.org/packages/Azure.ResourceManager.Communication/1.3.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Communication-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Communication_1.3.1/sdk/communication/Azure.ResourceManager.Communication/) | | Resource Management - Compute | NuGet [1.14.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.14.0)
NuGet [1.15.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.15.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.14.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.14.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.15.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.15.0-beta.1/sdk/compute/Azure.ResourceManager.Compute/) | | Resource Management - Compute Fleet | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeFleet-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.0.0/sdk/computefleet/Azure.ResourceManager.ComputeFleet/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.1.0-beta.1/sdk/computefleet/Azure.ResourceManager.ComputeFleet/) | -| Resource Management - Compute Schedule | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.1.0)
NuGet [1.2.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.2.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.1.0/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/)
GitHub [1.2.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.2.0-beta.2/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | +| Resource Management - Compute Schedule | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.1.0)
NuGet [1.2.0-beta.3](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.2.0-beta.3) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.1.0/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/)
GitHub [1.2.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.2.0-beta.3/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | | Resource Management - Compute.Recommender | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.Compute.Recommender/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute.Recommender-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute.Recommender_1.0.0-beta.2/sdk/computerecommender/Azure.ResourceManager.Compute.Recommender/) | | Resource Management - Computelimit | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeLimit/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeLimit-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeLimit_1.0.0/sdk/computelimit/Azure.ResourceManager.ComputeLimit/) | | Resource Management - Confidential Ledger | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ConfidentialLedger-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.1.0/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/) | @@ -425,13 +425,13 @@ | Resource Management - Workloadssapvirtualinstance | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.WorkloadsSapVirtualInstance/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.WorkloadsSapVirtualInstance-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.WorkloadsSapVirtualInstance_1.0.0/sdk/workloadssapvirtualinstance/Azure.ResourceManager.WorkloadsSapVirtualInstance/) | | App Configuration Extension | NuGet [8.5.0](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.Functions.Worker/8.5.0)
NuGet [8.6.0-preview](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.Functions.Worker/8.6.0-preview) | | | | App Configuration Provider | NuGet [8.5.0](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.AspNetCore/8.5.0)
NuGet [8.6.0-preview](https://www.nuget.org/packages/Microsoft.Azure.AppConfiguration.AspNetCore/8.6.0-preview) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.linux-arm64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.linux-arm64/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.linux-x64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.linux-x64/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.osx-arm64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.osx-arm64/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.osx-x64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.osx-x64/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.win-arm64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.win-arm64/3.0.0-beta.8) | | | -| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.win-x64/1.0.0)
NuGet [3.0.0-beta.8](https://www.nuget.org/packages/Azure.Mcp.win-x64/3.0.0-beta.8) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.linux-arm64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.linux-arm64/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.linux-x64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.linux-x64/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.osx-arm64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.osx-arm64/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.osx-x64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.osx-x64/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.win-arm64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.win-arm64/3.0.0-beta.9) | | | +| Azure MCP | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Mcp.win-x64/1.0.0)
NuGet [3.0.0-beta.9](https://www.nuget.org/packages/Azure.Mcp.win-x64/3.0.0-beta.9) | | | | Azure MCP Types Internal | NuGet [0.2.804](https://www.nuget.org/packages/Microsoft.Azure.Mcp.AzTypes.Internal.Compact/0.2.804) | | | | Azure.Communication.Administration | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Communication.Administration/1.0.0-beta.3) | | | | Caching - PostgreSQL | NuGet [1.2.2](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Postgres/1.2.2) | | | @@ -610,7 +610,7 @@ | Microsoft.Azure.Functions.Worker.Extensions.EventGrid | NuGet [3.6.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.EventGrid/3.6.0) | | | | Microsoft.Azure.Functions.Worker.Extensions.EventHubs | NuGet [6.5.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.EventHubs/6.5.0) | | | | Microsoft.Azure.Functions.Worker.Extensions.Http | NuGet [3.3.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Http/3.3.0) | | | -| Microsoft.Azure.Functions.Worker.Extensions.Kafka | NuGet [4.2.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Kafka/4.2.0) | | | +| Microsoft.Azure.Functions.Worker.Extensions.Kafka | NuGet [4.3.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Kafka/4.3.0) | | | | Microsoft.Azure.Functions.Worker.Extensions.Kusto | NuGet [1.0.13-Preview](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.Kusto/1.0.13-Preview) | | | | Microsoft.Azure.Functions.Worker.Extensions.OpenApi | NuGet [1.4.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/1.4.0)
NuGet [2.0.0-preview2](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/2.0.0-preview2) | | | | Microsoft.Azure.Functions.Worker.Extensions.RabbitMQ | NuGet [2.1.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.RabbitMQ/2.1.0) | | | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index 27deb0393eddc..929c23390dba8 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -36,7 +36,7 @@ | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.5/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Conversations Authoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.AI.Language.Conversations.Authoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations.Authoring_1.0.0-beta.3/sdk/cognitivelanguage/Azure.AI.Language.Conversations.Authoring/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.54.0](https://www.nuget.org/packages/Azure.Core/1.54.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.54.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.54.0/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.55.0](https://www.nuget.org/packages/Azure.Core/1.55.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.55.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.55.0/sdk/core/Azure.Core/) | | Core - Client - Core | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Core.Expressions.DataFactory/1.0.0) | [docs](/dotnet/api/overview/azure/Core.Expressions.DataFactory-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Expressions.DataFactory_1.0.0/sdk/core/Azure.Core.Expressions.DataFactory/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | @@ -64,9 +64,9 @@ | Identity | NuGet [1.21.0](https://www.nuget.org/packages/Azure.Identity/1.21.0) | [docs](/dotnet/api/overview/azure/Identity-readme) | GitHub [1.21.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Identity_1.21.0/sdk/identity/Azure.Identity/) | | Identity Broker | NuGet [1.6.0](https://www.nuget.org/packages/Azure.Identity.Broker/1.6.0) | [docs](/dotnet/api/overview/azure/Identity.Broker-readme) | GitHub [1.6.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Identity.Broker_1.6.0/sdk/identity/Azure.Identity.Broker/) | | Image Analysis | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.Vision.ImageAnalysis/1.0.0) | [docs](/dotnet/api/overview/azure/AI.Vision.ImageAnalysis-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Vision.ImageAnalysis_1.0.0/sdk/vision/Azure.AI.Vision.ImageAnalysis/) | -| Key Vault - Administration | NuGet [4.7.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Administration/4.7.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Administration-readme) | GitHub [4.7.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Administration_4.7.0/sdk/keyvault/Azure.Security.KeyVault.Administration/) | +| Key Vault - Administration | NuGet [4.8.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Administration/4.8.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Administration-readme) | GitHub [4.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Administration_4.8.0/sdk/keyvault/Azure.Security.KeyVault.Administration/) | | Key Vault - Certificates | NuGet [4.8.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Certificates/4.8.0)
NuGet [4.9.0-beta.1](https://www.nuget.org/packages/Azure.Security.KeyVault.Certificates/4.9.0-beta.1) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Certificates-readme) | GitHub [4.8.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Certificates_4.8.0/sdk/keyvault/Azure.Security.KeyVault.Certificates/)
GitHub [4.9.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Certificates_4.9.0-beta.1/sdk/keyvault/Azure.Security.KeyVault.Certificates/) | -| Key Vault - Keys | NuGet [4.9.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys/4.9.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Keys-readme) | GitHub [4.9.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Keys_4.9.0/sdk/keyvault/Azure.Security.KeyVault.Keys/) | +| Key Vault - Keys | NuGet [4.10.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Keys/4.10.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Keys-readme) | GitHub [4.10.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Keys_4.10.0/sdk/keyvault/Azure.Security.KeyVault.Keys/) | | Key Vault - Secrets | NuGet [4.11.0](https://www.nuget.org/packages/Azure.Security.KeyVault.Secrets/4.11.0) | [docs](/dotnet/api/overview/azure/Security.KeyVault.Secrets-readme) | GitHub [4.11.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Security.KeyVault.Secrets_4.11.0/sdk/keyvault/Azure.Security.KeyVault.Secrets/) | | Language Text | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.AI.Language.Text/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/AI.Language.Text-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Text_1.0.0-beta.4/sdk/cognitivelanguage/Azure.AI.Language.Text/) | | Load Testing | NuGet [1.0.2](https://www.nuget.org/packages/Azure.Developer.LoadTesting/1.0.2)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.Developer.LoadTesting/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/Developer.LoadTesting-readme) | GitHub [1.0.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.LoadTesting_1.0.2/sdk/loadtestservice/Azure.Developer.LoadTesting/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.LoadTesting_1.3.0-beta.1/sdk/loadtestservice/Azure.Developer.LoadTesting/) | @@ -127,7 +127,7 @@ | Synapse - Monitoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Analytics.Synapse.Monitoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Monitoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Monitoring_1.0.0-beta.3/sdk/synapse/Azure.Analytics.Synapse.Monitoring/) | | Synapse - Spark | NuGet [1.0.0-preview.8](https://www.nuget.org/packages/Azure.Analytics.Synapse.Spark/1.0.0-preview.8) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Spark-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-preview.8](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Spark_1.0.0-preview.8/sdk/synapse/Azure.Analytics.Synapse.Spark/) | | System Events | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Messaging.EventGrid.SystemEvents/1.0.0) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.SystemEvents-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.SystemEvents_1.0.0/sdk/eventgrid/Azure.Messaging.EventGrid.SystemEvents/) | -| System.ClientModel | NuGet [1.10.0](https://www.nuget.org/packages/System.ClientModel/1.10.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.10.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.10.0/sdk/core/System.ClientModel/) | +| System.ClientModel | NuGet [1.11.0](https://www.nuget.org/packages/System.ClientModel/1.11.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.11.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.11.0/sdk/core/System.ClientModel/) | | Tables | NuGet [12.11.0](https://www.nuget.org/packages/Azure.Data.Tables/12.11.0) | [docs](/dotnet/api/overview/azure/Data.Tables-readme) | GitHub [12.11.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.Tables_12.11.0/sdk/tables/Azure.Data.Tables/) | | Text Analytics | NuGet [5.3.0](https://www.nuget.org/packages/Azure.AI.TextAnalytics/5.3.0) | [docs](/dotnet/api/overview/azure/AI.TextAnalytics-readme) | GitHub [5.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.TextAnalytics_5.3.0/sdk/textanalytics/Azure.AI.TextAnalytics/) | | Text Authoring | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Language.Text.Authoring/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Language.Text.Authoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Text.Authoring_1.0.0-beta.2/sdk/cognitivelanguage/Azure.AI.Language.Text.Authoring/) | @@ -242,7 +242,7 @@ | Resource Management - Communication | NuGet [1.3.1](https://www.nuget.org/packages/Azure.ResourceManager.Communication/1.3.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Communication-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Communication_1.3.1/sdk/communication/Azure.ResourceManager.Communication/) | | Resource Management - Compute | NuGet [1.14.0](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.14.0)
NuGet [1.15.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.Compute/1.15.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute-readme) | GitHub [1.14.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.14.0/sdk/compute/Azure.ResourceManager.Compute/)
GitHub [1.15.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute_1.15.0-beta.1/sdk/compute/Azure.ResourceManager.Compute/) | | Resource Management - Compute Fleet | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ComputeFleet/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeFleet-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.0.0/sdk/computefleet/Azure.ResourceManager.ComputeFleet/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeFleet_1.1.0-beta.1/sdk/computefleet/Azure.ResourceManager.ComputeFleet/) | -| Resource Management - Compute Schedule | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.1.0)
NuGet [1.2.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.2.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.1.0/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/)
GitHub [1.2.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.2.0-beta.2/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | +| Resource Management - Compute Schedule | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.1.0)
NuGet [1.2.0-beta.3](https://www.nuget.org/packages/Azure.ResourceManager.ComputeSchedule/1.2.0-beta.3) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeSchedule-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.1.0/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/)
GitHub [1.2.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeSchedule_1.2.0-beta.3/sdk/computeschedule/Azure.ResourceManager.ComputeSchedule/) | | Resource Management - Compute.Recommender | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.Compute.Recommender/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.Compute.Recommender-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Compute.Recommender_1.0.0-beta.2/sdk/computerecommender/Azure.ResourceManager.Compute.Recommender/) | | Resource Management - Computelimit | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.ComputeLimit/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ComputeLimit-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ComputeLimit_1.0.0/sdk/computelimit/Azure.ResourceManager.ComputeLimit/) | | Resource Management - Confidential Ledger | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ConfidentialLedger/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ConfidentialLedger-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ConfidentialLedger_1.1.0/sdk/confidentialledger/Azure.ResourceManager.ConfidentialLedger/) | From 8e2b178f5583eee8d7c3adf6cf83605a4464cf0e Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 10:28:42 -0400 Subject: [PATCH 39/39] Fix incorrect comment label in partial property snippet (#53652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial plan * Fix incorrect comment in FieldProperty snippet: Defining → Implementing declaration Agent-Logs-Url: https://github.com/dotnet/docs/sessions/41c6c349-354f-4a06-8391-a7522dfa30a4 Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- .../snippets/partial-classes-and-methods/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/Program.cs b/docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/Program.cs index 2a8eff4250eda..986ec7834bf9c 100644 --- a/docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/Program.cs +++ b/docs/csharp/programming-guide/classes-and-structs/snippets/partial-classes-and-methods/Program.cs @@ -179,7 +179,7 @@ public partial class PropertyBag // In file2.cs public partial class PropertyBag { - // Defining declaration + // Implementing declaration public partial int MyProperty { get => field; set; } }