diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9433df44b..08fc9390e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "AXSharp.ixc": { - "version": "0.47.0-alpha.489", + "version": "0.47.0-alpha.495", "commands": [ "ixc" ], @@ -17,14 +17,14 @@ "rollForward": false }, "AXSharp.ixd": { - "version": "0.47.0-alpha.489", + "version": "0.47.0-alpha.495", "commands": [ "ixd" ], "rollForward": false }, "AXSharp.ixr": { - "version": "0.47.0-alpha.489", + "version": "0.47.0-alpha.495", "commands": [ "ixr" ], diff --git a/CHANGELOG.md b/CHANGELOG.md index 829937d94..be6e1abfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ +### [CORE] `AxoRemoteTask` start/done handshake priority is now configurable (default Normal) (#TBD) + +**Note:** API addition + behavioral change in `src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs` (.NET twin only). No PLC source or PLC-side API change. Branch: `deps-update-0-47-0-alpha-495`. PR link to be filled in before merge. Follow-up to the High-priority batching entry below (commit `2a70cb744`). + +- feat: new `HandshakeReadAccessPriority` and `HandshakeWriteAccessPriority` properties (default `eAccessPriority.Normal`) drive the access priority of the batched start/done read (`ReadBatchAsync` of `StartSignature` + `DoneSignature`) and the Done-ack write (`WriteBatchAsync`) in `ExecuteAsync`, replacing the previously hardcoded `eAccessPriority.High` at both legs. +- feat: all `Initialize(...)` / `InitializeExclusively(...)` overloads gain two optional args — `handshakeReadAccessPriority` and `handshakeWriteAccessPriority` (both default `eAccessPriority.Normal`) — that seed those properties. Existing call sites bind unchanged via the defaults; the properties can also be set directly any time. +- test: added `AxoRemoteTaskHandshakePriorityTests` (4 tests) in `src/core/tests/AXOpen.Core.Tests`. A recording `DummyConnector` subclass captures the `eAccessPriority` passed to `Read`/`WriteBatchAsync`; tests cover the read leg, the write leg (distinct value to prove the write property specifically), the default-`Normal` behavior (asserting `High` is no longer used), and a property-override-after-`Initialize` case. +- docs: `src/core/docs/CHANGELOG.md` (`0.62.3` — New features + Breaking changes) and `AxoRemoteTask.md` note updated to describe the configurable, `Normal`-default handshake. + +**Impact:** +- The remote-task start/done handshake now defaults to `eAccessPriority.Normal` instead of `High`. Callers that need the handshake serviced ahead of lower-priority traffic must opt in — pass `eAccessPriority.High` to `Initialize(...)` or set `HandshakeReadAccessPriority` / `HandshakeWriteAccessPriority`. + +**Risks/Review:** +- Behavioral change for upgraders: any code relying on the implicit `High` handshake from `2a70cb744` will now contend at `Normal` until it sets the priority explicitly. In the built-in connectors `High` and `Normal` share the same batch chunking; only the queue/ordering priority relative to other connector traffic differs. + +**Testing:** +- `dotnet test src/core/tests/AXOpen.Core.Tests` — 74 passed (incl. 4 new). Built strictly TDD red-first. +- Test note: the `DummyConnector` read cycle (`BuildAndStart`) self-deadlocks on its internal lock and never raises the value-changed event, so the tests invoke the protected handshake directly (no `BuildAndStart`) to capture priorities — a harness constraint only; production triggering is unchanged. + +### [CORE] `AxoRemoteTask` batches start/done handshake at High priority (#TBD) + +**Note:** Performance change in `src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs` (.NET twin only). No PLC source or public-API change. Branch: `deps-update-0-47-0-alpha-495`, commit `2a70cb744`. PR link to be filled in before merge. + +- perf: `ExecuteAsync` now reads `StartSignature` + `DoneSignature` with a single `Connector.ReadBatchAsync(..., eAccessPriority.High)` and writes the completed `DoneSignature` with `Connector.WriteBatchAsync(..., eAccessPriority.High)` (via `DoneSignature.Cyclic`), replacing the per-signal `GetAsync`/`SetAsync`. Collapses the remote-task start/done handshake into single batched, High-priority connector round-trips. +- docs: `src/core/docs/CHANGELOG.md` bumped to `0.61.1`; `AxoRemoteTask.md` gains a note describing the High-priority batched handshake. + +**Impact:** +- Fewer connector round-trips per `AxoRemoteTask` invocation. The start/done acknowledgement now contends at `eAccessPriority.High`, so it is serviced ahead of lower-priority operator/polling traffic. + +**Risks/Review:** +- Promoting the handshake to `High` priority shifts connector scheduling — under heavy remote-task fan-out, confirm it does not starve other High-priority traffic. + +**Testing:** +- Covered by the existing `AxoRemoteTaskTests` suite (`src/core/tests/AXOpen.Core.Tests`). No new test added specifically for the batching change. + ### [FIX] `AxoCmmtAs` loses axis position while in torque control **Note:** PLC bug fix in `src/components.festo.drives` (`AxoCmmtAs`, `PROFIdriveTelegram_111`) and `src/components.drives` (`AxoDrive_Config`). No public-API removal. Branch: `1152-bug-cmmt-as-while-in-torque-control-loses-axis-position`. Issue #1152, PR #1166. diff --git a/Directory.Packages.props b/Directory.Packages.props index 63f610038..43525db80 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,11 +11,11 @@ - - - - - + + + + + diff --git a/GitVersion.yml b/GitVersion.yml index a4cb25032..f91634499 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -1,5 +1,5 @@ mode: ContinuousDeployment -next-version: 0.61.1 +next-version: 0.62.3 branches: main: regex: ^master$|^main$ diff --git a/src/abstractions/ctrl/AXSharp.config.json b/src/abstractions/ctrl/AXSharp.config.json index c72192874..815cbd189 100644 --- a/src/abstractions/ctrl/AXSharp.config.json +++ b/src/abstractions/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Abstractions","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_abstractions.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Abstractions","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_abstractions.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.abb.robotics/ctrl/AXSharp.config.json b/src/components.abb.robotics/ctrl/AXSharp.config.json index a3bb12190..a1d2369f9 100644 --- a/src/components.abb.robotics/ctrl/AXSharp.config.json +++ b/src/components.abb.robotics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Abb.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_abb_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Abb.Robotics.blazor\\AXOpen.Components.Abb.Robotics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Abb.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_abb_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Abb.Robotics.blazor\\AXOpen.Components.Abb.Robotics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.abstractions/ctrl/AXSharp.config.json b/src/components.abstractions/ctrl/AXSharp.config.json index b3752f07f..08987dcc7 100644 --- a/src/components.abstractions/ctrl/AXSharp.config.json +++ b/src/components.abstractions/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Abstractions","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_abstractions.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Abstractions","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_abstractions.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.balluff.identification/ctrl/AXSharp.config.json b/src/components.balluff.identification/ctrl/AXSharp.config.json index 915ec84c9..448715025 100644 --- a/src/components.balluff.identification/ctrl/AXSharp.config.json +++ b/src/components.balluff.identification/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Balluff.Identification","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_balluff_identification.csproj","UiHostProject":"..\\src\\AXOpen.Components.Balluff.Identification.blazor\\AXOpen.Components.Balluff.Identification.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Balluff.Identification","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_balluff_identification.csproj","UiHostProject":"..\\src\\AXOpen.Components.Balluff.Identification.blazor\\AXOpen.Components.Balluff.Identification.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.cognex.vision/ctrl/AXSharp.config.json b/src/components.cognex.vision/ctrl/AXSharp.config.json index b6dec2a51..8d9c7bcf0 100644 --- a/src/components.cognex.vision/ctrl/AXSharp.config.json +++ b/src/components.cognex.vision/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Cognex.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_cognex_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Cognex.Vision.blazor\\AXOpen.Components.Cognex.Vision.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Cognex.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_cognex_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Cognex.Vision.blazor\\AXOpen.Components.Cognex.Vision.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.desoutter.tightening/ctrl/AXSharp.config.json b/src/components.desoutter.tightening/ctrl/AXSharp.config.json index f3c63ba69..27c073fdf 100644 --- a/src/components.desoutter.tightening/ctrl/AXSharp.config.json +++ b/src/components.desoutter.tightening/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Desoutter.Tightening","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_desoutter_tightening.csproj","UiHostProject":"..\\src\\AXOpen.Components.Desoutter.Tightening.blazor\\AXOpen.Components.Desoutter.Tightening.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Desoutter.Tightening","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_desoutter_tightening.csproj","UiHostProject":"..\\src\\AXOpen.Components.Desoutter.Tightening.blazor\\AXOpen.Components.Desoutter.Tightening.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.drives/ctrl/AXSharp.config.json b/src/components.drives/ctrl/AXSharp.config.json index 0ad74da8c..a3da6939c 100644 --- a/src/components.drives/ctrl/AXSharp.config.json +++ b/src/components.drives/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Drives.blazor\\AXOpen.Components.Drives.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Drives.blazor\\AXOpen.Components.Drives.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.dukane.welders/ctrl/AXSharp.config.json b/src/components.dukane.welders/ctrl/AXSharp.config.json index 43dd9a523..234a8e2f7 100644 --- a/src/components.dukane.welders/ctrl/AXSharp.config.json +++ b/src/components.dukane.welders/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Dukane.Welders","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_dukane_welders.csproj","UiHostProject":"..\\src\\AXOpen.Components.Dukane.Welders.blazor\\AXOpen.Components.Dukane.Welders.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Dukane.Welders","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_dukane_welders.csproj","UiHostProject":"..\\src\\AXOpen.Components.Dukane.Welders.blazor\\AXOpen.Components.Dukane.Welders.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.elements/ctrl/AXSharp.config.json b/src/components.elements/ctrl/AXSharp.config.json index 64cdd9ae1..0c73859f7 100644 --- a/src/components.elements/ctrl/AXSharp.config.json +++ b/src/components.elements/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Elements","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_elements.csproj","UiHostProject":"..\\src\\AXOpen.Components.Elements.blazor\\AXOpen.Components.Elements.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Elements","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_elements.csproj","UiHostProject":"..\\src\\AXOpen.Components.Elements.blazor\\AXOpen.Components.Elements.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.festo.drives/ctrl/AXSharp.config.json b/src/components.festo.drives/ctrl/AXSharp.config.json index 1fa4454ac..6559d3337 100644 --- a/src/components.festo.drives/ctrl/AXSharp.config.json +++ b/src/components.festo.drives/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Festo.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_festo_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Festo.Drives.blazor\\AXOpen.Components.Festo.Drives.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Festo.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_festo_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Festo.Drives.blazor\\AXOpen.Components.Festo.Drives.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.keyence.vision/ctrl/AXSharp.config.json b/src/components.keyence.vision/ctrl/AXSharp.config.json index 7f4987b1a..b512c9884 100644 --- a/src/components.keyence.vision/ctrl/AXSharp.config.json +++ b/src/components.keyence.vision/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Keyence.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_keyence_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Keyence.Vision.blazor\\AXOpen.Components.Keyence.Vision.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Keyence.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_keyence_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Keyence.Vision.blazor\\AXOpen.Components.Keyence.Vision.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.kuka.robotics/ctrl/AXSharp.config.json b/src/components.kuka.robotics/ctrl/AXSharp.config.json index 83bbc4994..ff5a84356 100644 --- a/src/components.kuka.robotics/ctrl/AXSharp.config.json +++ b/src/components.kuka.robotics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Kuka.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_kuka_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Kuka.Robotics.blazor\\AXOpen.Components.Kuka.Robotics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Kuka.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_kuka_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Kuka.Robotics.blazor\\AXOpen.Components.Kuka.Robotics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.mitsubishi.robotics/ctrl/AXSharp.config.json b/src/components.mitsubishi.robotics/ctrl/AXSharp.config.json index 352c37650..cfa88038c 100644 --- a/src/components.mitsubishi.robotics/ctrl/AXSharp.config.json +++ b/src/components.mitsubishi.robotics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Mitsubishi.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_mitsubishi_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Mitsubishi.Robotics.blazor\\AXOpen.Components.Mitsubishi.Robotics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Mitsubishi.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_mitsubishi_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Mitsubishi.Robotics.blazor\\AXOpen.Components.Mitsubishi.Robotics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.pneumatics/ctrl/AXSharp.config.json b/src/components.pneumatics/ctrl/AXSharp.config.json index 35a6fd0ae..df41a92e8 100644 --- a/src/components.pneumatics/ctrl/AXSharp.config.json +++ b/src/components.pneumatics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Pneumatics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_pneumatics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Pneumatics.blazor\\AXOpen.Components.Pneumatics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Pneumatics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_pneumatics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Pneumatics.blazor\\AXOpen.Components.Pneumatics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.rexroth.drives/ctrl/AXSharp.config.json b/src/components.rexroth.drives/ctrl/AXSharp.config.json index 428fc2170..3d266a429 100644 --- a/src/components.rexroth.drives/ctrl/AXSharp.config.json +++ b/src/components.rexroth.drives/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Drives.blazor\\AXOpen.Components.Rexroth.Drives.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Drives","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_drives.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Drives.blazor\\AXOpen.Components.Rexroth.Drives.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.rexroth.press/ctrl/AXSharp.config.json b/src/components.rexroth.press/ctrl/AXSharp.config.json index 9bfe57958..f9ca493e6 100644 --- a/src/components.rexroth.press/ctrl/AXSharp.config.json +++ b/src/components.rexroth.press/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Press","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_press.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Press.blazor\\AXOpen.Components.Rexroth.Press.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Press","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_press.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Press.blazor\\AXOpen.Components.Rexroth.Press.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.rexroth.tightening/ctrl/AXSharp.config.json b/src/components.rexroth.tightening/ctrl/AXSharp.config.json index 84c2d9887..d0ddc6fae 100644 --- a/src/components.rexroth.tightening/ctrl/AXSharp.config.json +++ b/src/components.rexroth.tightening/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Tightening","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_tightening.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Tightening.blazor\\AXOpen.Components.Rexroth.Tightening.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Rexroth.Tightening","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_rexroth_tightening.csproj","UiHostProject":"..\\src\\AXOpen.Components.Rexroth.Tightening.blazor\\AXOpen.Components.Rexroth.Tightening.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.robotics/ctrl/AXSharp.config.json b/src/components.robotics/ctrl/AXSharp.config.json index 076d54263..34b4d8ef3 100644 --- a/src/components.robotics/ctrl/AXSharp.config.json +++ b/src/components.robotics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Robotics.blazor\\AXOpen.Components.Robotics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Robotics.blazor\\AXOpen.Components.Robotics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.siem.communication/ctrl/AXSharp.config.json b/src/components.siem.communication/ctrl/AXSharp.config.json index 3334425f7..cddfa3169 100644 --- a/src/components.siem.communication/ctrl/AXSharp.config.json +++ b/src/components.siem.communication/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Siem.Communication","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_siem_communication.csproj","UiHostProject":"..\\src\\AXOpen.Components.Siem.Communication.blazor\\AXOpen.Components.Siem.Communication.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Siem.Communication","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_siem_communication.csproj","UiHostProject":"..\\src\\AXOpen.Components.Siem.Communication.blazor\\AXOpen.Components.Siem.Communication.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.siem.identification/ctrl/AXSharp.config.json b/src/components.siem.identification/ctrl/AXSharp.config.json index cdc0021d8..f522ec812 100644 --- a/src/components.siem.identification/ctrl/AXSharp.config.json +++ b/src/components.siem.identification/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Siem.Identification","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_siem_identification.csproj","UiHostProject":"..\\src\\AXOpen.Components.Siem.Identification.blazor\\AXOpen.Components.Siem.Identification.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Siem.Identification","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_siem_identification.csproj","UiHostProject":"..\\src\\AXOpen.Components.Siem.Identification.blazor\\AXOpen.Components.Siem.Identification.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.ur.robotics/ctrl/AXSharp.config.json b/src/components.ur.robotics/ctrl/AXSharp.config.json index 7c760117d..3927b63e0 100644 --- a/src/components.ur.robotics/ctrl/AXSharp.config.json +++ b/src/components.ur.robotics/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Ur.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_ur_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Ur.Robotics.blazor\\AXOpen.Components.Ur.Robotics.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Ur.Robotics","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_ur_robotics.csproj","UiHostProject":"..\\src\\AXOpen.Components.Ur.Robotics.blazor\\AXOpen.Components.Ur.Robotics.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/components.zebra.vision/ctrl/AXSharp.config.json b/src/components.zebra.vision/ctrl/AXSharp.config.json index e244f50da..f060a496e 100644 --- a/src/components.zebra.vision/ctrl/AXSharp.config.json +++ b/src/components.zebra.vision/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Components.Zebra.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_zebra_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Zebra.Vision.blazor\\AXOpen.Components.Zebra.Vision.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Components.Zebra.Vision","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_components_zebra_vision.csproj","UiHostProject":"..\\src\\AXOpen.Components.Zebra.Vision.blazor\\AXOpen.Components.Zebra.Vision.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/core/ctrl/AXSharp.config.json b/src/core/ctrl/AXSharp.config.json index 95739a208..39d9165ad 100644 --- a/src/core/ctrl/AXSharp.config.json +++ b/src/core/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Core","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_core.csproj","UiHostProject":"..\\src\\AXOpen.Core.Blazor\\axopen_core_blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Core","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_core.csproj","UiHostProject":"..\\src\\AXOpen.Core.Blazor\\axopen_core_blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/core/ctrl/src/AxoObject/AxoObject.st b/src/core/ctrl/src/AxoObject/AxoObject.st index 9948b5087..125428d0d 100644 --- a/src/core/ctrl/src/AxoObject/AxoObject.st +++ b/src/core/ctrl/src/AxoObject/AxoObject.st @@ -164,7 +164,8 @@ NAMESPACE AXOpen.Core END_METHOD - VAR + VAR + {#ix-attr:[RenderIgnore()]} _lastMessageAggregationCycle : ULINT; END_VAR diff --git a/src/core/docs/AxoRemoteTask.md b/src/core/docs/AxoRemoteTask.md index 71fccf7de..a25c24a1c 100644 --- a/src/core/docs/AxoRemoteTask.md +++ b/src/core/docs/AxoRemoteTask.md @@ -53,6 +53,9 @@ In this example, when the PLC invokes this task it will write a message into con ![Alt text](assets/remote_exect.gif) +> [!NOTE] +> The start/done handshake is serviced on the .NET side with **batched connector access at a configurable priority**. When `Execute()` runs, the twin reads `StartSignature` and `DoneSignature` together via a single `ReadBatchAsync`, and on completion writes the acknowledging `DoneSignature` via `WriteBatchAsync`. The access priority of each leg is configurable and defaults to `eAccessPriority.Normal`: pass it to `Initialize(...)` / `InitializeExclusively(...)` (`Initialize(handler, handshakeReadAccessPriority, handshakeWriteAccessPriority)`) or set the `HandshakeReadAccessPriority` / `HandshakeWriteAccessPriority` properties directly. Raise it (e.g. to `eAccessPriority.High`) to service the handshake ahead of lower-priority traffic. Batching reduces connector round-trips per invocation; it does not change the PLC-side API or the `IsBusy` / `IsDone` / `HasError` / `IsAborted` semantics. + ## Executing from PLC diff --git a/src/core/docs/AxoTask.md b/src/core/docs/AxoTask.md index 336e51de8..1a0ebb49d 100644 --- a/src/core/docs/AxoTask.md +++ b/src/core/docs/AxoTask.md @@ -174,11 +174,14 @@ and `ErrorDetails` from the bound task and updates 250 ms cyclically. | `Done` | `btn-success` | `check` | — | | `Aborted` | `btn-warning` | `stop` | `Resume` button (calls `Component.ResumeTask()`) appears next to `Reset task` | | `Error` | `btn-danger` | `x-mark` | Native `title` tooltip on the button reveals `Component.ErrorDetails` | -| _Disabled_ | `btn-inactive` | `lock-closed` (overrides the state icon) | Button is non-interactive | - -`IsDisabled` overrides the lifecycle state: a task that is `Busy` while -`IsDisabled` is `TRUE` renders as locked, not as running. State is still -announced to assistive technology via the button's `aria-label`. +| _Disabled_ | `btn-inactive` | state ring/icon retained (Ready, Kicking, Busy, … still render their normal indicator) | `lock-closed` icon shown in the action-button area (Reset/Resume hidden); button is non-interactive | + +`IsDisabled` no longer overrides the lifecycle icon — the activity indicator +keeps reflecting the task state, so a task that is `Busy` while `IsDisabled` is +`TRUE` still shows the running circle. Instead, a `lock-closed` icon replaces +the `Reset task` / `Resume` action buttons on the trailing edge of the control, +and the button itself is non-interactive. State is still announced to assistive +technology via the button's `aria-label`. ### Demonstrating the `Error` terminal state diff --git a/src/core/docs/CHANGELOG.md b/src/core/docs/CHANGELOG.md index 85e31215d..c16f1ae57 100644 --- a/src/core/docs/CHANGELOG.md +++ b/src/core/docs/CHANGELOG.md @@ -23,6 +23,18 @@ on every run. --> +### 0.62.3 + +**New features:** +- `AxoRemoteTask` (.NET twin) start/done handshake priority is now **configurable**. The batched `Connector.ReadBatchAsync` (Start+Done poll) and `Connector.WriteBatchAsync` (Done acknowledgement) each take their `eAccessPriority` from the new `HandshakeReadAccessPriority` / `HandshakeWriteAccessPriority` properties (default `eAccessPriority.Normal`). Seed them via the new optional `Initialize(handler, handshakeReadAccessPriority, handshakeWriteAccessPriority)` / `InitializeExclusively(...)` arguments, or set the properties directly any time. Raise to `eAccessPriority.High` to service the handshake ahead of lower-priority traffic. + +**Other:** +- `AxoRemoteTask` (.NET twin) start/done handshake batches connector I/O: `ExecuteAsync` reads `StartSignature` + `DoneSignature` via a single `Connector.ReadBatchAsync` and writes the completion `DoneSignature` (set through `DoneSignature.Cyclic`) via `Connector.WriteBatchAsync`, replacing the previous per-signal `GetAsync`/`SetAsync` calls. This cuts connector round-trips on the remote-task start/done acknowledgement. No PLC-side API change — `Invoke()`, `Execute()`, `Abort()`, `Restore()`, and the `IsBusy`/`IsDone`/`HasError`/`IsAborted` semantics are unchanged. + +**Breaking changes:** +- `AxoRemoteTask` handshake default priority is now `eAccessPriority.Normal` (previously hardcoded `eAccessPriority.High`). Existing callers that relied on the handshake being serviced at `High` should pass `eAccessPriority.High` to `Initialize(...)` or set `HandshakeReadAccessPriority` / `HandshakeWriteAccessPriority`. (In the built-in connectors `High` and `Normal` share the same batch chunking; the difference is queue/ordering priority relative to other connector traffic.) +- `AxoTaskView` (Blazor) disabled rendering: when `IsDisabled` is `TRUE` the activity indicator now keeps reflecting the task state (`Ready`/`Kicking`/`Busy` still render their ring/circle) instead of being replaced by the lock. The `lock-closed` icon moved to the trailing action-button area, hiding the `Reset task` / `Resume` buttons, while the control stays non-interactive. No `AxoTask` PLC-side API change. + ### 0.56.2 **Bug fixes:** diff --git a/src/core/src/AXOpen.Core.Blazor/AxoTask/AxoTaskView.razor b/src/core/src/AXOpen.Core.Blazor/AxoTask/AxoTaskView.razor index 1f001f2d3..862f8d30c 100644 --- a/src/core/src/AXOpen.Core.Blazor/AxoTask/AxoTaskView.razor +++ b/src/core/src/AXOpen.Core.Blazor/AxoTask/AxoTaskView.razor @@ -1,4 +1,4 @@ -@namespace AXOpen.Core +@namespace AXOpen.Core @using AXSharp.Connector; @using Microsoft.AspNetCore.Components.Authorization; @using Microsoft.AspNetCore.Components.Web; @@ -14,12 +14,8 @@ style="@Style" @onclick="this.InvokeTask" disabled="@IsDisabled"> - - @if (IsDisabled) - { - - } - else if (State == eAxoTaskState.Ready) + + @if (State == eAxoTaskState.Ready) { } @@ -49,6 +45,20 @@ @Description.ToUpper() + @if (IsDisabled) + { + + } + else + { + @if (!HideRestoreButton) + { + + } + } + @if (State == eAxoTaskState.Aborted && !HideRestoreButton) { } - @if (!HideRestoreButton) - { - - } @code { diff --git a/src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs b/src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs index cfe1fb768..5d1706e27 100644 --- a/src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs +++ b/src/core/src/AXOpen.Core/AxoRemoteTask/AxoRemoteTask.cs @@ -12,6 +12,24 @@ public partial class AxoRemoteTask public event PropertyChangedEventHandler PropertyChanged; + /// + /// Gets or sets the connector access priority used for the start/done handshake read + /// (the batched ReadBatchAsync of and + /// at the top of the execution cycle). Defaults to . + /// Can be seeded via the overloads + /// or set directly any time. + /// + public eAccessPriority HandshakeReadAccessPriority { get; set; } = eAccessPriority.Normal; + + /// + /// Gets or sets the connector access priority used for the start/done handshake write + /// (the batched WriteBatchAsync of the acknowledging after the + /// deferred action completes). Defaults to . + /// Can be seeded via the overloads + /// or set directly any time. + /// + public eAccessPriority HandshakeWriteAccessPriority { get; set; } = eAccessPriority.Normal; + protected void InitializeRemoteActionType() { _ActionType = RemoteActionType.Method; @@ -43,8 +61,14 @@ protected void InitializeRemoteActionType() /// Initializes this . /// /// Action to be executed on this call. - public void Initialize(Action deferredAction) + /// Connector access priority for the handshake read. Defaults to . + /// Connector access priority for the handshake write (Done ack). Defaults to . + public void Initialize(Action deferredAction, + eAccessPriority handshakeReadAccessPriority = eAccessPriority.Normal, + eAccessPriority handshakeWriteAccessPriority = eAccessPriority.Normal) { + HandshakeReadAccessPriority = handshakeReadAccessPriority; + HandshakeWriteAccessPriority = handshakeWriteAccessPriority; DeferredAction = deferredAction; this.IsInitialized.Cyclic = true; this.StartSignature.Subscribe(ExecuteAsync); @@ -57,8 +81,14 @@ public void Initialize(Action deferredAction) /// Initializes this . /// /// Action to be executed on this call. - public void Initialize(Func deferredAction) + /// Connector access priority for the handshake read. Defaults to . + /// Connector access priority for the handshake write (Done ack). Defaults to . + public void Initialize(Func deferredAction, + eAccessPriority handshakeReadAccessPriority = eAccessPriority.Normal, + eAccessPriority handshakeWriteAccessPriority = eAccessPriority.Normal) { + HandshakeReadAccessPriority = handshakeReadAccessPriority; + HandshakeWriteAccessPriority = handshakeWriteAccessPriority; DeferredAction = new Action(() => deferredAction()); this.IsInitialized.Cyclic = true; this.StartSignature.Subscribe(ExecuteAsync); @@ -74,13 +104,19 @@ public void Initialize(Func deferredAction) /// to initialize this will throw an exception. /// /// Action to be executed on this call. - public void InitializeExclusively(Action deferredAction) + /// Connector access priority for the handshake read. Defaults to . + /// Connector access priority for the handshake write (Done ack). Defaults to . + public void InitializeExclusively(Action deferredAction, + eAccessPriority handshakeReadAccessPriority = eAccessPriority.Normal, + eAccessPriority handshakeWriteAccessPriority = eAccessPriority.Normal) { if (_defferedActionCount > 0) { throw new MultipleRemoteCallInitializationException("There was an attempt to initialize exclusive RPC call more than once in this application."); } + HandshakeReadAccessPriority = handshakeReadAccessPriority; + HandshakeWriteAccessPriority = handshakeWriteAccessPriority; DeferredAction = deferredAction; this.IsInitialized.Cyclic = true; this.StartSignature.Subscribe(ExecuteAsync); @@ -94,13 +130,19 @@ public void InitializeExclusively(Action deferredAction) /// to initialize this will throw an exception. /// /// Action to be executed on this call. - public void InitializeExclusively(Func deferredAction) + /// Connector access priority for the handshake read. Defaults to . + /// Connector access priority for the handshake write (Done ack). Defaults to . + public void InitializeExclusively(Func deferredAction, + eAccessPriority handshakeReadAccessPriority = eAccessPriority.Normal, + eAccessPriority handshakeWriteAccessPriority = eAccessPriority.Normal) { if (_defferedActionCount > 0) { throw new MultipleRemoteCallInitializationException("There was an attempt to initialize exclusive RPC call more than once in this application."); } + HandshakeReadAccessPriority = handshakeReadAccessPriority; + HandshakeWriteAccessPriority = handshakeWriteAccessPriority; DeferredAction = new Action(() => deferredAction()); this.IsInitialized.Cyclic = true; this.StartSignature.Subscribe(ExecuteAsync); @@ -114,13 +156,19 @@ public void InitializeExclusively(Func deferredAction) /// to initialize this will throw an exception. /// /// Action to be executed on this call. - public void InitializeExclusively(Func deferredAction) + /// Connector access priority for the handshake read. Defaults to . + /// Connector access priority for the handshake write (Done ack). Defaults to . + public void InitializeExclusively(Func deferredAction, + eAccessPriority handshakeReadAccessPriority = eAccessPriority.Normal, + eAccessPriority handshakeWriteAccessPriority = eAccessPriority.Normal) { if (_defferedActionCount > 0) { throw new MultipleRemoteCallInitializationException("There was an attempt to initialize exclusive RPC call more than once in this application."); } + HandshakeReadAccessPriority = handshakeReadAccessPriority; + HandshakeWriteAccessPriority = handshakeWriteAccessPriority; DeferredAction = deferredAction; this.IsInitialized.Cyclic = true; this.StartSignature.Subscribe(ExecuteAsync); @@ -143,96 +191,99 @@ public void DeInitialize() protected async void ExecuteAsync(AXSharp.Connector.ITwinPrimitive sender, AXSharp.Connector.ValueTypes.ValueChangedEventArgs args) { - //await (this as ITwinObject).ReadAsync(); - await this.StartSignature.GetAsync(); - await this.DoneSignature.GetAsync(); - - if (this.StartSignature.LastValue != 0 && - !IsRunning && - this.StartSignature.LastValue != this.DoneSignature.LastValue) + //await (this as ITwinObject).ReadAsync(); + //await this.StartSignature.GetAsync(); + //await this.DoneSignature.GetAsync(); + + await this.Connector.ReadBatchAsync(new ITwinPrimitive[] { this.StartSignature, this.DoneSignature }, HandshakeReadAccessPriority); + + if (this.StartSignature.LastValue != 0 && + !IsRunning && + this.StartSignature.LastValue != this.DoneSignature.LastValue) + { + try { - try + IsRunning = true; + RemoteExecutionException = null; + switch (DeferredAction) { - IsRunning = true; - RemoteExecutionException = null; - - switch (DeferredAction) - { - case Action action: - await System.Threading.Tasks.Task.Run(() => { action(); }); - break; - case Func funcTask: - await System.Threading.Tasks.Task.Run(async () => { await funcTask(); }); - break; - case Func func: - await System.Threading.Tasks.Task.Run(() => { func(); }); - break; - } - - //switch (this._ActionType) - //{ - // case RemoteActionType.Func: - // await System.Threading.Tasks.Task.Run(() => { ((Func)DeferredAction)(); }); - // break; - - // case RemoteActionType.FuncRuturnTask: - - // Func castedDeferredAction = (Func)DeferredAction; - // await System.Threading.Tasks.Task.Factory.StartNew(castedDeferredAction).Unwrap(); - // break; - - // //await System.Threading.Tasks.Task.Run(async () => { await ((Func)DeferredAction)(); }); - // //break; - - // case RemoteActionType.Action: - - // await System.Threading.Tasks.Task.Factory.StartNew( - // (Action)DeferredAction - // , TaskCreationOptions.AttachedToParent - // ); - - // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); - - // break; - - // case RemoteActionType.Method: - // await Task.Factory.StartNew( - // (Action)DeferredAction - // , TaskCreationOptions.AttachedToParent - // ); - - // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); - - // break; - - // default: - // await Task.Factory.StartNew( - // (Action)DeferredAction - // , TaskCreationOptions.AttachedToParent - // ); - - // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); - - // break; - //} - } - catch (Exception ex) - { - await this.HasRemoteException.SetAsync(true); - await this.ErrorDetails.SetAsync(ex.Message); - RemoteExecutionException = ex; - RemoteExceptionDetails = ex.Message; - AxoApplication.Current.Logger.Error(ex.ToString(), this, new GenericIdentity("Controller")); - return; + case Action action: + await System.Threading.Tasks.Task.Run(() => { action(); }); + break; + case Func funcTask: + await System.Threading.Tasks.Task.Run(async () => { await funcTask(); }); + break; + case Func func: + await System.Threading.Tasks.Task.Run(() => { func(); }); + break; } - finally - { - IsRunning = false; - } - - await this.DoneSignature.SetAsync(this.StartSignature.LastValue); + + //switch (this._ActionType) + //{ + // case RemoteActionType.Func: + // await System.Threading.Tasks.Task.Run(() => { ((Func)DeferredAction)(); }); + // break; + + // case RemoteActionType.FuncRuturnTask: + + // Func castedDeferredAction = (Func)DeferredAction; + // await System.Threading.Tasks.Task.Factory.StartNew(castedDeferredAction).Unwrap(); + // break; + + // //await System.Threading.Tasks.Task.Run(async () => { await ((Func)DeferredAction)(); }); + // //break; + + // case RemoteActionType.Action: + + // await System.Threading.Tasks.Task.Factory.StartNew( + // (Action)DeferredAction + // , TaskCreationOptions.AttachedToParent + // ); + + // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); + + // break; + + // case RemoteActionType.Method: + // await Task.Factory.StartNew( + // (Action)DeferredAction + // , TaskCreationOptions.AttachedToParent + // ); + + // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); + + // break; + + // default: + // await Task.Factory.StartNew( + // (Action)DeferredAction + // , TaskCreationOptions.AttachedToParent + // ); + + // //await System.Threading.Tasks.Task.Run(() => { ((Action)DeferredAction).Invoke(); }); + + // break; + //} + } + catch (Exception ex) + { + await this.HasRemoteException.SetAsync(true); + await this.ErrorDetails.SetAsync(ex.Message); + RemoteExecutionException = ex; + RemoteExceptionDetails = ex.Message; + AxoApplication.Current.Logger.Error(ex.ToString(), this, new GenericIdentity("Controller")); + return; + } + finally + { + IsRunning = false; } + + //await this.DoneSignature.SetAsync(this.StartSignature.LastValue); + this.DoneSignature.Cyclic = this.StartSignature.LastValue; + await this.Connector.WriteBatchAsync(new ITwinPrimitive[] { this.DoneSignature }, HandshakeWriteAccessPriority); } + } private Exception _remoteExecutionException; diff --git a/src/core/tests/AXOpen.Core.Tests/AxoRemoteTask/AxoRemoteTaskTests.cs b/src/core/tests/AXOpen.Core.Tests/AxoRemoteTask/AxoRemoteTaskTests.cs index 01037abaf..57ab81078 100644 --- a/src/core/tests/AXOpen.Core.Tests/AxoRemoteTask/AxoRemoteTaskTests.cs +++ b/src/core/tests/AXOpen.Core.Tests/AxoRemoteTask/AxoRemoteTaskTests.cs @@ -1,4 +1,6 @@ -using System.Security.Principal; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Security.Principal; using AXOpen; using AXOpen.Logging; using AXSharp.Connector; @@ -141,4 +143,151 @@ public async void ResumeTask_WhenCalled_SetsRemoteResumeCyclicToTrue() Assert.True(await _axoTask.RemoteResume.GetAsync()); } } + + /// + /// A that records the passed to + /// every batch read/write, so a test can assert which priority the handshake used. + /// Captures into queues because the connector's background RwCycle also calls these methods + /// (with the default ); membership of the configured value + /// is the unambiguous signal. + /// + internal sealed class RecordingConnector : DummyConnector + { + public readonly ConcurrentQueue ReadPriorities = new(); + public readonly ConcurrentQueue WritePriorities = new(); + + public override Task ReadBatchAsync(IEnumerable primitives, + eAccessPriority priority = eAccessPriority.Normal, int chunkSize = 250, int interChunkDelay = 250) + { + ReadPriorities.Enqueue(priority); + return base.ReadBatchAsync(primitives, priority, chunkSize, interChunkDelay); + } + + public override Task WriteBatchAsync(IEnumerable primitives, + eAccessPriority priority = eAccessPriority.Normal, int chunkSize = 250, int interChunkDelay = 250) + { + WritePriorities.Enqueue(priority); + return base.WriteBatchAsync(primitives, priority, chunkSize, interChunkDelay); + } + } + + /// + /// Factory that yields a through the normal adapter pipeline, + /// so the connector's ConnectorAdapter gets wired (a directly-constructed connector would + /// NRE in the twin's constructor). + /// + internal sealed class RecordingConnectorFactory : DummyConnectorFactory + { + public override Connector CreateConnector(object[] parameters) => new RecordingConnector(); + } + + /// + /// Exposes the protected start/done handshake (ExecuteAsync(sender, args)) for direct + /// invocation. We drive the handshake directly rather than via the connector's read cycle: the + /// read cycle (BuildAndStart) self-deadlocks on its internal + /// lock, so it never raises the value-changed event that would normally fire the handshake. + /// Invoking directly (without BuildAndStart) keeps the connector lock free so the batched + /// read/write actually execute and the recording connector can capture their priorities. + /// + internal sealed class TestableAxoRemoteTask : AxoRemoteTask + { + public TestableAxoRemoteTask(ITwinObject parent, string readableTail, string symbolTail) + : base(parent, readableTail, symbolTail) { } + + // sender/args are unused by the handshake body; null! avoids nullable-ref warnings. + public void InvokeHandshake() => ExecuteAsync(null!, null!); + } + + public class AxoRemoteTaskHandshakePriorityTests + { + private static TestableAxoRemoteTask CreateSut(out RecordingConnector recording) + { + // Go through the adapter pipeline so the connector's ConnectorAdapter is wired + // (a directly-constructed connector would NRE in the twin's constructor). + var adapter = new ConnectorAdapter(typeof(RecordingConnectorFactory)) { Parameters = new object[] { } }; + recording = (RecordingConnector)adapter.GetConnector(null); + return new TestableAxoRemoteTask(recording, "a", "b"); + } + + private static async Task WaitUntilAsync(Func condition, int timeoutMs) + { + var sw = Stopwatch.StartNew(); + while (sw.ElapsedMilliseconds < timeoutMs) + { + if (condition()) return true; + await Task.Delay(20); + } + return condition(); + } + + [Fact] + public async Task Initialize_SetsHandshakeReadPriority_UsedByReadBatch() + { + var sut = CreateSut(out var recording); + sut.Initialize(() => { }, eAccessPriority.UserInterface, eAccessPriority.UserInterface); + + // StartSignature left at 0 so the handshake reads but takes no action branch: + // a clean, deterministic capture of just the read priority. + sut.InvokeHandshake(); + + var captured = await WaitUntilAsync( + () => recording.ReadPriorities.Contains(eAccessPriority.UserInterface), 5000); + + Assert.True(captured, "Read handshake (ReadBatchAsync) should use the configured HandshakeReadAccessPriority."); + } + + [Fact] + public async Task Initialize_SetsHandshakeWritePriority_UsedByWriteBatch() + { + var sut = CreateSut(out var recording); + // Distinct read (Normal) vs write (UserInterface) so the assertion proves the WRITE + // property specifically drives the Done-ack write. + sut.Initialize(() => { }, eAccessPriority.Normal, eAccessPriority.UserInterface); + + // Start != 0 and != Done so the deferred action runs and the Done-ack write fires. + await sut.StartSignature.SetAsync(2); + sut.InvokeHandshake(); + + var captured = await WaitUntilAsync( + () => recording.WritePriorities.Contains(eAccessPriority.UserInterface), 8000); + + Assert.True(captured, "Write ack (WriteBatchAsync) should use the configured HandshakeWriteAccessPriority."); + } + + [Fact] + public async Task Initialize_WithoutPriorityArgs_DefaultsToNormal_NotHigh() + { + var sut = CreateSut(out var recording); + sut.Initialize(() => { }); // no priority args + + Assert.Equal(eAccessPriority.Normal, sut.HandshakeReadAccessPriority); + Assert.Equal(eAccessPriority.Normal, sut.HandshakeWriteAccessPriority); + + await sut.StartSignature.SetAsync(2); + sut.InvokeHandshake(); + + // Pins the deliberate behavioral change: the handshake no longer runs at High. + var readOk = await WaitUntilAsync(() => recording.ReadPriorities.Contains(eAccessPriority.Normal), 5000); + var writeOk = await WaitUntilAsync(() => recording.WritePriorities.Contains(eAccessPriority.Normal), 8000); + Assert.True(readOk, "Default read handshake priority should be Normal."); + Assert.True(writeOk, "Default write handshake priority should be Normal."); + Assert.DoesNotContain(eAccessPriority.High, recording.ReadPriorities); + Assert.DoesNotContain(eAccessPriority.High, recording.WritePriorities); + } + + [Fact] + public async Task HandshakeReadAccessPriority_SetOnPropertyAfterInitialize_IsHonored() + { + var sut = CreateSut(out var recording); + sut.Initialize(() => { }); // defaults to Normal + sut.HandshakeReadAccessPriority = eAccessPriority.UserInterface; // retune via property + + sut.InvokeHandshake(); + + var captured = await WaitUntilAsync( + () => recording.ReadPriorities.Contains(eAccessPriority.UserInterface), 5000); + + Assert.True(captured, "Priority set on the property after Initialize should be honored by the handshake."); + } + } } \ No newline at end of file diff --git a/src/data/ctrl/AXSharp.config.json b/src/data/ctrl/AXSharp.config.json index cbfca1369..c0706c11d 100644 --- a/src/data/ctrl/AXSharp.config.json +++ b/src/data/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Data","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_data.csproj","UiHostProject":"..\\src\\AXOpen.Data.Blazor\\axopen_data_blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Data","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_data.csproj","UiHostProject":"..\\src\\AXOpen.Data.Blazor\\axopen_data_blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/inspectors/ctrl/AXSharp.config.json b/src/inspectors/ctrl/AXSharp.config.json index 3714a1dc5..59d47dded 100644 --- a/src/inspectors/ctrl/AXSharp.config.json +++ b/src/inspectors/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Inspectors","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_inspectors.csproj","UiHostProject":"..\\src\\AXOpen.Inspectors.blazor\\AxOpen.Inspectors.Blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Inspectors","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_inspectors.csproj","UiHostProject":"..\\src\\AXOpen.Inspectors.blazor\\AxOpen.Inspectors.Blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/io/ctrl/AXSharp.config.json b/src/io/ctrl/AXSharp.config.json index e7e6cc099..18c83161f 100644 --- a/src/io/ctrl/AXSharp.config.json +++ b/src/io/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Io","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_io.csproj","UiHostProject":"..\\src\\AXOpen.Io.blazor\\AXOpen.Io.blazor.csproj"} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Io","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_io.csproj","UiHostProject":"..\\src\\AXOpen.Io.blazor\\AXOpen.Io.blazor.csproj","SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/probers/ctrl/AXSharp.config.json b/src/probers/ctrl/AXSharp.config.json index fdd6bd4cc..661aa6085 100644 --- a/src/probers/ctrl/AXSharp.config.json +++ b/src/probers/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Probers","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_probers.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Probers","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_probers.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/showcase/app/AXSharp.config.json b/src/showcase/app/AXSharp.config.json index e6888ce9e..bd6c68ede 100644 --- a/src/showcase/app/AXSharp.config.json +++ b/src/showcase/app/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"ix","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"showcase.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"ix","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"showcase.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/showcase/app/hwc/hwc.gen/plc_line.SecurityConfiguration.json b/src/showcase/app/hwc/hwc.gen/plc_line.SecurityConfiguration.json index 716d0466d..69f1f54bb 100644 --- a/src/showcase/app/hwc/hwc.gen/plc_line.SecurityConfiguration.json +++ b/src/showcase/app/hwc/hwc.gen/plc_line.SecurityConfiguration.json @@ -1,9 +1,9 @@ { - "PKIData": "AQAAAAAAAAAAAAAAAAAAAAEBAb4gAAACAAAAAAAAAAAAAwAAAN8ALS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkdsYW1ZSHdRUzRpMjVlU2kvdHE1TzlIb0k1YgpQb1l3MFJiaDF2bTlVRFY4SHVVVXkrSiswM1c4RklrVmhhRG1IbjVMQ0Q5T01TZEs4VTNMQUp6OE1PcDhZMTAwCk91T3lCYnhmam5zT1RpNVZlMERCUlp6MWM1b0xsRjJkK3hhR2NBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCnsBAQACAAAnEAAgnsAjq+7cjygk1ZekVCSLVoaYwBE5U7VZFHO517+umjEBACAADAAQV3bwXMC9ZEyD26iryWx8WwEAAAE2JMWPXDSGhOCk43nnssaQua6rtSc1GAyveGPNqx1x6RkGSJBTDkSBa9yVkHesruve/lR6hGgnfN+fpT39LIPg7eiKZeZv+GsTwuRNSK/YZOSRigZhc1Ngtp8EcI6j/sjWzPmnErcmnypwXuZIAR4p4iERHkRtUdgGPeGNs19DxBKQcD2BTrcOE596UuiLGjDu7qvnv6I1SAnm7bqu4EQ1ABk7JglqbU7YjLE1Y/b47ebihx+J89thRQh5xInQUJuxd8kcB+pjVEsvgC99J4GaLqLpXJPlBwVnrVPRpNFkkfmAgVSxmZEt+I87aGnHTQg5hclrXdnpipuGS6lOOnq9aMF9OXf1QfplxrSGRaubcJEBSTrBbPOzEFWeO9X0fz1c/gBfGs8897uT8g4UzNPfMdlll/AdQQIACWxvY2FsaG9zdAEAAAAAAAAAAQAAAAIAAAAAAAAAFADfZfmK8KmL0EF8M7zqbCWJPcaRM7QGAQAGsC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQ0KTUlJRXN6Q0NBNXVnQXdJQkFnSVVDUGdQeTR6RFdUb2VBZVl1T0tWRzYrMUdtaTh3RFFZSktvWklodmNOQVFFTEJRQXdlekVMTUFrRw0KQTFVRUJoTUNXRmd4RWpBUUJnTlZCQWdNQ1ZOMFlYUmxUbUZ0WlRFUk1BOEdBMVVFQnd3SVEybDBlVTVoYldVeEZEQVNCZ05WQkFvTQ0KQzBOdmJYQmhibmxPWVcxbE1Sc3dHUVlEVlFRTERCSkRiMjF3WVc1NVUyVmpkR2x2Yms1aGJXVXhFakFRQmdOVkJBTU1DV3h2WTJGcw0KYUc5emREQWVGdzB5TmpBMU16QXhPVEF6TXpSYUZ3MHpOakExTWpjeE9UQXpNelJhTUhzeEN6QUpCZ05WQkFZVEFsaFlNUkl3RUFZRA0KVlFRSURBbFRkR0YwWlU1aGJXVXhFVEFQQmdOVkJBY01DRU5wZEhsT1lXMWxNUlF3RWdZRFZRUUtEQXREYjIxd1lXNTVUbUZ0WlRFYg0KTUJrR0ExVUVDd3dTUTI5dGNHRnVlVk5sWTNScGIyNU9ZVzFsTVJJd0VBWURWUVFEREFsc2IyTmhiR2h2YzNRd2dnRWlNQTBHQ1NxRw0KU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRRG9IY2tOZzhtcUszcXdsei9velhUS2RUTkVvbC93YkMxTVJLNFc5N1Y4a1JENQ0KeW04S1ljOUs0dHBTQXh6ck1QcUkvaG9SMXJpTjhmRlhvNU1HeHNVeDdpRTZrRXNjZ1RhL1p4NWZDMWhzRFEzL3NMVnhtblJLb29SSA0KdktWbVZtS1g1UDE4NVBLTUUyaUtyWDNNY0xxUkJ1WS9EbE5weVgxQmlndFFISFZhaFJSSlhDWElZYjlOZ0ZSVnlOTzNnL29qTFdabg0KWVcyWGhGMS9xaGNzOFRZS0MzS2dXNlRyc2FLcS9YZ3dtRDRBN3JtMksvNllUYXdLTy9tVEd2YjJGcCtWcUVhY0UzZ3YxMFdGaTVycQ0KalNkcXBOZWFySUJtSVZCalRwdjVKVEs3cHlzTzRDNmJTTlFHb1lnWmZDblJJSEpmK2cxVUlZYkZ6R29iZ0JHMVpXS3pBZ01CQUFHag0KZ2dFdE1JSUJLVEFKQmdOVkhSTUVBakFBTUE0R0ExVWREd0VCL3dRRUF3SUM5REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSQ0KS3dZQkJRVUhBd0l3RXdZRFZSMFJCQXd3Q29JQWh3VEFxR1FCaGdBd0hRWURWUjBPQkJZRUZBOTh4WGFXVEJNUDloL0FmZWxwT2R2Kw0KVXZYME1JRzRCZ05WSFNNRWdiQXdnYTJBRkE5OHhYYVdUQk1QOWgvQWZlbHBPZHYrVXZYMG9YK2tmVEI3TVFzd0NRWURWUVFHRXdKWQ0KV0RFU01CQUdBMVVFQ0F3SlUzUmhkR1ZPWVcxbE1SRXdEd1lEVlFRSERBaERhWFI1VG1GdFpURVVNQklHQTFVRUNnd0xRMjl0Y0dGdQ0KZVU1aGJXVXhHekFaQmdOVkJBc01Fa052YlhCaGJubFRaV04wYVc5dVRtRnRaVEVTTUJBR0ExVUVBd3dKYkc5allXeG9iM04wZ2hRSQ0KK0EvTGpNTlpPaDRCNWk0NHBVYnI3VWFhTHpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQUZGd05BWGd2OGt1OW1jZmFOcE1ydWRPdg0KTHpleHB0QnpzUUlvQUd5K09raEQzbTVOekpvc2tUWFIyb3FUL1NJeGp1OGVyczg4NjNKQ2lRMVdwSnZnMUZoVVNXaUI4dDQvbFAxbQ0KcGdaOVBoQVJHY0c5czlNSUVqaUNjbWxiOFpoMDNHNGVZN09ydmNZZ1ZPWjR5MGx2dThrNzFyN1pzVTB2eXBzaHd5NEg3MisyQ1A1dg0KcVZlUEdiQ3pVcEowT2JYVHd0bXpxMHVIVE9GVFl1N3A0bnhMVzhPcklaaDBGMFk1R0hTcEJ3VDVFb3BVY3BmbnhadnFuS0l1em5WWg0KOVlEdzNxMUt6VFh6UTdtL3c3QnlWMkk4MldReGVCSmhZTXBmOEFsYXZ3UHFMdFNyQWI5VHl5UkJCSWNYaGFNa1N1RTM4SHVpYjR0VQ0KSGZkQWxMZzVOWHlGdEE9PQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ0KFwgBAACzAQACAHwwejAUBgcqhkjOPQIBBgkrJAMDAggBAQsDYgAEesms4Jr2FTqrIcOap2DlOx8AHNBX/zq4jx+k9SCw95moNI7LUxmf89RsDA3EOh3dRuUftkZZ2E1WsLqh0TLflgDK3x66P9OoakIplJ5saZLamHsrp1J7RsBz/vc4FHOrGc8R/d8aP8yqCh2C5jJP4QAgORTMYx+3he7iDh5VU3YKo7e6HyFD9FkD06n4vFjRCaEHXi0tLS0tQkVHSU4gRU5DUllQVEVEIFBSSVZBVEUgS0VZLS0tLS0KTUlJRk5UQmZCZ2txaGtpRzl3MEJCUTB3VWpBeEJna3Foa2lHOXcwQkJRd3dKQVFRYkNCbUZTZGx3dHFCZ2RpUQpyL2Jub3dJQ0NBQXdEQVlJS29aSWh2Y05BZ2tGQURBZEJnbGdoa2dCWlFNRUFTb0VFSFRvMTNrcHRuVGFQZFVkCitSakR4N0VFZ2dUUURyT1pvM0VadGY2RVd3YnQwY1JSSk8yWHdPUUd4c2xvd1JXZ3dIc1c4bU9xL2ZhNnV4dGsKbmw2T1p6a2VGU1ltTTlSWFdoME5Fd3c4ZE01RkhiZG1qU0pkREVKOFdnWFVnZDJJMjJHWDFROFVqNFlHZ0FqWgpHM2VUTlVadmFjRDNUamZwVHEySE9SS0g4MjJkV3R3dkJlRDQ3WHpzOXVUN21sQzVSQ0lzQ0MzUW03V25PRmNNCm1YMjBMRWFPSk9tVFRDYmtlcFBWQVhXV2hGWlRnK1BxSElmOHNOczBjOE5YcEg2b2NGaTE3elY1dDR6Z2dNL0cKRkgyb2lJaFEyMkxxMjhLa2I5YTlBaThhMWZvd3pFUFhKTGhoQUtMV25zUVJ1bTcveHhlZDJzSmF1dDJpbUpyNApXMHBZeW5zOW85Q3hjaXlySEd5MWs4dVNxTFh3ajc3ZE5ISVNZcVdvRUFKMkJXMkF5c0tlMXlTdTdNZ3dxd0ZICnM0OGV5ZGNnTFJmY003TGo1a1ZkSUZhUDlHM054RW1DeWZLaEJ6WGhUS2tKQk1leXArZXRJTkE3SDVJNnRiem8KTWdSbWRVdUFJZ3l3VitIamFMbWp3dmFyL3gzYk52YkhRRjNBQjRCbHZmQVpaYjNmbitRSWVmdk9WekJKeUhTMgpVMjN4eGh3Q0RnY2xmU0VGemxFNGVWL1ZSMndrcDRBWWVUN0QzOVhFeUV3SFVRREExV3FJSVI1UG1QblBlVU9tCm41VCtEL24xQmVrTE9WVFpnb0NhSExuZ21mcmNHUnBydFd6bGRqc1V4ZWpCZ1dBNTNIQjZnMUlEWVdKY1UwaEwKTzBTNlBuTGVZYjZ3K1ovcUI1Z0RpZG55TFRTVDVUbzVGcGRtblFUOGNuSFA2bHhNRW10TzFsY0dzVjRoWlRWdwpDNTVuQytzeHZwaXJVY2EvTHFzdzBUSFhjSTJmd2RVN1lQamlKcTV2WTlDRlFUKzAybVVBMlJJZjIvcmh1VnBrCnFCZlpPYVZTa0FiNTBvRnU5blFtRkY3UC80Z2RudWxFT0xldm43NmJyaVE2R1BhK0J0S2tINDlRcnZFNWZnY0oKUlRVZ0FoZ0tqSjJ1NFo1MWw0blVxWHR0VVQxa2J6OCtSVXRLSGFsc1lscERubTVpc2pBWS91ZVFwcGhlKzR5RAp0ejNJNkRJaTd2dTRjTktLTmlUeC9hbytkWTRTbGt3cjVQNkRiNzNHRk5EczhSNHliaDJYYlBJZCtRckRWR0FnCnkwSDVpRVZEUGhZcERCS05GWGdUdTNOVS9FOS8zS3lQZkcvM3pTZ3dJNlZmV2dCd1Era2JvajVXU0FBcWVaSDMKOU5XZitPcVgwb1FFVWhENExONWxiYmhtVEJqcjlrL0dMUmtKdm9kZ0RiV0pqUFE3VUhSQUhjOVI5MjhBZHJndgpaT0g1WFl1Z2xYaktzeldyNUZQc2szVjF2QXBBOTh5K3ptVm5kU0MrZmZMdmoySXphY0pXSkRsQVByZHhzZUcyClJqYlJUaG5BT05zc2JYSnoyTVFxRkpYcXFPQzQ3c3BCemlHM0Y2T3dHQW9Qc3VaUXQ4OGl3YlR1SWpLSE9jYXkKUGlQaG96cm9VY0JsTHZhVllhdU5xNFdkNDFnRUROWnVtSkptVXR4NkExQVFQSk1kTWluN2NDSDhWYVZBMUNYSgo3SU05S09zYXRqYUdJNkFUUWpEb0UyaHNHL0YvZjBNNnU2dTZkY1JQYWFxKzRpQWlDV24yNTljMGVEQzdRdWlhCjVQZjRiZ2Y0T2UrTDBQOGNiWmxXR0JpYjZLSVFoKzJteXRKYnZ1ZkpGWTE3OWh3Ukx2bEJMUzRRSHoxNmJoNVYKY09MOW5WTmpVWjQ1bG9WMjdtdGVNdmZITkVadGYvQzdSUFViaG5wcGJlVHgrVHNsOUdoTWs5bm0rd2hvOTVrRQpEVENiamFvdlgycmtQSEMyRTA4UGZPanc2NHBBRXk1U0JQNXdtOGR0UTJYeFdKN2llOHFUR1phTkZsbTVrRlNQCkIzTVFPZzZEaFlqaWw0ZW5DL2R3eVJaK3lJQUxIVUVEdkE1LzM5MzRMc2hOejYzaVorTnhwd1FkSytEZjgxWlAKeGJwdWtINUVLdmdvYmt2R3pwLzk3TmhBNzA2SHhaVlQ5NWczTFlheU5XWkJuVm1XM0xMdWJOUT0KLS0tLS1FTkQgRU5DUllQVEVEIFBSSVZBVEUgS0VZLS0tLS0KJEROUzosIElQIEFkZHJlc3M6MTkyLjE2OC4xMDAuMSwgVVJJOglsb2NhbGhvc3QCAAAAAAAAAAEAAAACAAAAAAAAABQA32X5ivCpi9BBfDO86mwliT3GkTO0BgEABrAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0NCk1JSUVzekNDQTV1Z0F3SUJBZ0lVQ1BnUHk0ekRXVG9lQWVZdU9LVkc2KzFHbWk4d0RRWUpLb1pJaHZjTkFRRUxCUUF3ZXpFTE1Ba0cNCkExVUVCaE1DV0ZneEVqQVFCZ05WQkFnTUNWTjBZWFJsVG1GdFpURVJNQThHQTFVRUJ3d0lRMmwwZVU1aGJXVXhGREFTQmdOVkJBb00NCkMwTnZiWEJoYm5sT1lXMWxNUnN3R1FZRFZRUUxEQkpEYjIxd1lXNTVVMlZqZEdsdmJrNWhiV1V4RWpBUUJnTlZCQU1NQ1d4dlkyRnMNCmFHOXpkREFlRncweU5qQTFNekF4T1RBek16UmFGdzB6TmpBMU1qY3hPVEF6TXpSYU1Ic3hDekFKQmdOVkJBWVRBbGhZTVJJd0VBWUQNClZRUUlEQWxUZEdGMFpVNWhiV1V4RVRBUEJnTlZCQWNNQ0VOcGRIbE9ZVzFsTVJRd0VnWURWUVFLREF0RGIyMXdZVzU1VG1GdFpURWINCk1Ca0dBMVVFQ3d3U1EyOXRjR0Z1ZVZObFkzUnBiMjVPWVcxbE1SSXdFQVlEVlFRRERBbHNiMk5oYkdodmMzUXdnZ0VpTUEwR0NTcUcNClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURvSGNrTmc4bXFLM3F3bHovb3pYVEtkVE5Fb2wvd2JDMU1SSzRXOTdWOGtSRDUNCnltOEtZYzlLNHRwU0F4enJNUHFJL2hvUjFyaU44ZkZYbzVNR3hzVXg3aUU2a0VzY2dUYS9aeDVmQzFoc0RRMy9zTFZ4bW5SS29vUkgNCnZLVm1WbUtYNVAxODVQS01FMmlLclgzTWNMcVJCdVkvRGxOcHlYMUJpZ3RRSEhWYWhSUkpYQ1hJWWI5TmdGUlZ5Tk8zZy9vakxXWm4NCllXMlhoRjEvcWhjczhUWUtDM0tnVzZUcnNhS3EvWGd3bUQ0QTdybTJLLzZZVGF3S08vbVRHdmIyRnArVnFFYWNFM2d2MTBXRmk1cnENCmpTZHFwTmVhcklCbUlWQmpUcHY1SlRLN3B5c080QzZiU05RR29ZZ1pmQ25SSUhKZitnMVVJWWJGekdvYmdCRzFaV0t6QWdNQkFBR2oNCmdnRXRNSUlCS1RBSkJnTlZIUk1FQWpBQU1BNEdBMVVkRHdFQi93UUVBd0lDOURBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUkNCkt3WUJCUVVIQXdJd0V3WURWUjBSQkF3d0NvSUFod1RBcUdRQmhnQXdIUVlEVlIwT0JCWUVGQTk4eFhhV1RCTVA5aC9BZmVscE9kdisNClV2WDBNSUc0QmdOVkhTTUVnYkF3Z2EyQUZBOTh4WGFXVEJNUDloL0FmZWxwT2R2K1V2WDBvWCtrZlRCN01Rc3dDUVlEVlFRR0V3SlkNCldERVNNQkFHQTFVRUNBd0pVM1JoZEdWT1lXMWxNUkV3RHdZRFZRUUhEQWhEYVhSNVRtRnRaVEVVTUJJR0ExVUVDZ3dMUTI5dGNHRnUNCmVVNWhiV1V4R3pBWkJnTlZCQXNNRWtOdmJYQmhibmxUWldOMGFXOXVUbUZ0WlRFU01CQUdBMVVFQXd3SmJHOWpZV3hvYjNOMGdoUUkNCitBL0xqTU5aT2g0QjVpNDRwVWJyN1VhYUx6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFGRndOQVhndjhrdTltY2ZhTnBNcnVkT3YNCkx6ZXhwdEJ6c1FJb0FHeStPa2hEM201TnpKb3NrVFhSMm9xVC9TSXhqdThlcnM4ODYzSkNpUTFXcEp2ZzFGaFVTV2lCOHQ0L2xQMW0NCnBnWjlQaEFSR2NHOXM5TUlFamlDY21sYjhaaDAzRzRlWTdPcnZjWWdWT1o0eTBsdnU4azcxcjdac1Uwdnlwc2h3eTRINzIrMkNQNXYNCnFWZVBHYkN6VXBKME9iWFR3dG16cTB1SFRPRlRZdTdwNG54TFc4T3JJWmgwRjBZNUdIU3BCd1Q1RW9wVWNwZm54WnZxbktJdXpuVloNCjlZRHczcTFLelRYelE3bS93N0J5VjJJODJXUXhlQkpoWU1wZjhBbGF2d1BxTHRTckFiOVR5eVJCQkljWGhhTWtTdUUzOEh1aWI0dFUNCkhmZEFsTGc1Tlh5RnRBPT0NCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NChcIAQAAswEAAgB8MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABFxKLs7Le4khH9IYkEsz9kcDDGDF8nvEVwgn+eeo0AtGH8Grj+KWKY5rS+d89rmWV2QhEsLD6MCq1wF3RvCRE3/4SboaY6x3+Sg5/roZ+lZ4KHRPJ1k59MfQ+CAUeYZIKIUNNk0LoDNbtoVKaMPRJ0QAINkAgqWvmvNdaLoz5A4cw06qvAvDvPM0TQcAvh10fZSQB14tLS0tLUJFR0lOIEVOQ1JZUFRFRCBQUklWQVRFIEtFWS0tLS0tCk1JSUZOVEJmQmdrcWhraUc5dzBCQlEwd1VqQXhCZ2txaGtpRzl3MEJCUXd3SkFRUXQvOHkzTXNtbUo1L25YdmYKbllUdWh3SUNDQUF3REFZSUtvWklodmNOQWdrRkFEQWRCZ2xnaGtnQlpRTUVBU29FRUh3ZVZURDBKUVltYmxmSQpITmNuRkgwRWdnVFFtRy9NanZabTFobUpHWHJZeUJxMU9iNjU5Mmx0V1pndlE5VmR0RzBYTHpocW1VS1JZbFVqCktXaTE3K1NiNi94VldHUHZMRU1HNDR6NVZPYWlXR1FSODA4cWY3cVZJY3NkNVdBNlk2UDJmR2JOeFBxYzNCWVUKK0xhUlJVdTRiSkZMSUNpM2htY1FFRFpzQkh4Ti8vekM4Wm9Balp2ajZoajlPcnoyMXhSK0hoTkRUUEtlelIzaApTTnExU2hSL0Yrb0haUXN2ZklwckxXQ1ppMEVEU0NRY2E0N2dVc1FHK2JyRkFlTHh1NlZ0azl0OGthVG5JTUk0CkJtc1gyRWYrem4yUmRmamhPVEh1SlZjcjRwRG1mQTVqT1E4NzNtOWdGM0NtWXlsTjgwK1huaFlGRm9WM3hqdjMKL0wxM01xU2x2Yldpa2VMUjhEcW1qZWhJaUlnVnZVazlzU3BEbnBQZjVVbEpwa1owb3VuMlVKTGpRN2ZVVDNWMApQZFBBN0o4TzVpdnJlMEFINkFKamVDdy9rZzlubWhmZDluYVZVazdOMjdPWHBOSEhLRDNjSFpkbDI3NDhPY2ZVCnl6K3hpRDlIY0FBdVRiSTNXdmQ2c0toVXhzbWZaQzk1dWhqWlNyR3FqTkdUVHRsbm1Od1JseURtc0tTZDZVaVkKclMxalR4ZFkzSWFwckxManRHZFlSeFFPaEcrcjZWakRoay9WT1V4UTQ1TklvWno0QXFNZm5XcnRYQktsd25nWgp6VS9BUEN5dGhEUWxGeHZOMGNadnM2bnp2RTVRMVpaN0wwaStEc01vbTR3MEZTWFhua1hWZzZzdVhNSmVBR0k4CmlwNC9NanFFM2x2Z2NqRE11cXRwZytzQzlyU0RqMzR5ZUtabTU1R0o3dmhSd2c0dlJ4TUVsbkNnR2ZjS2NQSFoKS0FqNlZaU3Y1cnE2Y0dEeEhYRTJYbTBEajlTd01qeFJqcnJ0QThEY3pycWdOZ2pYNzV4S3d3TkY5SlY5U3VEdAp2enlMYktZcFpHMUpIRThPT2ZWK3VVdFdCeXZwemJmLzEwWjZ2RHhTUkdJbFZmSzA4L0NJRmFzeEd3RG10VEsrCnJDNHdWS29aWk5vWWg4OHJiMGhVdGlCbnRDdlpqN1VoWFlHL1lOdjNmQ2NPSUVUb2hrcDIvQ3JFR1RJVjVTZFMKU1ltRDhVYlJJbzFNTExQSFhPMld4SC8rYU9aVmhubkY3N0tiTzlYdU1Md0VNVWh2V0FrM05jN1Vhdy9SQXY1UQo2b0NvOUMvZXdtTlFaU2NwRzN0eFN2QUh4bENKTG5tb05ISDNMOUtYZHhiNHU2MUpzN2JlamI4WnBVUFg0bGlRCnNwWGQ5ZXpWQ2Z4bkJ4LzNoSzJtNzZXMkRLNTVYOGQ5Vis0WjZzVFZwNnpWQ3g5cW9ldnNGTUk4Z0wrL1htVjkKUEtXeGREQW5SSXlXbGFkVm5BZ25ZUWJFSU1vZnF5Q0d3OE9Hb1BZeHl6eEtFeU1XM2RqaWlObG1HajllOFovVgp3NE5xNnV5SERyNlBER1ZNaFRWSXgrL3dieStCcDVhTXlpNEh2dElPcTQxZEhFVmhMb2pkMVRVRFFaYW51RFpJCmxia1ZtaFZBTjFld0trclY1QzNPTE9leUt0ZklITUliZVM1Q2lmRjJjRDh1YUIybG1jSDljMGtLblBQa2R3bTcKQUpSRktYZTV1REtTMG05WE9lMWVhdVVBMGpUWGxhRXV5dnZCNHh1Nmpzay96ZDM5V1lKQ0x3RUhXR2NuaWR1QgppSGcwOFliVTNJT2l0NVM5K2FZaU8zLzJpTGw2VEFtZnFEVldmdlpKSDdsY2Y4aTczbHpNaVNLM0haam5EeXgyCm0yUkJ0NVVlREZmUGcxelFmdFpCQTJQOGt6UnZYQ1Z2ZlZ0b25JY0ppdEgxSlRTb2U3UHpRQnYxS3RNV0ZzblUKbnZBb3VEVkkrcHVGTE1DelN0QUZBVXk2SDFrWGZsL1FYUFRtWE9ZK0NJakN1ZDZUVElMdUNyVC8wQ1ZncmN5cgpMSVFRWkRqUTVDNUdkWWg0RHRha3MyOEU4emV5S0M1MmZEZ0RCRkowcE11UEdGanJlRTUvLzhQZGtWZDl0VkpiCkdEdVhuODlQTWdhV0czYUxtY1ZtM1F4UkZKcHJCcEF5T3VnZzFKbEtQcDRtY1lLM3J6SGdFWFU9Ci0tLS0tRU5EIEVOQ1JZUFRFRCBQUklWQVRFIEtFWS0tLS0tCiRETlM6LCBJUCBBZGRyZXNzOjE5Mi4xNjguMTAwLjEsIFVSSTo=", - "UserData": "AgAAAAAAAAAAAAAAAAAAAAEAAAAFAGFkbWludAAAAAEAAAEBAAEFAAAnEAAAACAKxabqh8/HqSSmiUjmPTle47rkpbXX5RLQz3bEWqEJBQAAAECno5ExkpVRGcsAI9wjyUgLDqKgCbjXLR+ywfJt1ccUqxR9KuiOEwmq+UTuKxk1pLjkm2qOmARp03EtMTgAE1tBAA==", + "PKIData": "AQAAAAAAAAAAAAAAAAAAAAEBAb4gAAACAAAAAAAAAAAAAwAAAN8ALS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUhvd0ZBWUhLb1pJemowQ0FRWUpLeVFEQXdJSUFRRUxBMklBQkhKb2xiY2ZjODJ6c2M1N1pma2pVVm1OSmM2OApvMzV0am1yT3pTMTg2ZENpSnRNL2orVmQ1OStuK2VjRGZ2Z216akFHbVBlTThmR0xBTEpIS25sQkZIN2wva3krCjBwY1gwMldUVFEzejFKdmRIVmNyRlNXM0w0QlNjVjRBdlFWTGVnPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCnsBAQACAAAnEAAgY5oc5IhIfOMU6ti+bzmPj0Quhbi7QrXUD4weV32bO1YBACAADAAQ+wv2eA6ERCqiw9vMH4SntgEAAAE2F2NKqZDJejo5xZ/swJky3Ue+Zk2u4mHvBeFzejw4CRKH+haOka0yzF1FYfYpK01s4RneKbx0pP9D8MNyKHswu2xk6EEizhl1wJLmfw05M9hUyTqWoUM6SHg57G2aU7N8L6iNVQqBA2QB9a4p/nTGF+QRRaWWDnRzJ/5wcuc0/qdfesztbECCyc4Ktlp4aflTsedcT0mJ2nl0lclyYS6Y9/3q/UtOpMQ61M1aY3a5A2odW3dRyyJ9UHexQohrZCntpsfCO1mz9shJ/l2Gubek3G+HNGsXD39w0EqRIkE0jjpAPc7U32W/YXJlYvDWs0I+SfZtGT6Yyeek3YGssGSYfQKxR/xjBogsl/jB2FkKMimnPKnyU7/70y42QtsiSvhBu4HSQZUsVZFpN8810IHCSoCT4ek2xgIACWxvY2FsaG9zdAEAAAAAAAAAAQAAAAIAAAAAAAAAFAD0Di+A5nb0SP62Lv1ebsgRoLAmqbQGAQAGsC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQ0KTUlJRXN6Q0NBNXVnQXdJQkFnSVVHMDg2QVRmbDhiM0pjUE9PWkwzLzJVREdldTR3RFFZSktvWklodmNOQVFFTEJRQXdlekVMTUFrRw0KQTFVRUJoTUNXRmd4RWpBUUJnTlZCQWdNQ1ZOMFlYUmxUbUZ0WlRFUk1BOEdBMVVFQnd3SVEybDBlVTVoYldVeEZEQVNCZ05WQkFvTQ0KQzBOdmJYQmhibmxPWVcxbE1Sc3dHUVlEVlFRTERCSkRiMjF3WVc1NVUyVmpkR2x2Yms1aGJXVXhFakFRQmdOVkJBTU1DV3h2WTJGcw0KYUc5emREQWVGdzB5TmpBMk1ETXhNek0yTXpoYUZ3MHpOakExTXpFeE16TTJNemhhTUhzeEN6QUpCZ05WQkFZVEFsaFlNUkl3RUFZRA0KVlFRSURBbFRkR0YwWlU1aGJXVXhFVEFQQmdOVkJBY01DRU5wZEhsT1lXMWxNUlF3RWdZRFZRUUtEQXREYjIxd1lXNTVUbUZ0WlRFYg0KTUJrR0ExVUVDd3dTUTI5dGNHRnVlVk5sWTNScGIyNU9ZVzFsTVJJd0VBWURWUVFEREFsc2IyTmhiR2h2YzNRd2dnRWlNQTBHQ1NxRw0KU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3A1N3dIS3l4aXdBa0NRaTJIWElkN0puWThGTkxxZFhSZWt6MDJnOTFRbWFYdg0KTlVBUVpRRkRHdFBtNW83cXVtc04yM3QyOXRyQmgwMGpoL0V6TWZ4Q1pOeDBCYnFNaVhndng2Tk8yNmJwVGxEa1JYRm1RMDRmN2F6ZQ0KbWhPZWcrVWxHZm96L2Y4czRLcTAwY3U4eW9zU0xoZEtneUxmUGtSMzJjWkFNZENFMzRsL1dYTm5GVjVNOXA3b3QxZHZ2Y2s2RXFucg0KSXJYN3dxZm5wck1pMEVJTWxPVWdPbUd2MGRLSUdTOFdBUGNoN1VSRk5HU3ZlZ2RIV2p2ZjVlZ01BcVdhaXU1UnJEMEJDNnZsQlMxYw0KdGtQYlRxVkR0NEJUQ0g5VjltUXAzSm9MOWozOER6NndEdVl5SGI0M1p2S3hKQlN3NTJDUk15cFRVZ0hUWnVoSHZQL3pBZ01CQUFHag0KZ2dFdE1JSUJLVEFKQmdOVkhSTUVBakFBTUE0R0ExVWREd0VCL3dRRUF3SUM5REFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSQ0KS3dZQkJRVUhBd0l3RXdZRFZSMFJCQXd3Q29JQWh3VEFxR1FCaGdBd0hRWURWUjBPQkJZRUZFMC9QQTJ4NXMwSjIxWG5aVU84cWNPRw0KaW1oNE1JRzRCZ05WSFNNRWdiQXdnYTJBRkUwL1BBMng1czBKMjFYblpVTzhxY09HaW1oNG9YK2tmVEI3TVFzd0NRWURWUVFHRXdKWQ0KV0RFU01CQUdBMVVFQ0F3SlUzUmhkR1ZPWVcxbE1SRXdEd1lEVlFRSERBaERhWFI1VG1GdFpURVVNQklHQTFVRUNnd0xRMjl0Y0dGdQ0KZVU1aGJXVXhHekFaQmdOVkJBc01Fa052YlhCaGJubFRaV04wYVc5dVRtRnRaVEVTTUJBR0ExVUVBd3dKYkc5allXeG9iM04wZ2hRYg0KVHpvQk4rWHh2Y2x3ODQ1a3ZmL1pRTVo2N2pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVEyMHFLK3pWbU1IZzB4ajRZTFg5RXBXcg0KRitGVzZwb0JBZEc3UnBnNm5rTFd5ZGU3dTRDL3hqbDQyblNmeWVtV2dubSsxemFjdUJHU3ZDUFFEcHd1ODRYVno2TE9pL09tVDQzaQ0KYXMwaTNkTWV3Z2lwQ2FqTkp4M3lCSkwrWmJJU0lCUG8xY2lGMmZ2ZlE2d1hlQUg0WUtXU2RXRVo2OEhUMkpXVmNoNkZmOXJmUjFlYw0KRU43VnJ3ZE10NGxoTTZaSjl4bCtvbkRhR2NGa1VBY3BRc0lxRGhhUGdMUjBJNVlqbEl2Qi9zb3hkaE84ZjQ3UWVMcHNlSFI1N0J1NQ0KUnVETVVpNHp1cmJxM0xvRVJXUjEzUHBrU3dla2RjbEUrbGZLRmUyaHlObVlzUml2NEpJVE5pd2dyM2lPYm9IV2tDcDI2dUJYTUw0bw0KUUlmWHV4WHN5WGpmYkE9PQ0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ0KFwgBAACzAQACAHwwejAUBgcqhkjOPQIBBgkrJAMDAggBAQsDYgAEPb3QfFw1pAYrhQC/dOL9DcVuHD/GBQrqxSL7fRGwVEqD7wJOiTbS8NstXwAFSgA/XMSO80E4jBTd5K9A5JMUN2INAKIYoLljfthkGHDMfL3yTetRn21F8PU+FfPh87isgKFunR5EUVY6EYDt7BgXQwAgGLzIDwCaSNGAjMaoM35azRFLUvTZh17cxFs0Dwm1f28HXi0tLS0tQkVHSU4gRU5DUllQVEVEIFBSSVZBVEUgS0VZLS0tLS0KTUlJRk5UQmZCZ2txaGtpRzl3MEJCUTB3VWpBeEJna3Foa2lHOXcwQkJRd3dKQVFRSTNBWkFqRFRJbGd5UWtFSwo1TmRPbFFJQ0NBQXdEQVlJS29aSWh2Y05BZ2tGQURBZEJnbGdoa2dCWlFNRUFTb0VFQ1p1VXdQaTRCbkVNdUNOCnNVZmdVWUlFZ2dUUVBIbFhTWWphSmZmNVJrZ1Y5RVRuQVJsdlM5NWdoTElhRGpOWEtDU1dzQWYzNGxpcTcxaTIKRVZUUUZRNTlQdVNXU25KUjM2d3lURHRPTlFLYUNSMmRmTTVlRU9Mc29BcldEZEIxQkNDMmVhMm4wTTJocUxzZgpKeVplMGdvSVFGRXoxZGs1K3ZQVHBEMk1IZ0xucCtlQUo4VXp5N25tWEU5RWJma3FQc3R5UEJzcHpWUzZCZ3IzCmpvMlJlUHl0OENWTDhNWG52amROSGhnYUFGNGNNNzFEdGgrS2VnR1dKVjBpZC80TzB6WnFBaXhuTG5yZzBkNksKbXgyWTFJdXBTaE5JZEFzdHozZDNTYU1aTWJ2V2V6QmhQdnR5VlNWL1pzcUZIbU1FK1JseGZwbnZqMzgvSko0MgpLSzJTdGxyREpKN0w3Wk81VmdzSVo2Kzh4VUY0YW1KSXQ4dkVkNUZGZUgrQ2lvSWVid0NBMUV2ZVBDc2hNUEtSCmRkNS9kaVUwVjBFWUYxa2NNaENEOFR4U0ZjdU9wL3RRZTN4NTdvdW9lOUo1ZkJ0cVVwcGx1QmFqUjRraHpERWgKRFJYaHJrY1dVU3FjNUJjVFJiYXhuRHBsaDNZWDBkUzBmZDRtTXVCc0RZajJnMitOQVNpdkJKTE9nQURGNnFrWApCWTlZT1MwS3BpYjdZSnRXc05IRjZNSjVGZU5kd0UwQ3JYN0NDSjV4Y1l1WmcrT2srUXRRbVdSYlZzbDFLemMyCmtlTEJGRVZmWjlWUW8wSHpCWXBuNFJ5a0tCZ2sxNlc2MSs1dE1QYjlTK0J5Tk1YZ0ZXVWdQQlBzTWYrS3E1Mk4KU0VNTlBMQVJ3TVhUYXh3Rkt6QjZtbUNkUkM0OUdTVUhWNUxTbEkrK0p2aTQ4ZW1WUk01dzIySStNVXdwcEtpQgo1TnBTbG1ObUxwc2R2NDBsd09MWkRQeklYQ3RYN3hUeUNQS0xNTlg3Q1ArQWJNWWtNbGhRM0JOUWxYY3lxelR2CkR2VWVITFVRaU04aU5mQXhaN0U1WUpxNnViS3orbmhiYXhicDdrVURzb0dDMGdPbXFwRGpBTVdYUlBBRWZzRSsKZXlzV29acTh4RlN2Ujh5b1pYN0Fxb3FWUlJ3NmVnNWJvWXQzNFQ5K1E2eXBqMEl0QnlnTGptbXZydUFNcytyagpwYkRrZjcya29KTmdUOWxsZVdEa0pwZDZUVVVucWJ2TnhYL0xncUwyMmNyQUVyS3crMXBpdHJYWXU5RWFaejNTCkU5YkFZQXBDaG1vek5OcGhGNEphY1YvaGJBZHh2bCtVSFZrZU41MnhBSEcreEpkUU4wa1h2bHBIVVBGdHd0NEwKQm9Gd2xLeFZFTXZzK3Bta1M5WW44REJXL25uMWl3Z1lyZVBjbjRiZ1RjT3ZhMnBsdGd5ZEZhc2IwVG94alNKUQpsR2RMak9UL2RKTXRKeTE4bjFiOGJFeTRVWVlPK0pVbHlsZGYvU1JBVW1wdml3aXE2WFNmK0JERHE3bE54UTM1CkE0VTU1bnZ0WmhOSHZVNFRub2JnVGhkTUpJaGdiVlZPRWpXcUlvZ2ZUS0g5enJaY0poUUpocWhKdDRMcHNJbE0KZktjdlZGbVNjNTRHNFFSc3hSL3ZQWTQxTXRNYUdjNXJMVG5GdkJXeWFWa2NzdVRMV1piQTFvb3ZZUkNMWlA2ZApWcmpnK3NpL2M0bGd6OHNrZ0RENUp4SlRKT2dOUFZEbUp2aEFMZG9jTk41emxzTy9HNVBpUXQ0M0ZnSHh6TXBECnQzam9TRDJvR3V3ZnUzUHZJVW9YUUdrMjRpWHFoQVozL2lJcnl4cHNlN2NmNmZ3RU5zNkFpTVVyS3U3YXdrekcKNGxkUGpFckcrRit2Z1dkTU8veXlVZUlYd2Z2SysxRlF3YVNjQTE5aDdrZnRreVdpc1RieVhSYW9FSFI2SUxZRwpoVnU4djIwY1RHWnZKVmlYMVBBbnd2YXVsaTlmSUVZcmtRWlZwQitFNU51elhFa3FQcGZtUFBvTHdDV01KMU5uCmtVak4rVkNWWE5kWGEwbHdFVXE3OHdFSVQrNWRUQXZMTmZERkJOZC9EZklkM0FaWVZnaDFucXdmLytNS3dzV20KVTBDc1pEMUNRbm82S2ExWXY1MnYwWW9KajVLblNzbUZOcjVqbVJjazBjNnhSd081OWZsSHAvcz0KLS0tLS1FTkQgRU5DUllQVEVEIFBSSVZBVEUgS0VZLS0tLS0KJEROUzosIElQIEFkZHJlc3M6MTkyLjE2OC4xMDAuMSwgVVJJOglsb2NhbGhvc3QCAAAAAAAAAAEAAAACAAAAAAAAABQA9A4vgOZ29Ej+ti79Xm7IEaCwJqm0BgEABrAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0NCk1JSUVzekNDQTV1Z0F3SUJBZ0lVRzA4NkFUZmw4YjNKY1BPT1pMMy8yVURHZXU0d0RRWUpLb1pJaHZjTkFRRUxCUUF3ZXpFTE1Ba0cNCkExVUVCaE1DV0ZneEVqQVFCZ05WQkFnTUNWTjBZWFJsVG1GdFpURVJNQThHQTFVRUJ3d0lRMmwwZVU1aGJXVXhGREFTQmdOVkJBb00NCkMwTnZiWEJoYm5sT1lXMWxNUnN3R1FZRFZRUUxEQkpEYjIxd1lXNTVVMlZqZEdsdmJrNWhiV1V4RWpBUUJnTlZCQU1NQ1d4dlkyRnMNCmFHOXpkREFlRncweU5qQTJNRE14TXpNMk16aGFGdzB6TmpBMU16RXhNek0yTXpoYU1Ic3hDekFKQmdOVkJBWVRBbGhZTVJJd0VBWUQNClZRUUlEQWxUZEdGMFpVNWhiV1V4RVRBUEJnTlZCQWNNQ0VOcGRIbE9ZVzFsTVJRd0VnWURWUVFLREF0RGIyMXdZVzU1VG1GdFpURWINCk1Ca0dBMVVFQ3d3U1EyOXRjR0Z1ZVZObFkzUnBiMjVPWVcxbE1SSXdFQVlEVlFRRERBbHNiMk5oYkdodmMzUXdnZ0VpTUEwR0NTcUcNClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUNwNTd3SEt5eGl3QWtDUWkySFhJZDdKblk4Rk5McWRYUmVrejAyZzkxUW1hWHYNCk5VQVFaUUZER3RQbTVvN3F1bXNOMjN0Mjl0ckJoMDBqaC9Fek1meENaTngwQmJxTWlYZ3Z4Nk5PMjZicFRsRGtSWEZtUTA0ZjdhemUNCm1oT2VnK1VsR2Zvei9mOHM0S3EwMGN1OHlvc1NMaGRLZ3lMZlBrUjMyY1pBTWRDRTM0bC9XWE5uRlY1TTlwN290MWR2dmNrNkVxbnINCklyWDd3cWZucHJNaTBFSU1sT1VnT21HdjBkS0lHUzhXQVBjaDdVUkZOR1N2ZWdkSFdqdmY1ZWdNQXFXYWl1NVJyRDBCQzZ2bEJTMWMNCnRrUGJUcVZEdDRCVENIOVY5bVFwM0pvTDlqMzhEejZ3RHVZeUhiNDNadkt4SkJTdzUyQ1JNeXBUVWdIVFp1aEh2UC96QWdNQkFBR2oNCmdnRXRNSUlCS1RBSkJnTlZIUk1FQWpBQU1BNEdBMVVkRHdFQi93UUVBd0lDOURBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUkNCkt3WUJCUVVIQXdJd0V3WURWUjBSQkF3d0NvSUFod1RBcUdRQmhnQXdIUVlEVlIwT0JCWUVGRTAvUEEyeDVzMEoyMVhuWlVPOHFjT0cNCmltaDRNSUc0QmdOVkhTTUVnYkF3Z2EyQUZFMC9QQTJ4NXMwSjIxWG5aVU84cWNPR2ltaDRvWCtrZlRCN01Rc3dDUVlEVlFRR0V3SlkNCldERVNNQkFHQTFVRUNBd0pVM1JoZEdWT1lXMWxNUkV3RHdZRFZRUUhEQWhEYVhSNVRtRnRaVEVVTUJJR0ExVUVDZ3dMUTI5dGNHRnUNCmVVNWhiV1V4R3pBWkJnTlZCQXNNRWtOdmJYQmhibmxUWldOMGFXOXVUbUZ0WlRFU01CQUdBMVVFQXd3SmJHOWpZV3hvYjNOMGdoUWINClR6b0JOK1h4dmNsdzg0NWt2Zi9aUU1aNjdqQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFRMjBxSyt6Vm1NSGcweGo0WUxYOUVwV3INCkYrRlc2cG9CQWRHN1JwZzZua0xXeWRlN3U0Qy94amw0Mm5TZnllbVdnbm0rMXphY3VCR1N2Q1BRRHB3dTg0WFZ6NkxPaS9PbVQ0M2kNCmFzMGkzZE1ld2dpcENhak5KeDN5QkpMK1piSVNJQlBvMWNpRjJmdmZRNndYZUFINFlLV1NkV0VaNjhIVDJKV1ZjaDZGZjlyZlIxZWMNCkVON1Zyd2RNdDRsaE02Wko5eGwrb25EYUdjRmtVQWNwUXNJcURoYVBnTFIwSTVZamxJdkIvc294ZGhPOGY0N1FlTHBzZUhSNTdCdTUNClJ1RE1VaTR6dXJicTNMb0VSV1IxM1Bwa1N3ZWtkY2xFK2xmS0ZlMmh5Tm1Zc1JpdjRKSVROaXdncjNpT2JvSFdrQ3AyNnVCWE1MNG8NClFJZlh1eFhzeVhqZmJBPT0NCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0NChcIAQAAswEAAgB8MHowFAYHKoZIzj0CAQYJKyQDAwIIAQELA2IABEyQfGzVMv6LKxKmf6pfYo3UGWT3POKdWafSrQS0LgOMDASXoJnW7E2s6Yd4u8KnKCBhlBudtYN7jb0+Cdji5UPe82xv4tYsZcsr5Gid/W100aKwPP/LIOStk6UOAPhMicBmAE2LE19aXJFbO/9kfuUAINzympuVrtxyDi250XRzrMSfr7CeLM7pwtgdaJekJGwWB14tLS0tLUJFR0lOIEVOQ1JZUFRFRCBQUklWQVRFIEtFWS0tLS0tCk1JSUZOVEJmQmdrcWhraUc5dzBCQlEwd1VqQXhCZ2txaGtpRzl3MEJCUXd3SkFRUU1MekdqV1VFL0pKS0tIZVgKZUhrczFBSUNDQUF3REFZSUtvWklodmNOQWdrRkFEQWRCZ2xnaGtnQlpRTUVBU29FRVBQTTRHZFFwd08rdDhadApLcXZkbndBRWdnVFEzVWJWU3JDaEpYaXE0NDlqQnZSZE1WRFB5UC9zNWFDNkRtZytoYnhwc2ZrbU8zQkEvbm11ClgrMHUvYmV2VXNLYVJLREZNWXNvK2wxc1lTUmhsV05iL0lYQ3VTbTZVdnlVd1hyQXRzdFBxVFJJR2tPeU11aU0KSUlXZWVFUmljb2E3LzJTSVZ5K2ZjMTE3K2FwRExmZHBSVEJjcjZDMzFXaldjWE5taTVsejh2NklrQnVnK2tPQgptSnRybWJlbFpHVWtmSm1Dc2VVWGVLSVNpcDNsTUpJayt4bk9WWTBLVUxsbFJ3anlSeUZWVVhDQWdkLzE2RS9DCjMza2draEN2SFhKVlBCQm1QZWtWOHc2ZWc1eHFIRGNzYzJrRXNtZUlPWlByY01YSVRLOEFIMUlMWDNHb3ZVN2cKVE1UQXR5YnhqVU5hOVZnRDJLMlQ0eWJGZEx0Slhyd25vV1l2YUR2ckQ3anNXWUlGQ1lMTkw1TjJyaWNieVJ2bgo0dHJBSFdyUHpPSnFYMXdrWHU5cnMvUFlNYmVDdFhld2dhWlRqZ0FhWXBEL0JueldkRmxWTmJGeGtyNGN6aVFRCk1tOHBYMUhOdS90WDhJazJiQlBRejdGWFZDclBFY1EwWjFNQllyVlRlTERMUjM3M1MrK2ZZMFRDNEJyWTMvL1QKTDZzdVlGa1RTbC83aGxxR2VXa0hNSU0yeFhHWWpDRE9VK2NFL3BFbmxUaUt5STh0aVJrZVFqdmYxVGtvbE8vRwpKcGd2MG0ra1NTTjBmUWFBVlhyUHE5MFR1S1N6OENJdDlNWEhkR0hqU2pGS3dSdnByNkZSYzYxaFlKYktCdUk2CmUxNXh0YStGMTJLdE9nTmE1U0dtRWUzT3A5bXhnTHNPRTNWUFhHbUw0R1F6U0pVNGhPY3E1Z24vVEVSQ2U5d0sKbkppeUV4KzUyVWp1YXoxMVltTU14eFMveEtIblpmU1F0OEI1aXVOaEZiNkx4YmM4cjgxZ3JGemhnSUF0M3Q5RApQemxQSUFYaG11Y3NPbllyOFhiQTFVZXFDK2RONFAxS3k0M25RZ1lJcmZ5dWN3ZVJiVGg2Rm1YdEVtaGJJY28xCkNKTlVXU3hoaXcwUkZzWGlZcmRmM2hqa004em1MQyszZG9QUWpzTndGUXlFU1htYjlRV2VFUmZQcUx4eUViaFQKY1duQlVZTEZxSEprQ0N5cmtzRE9JVHB3S2xDM2tkZWFZTmlUZ1dTM3ZtVWIwOEMxQ3lvMXZTZWR6SFBHMUNBRwoyWGZ4Q214UVU2QU9mSEIyR0xFakVUWm01L0UyTnFXOXJXWVVBZW1hNE4vNXpSSC80blk2S2ZlR3NoQ1ZtczJhCkZXMDRvSjliWEpaWWpIMjAxWDlGS2xVV1pxWnJFQSswOTNUSEhaZ1FrdjllUDdhcHlyT0lhM0w2TThGVGRXakQKdUlTWnUwN1pqNTJYRWhRQlFYYWpHUjhNeGo4Tm92SnlSRk13L256M0F4T3ZqSFNhUDJFMzhXR2trcFJkUEN0aQp1TVNJcVNtVHhGOE10YzVDdkFtL0xkTFNGWFV1MUk4WUwzY253c2JpdUtoLzhFMVltWUhBZkx2ZHFrL2pZRHJzClJhdExLQzhSMisyeHB5WUs0Z3Z1K0dmaG4zYUpXcGVabUN5RXF2eEwzb1dXMmFHd1Q3cVRBNFMwY3JtM2JzeUYKdGpBbVo1OE1ZOWlXS09USyt6V2hPTW5CZTNkSXJKZlJuV0JuZFRKc29WT1RZWVBhejlhWjhNZjFxUThidmZyUAprWllnSk1rdEtTRlF4NHllUUpJOVpDeit5UEt6VUhqeGgzUkVDOFVaRGxhcDI3bmlaVitCc0krb3BZYXhNNzk0CjN6NHlTb0JpYWhWMlNJeU54VUV5cGNOZ1c4YW05VkVhVC93NitDQ3F0RGlEeE5SemN1SmIzZ2ozSkdaSTM3WlEKQUNNNVlyb2Z5NEVwbWt0VUNraW4yVGRQdXIzdzBweVQ1WEJ5UGV6NExDV0ZWaUZKRTA4UVptc2dDL2QrSTVUNgpwOGdVOTRTNkhwZ1ZTcXR1QUk4bXJ5Vk5TbTVnZTR0VURGQ1hIcjdxYnQvR3JYUGsxNGZtR0tUQTdlTmN5dy84Ck1GQ3gvMmRidC9wb3BvbkxNS0J5aFE2QTdaMEpTR0d6VGYzakp6WU05MEk2WUF1bklzOEZnUjg9Ci0tLS0tRU5EIEVOQ1JZUFRFRCBQUklWQVRFIEtFWS0tLS0tCiRETlM6LCBJUCBBZGRyZXNzOjE5Mi4xNjguMTAwLjEsIFVSSTo=", + "UserData": "AgAAAAAAAAAAAAAAAAAAAAEAAAAFAGFkbWludAAAAAEAAAEBAAEFAAAnEAAAACBBh8KeEcTRiRc0Uj4zNk64FKeh5ImQdkKhIuL8ybRCuwAAAECUuoMx3KMOqWjxhT/hnuu8ynMdEtRLXzewKMuwcWk28iPCe55DyNN3fbGjf3CUYeE9rw2lXCIAEGM/Eg4ckvQUAA==", "CertificateAssignments": { "TLS": 1, "WebServer": 2 }, - "AccessProtectionData": "AQAAAAAAAAAAAAAAAAAAAAABAABQAAAAAAEBAAAAAgDQBwAAIAANpF3looMeZYCQW82Ez/m7ygNZ4GOQh/SOZVs+tSWiISAAaEJNxqgEdFxXPR2gDNGn9FjPUzRFBg6WoJ3btPYSa/dQAAAAAAEBAAAAAgDQBwAAIAANpF3looMeZYCQW82Ez/m7ygNZ4GOQh/SOZVs+tSWiISAAGkVXUjiOBK8kPCZRHAArnvGe9nDngtos9GOsXUHRt41QAAAAAAEBAAAAAgDQBwAAIAANpF3looMeZYCQW82Ez/m7ygNZ4GOQh/SOZVs+tSWiISAAaEJNxqgEdFxXPR2gDNGn9FjPUzRFBg6WoJ3btPYSa/dQAAAAAAEBAAAAAgDQBwAAIAANpF3looMeZYCQW82Ez/m7ygNZ4GOQh/SOZVs+tSWiISAAaEJNxqgEdFxXPR2gDNGn9FjPUzRFBg6WoJ3btPYSa/cgAAAADaRd5aKDHmWAkFvNhM/5u8oDWeBjkIf0jmVbPrUloiE=" + "AccessProtectionData": "AQAAAAAAAAAAAAAAAAAAAAABAABQAAAAAAEBAAAAAgDQBwAAIAAaFivN/X5db84FXOnYNmQnGyd4OK3ELBLa9utCxhrurSAAsfyuPU9QwbRWVOp7yhdfMXgmgaXQjupD3cv46HMgyeVQAAAAAAEBAAAAAgDQBwAAIAAaFivN/X5db84FXOnYNmQnGyd4OK3ELBLa9utCxhrurSAASkoULcICwp1Uk41lqVRQ4TBr9vaSRqLicEF3VYlAFjZQAAAAAAEBAAAAAgDQBwAAIAAaFivN/X5db84FXOnYNmQnGyd4OK3ELBLa9utCxhrurSAAsfyuPU9QwbRWVOp7yhdfMXgmgaXQjupD3cv46HMgyeVQAAAAAAEBAAAAAgDQBwAAIAAaFivN/X5db84FXOnYNmQnGyd4OK3ELBLa9utCxhrurSAAsfyuPU9QwbRWVOp7yhdfMXgmgaXQjupD3cv46HMgyeUgAAAAGhYrzf1+XW/OBVzp2DZkJxsneDitxCwS2vbrQsYa7q0=" } \ No newline at end of file diff --git a/src/showcase/app/ix-blazor/showcase.blazor/Pages/core/AxoTask.razor b/src/showcase/app/ix-blazor/showcase.blazor/Pages/core/AxoTask.razor index d6c88eff6..6198ff959 100644 --- a/src/showcase/app/ix-blazor/showcase.blazor/Pages/core/AxoTask.razor +++ b/src/showcase/app/ix-blazor/showcase.blazor/Pages/core/AxoTask.razor @@ -49,7 +49,8 @@
  • -
  • +
  • +
  • @@ -116,6 +117,32 @@

    Click Invoke. After a short run the task calls Abort() and lands in Aborted — the button turns amber, a stop icon appears, and a Resume button shows next to Reset task. Resume continues; Reset returns to Ready.

    +
    +

    AxoTaskView — Disabled (display-only) rendering

    +

    + A disabled AxoTaskView keeps its activity indicator live: the state ring/circle for active + states (Ready, Kicking, Busy) and the terminal icons (Done, Aborted, Error) render just as when enabled. What changes is + the trailing edge: a lock-closed icon replaces the Reset / Resume buttons and the control is non-interactive. One task below is kept + perpetually Busy, a second stays Ready (not busy) — compare the controllable + view with the disabled / display-only views for both an active and an idle task. +
    + Note: disabling a task on the PLC side (SetIsDisabled(TRUE)) aborts it while Busy, so this is a view-level disable of a genuinely running task. +

    +
    +
    +

    Controllable — AxoTaskCommandView

    + +
    +
    +

    Disabled, active (Busy) — AxoTaskStatusView (live Busy circle + lock in the action area)

    + +
    +
    +

    Disabled, idle (Ready) — AxoTaskStatusView (Ready ring + lock in the action area)

    + +
    +
    +
    @@ -409,6 +436,7 @@ private readonly string _plcTaskExamplePath = "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskExample.st"; private readonly string _plcTaskErrorPath = "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskErrorExample.st"; private readonly string _plcTaskAbortedPath = "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskAbortedExample.st"; + private readonly string _plcTaskDisabledPath = "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDisabledExample.st"; private readonly string _plcMomentaryDocuPath = "src/showcase/app/src/core/AXOpen.AxoMomentaryTask/AxoMomentaryTaskDocuExample.st"; private readonly string _plcToggleDocuPath = "src/showcase/app/src/core/AXOpen.AxoToggleTask/AxoToggleTaskDocuExample.st"; private readonly string _plcRemoteDocuPath = "src/showcase/app/src/core/AXOpen.AxoRemoteTask/AxoRemoteTaskDocuExample.st"; @@ -482,5 +510,7 @@ this.StartPolling(Entry.Plc.Ctx.AxoRemoteTasks._remoteTask, 250); this.StartPolling(Entry.Plc.Ctx.AxoTaskError._failingTask, 250); this.StartPolling(Entry.Plc.Ctx.AxoTaskAborted._abortingTask, 250); + this.StartPolling(Entry.Plc.Ctx.AxoTaskDisabled._activeTask, 250); + this.StartPolling(Entry.Plc.Ctx.AxoTaskDisabled._idleTask, 250); } } diff --git a/src/showcase/app/ix-blazor/showcase.blazor/Services/Search/ShowcasePageRegistry.cs b/src/showcase/app/ix-blazor/showcase.blazor/Services/Search/ShowcasePageRegistry.cs index a8e4dbe93..23a552a85 100644 --- a/src/showcase/app/ix-blazor/showcase.blazor/Services/Search/ShowcasePageRegistry.cs +++ b/src/showcase/app/ix-blazor/showcase.blazor/Services/Search/ShowcasePageRegistry.cs @@ -18,12 +18,13 @@ public static List GetAllPages() => Category = "Core", Description = "Task execution for PLC programs. Covers AxoTask, AxoMomentaryTask, AxoToggleTask, and AxoRemoteTask.", Icon = "play", - Tags = ["task", "fire and forget", "momentary", "toggle", "remote task", "control flow", "error", "aborted", "state"], + Tags = ["task", "fire and forget", "momentary", "toggle", "remote task", "control flow", "error", "aborted", "state", "disabled", "lock", "display only"], SourceFilePaths = [ "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDocuExample.st", "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskExample.st", "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskErrorExample.st", "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskAbortedExample.st", + "src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDisabledExample.st", "src/showcase/app/src/core/AXOpen.AxoMomentaryTask/AxoMomentaryTaskDocuExample.st", "src/showcase/app/src/core/AXOpen.AxoToggleTask/AxoToggleTaskDocuExample.st", "src/showcase/app/src/core/AXOpen.AxoRemoteTask/AxoRemoteTaskDocuExample.st", diff --git a/src/showcase/app/src/ShowcaseContext.st b/src/showcase/app/src/ShowcaseContext.st index 8ddda6493..63973c421 100644 --- a/src/showcase/app/src/ShowcaseContext.st +++ b/src/showcase/app/src/ShowcaseContext.st @@ -18,6 +18,7 @@ CLASS ShowcaseContext EXTENDS AXOpen.Core.AxoContext AxoTaskDocu : AxoTaskExamples.AxoTaskDocuExample; AxoTaskError : AxoTaskExamples.AxoTaskErrorExample; AxoTaskAborted : AxoTaskExamples.AxoTaskAbortedExample; + AxoTaskDisabled : AxoTaskExamples.AxoTaskDisabledExample; // ---- Core: AxoToggleTask ---- AxoToggleTasks : AxoToggleTaskExamples.Tasks; @@ -154,6 +155,9 @@ CLASS ShowcaseContext EXTENDS AXOpen.Core.AxoContext THIS.InitializeRootObject(AxoTaskAborted); AxoTaskAborted.Execute(); + THIS.InitializeRootObject(AxoTaskDisabled); + AxoTaskDisabled.Execute(); + THIS.InitializeRootObject(AxoToggleTasks); AxoToggleTasks.Execute(); diff --git a/src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDisabledExample.st b/src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDisabledExample.st new file mode 100644 index 000000000..82e5b2dc8 --- /dev/null +++ b/src/showcase/app/src/core/AXOpen.AxoTask/AxoTaskDisabledExample.st @@ -0,0 +1,49 @@ +USING AXOpen.Core; + +NAMESPACE AxoTaskExamples + + // Demonstrates the disabled-state indicator in AxoTaskView: + // - The task is kept perpetually Busy (self-invoked, never completed), + // so it always sits in an "active" state. + // - Rendering this task through a DISABLED / display-only AxoTaskView + // (Disable=true, e.g. the Status presentation) draws the activity + // circle with a lock icon INSIDE it, instead of replacing the circle. + // - Note: a task disabled on the PLC side via SetIsDisabled(TRUE) aborts + // while Busy (see AxoTaskLight.Execute), so the lock-inside-circle + // visual is a VIEW-level disable of a genuinely running task. + {S7.extern=ReadWrite} + CLASS AxoTaskDisabledExample EXTENDS AXOpen.Core.AxoObject + + // + VAR PUBLIC + {#ix-set:AttributeName = "<#Always-active task — render display-only#>"} + _activeTask : AXOpen.Core.AxoTask; + {#ix-set:AttributeName = "<#Idle (Ready) task — render display-only#>"} + _idleTask : AXOpen.Core.AxoTask; + END_VAR + // + + METHOD PUBLIC Execute + + // + _activeTask.Run(THIS); + _idleTask.Run(THIS); + // + + // + // Execute() first (satisfies the cyclic-execute-called check), then + // Invoke(). Invoke() only acts while the task is Ready, so once the + // task is Busy it is a no-op and the task stays active indefinitely. + _activeTask.Execute(); + _activeTask.Invoke(); + // + + // + // _idleTask is wired into the object tree but never invoked, so it + // stays in the Ready (not-busy) state. Rendered through a disabled + // view it shows the lock inside the empty Ready circle. + // + + END_METHOD + END_CLASS +END_NAMESPACE diff --git a/src/simatic1500/ctrl/AXSharp.config.json b/src/simatic1500/ctrl/AXSharp.config.json index 444624184..2159d2507 100644 --- a/src/simatic1500/ctrl/AXSharp.config.json +++ b/src/simatic1500/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"ix","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_simatic1500.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"ix","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_simatic1500.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/styling/src/wwwroot/css/momentum.css b/src/styling/src/wwwroot/css/momentum.css index 049a6f306..182a9cae2 100644 --- a/src/styling/src/wwwroot/css/momentum.css +++ b/src/styling/src/wwwroot/css/momentum.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-orange-50:oklch(98% .016 73.684);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-lime-400:oklch(84.1% .238 128.85);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-cyan-50:oklch(98.4% .019 200.873);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-900:oklch(39.8% .07 227.392);--color-sky-400:oklch(74.6% .16 232.661);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-500:oklch(62.7% .265 303.9);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-3xl:48rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.bottom-0{bottom:calc(var(--spacing) * 0)}.-z-1{z-index:calc(1 * -1)}.z-10{z-index:10}.z-\[600\]{z-index:600}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing) * 0)!important}.m-0{margin:calc(var(--spacing) * 0)}.m-0\!{margin:calc(var(--spacing) * 0)!important}.m-1{margin:calc(var(--spacing) * 1)}.m-2{margin:calc(var(--spacing) * 2)}.m-4{margin:calc(var(--spacing) * 4)}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-auto{margin-block:auto}.ms-1{margin-inline-start:calc(var(--spacing) * 1)}.ms-2{margin-inline-start:calc(var(--spacing) * 2)}.ms-4{margin-inline-start:calc(var(--spacing) * 4)}.ms-auto{margin-inline-start:auto}.me-1{margin-inline-end:calc(var(--spacing) * 1)}.me-2{margin-inline-end:calc(var(--spacing) * 2)}.me-4{margin-inline-end:calc(var(--spacing) * 4)}.me-6{margin-inline-end:calc(var(--spacing) * 6)}.me-auto{margin-inline-end:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-\[15vh\]{margin-top:15vh}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flex\!{display:flex!important}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-auto{height:auto}.h-full{height:100%}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.min-h-40{min-height:calc(var(--spacing) * 40)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-50{width:calc(var(--spacing) * 50)}.w-75{width:calc(var(--spacing) * 75)}.w-100{width:calc(var(--spacing) * 100)}.w-125{width:calc(var(--spacing) * 125)}.w-\[1px\]{width:1px}.w-auto{width:auto}.w-full{width:100%}.w-md{width:var(--container-md)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-200{max-width:calc(var(--spacing) * 200)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-20{min-width:calc(var(--spacing) * 20)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-\[10rem\]{min-width:10rem}.min-w-\[12rem\]{min-width:12rem}.flex-1{flex:1}.flex-\[2\]{flex:2}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow-1,.grow,.grow-1{flex-grow:1}.basis-1\/3{flex-basis:33.3333%}.basis-2\/3{flex-basis:66.6667%}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-row\!{flex-direction:row!important}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-center\!{align-items:center!important}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing) * 0)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-visible{overflow-y:visible}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b,.border-b-1{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-solid{--tw-border-style:solid;border-style:solid}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/50{border-color:color-mix(in oklab, var(--color-blue-500) 50%, transparent)}}.border-current{border-color:currentColor}.border-cyan-200{border-color:var(--color-cyan-200)}.border-cyan-400{border-color:var(--color-cyan-400)}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.border-green-500\/50{border-color:color-mix(in oklab, var(--color-green-500) 50%, transparent)}}.border-orange-200{border-color:var(--color-orange-200)}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab, red, red)){.border-orange-400\/50{border-color:color-mix(in oklab, var(--color-orange-400) 50%, transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-slate-400\/35{border-color:#90a1b959}@supports (color:color-mix(in lab, red, red)){.border-slate-400\/35{border-color:color-mix(in oklab, var(--color-slate-400) 35%, transparent)}}.border-slate-500\/40{border-color:#62748e66}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/40{border-color:color-mix(in oklab, var(--color-slate-500) 40%, transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/50{border-color:color-mix(in oklab, var(--color-yellow-500) 50%, transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-current{background-color:currentColor}.bg-cyan-50{background-color:var(--color-cyan-50)}.bg-cyan-100\/40{background-color:#cefafe66}@supports (color:color-mix(in lab, red, red)){.bg-cyan-100\/40{background-color:color-mix(in oklab, var(--color-cyan-100) 40%, transparent)}}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-green-500{background-color:var(--color-green-500)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-400\/20{background-color:#90a1b933}@supports (color:color-mix(in lab, red, red)){.bg-slate-400\/20{background-color:color-mix(in oklab, var(--color-slate-400) 20%, transparent)}}.bg-slate-500{background-color:var(--color-slate-500)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-700\/40{background-color:#31415866}@supports (color:color-mix(in lab, red, red)){.bg-slate-700\/40{background-color:color-mix(in oklab, var(--color-slate-700) 40%, transparent)}}.bg-slate-800\/60{background-color:#1d293d99}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/60{background-color:color-mix(in oklab, var(--color-slate-800) 60%, transparent)}}.bg-slate-900\/35{background-color:#0f172b59}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/35{background-color:color-mix(in oklab, var(--color-slate-900) 35%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\/60{background-color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab, red, red)){.bg-white\/80{background-color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-linear-to-br{--tw-gradient-position:to bottom right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-br{--tw-gradient-position:to bottom right in oklab}}.bg-linear-to-br{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-r{--tw-gradient-position:to right in oklab}}.bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-cyan-50{--tw-gradient-from:var(--color-cyan-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-green-500{--tw-gradient-from:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-0\%{--tw-gradient-from-position:0%}.via-amber-400{--tw-gradient-via:var(--color-amber-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-cyan-500{--tw-gradient-via:var(--color-cyan-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-lime-400{--tw-gradient-via:var(--color-lime-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-500{--tw-gradient-via:var(--color-purple-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-sky-400{--tw-gradient-via:var(--color-sky-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-yellow-400{--tw-gradient-via:var(--color-yellow-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-green-500{--tw-gradient-to:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-50\%{--tw-gradient-to-position:50%}.\!p-0{padding:calc(var(--spacing) * 0)!important}.p-0{padding:calc(var(--spacing) * 0)}.p-0\!{padding:calc(var(--spacing) * 0)!important}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\!{padding-inline:calc(var(--spacing) * 1)!important}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\!{padding-inline:calc(var(--spacing) * 2)!important}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\!{padding-block:calc(var(--spacing) * 1)!important}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\!{padding-block:calc(var(--spacing) * 2)!important}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-nowrap{text-wrap:nowrap}.wrap-anywhere{overflow-wrap:anywhere}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-600\/80{color:#dd7400cc}@supports (color:color-mix(in lab, red, red)){.text-amber-600\/80{color:color-mix(in oklab, var(--color-amber-600) 80%, transparent)}}.text-amber-700{color:var(--color-amber-700)}.text-blue-500{color:var(--color-blue-500)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-900{color:var(--color-cyan-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-100{color:var(--color-gray-100)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-inherit{color:inherit}.text-inherit\!{color:inherit!important}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-slate-100\/95{color:#f1f5f9f2}@supports (color:color-mix(in lab, red, red)){.text-slate-100\/95{color:color-mix(in oklab, var(--color-slate-100) 95%, transparent)}}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-400\/90{color:#90a1b9e6}@supports (color:color-mix(in lab, red, red)){.text-slate-400\/90{color:color-mix(in oklab, var(--color-slate-400) 90%, transparent)}}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-slate-900\/70{color:#0f172bb3}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/70{color:color-mix(in oklab, var(--color-slate-900) 70%, transparent)}}.text-slate-900\/85{color:#0f172bd9}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/85{color:color-mix(in oklab, var(--color-slate-900) 85%, transparent)}}.text-slate-900\/90{color:#0f172be6}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/90{color:color-mix(in oklab, var(--color-slate-900) 90%, transparent)}}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.placeholder-slate-400::placeholder{color:var(--color-slate-400)}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(34\,197\,94\,0\.6\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#22c55e99);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-blue-500\/50{--tw-shadow-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.shadow-blue-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-green-500\/50{--tw-shadow-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.shadow-green-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-green-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-orange-400\/40{--tw-shadow-color:#ff8b1a66}@supports (color:color-mix(in lab, red, red)){.shadow-orange-400\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-orange-400) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-red-500\/50{--tw-shadow-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.shadow-red-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-red-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-yellow-500\/50{--tw-shadow-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.shadow-yellow-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-yellow-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-400{--tw-duration:.4s;transition-duration:.4s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[assembly\:InternalsVisibleTo\(\"axopen\.inspectors_tests\"\)\]{assembly:InternalsVisibleTo("axopen.inspectors tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests\"\)\]{assembly:InternalsVisibleTo("axopen core tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests_L1\"\)\]{assembly:InternalsVisibleTo("axopen core tests L1")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsabbrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsabbrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsballuffidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsballuffidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentscognexvision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentscognexvision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdesouttertightening_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdesouttertightening tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsfestodrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsfestodrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskeyencevision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskeyencevision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskukarobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskukarobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsmitsubishirobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsmitsubishirobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothpress_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothpress tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentssiemidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentssiemidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsurrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsurrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopenio_tests\"\)\]{assembly:InternalsVisibleTo("axopenio tests")}.\[assembly\:InternalsVisibleTo\(\"components\.dukane\.welders_tests\"\)\]{assembly:InternalsVisibleTo("components.dukane.welders tests")}.\[assembly\:InternalsVisibleTo\(\"components\.rexroth\.tightening_tests\"\)\]{assembly:InternalsVisibleTo("components.rexroth.tightening tests")}.\[assembly\:InternalsVisibleTo\(\"components\.siem\.communication_tests\"\)\]{assembly:InternalsVisibleTo("components.siem.communication tests")}.\[assembly\:InternalsVisibleTo\(\"components\.zebra\.vision_tests\"\)\]{assembly:InternalsVisibleTo("components.zebra.vision tests")}.\[assembly\:InternalsVisibleTo\(\"elementscomponents_tests\"\)\]{assembly:InternalsVisibleTo("elementscomponents tests")}.\[assembly\:InternalsVisibleTo\(\"librarytemplate_tests\"\)\]{assembly:InternalsVisibleTo("librarytemplate tests")}.\[assembly\:InternalsVisibleTo\(\"pneumaticcomponents_tests\"\)\]{assembly:InternalsVisibleTo("pneumaticcomponents tests")}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-slate-300:hover{border-color:var(--color-slate-300)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-600:hover{background-color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-cyan-500:focus{border-color:var(--color-cyan-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-cyan-200:focus{--tw-ring-color:var(--color-cyan-200)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:inline{display:inline}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media (min-width:48rem){.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (min-width:80rem){.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}} \ No newline at end of file +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-orange-50:oklch(98% .016 73.684);--color-orange-200:oklch(90.1% .076 70.697);--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-600:oklch(64.6% .222 41.116);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-lime-400:oklch(84.1% .238 128.85);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-cyan-50:oklch(98.4% .019 200.873);--color-cyan-100:oklch(95.6% .045 203.388);--color-cyan-200:oklch(91.7% .08 205.041);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-cyan-700:oklch(52% .105 223.128);--color-cyan-900:oklch(39.8% .07 227.392);--color-sky-400:oklch(74.6% .16 232.661);--color-blue-500:oklch(62.3% .214 259.815);--color-purple-500:oklch(62.7% .265 303.9);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-xl:36rem;--container-3xl:48rem;--container-4xl:56rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-2{top:calc(var(--spacing) * 2)}.right-2{right:calc(var(--spacing) * 2)}.bottom-0{bottom:calc(var(--spacing) * 0)}.-z-1{z-index:calc(1 * -1)}.z-10{z-index:10}.z-\[600\]{z-index:600}.col-span-2{grid-column:span 2/span 2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.\!m-0{margin:calc(var(--spacing) * 0)!important}.m-0{margin:calc(var(--spacing) * 0)}.m-0\!{margin:calc(var(--spacing) * 0)!important}.m-1{margin:calc(var(--spacing) * 1)}.m-2{margin:calc(var(--spacing) * 2)}.m-4{margin:calc(var(--spacing) * 4)}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-auto{margin-block:auto}.ms-1{margin-inline-start:calc(var(--spacing) * 1)}.ms-2{margin-inline-start:calc(var(--spacing) * 2)}.ms-4{margin-inline-start:calc(var(--spacing) * 4)}.ms-auto{margin-inline-start:auto}.me-1{margin-inline-end:calc(var(--spacing) * 1)}.me-2{margin-inline-end:calc(var(--spacing) * 2)}.me-4{margin-inline-end:calc(var(--spacing) * 4)}.me-6{margin-inline-end:calc(var(--spacing) * 6)}.me-auto{margin-inline-end:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-\[15vh\]{margin-top:15vh}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0{margin-bottom:calc(var(--spacing) * 0)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-4{margin-left:calc(var(--spacing) * 4)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.flex\!{display:flex!important}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-15{height:calc(var(--spacing) * 15)}.h-auto{height:auto}.h-full{height:100%}.max-h-\[50vh\]{max-height:50vh}.max-h-\[70vh\]{max-height:70vh}.min-h-40{min-height:calc(var(--spacing) * 40)}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-15{width:calc(var(--spacing) * 15)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-50{width:calc(var(--spacing) * 50)}.w-75{width:calc(var(--spacing) * 75)}.w-100{width:calc(var(--spacing) * 100)}.w-125{width:calc(var(--spacing) * 125)}.w-\[1px\]{width:1px}.w-auto{width:auto}.w-full{width:100%}.w-md{width:var(--container-md)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-200{max-width:calc(var(--spacing) * 200)}.max-w-none{max-width:none}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-20{min-width:calc(var(--spacing) * 20)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-\[10rem\]{min-width:10rem}.min-w-\[12rem\]{min-width:12rem}.flex-1{flex:1}.flex-\[2\]{flex:2}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow-1,.grow,.grow-1{flex-grow:1}.basis-1\/3{flex-basis:33.3333%}.basis-2\/3{flex-basis:66.6667%}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-move{cursor:move}.cursor-pointer{cursor:pointer}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-row\!{flex-direction:row!important}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-center\!{align-items:center!important}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing) * 0)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 4) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-1{row-gap:calc(var(--spacing) * 1)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-slate-100>:not(:last-child)){border-color:var(--color-slate-100)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-y-visible{overflow-y:visible}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.rounded-l-md{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md)}.rounded-r-md{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.border-b,.border-b-1{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-solid{--tw-border-style:solid;border-style:solid}.border-blue-500\/50{border-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/50{border-color:color-mix(in oklab, var(--color-blue-500) 50%, transparent)}}.border-current{border-color:currentColor}.border-cyan-200{border-color:var(--color-cyan-200)}.border-cyan-400{border-color:var(--color-cyan-400)}.border-green-500\/50{border-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.border-green-500\/50{border-color:color-mix(in oklab, var(--color-green-500) 50%, transparent)}}.border-orange-200{border-color:var(--color-orange-200)}.border-orange-400\/50{border-color:#ff8b1a80}@supports (color:color-mix(in lab, red, red)){.border-orange-400\/50{border-color:color-mix(in oklab, var(--color-orange-400) 50%, transparent)}}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-slate-100{border-color:var(--color-slate-100)}.border-slate-200{border-color:var(--color-slate-200)}.border-slate-300{border-color:var(--color-slate-300)}.border-slate-400\/35{border-color:#90a1b959}@supports (color:color-mix(in lab, red, red)){.border-slate-400\/35{border-color:color-mix(in oklab, var(--color-slate-400) 35%, transparent)}}.border-slate-500\/40{border-color:#62748e66}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/40{border-color:color-mix(in oklab, var(--color-slate-500) 40%, transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/50{border-color:color-mix(in oklab, var(--color-yellow-500) 50%, transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-current{background-color:currentColor}.bg-cyan-50{background-color:var(--color-cyan-50)}.bg-cyan-100\/40{background-color:#cefafe66}@supports (color:color-mix(in lab, red, red)){.bg-cyan-100\/40{background-color:color-mix(in oklab, var(--color-cyan-100) 40%, transparent)}}.bg-cyan-500{background-color:var(--color-cyan-500)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-green-500{background-color:var(--color-green-500)}.bg-orange-50{background-color:var(--color-orange-50)}.bg-red-500{background-color:var(--color-red-500)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-slate-200{background-color:var(--color-slate-200)}.bg-slate-400\/20{background-color:#90a1b933}@supports (color:color-mix(in lab, red, red)){.bg-slate-400\/20{background-color:color-mix(in oklab, var(--color-slate-400) 20%, transparent)}}.bg-slate-500{background-color:var(--color-slate-500)}.bg-slate-700{background-color:var(--color-slate-700)}.bg-slate-700\/40{background-color:#31415866}@supports (color:color-mix(in lab, red, red)){.bg-slate-700\/40{background-color:color-mix(in oklab, var(--color-slate-700) 40%, transparent)}}.bg-slate-800\/60{background-color:#1d293d99}@supports (color:color-mix(in lab, red, red)){.bg-slate-800\/60{background-color:color-mix(in oklab, var(--color-slate-800) 60%, transparent)}}.bg-slate-900\/35{background-color:#0f172b59}@supports (color:color-mix(in lab, red, red)){.bg-slate-900\/35{background-color:color-mix(in oklab, var(--color-slate-900) 35%, transparent)}}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/60{background-color:#fff9}@supports (color:color-mix(in lab, red, red)){.bg-white\/60{background-color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab, red, red)){.bg-white\/80{background-color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.bg-yellow-400{background-color:var(--color-yellow-400)}.bg-yellow-500{background-color:var(--color-yellow-500)}.bg-linear-to-br{--tw-gradient-position:to bottom right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-br{--tw-gradient-position:to bottom right in oklab}}.bg-linear-to-br{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-linear-to-r{--tw-gradient-position:to right}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-r{--tw-gradient-position:to right in oklab}}.bg-linear-to-r{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-cyan-50{--tw-gradient-from:var(--color-cyan-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-emerald-50{--tw-gradient-from:var(--color-emerald-50);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-green-500{--tw-gradient-from:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-red-500{--tw-gradient-from:var(--color-red-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-0\%{--tw-gradient-from-position:0%}.via-amber-400{--tw-gradient-via:var(--color-amber-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-cyan-500{--tw-gradient-via:var(--color-cyan-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-lime-400{--tw-gradient-via:var(--color-lime-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-purple-500{--tw-gradient-via:var(--color-purple-500);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-sky-400{--tw-gradient-via:var(--color-sky-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-yellow-400{--tw-gradient-via:var(--color-yellow-400);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-blue-500{--tw-gradient-to:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-green-500{--tw-gradient-to:var(--color-green-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-white{--tw-gradient-to:var(--color-white);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-50\%{--tw-gradient-to-position:50%}.\!p-0{padding:calc(var(--spacing) * 0)!important}.p-0{padding:calc(var(--spacing) * 0)}.p-0\!{padding:calc(var(--spacing) * 0)!important}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-10{padding:calc(var(--spacing) * 10)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\!{padding-inline:calc(var(--spacing) * 1)!important}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\!{padding-inline:calc(var(--spacing) * 2)!important}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0{padding-block:calc(var(--spacing) * 0)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\!{padding-block:calc(var(--spacing) * 1)!important}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\!{padding-block:calc(var(--spacing) * 2)!important}.py-3{padding-block:calc(var(--spacing) * 3)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.text-start{text-align:start}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.95rem\]{font-size:.95rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-nowrap{text-wrap:nowrap}.wrap-anywhere{overflow-wrap:anywhere}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-600\/80{color:#dd7400cc}@supports (color:color-mix(in lab, red, red)){.text-amber-600\/80{color:color-mix(in oklab, var(--color-amber-600) 80%, transparent)}}.text-amber-700{color:var(--color-amber-700)}.text-blue-500{color:var(--color-blue-500)}.text-cyan-700{color:var(--color-cyan-700)}.text-cyan-900{color:var(--color-cyan-900)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-100{color:var(--color-gray-100)}.text-gray-900{color:var(--color-gray-900)}.text-green-500{color:var(--color-green-500)}.text-inherit{color:inherit}.text-inherit\!{color:inherit!important}.text-orange-500{color:var(--color-orange-500)}.text-orange-600{color:var(--color-orange-600)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-slate-100\/95{color:#f1f5f9f2}@supports (color:color-mix(in lab, red, red)){.text-slate-100\/95{color:color-mix(in oklab, var(--color-slate-100) 95%, transparent)}}.text-slate-200{color:var(--color-slate-200)}.text-slate-300{color:var(--color-slate-300)}.text-slate-400{color:var(--color-slate-400)}.text-slate-400\/90{color:#90a1b9e6}@supports (color:color-mix(in lab, red, red)){.text-slate-400\/90{color:color-mix(in oklab, var(--color-slate-400) 90%, transparent)}}.text-slate-500{color:var(--color-slate-500)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-800{color:var(--color-slate-800)}.text-slate-900{color:var(--color-slate-900)}.text-slate-900\/70{color:#0f172bb3}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/70{color:color-mix(in oklab, var(--color-slate-900) 70%, transparent)}}.text-slate-900\/85{color:#0f172bd9}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/85{color:color-mix(in oklab, var(--color-slate-900) 85%, transparent)}}.text-slate-900\/90{color:#0f172be6}@supports (color:color-mix(in lab, red, red)){.text-slate-900\/90{color:color-mix(in oklab, var(--color-slate-900) 90%, transparent)}}.text-white{color:var(--color-white)}.text-yellow-500{color:var(--color-yellow-500)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.placeholder-slate-400::placeholder{color:var(--color-slate-400)}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_8px_rgba\(34\,197\,94\,0\.6\)\]{--tw-shadow:0 0 8px var(--tw-shadow-color,#22c55e99);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-blue-500\/50{--tw-shadow-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.shadow-blue-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-blue-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-green-500\/50{--tw-shadow-color:#00c75880}@supports (color:color-mix(in lab, red, red)){.shadow-green-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-green-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-orange-400\/40{--tw-shadow-color:#ff8b1a66}@supports (color:color-mix(in lab, red, red)){.shadow-orange-400\/40{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-orange-400) 40%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-red-500\/50{--tw-shadow-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.shadow-red-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-red-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.shadow-yellow-500\/50{--tw-shadow-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.shadow-yellow-500\/50{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-yellow-500) 50%, transparent) var(--tw-shadow-alpha), transparent)}}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-400{--tw-duration:.4s;transition-duration:.4s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[assembly\:InternalsVisibleTo\(\"axopen\.inspectors_tests\"\)\]{assembly:InternalsVisibleTo("axopen.inspectors tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests\"\)\]{assembly:InternalsVisibleTo("axopen core tests")}.\[assembly\:InternalsVisibleTo\(\"axopen_core_tests_L1\"\)\]{assembly:InternalsVisibleTo("axopen core tests L1")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsabbrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsabbrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsballuffidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsballuffidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentscognexvision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentscognexvision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdesouttertightening_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdesouttertightening tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsfestodrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsfestodrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskeyencevision_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskeyencevision tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentskukarobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentskukarobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsmitsubishirobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsmitsubishirobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothdrives_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothdrives tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrexrothpress_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrexrothpress tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentssiemidentification_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentssiemidentification tests")}.\[assembly\:InternalsVisibleTo\(\"axopencomponentsurrobotics_tests\"\)\]{assembly:InternalsVisibleTo("axopencomponentsurrobotics tests")}.\[assembly\:InternalsVisibleTo\(\"axopenio_tests\"\)\]{assembly:InternalsVisibleTo("axopenio tests")}.\[assembly\:InternalsVisibleTo\(\"components\.dukane\.welders_tests\"\)\]{assembly:InternalsVisibleTo("components.dukane.welders tests")}.\[assembly\:InternalsVisibleTo\(\"components\.rexroth\.tightening_tests\"\)\]{assembly:InternalsVisibleTo("components.rexroth.tightening tests")}.\[assembly\:InternalsVisibleTo\(\"components\.siem\.communication_tests\"\)\]{assembly:InternalsVisibleTo("components.siem.communication tests")}.\[assembly\:InternalsVisibleTo\(\"components\.zebra\.vision_tests\"\)\]{assembly:InternalsVisibleTo("components.zebra.vision tests")}.\[assembly\:InternalsVisibleTo\(\"elementscomponents_tests\"\)\]{assembly:InternalsVisibleTo("elementscomponents tests")}.\[assembly\:InternalsVisibleTo\(\"librarytemplate_tests\"\)\]{assembly:InternalsVisibleTo("librarytemplate tests")}.\[assembly\:InternalsVisibleTo\(\"pneumaticcomponents_tests\"\)\]{assembly:InternalsVisibleTo("pneumaticcomponents tests")}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:-translate-y-0\.5:hover{--tw-translate-y:calc(var(--spacing) * -.5);translate:var(--tw-translate-x) var(--tw-translate-y)}.hover\:border-slate-300:hover{border-color:var(--color-slate-300)}.hover\:bg-slate-50:hover{background-color:var(--color-slate-50)}.hover\:bg-slate-600:hover{background-color:var(--color-slate-600)}.hover\:text-slate-700:hover{color:var(--color-slate-700)}.hover\:text-slate-800:hover{color:var(--color-slate-800)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}.focus\:border-cyan-500:focus{border-color:var(--color-cyan-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-cyan-200:focus{--tw-ring-color:var(--color-cyan-200)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:inline{display:inline}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}}@media (min-width:48rem){.md\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:items-center{align-items:center}.lg\:justify-between{justify-content:space-between}.lg\:px-8{padding-inline:calc(var(--spacing) * 8)}}@media (min-width:80rem){.xl\:col-span-1{grid-column:span 1/span 1}.xl\:col-span-2{grid-column:span 2/span 2}.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}} \ No newline at end of file diff --git a/src/timers/ctrl/AXSharp.config.json b/src/timers/ctrl/AXSharp.config.json index 70f898d0e..6439b347c 100644 --- a/src/timers/ctrl/AXSharp.config.json +++ b/src/timers/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Timers","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_timers.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Timers","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_timers.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file diff --git a/src/utils/ctrl/AXSharp.config.json b/src/utils/ctrl/AXSharp.config.json index fbc31b4a2..bc87ca8ba 100644 --- a/src/utils/ctrl/AXSharp.config.json +++ b/src/utils/ctrl/AXSharp.config.json @@ -1 +1 @@ -{"OutputProjectFolder":"..\\src\\AXOpen.Utils","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_utils.csproj","UiHostProject":null} \ No newline at end of file +{"OutputProjectFolder":"..\\src\\AXOpen.Utils","UseBase":false,"NoDependencyUpdate":false,"IgnoreS7Pragmas":false,"SkipDependencyCompilation":false,"TargetPlatfromMoniker":"ax","ProjectFile":"inxton_axopen_utils.csproj","UiHostProject":null,"SourceOrigin":"auto"} \ No newline at end of file