From 0929211f114b6c288f2d117c8468a8e8739936f7 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 14:52:11 +0200
Subject: [PATCH 01/13] chore: update AXSharp package versions to
0.47.0-alpha.484 and reconcile transitive dependencies
---
.config/dotnet-tools.json | 6 +-
Directory.Packages.props | 12 +-
scripts/update_axsharp_versions.ps1 | 170 +++++++++++++++++++++++++++-
3 files changed, 176 insertions(+), 12 deletions(-)
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index d91096d5a..d48523e89 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.479",
+ "version": "0.47.0-alpha.484",
"commands": [
"ixc"
],
@@ -17,14 +17,14 @@
"rollForward": false
},
"AXSharp.ixd": {
- "version": "0.47.0-alpha.479",
+ "version": "0.47.0-alpha.484",
"commands": [
"ixd"
],
"rollForward": false
},
"AXSharp.ixr": {
- "version": "0.47.0-alpha.479",
+ "version": "0.47.0-alpha.484",
"commands": [
"ixr"
],
diff --git a/Directory.Packages.props b/Directory.Packages.props
index b0b218dc6..f99f35460 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -11,12 +11,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/scripts/update_axsharp_versions.ps1 b/scripts/update_axsharp_versions.ps1
index 839983692..7082969da 100644
--- a/scripts/update_axsharp_versions.ps1
+++ b/scripts/update_axsharp_versions.ps1
@@ -8,7 +8,11 @@
3. Updates versions for:
- .config/dotnet-tools.json (all tools whose name starts with AXSharp. or Inxton.Operon.)
- src/Directory.Packages.props (all and Include="Inxton.Operon.*" ... /> entries)
- 4. Supports -DryRun to preview changes and -Verbose for detailed logging.
+ 4. Reconciles AXSharp's transitive (third-party) dependencies: reads each AXSharp.* package's
+ .nuspec at the resolved version, and bumps any already-pinned entry up to the
+ version AXSharp requires (bump-up only; never downgrades, never adds new entries). Useful with
+ CentralPackageTransitivePinningEnabled. Disable with -SkipTransitive.
+ 5. Supports -DryRun to preview changes and -Verbose for detailed logging.
.PARAMETER AxSharpVersion
Explicit version to set for AXSharp.* packages instead of auto-detecting the latest from NuGet.
@@ -39,7 +43,8 @@ param(
[string]$Username, # Optional for private feed auth (GitHub Packages). If omitted and Token supplied, 'USERNAME' placeholder is used.
[string]$Token, # Personal Access Token or NuGet API key for private feed (PAT needs packaging:read scope)
[switch]$NormalizeJson, # When set, rewrites dotnet-tools.json with standard compact formatting instead of preserving existing indentation
- [switch]$ListAvailable # If set, lists available versions (after auth) and exits (unless versions also supplied)
+ [switch]$ListAvailable, # If set, lists available versions (after auth) and exits (unless versions also supplied)
+ [switch]$SkipTransitive # If set, does not reconcile AXSharp's transitive (third-party) dependencies in Directory.Packages.props
)
Set-StrictMode -Version Latest
@@ -181,6 +186,107 @@ function Get-LatestVersion {
}
}
+function Get-FeedContext {
+ # Resolves the service index once and returns the PackageBaseAddress + auth headers
+ # for reuse across multiple package requests (versions, nuspec, ...).
+ param([string]$Feed,[string]$User,[string]$Tok)
+ $serviceIndexUrl = if($Feed.ToLower().EndsWith('index.json')) { $Feed } else { ($Feed.TrimEnd('/')) + '/index.json' }
+ $headers = @{}
+ if($Tok){
+ $u = if($User){$User}else{'USERNAME'}
+ $basic = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $u,$Tok)))
+ $headers['Authorization'] = "Basic $basic"
+ }
+ $si = Invoke-RestMethod -Uri $serviceIndexUrl -Headers $headers -TimeoutSec 30
+ if(-not $si.resources){ throw "Service index missing resources at $serviceIndexUrl" }
+ $pkgBase = ($si.resources | Where-Object { $_.'@type' -eq 'PackageBaseAddress/3.0.0' } | Select-Object -First 1).'@id'
+ if(-not $pkgBase){ throw 'PackageBaseAddress/3.0.0 resource not found in service index.' }
+ if($pkgBase[-1] -ne '/') { $pkgBase += '/' }
+ [PSCustomObject]@{ PkgBase=$pkgBase; Headers=$headers }
+}
+
+function Get-NuspecXml {
+ # Returns the .nuspec of a package@version as an [xml]. Tries the flat-container .nuspec
+ # endpoint first (served by nuget.org); on 404 (GitHub Packages does not expose it) falls
+ # back to downloading the .nupkg and extracting the .nuspec entry from the zip.
+ param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId,[string]$Version)
+ $lowerId = $PackageId.ToLower()
+
+ $nuspecUrl = "$PkgBase$lowerId/$Version/$lowerId.nuspec"
+ try {
+ $resp = Invoke-WebRequest -Uri $nuspecUrl -Headers $Headers -TimeoutSec 30 -UseBasicParsing
+ return [xml]$resp.Content
+ } catch {
+ $code = $null
+ if($_.Exception.Response){ $code = [int]$_.Exception.Response.StatusCode }
+ if($code -and $code -ne 404){ throw "Failed to fetch nuspec ($nuspecUrl): $($_.Exception.Message)" }
+ # 404 -> feed does not serve standalone .nuspec; fall back to the .nupkg below.
+ }
+
+ $nupkgUrl = "$PkgBase$lowerId/$Version/$lowerId.$Version.nupkg"
+ $tmpPkg = [System.IO.Path]::GetTempFileName() + '.nupkg'
+ try {
+ Invoke-WebRequest -Uri $nupkgUrl -Headers $Headers -TimeoutSec 60 -UseBasicParsing -OutFile $tmpPkg
+ Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction SilentlyContinue
+ $zip = [System.IO.Compression.ZipFile]::OpenRead($tmpPkg)
+ try {
+ $entry = $zip.Entries | Where-Object { $_.FullName.ToLower().EndsWith('.nuspec') } | Select-Object -First 1
+ if(-not $entry){ throw "No .nuspec entry inside $nupkgUrl" }
+ $sr = New-Object System.IO.StreamReader($entry.Open())
+ try { $content = $sr.ReadToEnd() } finally { $sr.Dispose() }
+ } finally {
+ $zip.Dispose()
+ }
+ return [xml]$content
+ } catch {
+ throw "Failed to read package metadata for ${PackageId}@${Version} (tried nuspec + nupkg): $($_.Exception.Message)"
+ } finally {
+ Remove-Item -LiteralPath $tmpPkg -ErrorAction SilentlyContinue
+ }
+}
+
+function Get-PackageDependencies {
+ # Reads a package's .nuspec at a specific version and returns its declared dependencies
+ # as a flat list of [PSCustomObject]@{ Id; Version }, across all target frameworks.
+ param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId,[string]$Version)
+ $doc = Get-NuspecXml -PkgBase $PkgBase -Headers $Headers -PackageId $PackageId -Version $Version
+ $nsUri = $doc.DocumentElement.NamespaceURI
+ if($nsUri){
+ $nsm = New-Object System.Xml.XmlNamespaceManager($doc.NameTable)
+ $nsm.AddNamespace('n',$nsUri)
+ $nodes = $doc.SelectNodes('//n:dependency',$nsm)
+ } else {
+ $nodes = $doc.SelectNodes('//dependency')
+ }
+ $deps = @()
+ foreach($n in $nodes){
+ $id = $n.GetAttribute('id')
+ $ver = $n.GetAttribute('version')
+ if($id){ $deps += [PSCustomObject]@{ Id=$id; Version=$ver } }
+ }
+ return $deps
+}
+
+function Get-VersionLowerBound {
+ # Extracts the lower-bound version from a NuGet dependency version string.
+ # Handles plain ("1.2.3"), exact ("[1.2.3]") and range ("[1.2.3, )", "(1.0,2.0)") forms.
+ # Returns $null when no usable lower bound exists (e.g. "(,2.0)").
+ param([string]$Range)
+ if([string]::IsNullOrWhiteSpace($Range)){ return $null }
+ $r = $Range.Trim().Trim('[',']','(',')',' ')
+ $r = $r.Split(',')[0].Trim()
+ if([string]::IsNullOrWhiteSpace($r)){ return $null }
+ return $r
+}
+
+function Test-VersionGreater {
+ # Returns $true when semver-ish version $A is strictly greater than $B.
+ param([string]$A,[string]$B)
+ if([string]::IsNullOrWhiteSpace($B)){ return $true }
+ if([string]::IsNullOrWhiteSpace($A)){ return $false }
+ return ( (Compare-VersionRecord (ConvertTo-VersionRecord $A) (ConvertTo-VersionRecord $B)) -gt 0 )
+}
+
# Query for AXSharp version
if(-not $AxSharpVersion){
Write-Info "Discovering latest AXSharp.ixc version from source: $Source ..."
@@ -340,12 +446,70 @@ $propsUpdated = [System.Text.RegularExpressions.Regex]::Replace($propsUpdated, $
}
})
+### Reconcile AXSharp transitive (third-party) dependencies
+# Read each AXSharp.* package's .nuspec at the resolved version, then bump any already-pinned
+# entry up to the version AXSharp requires. Bump-up only: never downgrades a
+# deliberately-pinned newer version, and never adds entries that aren't already listed.
+if(-not $SkipTransitive){
+ Write-Info 'Reconciling AXSharp transitive dependencies...'
+ $axPkgIds = [regex]::Matches($propsRaw,')'
+ $propsUpdated = [System.Text.RegularExpressions.Regex]::Replace($propsUpdated, $pattern, {
+ param($m)
+ $old = $m.Groups[2].Value
+ if(Test-VersionGreater $newVer $old){
+ $script:changes += "Directory.Packages.props (transitive): $depId $old -> $newVer"
+ return $m.Groups[1].Value + $newVer + $m.Groups[3].Value
+ } else {
+ if($Detailed -and $old -ne $newVer){ Write-Info "Transitive $depId left at $old (AXSharp requires >= $newVer; pinned version is newer)" }
+ return $m.Value
+ }
+ })
+ }
+ }
+}
+
if(-not $DryRun){
if($propsUpdated -ne $propsRaw){
#Set-Content -Path $propsPath -Value $propsUpdated -Encoding UTF8
Write-Utf8NoBom-LF -Path $propsPath -Content $propsUpdated
} elseif($Detailed){
- Write-Info 'No AXSharp.* or Inxton.Operon.* entries needed updating in Directory.Packages.props.'
+ Write-Info 'No AXSharp.*, Inxton.Operon.* or transitive entries needed updating in Directory.Packages.props.'
}
}
From 32e04d4a00632d5b806b008b2c5ff81c5072ba3f Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 16:17:31 +0200
Subject: [PATCH 02/13] chore: remove package-lock.json from AXOpen.Data.Blazor
---
src/data/src/AXOpen.Data.Blazor/package-lock.json | 11 -----------
1 file changed, 11 deletions(-)
delete mode 100644 src/data/src/AXOpen.Data.Blazor/package-lock.json
diff --git a/src/data/src/AXOpen.Data.Blazor/package-lock.json b/src/data/src/AXOpen.Data.Blazor/package-lock.json
deleted file mode 100644
index a1067c7ca..000000000
--- a/src/data/src/AXOpen.Data.Blazor/package-lock.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "requires": true,
- "lockfileVersion": 1,
- "dependencies": {
- "bootstrap-icons": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz",
- "integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw=="
- }
- }
-}
From f0bd4da8760e343e830a15160b6789aafc2a5a95 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 16:21:38 +0200
Subject: [PATCH 03/13] chore: add skill for updating AXSharp and Inxton.Operon
package versions
---
.../skills/update-axsharp-version/SKILL.md | 167 ++++++++++++++++++
1 file changed, 167 insertions(+)
create mode 100644 .claude/skills/update-axsharp-version/SKILL.md
diff --git a/.claude/skills/update-axsharp-version/SKILL.md b/.claude/skills/update-axsharp-version/SKILL.md
new file mode 100644
index 000000000..3cfc27e2d
--- /dev/null
+++ b/.claude/skills/update-axsharp-version/SKILL.md
@@ -0,0 +1,167 @@
+---
+name: update-axsharp-version
+description: Update AXSharp.* and Inxton.Operon.* package versions in this repo (via scripts/update_axsharp_versions.ps1), verify the build, update the central CHANGELOG.md, and open a PR with a generated description. Use when the user asks to bump/update AXSharp versions or open a dependency-update PR. Defaults to the latest versions from the feed; accepts optional explicit versions.
+---
+
+# Update AXSharp version
+
+Drives the AXSharp / Inxton.Operon dependency bump end to end: run the existing update script →
+verify the build → record the change in the central `CHANGELOG.md` → open a PR.
+
+The actual file edits live in [`scripts/update_axsharp_versions.ps1`](../../../scripts/update_axsharp_versions.ps1).
+**Do not reimplement version rewriting** — this skill only orchestrates around that script.
+
+By default the script auto-detects the latest `AXSharp.ixc` and `Inxton.Operon` versions from the
+GitHub Packages feed. The user may pass explicit versions; thread them through as
+`-AxSharpVersion ` / `-OperonVersion ` on every script invocation below.
+
+## Procedure
+
+### 1. Preconditions
+
+- Run all commands from the **repo root**. The script resolves its own `repoRoot`, but `git`/`gh`
+ operations assume root.
+- **Token (auto-detect mode only):** the script needs a feed token with `read:packages` scope. It
+ reads, in order, `AXSHARP_FEED_TOKEN`, `GITHUB_PACKAGES_TOKEN`, `GITHUB_TOKEN`, `GH_TOKEN`,
+ `NUGET_TOKEN`. If none is set **and** no explicit versions were given, tell the user to set one
+ (or pass `-Token`) and stop. Skip this check when explicit versions are supplied.
+- **Clean tree:** run `git status`. If the working tree is dirty, surface it and stop — do not bundle
+ unrelated changes into a dependency PR.
+
+### 2. Branch
+
+Check the current branch (`git branch --show-current`). If on the default branch `dev` (or any
+protected branch), create a working branch first. Prefer a version-tagged name once the version is
+known, otherwise a generic one:
+
+```powershell
+git switch -c chore/update-axsharp-versions
+```
+
+If already on a non-default working branch, stay on it.
+
+### 3. Preview (recommended)
+
+Show the user what will change before touching files:
+
+```powershell
+pwsh -File scripts/update_axsharp_versions.ps1 -DryRun -Detailed
+```
+
+Append `-AxSharpVersion -OperonVersion ` to override. Use `-ListAvailable` to inspect feed
+versions. The dry run must not modify files — `git status` stays clean.
+
+### 4. Apply
+
+Run for real and **capture stdout** — the `Summary of changes:` and `Target versions:` blocks feed
+the CHANGELOG entry, commit message, and PR body:
+
+```powershell
+pwsh -File scripts/update_axsharp_versions.ps1
+# or, with overrides:
+pwsh -File scripts/update_axsharp_versions.ps1 -AxSharpVersion -OperonVersion
+```
+
+Handle outcomes:
+- **Non-zero exit** — exit `2` = feed/auth failure, exit `3` = JSON parse failure. Report the error
+ output and stop.
+- **No changes** — if `git status` shows nothing changed, report "already up to date at
+ ``" and stop. Do **not** open a PR.
+
+Record the resolved `` and `` from the script's `Target versions:`
+block for the steps below.
+
+### 5. Verify build
+
+Confirm the new package set resolves before opening the PR (build only, no tests):
+
+```powershell
+dotnet run --project cake/Build.csproj -- --do-apax-update
+```
+
+`--do-apax-update` pulls the apax-side packages; the .NET restore covers the central-managed NuGet
+bumps. For a heavier check, [`scripts/build_with_update.ps1`](../../../scripts/build_with_update.ps1)
+runs build + tests at level 10.
+
+If the build **fails**: report the failure with output and **do not open the PR**. Leave the changes
+on the branch for the user to inspect.
+
+### 6. Update central CHANGELOG.md
+
+Prepend a new entry at the **top** of [`CHANGELOG.md`](../../../CHANGELOG.md) (newest-on-top, above
+the current first `###` heading), matching the existing structured format. Use category tag `[DEPS]`.
+Fill bullets from the script's `Summary of changes:` block.
+
+```markdown
+### [DEPS] Update AXSharp / Inxton.Operon package versions to
+
+**Note:** Dependency version bump via `scripts/update_axsharp_versions.ps1`. No source change.
+Branch: ``.
+
+- chore: AXSharp.* packages updated to `` in `.config/dotnet-tools.json` and `Directory.Packages.props`.
+- chore: Inxton.Operon.* packages updated to ``.
+- chore: reconciled AXSharp transitive (third-party) dependencies in `Directory.Packages.props` (bump-up only).
+
+
+**Impact:**
+- Repo now builds and tests against AXSharp `` / Inxton.Operon ``.
+
+**Risks/Review:**
+- Transitive pinned versions were bumped up to satisfy AXSharp's nuspec requirements; review `Directory.Packages.props` diff.
+
+**Testing:**
+- `dotnet run --project cake/Build.csproj -- --do-apax-update` — build succeeds with the new package set.
+```
+
+### 7. Commit
+
+Match the repo convention (see commit `0929211f1`):
+
+```powershell
+git add .config/dotnet-tools.json Directory.Packages.props CHANGELOG.md
+git commit -m "chore: update AXSharp package versions to and reconcile transitive dependencies"
+git push -u origin HEAD
+```
+
+Scope the `git add` to the touched files. (The script edits only these in a normal run.)
+
+### 8. Create PR
+
+```powershell
+gh pr create --base dev --title "chore: update AXSharp package versions to " --body ""
+```
+
+Use the template below for ``, filling placeholders and pasting the script's
+`Summary of changes:` lines as a bullet list. Report the resulting PR URL to the user.
+
+#### PR body template
+
+```markdown
+## Update AXSharp / Inxton.Operon package versions
+
+Bumps AXSharp.* and Inxton.Operon.* packages and reconciles transitive (third-party) dependencies
+that AXSharp requires, via `scripts/update_axsharp_versions.ps1`.
+
+### Target versions
+- **AXSharp.\***: ``
+- **Inxton.Operon.\***: ``
+
+### Changes
+- `.config/dotnet-tools.json` — tool versions bumped
+- `Directory.Packages.props` — package versions + bump-up of pinned transitive deps
+- `CHANGELOG.md` — `[DEPS]` entry prepended
+
+
+
+### Verification
+- [x] `dotnet run --project cake/Build.csproj -- --do-apax-update` succeeded
+
+🤖 Generated with [Claude Code](https://claude.com/claude-code)
+```
+
+## Notes
+
+- Script switches: `-DryRun`, `-Detailed`, `-ListAvailable`, `-AxSharpVersion`, `-OperonVersion`,
+ `-SkipTransitive`, `-Source`, `-Token`, `-Username`, `-NormalizeJson`.
+- Default PR base branch: `dev`.
+- Build options live in [`cake/BuildParameters.cs`](../../../cake/BuildParameters.cs).
From fd90b840c7f8545239d82e43846ce61dd8e40dd3 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 16:21:50 +0200
Subject: [PATCH 04/13] chore: change develop branch mode to
ContinuousDeployment in GitVersion.yml
---
GitVersion.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/GitVersion.yml b/GitVersion.yml
index ef800d38e..c4aeb37fd 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -15,7 +15,7 @@ branches:
pre-release-weight: 55000
develop:
regex: ^dev(elop)?(ment)?$
- mode: ManualDeployment
+ mode: ContinuousDeployment
label: alpha
increment: Minor
prevent-increment:
From 029813e444b10e1629a6bbd93e618eff969d71ec Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 17:12:47 +0200
Subject: [PATCH 05/13] feat: add vulnerability scanning and reporting for npm
and NuGet dependencies
- Implemented `update-vulnerable-deps.ps1` script to scan for vulnerable dependencies and apply safe fixes.
- Introduced `_deps-common.ps1` for shared helper functions used in dependency management.
- Updated `Directory.Packages.props` to include security pins for vulnerable packages.
- Added `.gitignore` entries to exclude vulnerability scan reports.
- Created `apax.yml` for managing dependencies in the apax traversal project.
---
.gitignore | 3 +
Directory.Packages.props | 18 +-
scripts/_deps-common.ps1 | 153 ++++++++
scripts/update-vulnerable-deps.ps1 | 594 +++++++++++++++++++++++++++++
src/traversals/apax/apax.yml | 51 +++
5 files changed, 807 insertions(+), 12 deletions(-)
create mode 100644 scripts/_deps-common.ps1
create mode 100644 scripts/update-vulnerable-deps.ps1
create mode 100644 src/traversals/apax/apax.yml
diff --git a/.gitignore b/.gitignore
index 6188d277e..cb9410427 100644
--- a/.gitignore
+++ b/.gitignore
@@ -439,3 +439,6 @@ operon-variables.css
**/app/gsd/source/**
*.lscache
+
+# Vulnerability scan reports (scripts/update-vulnerable-deps.ps1)
+scripts/reports/
diff --git a/Directory.Packages.props b/Directory.Packages.props
index f99f35460..6ccee4040 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -88,15 +88,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/scripts/_deps-common.ps1 b/scripts/_deps-common.ps1
new file mode 100644
index 000000000..6db927c92
--- /dev/null
+++ b/scripts/_deps-common.ps1
@@ -0,0 +1,153 @@
+#!/usr/bin/env pwsh
+<#
+.SYNOPSIS
+Shared helpers for dependency-management scripts (dot-source this file).
+
+.DESCRIPTION
+Common logging, file IO, semver comparison, NuGet v3 feed access, token discovery and
+severity utilities used by scripts/update-vulnerable-deps.ps1 (and reusable by
+scripts/update_axsharp_versions.ps1). Several functions here originated in
+update_axsharp_versions.ps1 and were factored out so the two scripts share one source of truth.
+
+Dot-source it from a script:
+ . "$PSScriptRoot/_deps-common.ps1"
+#>
+
+# ---------------------------------------------------------------------------
+# Logging
+# ---------------------------------------------------------------------------
+function Write-Info($msg){ Write-Host "[INFO ] $msg" -ForegroundColor Cyan }
+function Write-Warn($msg){ Write-Host "[WARN ] $msg" -ForegroundColor Yellow }
+function Write-Err ($msg){ Write-Host "[ERROR] $msg" -ForegroundColor Red }
+
+# ---------------------------------------------------------------------------
+# File IO
+# ---------------------------------------------------------------------------
+function Write-Utf8NoBom-LF {
+ # Writes text as UTF-8 (no BOM) with LF line endings to preserve repo conventions.
+ param([string]$Path, [string]$Content)
+ $lf = ($Content -replace "`r`n", "`n") -replace "`r", "`n"
+ [System.IO.File]::WriteAllText($Path, $lf, [System.Text.UTF8Encoding]::new($false))
+}
+
+# ---------------------------------------------------------------------------
+# Token discovery
+# ---------------------------------------------------------------------------
+function Resolve-FeedToken {
+ # Returns the first non-empty token from the supplied value or the candidate env vars.
+ param(
+ [string]$Token,
+ [string[]]$EnvCandidates = @('NUGET_TOKEN','GITHUB_PACKAGES_TOKEN','GITHUB_TOKEN','GH_TOKEN'),
+ [switch]$Detailed
+ )
+ if($Token){ return $Token }
+ foreach($c in $EnvCandidates){
+ $candidate = [Environment]::GetEnvironmentVariable($c)
+ if($candidate){
+ if($Detailed){ Write-Info "Using token from environment variable $c" }
+ return $candidate
+ }
+ }
+ return $null
+}
+
+# ---------------------------------------------------------------------------
+# Semver parsing / comparison (build metadata ignored for ordering)
+# ---------------------------------------------------------------------------
+function ConvertTo-VersionRecord {
+ param([string]$v)
+ $core = $v
+ $pre = ''
+ $buildSplit = $core.Split('+',2)
+ if($buildSplit.Count -gt 1){ $core = $buildSplit[0] }
+ $dashIdx = $core.IndexOf('-')
+ if($dashIdx -ge 0){
+ $pre = $core.Substring($dashIdx + 1)
+ $core = $core.Substring(0,$dashIdx)
+ }
+ $parts = $core.Split('.')
+ [int]$maj = if($parts.Count -gt 0){ $parts[0] } else { 0 }
+ [int]$min = if($parts.Count -gt 1){ $parts[1] } else { 0 }
+ [int]$pat = if($parts.Count -gt 2){ $parts[2] } else { 0 }
+ $preSegs = @()
+ if($pre){ $preSegs = $pre.Split('.') }
+ [PSCustomObject]@{ Original=$v; Major=$maj; Minor=$min; Patch=$pat; Pre=$pre; PreSegs=$preSegs }
+}
+
+function Compare-VersionRecord {
+ param($a,$b)
+ if($a.Major -ne $b.Major){ return [Math]::Sign($a.Major - $b.Major) }
+ if($a.Minor -ne $b.Minor){ return [Math]::Sign($a.Minor - $b.Minor) }
+ if($a.Patch -ne $b.Patch){ return [Math]::Sign($a.Patch - $b.Patch) }
+ $aHasPre = [string]::IsNullOrEmpty($a.Pre) -ne $true
+ $bHasPre = [string]::IsNullOrEmpty($b.Pre) -ne $true
+ if($aHasPre -and -not $bHasPre){ return -1 }
+ if($bHasPre -and -not $aHasPre){ return 1 }
+ if(-not $aHasPre -and -not $bHasPre){ return 0 }
+ $len = [Math]::Max($a.PreSegs.Count,$b.PreSegs.Count)
+ for($i=0;$i -lt $len;$i++){
+ if($i -ge $a.PreSegs.Count){ return -1 }
+ if($i -ge $b.PreSegs.Count){ return 1 }
+ $as = $a.PreSegs[$i]; $bs = $b.PreSegs[$i]
+ $aNum = $as -as [int]; $bNum = $bs -as [int]
+ $aIsNum = $aNum -ne $null; $bIsNum = $bNum -ne $null
+ if($aIsNum -and $bIsNum){ if($aNum -ne $bNum){ return [Math]::Sign($aNum - $bNum) } }
+ elseif($aIsNum -and -not $bIsNum){ return -1 }
+ elseif($bIsNum -and -not $aIsNum){ return 1 }
+ else { $cmp = [string]::Compare($as,$bs,$true); if($cmp -ne 0){ return [Math]::Sign($cmp) } }
+ }
+ return 0
+}
+
+function Test-VersionGreater {
+ # Returns $true when semver-ish version $A is strictly greater than $B.
+ param([string]$A,[string]$B)
+ if([string]::IsNullOrWhiteSpace($B)){ return $true }
+ if([string]::IsNullOrWhiteSpace($A)){ return $false }
+ return ( (Compare-VersionRecord (ConvertTo-VersionRecord $A) (ConvertTo-VersionRecord $B)) -gt 0 )
+}
+
+function Test-IsPrerelease {
+ param([string]$v)
+ if([string]::IsNullOrWhiteSpace($v)){ return $false }
+ return -not [string]::IsNullOrEmpty((ConvertTo-VersionRecord $v).Pre)
+}
+
+# ---------------------------------------------------------------------------
+# NuGet v3 feed access
+# ---------------------------------------------------------------------------
+function Get-FeedContext {
+ # Resolves the service index once and returns the PackageBaseAddress + auth headers
+ # for reuse across multiple package requests.
+ param([string]$Feed,[string]$User,[string]$Tok)
+ $serviceIndexUrl = if($Feed.ToLower().EndsWith('index.json')) { $Feed } else { ($Feed.TrimEnd('/')) + '/index.json' }
+ $headers = @{}
+ if($Tok){
+ $u = if($User){$User}else{'USERNAME'}
+ $basic = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $u,$Tok)))
+ $headers['Authorization'] = "Basic $basic"
+ }
+ $si = Invoke-RestMethod -Uri $serviceIndexUrl -Headers $headers -TimeoutSec 30
+ if(-not $si.resources){ throw "Service index missing resources at $serviceIndexUrl" }
+ $pkgBase = ($si.resources | Where-Object { $_.'@type' -eq 'PackageBaseAddress/3.0.0' } | Select-Object -First 1).'@id'
+ if(-not $pkgBase){ throw 'PackageBaseAddress/3.0.0 resource not found in service index.' }
+ if($pkgBase[-1] -ne '/') { $pkgBase += '/' }
+ [PSCustomObject]@{ PkgBase=$pkgBase; Headers=$headers }
+}
+
+function Get-PackageVersionsFromFeed {
+ # Returns the raw list of available version strings for a package id on a v3 feed.
+ param([string]$PkgBase,[hashtable]$Headers,[string]$PackageId)
+ $lowerId = $PackageId.ToLower()
+ $indexUrl = "$PkgBase$lowerId/index.json"
+ try {
+ $idx = Invoke-RestMethod -Uri $indexUrl -Headers $Headers -TimeoutSec 30
+ } catch {
+ $code = $null
+ if($_.Exception.Response){ $code = [int]$_.Exception.Response.StatusCode }
+ if($code -eq 404){ return @() } # package id unknown on this feed
+ throw "Failed to fetch version index ($indexUrl): $($_.Exception.Message)"
+ }
+ if(-not $idx.versions){ return @() }
+ return $idx.versions
+}
diff --git a/scripts/update-vulnerable-deps.ps1 b/scripts/update-vulnerable-deps.ps1
new file mode 100644
index 000000000..c2d68c6a3
--- /dev/null
+++ b/scripts/update-vulnerable-deps.ps1
@@ -0,0 +1,594 @@
+#!/usr/bin/env pwsh
+<#
+.SYNOPSIS
+Scans the whole repository for vulnerable npm and NuGet dependencies and applies safe fixes.
+
+.DESCRIPTION
+One command to remediate moderate-and-above security advisories across both ecosystems:
+
+ NuGet - iterates every .csproj, restores it, runs `dotnet list package --vulnerable
+ --include-transitive`, dedupes advisories, SKIPS AXSharp.*/Inxton.Operon.* (those are
+ owned by scripts/update_axsharp_versions.ps1), resolves the minimum safe version from
+ the GitHub Advisory Database, and writes the bump to Directory.Packages.props
+ (direct = bump in place, transitive = add a new pinned ).
+
+ npm - audits the 6 source package.json projects (installing node_modules when missing) and
+ runs `npm audit fix` (safe, no --force). Advisories that would need a breaking major
+ bump are reported as unfixed.
+
+A timestamped Markdown + JSON report is written to scripts/reports/. With -CreatePR the changes
+are committed to branch 'fix/vulnerable-dependencies' off dev and a PR is opened against dev.
+
+Exit code is non-zero when vulnerabilities at/above -MinSeverity remain unfixed, so CI can gate on
+it.
+
+.PARAMETER DryRun
+Preview everything; make no file changes, no commits, no PR. (Still exits non-zero if vulns found.)
+
+.PARAMETER NpmOnly
+Scan/fix npm only.
+
+.PARAMETER NuGetOnly
+Scan/fix NuGet only.
+
+.PARAMETER CreatePR
+Commit fixes to branch 'fix/vulnerable-dependencies' off origin/dev and open a PR against dev.
+Cannot be combined with -DryRun.
+
+.PARAMETER MinSeverity
+Lowest severity to act on: low | moderate | high | critical. Default: moderate.
+
+.PARAMETER Source
+NuGet v3 feed used to look up available versions (public packages). Default nuget.org.
+
+.PARAMETER Token
+Token for the GitHub Advisory API (avoids rate limits). Falls back to NUGET_TOKEN /
+GITHUB_PACKAGES_TOKEN / GITHUB_TOKEN / GH_TOKEN.
+
+.PARAMETER Detailed
+Verbose logging.
+
+.EXAMPLE
+./update-vulnerable-deps.ps1 -DryRun -Detailed
+
+.EXAMPLE
+./update-vulnerable-deps.ps1 -NuGetOnly
+
+.EXAMPLE
+./update-vulnerable-deps.ps1 -CreatePR
+#>
+
+[CmdletBinding()]
+param(
+ [switch]$DryRun,
+ [switch]$NpmOnly,
+ [switch]$NuGetOnly,
+ [switch]$CreatePR,
+ [ValidateSet('low','moderate','high','critical')]
+ [string]$MinSeverity = 'moderate',
+ [string]$Source = 'https://api.nuget.org/v3/index.json',
+ [string]$Token,
+ [switch]$Detailed
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
+. "$scriptRoot/_deps-common.ps1"
+
+$repoRoot = Split-Path -Parent $scriptRoot
+$propsPath = Join-Path $repoRoot 'Directory.Packages.props'
+
+# ---------------------------------------------------------------------------
+# Validation & constants
+# ---------------------------------------------------------------------------
+if($DryRun -and $CreatePR){ Write-Err '-DryRun and -CreatePR cannot be combined.'; exit 1 }
+if($NpmOnly -and $NuGetOnly){ Write-Err '-NpmOnly and -NuGetOnly cannot be combined.'; exit 1 }
+
+$doNuget = -not $NpmOnly
+$doNpm = -not $NuGetOnly
+
+$SeverityRank = @{ low = 1; moderate = 2; high = 3; critical = 4 }
+$minRank = $SeverityRank[$MinSeverity]
+
+# Packages owned by update_axsharp_versions.ps1 - never touched here.
+$SkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b'
+
+$Token = Resolve-FeedToken -Token $Token -Detailed:$Detailed
+
+# Source npm projects (explicit list - avoids bin/obj/ctrl generated copies).
+$NpmProjects = @(
+ 'src/components.abb.robotics/package.json'
+ 'src/components.abstractions/package.json'
+ 'src/data/package.json'
+ 'src/inspectors/package.json'
+ 'src/showcase/app/ix-blazor/showcase.blazor/package.json'
+ 'src/styling/src/package.json'
+) | ForEach-Object { Join-Path $repoRoot $_ }
+
+# Accumulators for the report.
+$NuGetFixed = New-Object System.Collections.ArrayList
+$NuGetSkipped = New-Object System.Collections.ArrayList
+$NuGetUnfixed = New-Object System.Collections.ArrayList
+$NpmResults = New-Object System.Collections.ArrayList
+$ScanErrors = New-Object System.Collections.ArrayList
+
+# ---------------------------------------------------------------------------
+# Helpers
+# ---------------------------------------------------------------------------
+function Test-CommandAvailable {
+ param([string]$Name)
+ $null -ne (Get-Command $Name -ErrorAction SilentlyContinue)
+}
+
+function Get-GhsaIdFromUrl {
+ param([string]$Url)
+ if($Url -and ($Url -match '(GHSA-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4})')){ return $Matches[1] }
+ return $null
+}
+
+$script:AdvisoryCache = @{}
+function Get-AdvisoryPatchedVersion {
+ # Queries the GitHub Advisory Database for the first patched version of $PackageId.
+ # Returns the patched version string, or $null when it cannot be determined.
+ param([string]$GhsaId,[string]$PackageId)
+ if(-not $GhsaId){ return $null }
+ if(-not $script:AdvisoryCache.ContainsKey($GhsaId)){
+ $headers = @{ 'User-Agent' = 'axopen-update-vulnerable-deps'; 'Accept' = 'application/vnd.github+json' }
+ if($Token){ $headers['Authorization'] = "Bearer $Token" }
+ try {
+ $script:AdvisoryCache[$GhsaId] = Invoke-RestMethod -Uri "https://api.github.com/advisories/$GhsaId" -Headers $headers -TimeoutSec 30
+ } catch {
+ if($Detailed){ Write-Warn "Advisory lookup failed for ${GhsaId}: $($_.Exception.Message)" }
+ $script:AdvisoryCache[$GhsaId] = $null
+ }
+ }
+ $adv = $script:AdvisoryCache[$GhsaId]
+ if(-not $adv -or -not $adv.vulnerabilities){ return $null }
+ foreach($v in $adv.vulnerabilities){
+ if($v.package -and $v.package.ecosystem -eq 'nuget' -and $v.package.name -and ($v.package.name.ToLower() -eq $PackageId.ToLower())){
+ $fpv = $v.first_patched_version
+ if($null -eq $fpv){ return $null }
+ if($fpv -is [string]){ return $fpv }
+ if($fpv.PSObject.Properties.Name -contains 'identifier'){ return $fpv.identifier }
+ }
+ }
+ return $null
+}
+
+function Resolve-SafeNuGetVersion {
+ # Determines the minimum safe version for a vulnerable package:
+ # 1. the highest 'first patched version' across the package's advisories, then
+ # 2. snapped up to the lowest version actually available on the feed that is >= that patch
+ # and strictly greater than the current resolved version.
+ # Returns $null (=> report as unfixed) when no safe version can be determined.
+ param([string]$PackageId,[string]$CurrentVersion,[string[]]$GhsaIds,$FeedCtx)
+ $patched = $null
+ foreach($g in $GhsaIds){
+ $p = Get-AdvisoryPatchedVersion -GhsaId $g -PackageId $PackageId
+ if($p -and (Test-VersionGreater $p $patched)){ $patched = $p }
+ }
+ if(-not $patched){ return $null }
+
+ $available = @()
+ try { $available = Get-PackageVersionsFromFeed -PkgBase $FeedCtx.PkgBase -Headers $FeedCtx.Headers -PackageId $PackageId } catch { $available = @() }
+ if(-not $available -or $available.Count -eq 0){
+ # Feed gave us nothing; trust the advisory's patched version if it improves on current.
+ if(Test-VersionGreater $patched $CurrentVersion){ return $patched } else { return $null }
+ }
+
+ $currentIsPre = Test-IsPrerelease $CurrentVersion
+ $candidates = $available |
+ Where-Object { ($currentIsPre) -or (-not (Test-IsPrerelease $_)) } | # stable only unless current is pre
+ Where-Object { (Test-VersionGreater $_ $CurrentVersion) -and -not (Test-VersionGreater $patched $_) } # > current AND >= patched
+
+ if(-not $candidates -or @($candidates).Count -eq 0){ return $null }
+
+ # lowest such candidate = minimum safe bump
+ $best = @($candidates)[0]
+ foreach($c in $candidates){ if(Test-VersionGreater $best $c){ $best = $c } }
+ return $best
+}
+
+# ---------------------------------------------------------------------------
+# Directory.Packages.props editing
+# ---------------------------------------------------------------------------
+function Update-PropsDirect {
+ # Bumps an existing in place.
+ # Returns updated content, or $null if the package id was not found.
+ param([string]$Content,[string]$PackageId,[string]$NewVersion)
+ $idEsc = [regex]::Escape($PackageId)
+ # Include before Version (repo convention)
+ $rx1 = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")"
+ if([regex]::IsMatch($Content,$rx1)){
+ return [regex]::Replace($Content,$rx1,"`${1}$NewVersion`${2}",1)
+ }
+ # Version before Include (defensive)
+ $rx2 = "(]*\bVersion=`")[^`"]*(`"[^>]*\bInclude=`"$idEsc`")"
+ if([regex]::IsMatch($Content,$rx2)){
+ return [regex]::Replace($Content,$rx2,"`${1}$NewVersion`${2}",1)
+ }
+ return $null
+}
+
+function Test-PropsHasPackage {
+ param([string]$Content,[string]$PackageId)
+ $idEsc = [regex]::Escape($PackageId)
+ return [regex]::IsMatch($Content,"]*\bInclude=`"$idEsc`"")
+}
+
+function Add-PropsTransitivePin {
+ # Adds a into a managed "security pins" ItemGroup, creating it before
+ # if absent. Returns updated content.
+ param([string]$Content,[string]$PackageId,[string]$NewVersion)
+ $marker = ''
+ $entry = " "
+ if($Content.Contains($marker)){
+ # Insert as the first entry inside the existing managed ItemGroup.
+ $rx = [regex]::Escape($marker) + "(\r?\n\s*)"
+ return [regex]::Replace($Content,$rx,"`$0`r`n$entry",1)
+ }
+ $block = " $marker`r`n `r`n$entry`r`n `r`n"
+ return ($Content -replace '\s*$',$block)
+}
+
+# ---------------------------------------------------------------------------
+# NuGet scan & fix
+# ---------------------------------------------------------------------------
+function Invoke-NuGetScan {
+ Write-Info 'Scanning NuGet dependencies...'
+ if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet CLI not found on PATH.'; [void]$ScanErrors.Add('dotnet CLI not found'); return }
+
+ $csprojFiles = Get-ChildItem -Path (Join-Path $repoRoot 'src') -Recurse -Filter '*.csproj' -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notmatch '[\\/](bin|obj)[\\/]' }
+ # Include the cake build project (ships in the repo).
+ $cakeProj = Get-ChildItem -Path (Join-Path $repoRoot 'cake') -Recurse -Filter '*.csproj' -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notmatch '[\\/](bin|obj)[\\/]' }
+ $csprojFiles = @($csprojFiles) + @($cakeProj)
+
+ Write-Info "Found $($csprojFiles.Count) project(s) to scan."
+
+ # packageId -> aggregated advisory record
+ $vuln = @{}
+ $total = $csprojFiles.Count
+ $i = 0
+ foreach($proj in $csprojFiles){
+ $i++
+ $pct = if($total -gt 0){ [int](($i-1) / $total * 100) } else { 0 }
+ Write-Progress -Activity 'Scanning NuGet projects' `
+ -Status ("[$i/$total] $($proj.Name) - $($vuln.Count) vulnerable package(s) so far") `
+ -CurrentOperation 'restoring...' -PercentComplete $pct
+ if($Detailed){ Write-Info "[$i/$total] $($proj.FullName)" }
+ try {
+ & dotnet restore $proj.FullName --nologo *> $null
+ } catch {
+ [void]$ScanErrors.Add("restore failed: $($proj.FullName)")
+ if($Detailed){ Write-Warn "restore failed: $($proj.Name)" }
+ continue
+ }
+ Write-Progress -Activity 'Scanning NuGet projects' `
+ -Status ("[$i/$total] $($proj.Name) - $($vuln.Count) vulnerable package(s) so far") `
+ -CurrentOperation 'listing vulnerabilities...' -PercentComplete $pct
+ $raw = & dotnet list $proj.FullName package --vulnerable --include-transitive --format json 2>$null | Out-String
+ if(-not $raw.Trim()){ continue }
+ try { $parsed = $raw | ConvertFrom-Json } catch { [void]$ScanErrors.Add("unparseable output: $($proj.FullName)"); continue }
+ if(-not ($parsed.PSObject.Properties.Name -contains 'projects')){ continue }
+ foreach($p in $parsed.projects){
+ if(-not ($p.PSObject.Properties.Name -contains 'frameworks') -or -not $p.frameworks){ continue }
+ foreach($fw in $p.frameworks){
+ foreach($kind in @('topLevelPackages','transitivePackages')){
+ if(-not ($fw.PSObject.Properties.Name -contains $kind) -or -not $fw.$kind){ continue }
+ $isDirect = ($kind -eq 'topLevelPackages')
+ foreach($pkg in $fw.$kind){
+ if(-not ($pkg.PSObject.Properties.Name -contains 'vulnerabilities') -or -not $pkg.vulnerabilities){ continue }
+ $id = $pkg.id
+ $resolved = $pkg.resolvedVersion
+ foreach($adv in $pkg.vulnerabilities){
+ $sev = ("$($adv.severity)").ToLower()
+ $rank = if($SeverityRank.ContainsKey($sev)){ $SeverityRank[$sev] } else { 0 }
+ if($rank -lt $minRank){ continue }
+ $url = if($adv.PSObject.Properties.Name -contains 'advisoryurl'){ $adv.advisoryurl } else { '' }
+ if(-not $vuln.ContainsKey($id)){
+ $vuln[$id] = [PSCustomObject]@{
+ Id=$id; Resolved=$resolved; IsDirect=$isDirect; MaxRank=$rank;
+ Severity=$sev; Urls=(New-Object System.Collections.ArrayList); Projects=(New-Object System.Collections.ArrayList)
+ }
+ }
+ $rec = $vuln[$id]
+ if($isDirect){ $rec.IsDirect = $true }
+ if($rank -gt $rec.MaxRank){ $rec.MaxRank = $rank; $rec.Severity = $sev }
+ if($url -and -not $rec.Urls.Contains($url)){ [void]$rec.Urls.Add($url) }
+ if(-not $rec.Projects.Contains($proj.Name)){ [void]$rec.Projects.Add($proj.Name) }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Write-Progress -Activity 'Scanning NuGet projects' -Completed
+
+ if($vuln.Count -eq 0){ Write-Info 'No NuGet vulnerabilities at/above the threshold.'; return }
+ Write-Info "Found $($vuln.Count) vulnerable NuGet package(s) at/above '$MinSeverity'."
+
+ # Resolve safe versions & apply.
+ $feedCtx = $null
+ try { $feedCtx = Get-FeedContext -Feed $Source -Tok $null } catch { Write-Warn "Could not initialise NuGet feed context: $($_.Exception.Message)" }
+
+ $content = Get-Content -LiteralPath $propsPath -Raw
+ $changed = $false
+
+ foreach($id in ($vuln.Keys | Sort-Object)){
+ $rec = $vuln[$id]
+ if($id -match $SkipPattern){
+ [void]$NuGetSkipped.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Reason='skipped-AXSharp (owned by update_axsharp_versions.ps1)' })
+ continue
+ }
+ $ghsaIds = @($rec.Urls | ForEach-Object { Get-GhsaIdFromUrl $_ } | Where-Object { $_ })
+ $safe = $null
+ if($feedCtx){ $safe = Resolve-SafeNuGetVersion -PackageId $id -CurrentVersion $rec.Resolved -GhsaIds $ghsaIds -FeedCtx $feedCtx }
+
+ if(-not $safe){
+ [void]$NuGetUnfixed.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Direct=$rec.IsDirect; Advisories=($rec.Urls -join ' '); Reason='no safe version determined (manual review)' })
+ continue
+ }
+
+ $action = $null
+ if(Test-PropsHasPackage -Content $content -PackageId $id){
+ $updated = Update-PropsDirect -Content $content -PackageId $id -NewVersion $safe
+ if($updated){ $content = $updated; $action = 'bumped (direct)' }
+ } else {
+ $content = Add-PropsTransitivePin -Content $content -PackageId $id -NewVersion $safe
+ $action = 'pinned (transitive)'
+ }
+ if($action){
+ $changed = $true
+ [void]$NuGetFixed.Add([PSCustomObject]@{ Id=$id; From=$rec.Resolved; To=$safe; Severity=$rec.Severity; Direct=$rec.IsDirect; Action=$action; Advisories=($rec.Urls -join ' ') })
+ Write-Info (" {0}: {1} -> {2} [{3}]" -f $id,$rec.Resolved,$safe,$action)
+ } else {
+ [void]$NuGetUnfixed.Add([PSCustomObject]@{ Id=$id; Current=$rec.Resolved; Severity=$rec.Severity; Direct=$rec.IsDirect; Advisories=($rec.Urls -join ' '); Reason='could not edit Directory.Packages.props' })
+ }
+ }
+
+ if($changed){
+ if($DryRun){
+ Write-Warn '[DRY RUN] Directory.Packages.props would be updated (not written).'
+ } else {
+ Write-Utf8NoBom-LF -Path $propsPath -Content $content
+ Write-Info 'Directory.Packages.props updated.'
+ }
+ }
+}
+
+# ---------------------------------------------------------------------------
+# npm scan & fix
+# ---------------------------------------------------------------------------
+function Get-NpmCountsAtOrAbove {
+ param($AuditObj)
+ $total = 0
+ if($AuditObj -and $AuditObj.PSObject.Properties.Name -contains 'metadata' -and $AuditObj.metadata.PSObject.Properties.Name -contains 'vulnerabilities'){
+ $v = $AuditObj.metadata.vulnerabilities
+ foreach($sev in @('moderate','high','critical')){
+ if($SeverityRank[$sev] -ge $minRank -and ($v.PSObject.Properties.Name -contains $sev)){ $total += [int]$v.$sev }
+ }
+ if($minRank -le 1 -and ($v.PSObject.Properties.Name -contains 'low')){ $total += [int]$v.low }
+ }
+ return $total
+}
+
+function Invoke-NpmScan {
+ Write-Info 'Scanning npm dependencies...'
+ if(-not (Test-CommandAvailable 'npm')){ Write-Err 'npm not found on PATH.'; [void]$ScanErrors.Add('npm not found'); return }
+
+ $npmTotal = $NpmProjects.Count
+ $npmIdx = 0
+ foreach($pkgJson in $NpmProjects){
+ $npmIdx++
+ if(-not (Test-Path -LiteralPath $pkgJson)){ if($Detailed){ Write-Warn "missing: $pkgJson" }; continue }
+ $dir = Split-Path -Parent $pkgJson
+ $name = (Resolve-Path -LiteralPath $dir).Path.Replace((Resolve-Path $repoRoot).Path,'').TrimStart('\','/')
+ Write-Progress -Activity 'Scanning npm projects' -Status "[$npmIdx/$npmTotal] $name" `
+ -PercentComplete ([int](($npmIdx-1) / $npmTotal * 100))
+ Write-Info " $name"
+ Push-Location $dir
+ try {
+ if(-not (Test-Path 'node_modules')){
+ if($DryRun){ Write-Warn " [DRY RUN] would run: npm install" }
+ else { & npm install --no-audit --no-fund *> $null }
+ }
+
+ $beforeRaw = & npm audit --json 2>$null | Out-String
+ $before = $null; try { $before = $beforeRaw | ConvertFrom-Json } catch {}
+ $beforeCount = Get-NpmCountsAtOrAbove $before
+
+ if($beforeCount -le 0){
+ [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=0; After=0; Fixed=0; Note='clean' })
+ Pop-Location; continue
+ }
+
+ if($DryRun){
+ Write-Warn " [DRY RUN] would run: npm audit fix ($beforeCount vuln >= $MinSeverity)"
+ [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=$beforeCount; After=$beforeCount; Fixed=0; Note='dry-run (not fixed)' })
+ Pop-Location; continue
+ }
+
+ & npm audit fix *> $null
+ $afterRaw = & npm audit --json 2>$null | Out-String
+ $after = $null; try { $after = $afterRaw | ConvertFrom-Json } catch {}
+ $afterCount = Get-NpmCountsAtOrAbove $after
+ $note = if($afterCount -gt 0){ "$afterCount remain (need --force / breaking major)" } else { 'all fixed' }
+ [void]$NpmResults.Add([PSCustomObject]@{ Project=$name; Before=$beforeCount; After=$afterCount; Fixed=($beforeCount-$afterCount); Note=$note })
+ Write-Info (" before={0} after={1} ({2})" -f $beforeCount,$afterCount,$note)
+ } catch {
+ [void]$ScanErrors.Add("npm error in ${name}: $($_.Exception.Message)")
+ Write-Warn " error: $($_.Exception.Message)"
+ } finally {
+ Pop-Location
+ }
+ }
+ Write-Progress -Activity 'Scanning npm projects' -Completed
+}
+
+# ---------------------------------------------------------------------------
+# Report
+# ---------------------------------------------------------------------------
+function Write-Report {
+ param([string]$Stamp)
+ $reportsDir = Join-Path $scriptRoot 'reports'
+ if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null }
+ $mdPath = Join-Path $reportsDir "vuln-report-$Stamp.md"
+ $jsonPath = Join-Path $reportsDir "vuln-report-$Stamp.json"
+
+ $payload = [PSCustomObject]@{
+ timestamp = $Stamp
+ minSeverity = $MinSeverity
+ dryRun = [bool]$DryRun
+ ecosystems = @{ nuget = [bool]$doNuget; npm = [bool]$doNpm }
+ nuget = @{ fixed = $NuGetFixed; skipped = $NuGetSkipped; unfixed = $NuGetUnfixed }
+ npm = $NpmResults
+ scanErrors = $ScanErrors
+ }
+ Write-Utf8NoBom-LF -Path $jsonPath -Content ($payload | ConvertTo-Json -Depth 8)
+
+ $sb = New-Object System.Text.StringBuilder
+ [void]$sb.AppendLine("# Vulnerable dependency report")
+ [void]$sb.AppendLine("")
+ [void]$sb.AppendLine("- Generated: $Stamp")
+ [void]$sb.AppendLine("- Min severity: **$MinSeverity**")
+ [void]$sb.AppendLine("- Dry run: $([bool]$DryRun)")
+ [void]$sb.AppendLine("- Ecosystems: NuGet=$doNuget, npm=$doNpm")
+ [void]$sb.AppendLine("")
+ if($doNuget){
+ [void]$sb.AppendLine("## NuGet")
+ [void]$sb.AppendLine("")
+ [void]$sb.AppendLine("### Fixed ($($NuGetFixed.Count))")
+ [void]$sb.AppendLine("| Package | From | To | Severity | Kind | Action |")
+ [void]$sb.AppendLine("|---|---|---|---|---|---|")
+ foreach($f in $NuGetFixed){ [void]$sb.AppendLine("| $($f.Id) | $($f.From) | $($f.To) | $($f.Severity) | $(if($f.Direct){'direct'}else{'transitive'}) | $($f.Action) |") }
+ [void]$sb.AppendLine("")
+ [void]$sb.AppendLine("### Unfixed - manual review ($($NuGetUnfixed.Count))")
+ [void]$sb.AppendLine("| Package | Current | Severity | Reason | Advisories |")
+ [void]$sb.AppendLine("|---|---|---|---|---|")
+ foreach($u in $NuGetUnfixed){ [void]$sb.AppendLine("| $($u.Id) | $($u.Current) | $($u.Severity) | $($u.Reason) | $($u.Advisories) |") }
+ [void]$sb.AppendLine("")
+ [void]$sb.AppendLine("### Skipped ($($NuGetSkipped.Count))")
+ foreach($s in $NuGetSkipped){ [void]$sb.AppendLine("- $($s.Id) ($($s.Current), $($s.Severity)) - $($s.Reason)") }
+ [void]$sb.AppendLine("")
+ }
+ if($doNpm){
+ [void]$sb.AppendLine("## npm")
+ [void]$sb.AppendLine("")
+ [void]$sb.AppendLine("| Project | Before | After | Fixed | Note |")
+ [void]$sb.AppendLine("|---|---|---|---|---|")
+ foreach($n in $NpmResults){ [void]$sb.AppendLine("| $($n.Project) | $($n.Before) | $($n.After) | $($n.Fixed) | $($n.Note) |") }
+ [void]$sb.AppendLine("")
+ }
+ if($ScanErrors.Count -gt 0){
+ [void]$sb.AppendLine("## Scan errors")
+ foreach($e in $ScanErrors){ [void]$sb.AppendLine("- $e") }
+ }
+ Write-Utf8NoBom-LF -Path $mdPath -Content $sb.ToString()
+
+ Write-Info "Report: $mdPath"
+ return $mdPath
+}
+
+# ---------------------------------------------------------------------------
+# Commit + PR
+# ---------------------------------------------------------------------------
+function Invoke-CreatePR {
+ param([string]$ReportPath)
+ if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot create PR.'; return }
+ if(-not (Test-CommandAvailable 'gh')){ Write-Err 'gh CLI not found; cannot open PR.'; return }
+
+ $branch = 'fix/vulnerable-dependencies'
+ Write-Info "Creating branch '$branch' off origin/dev and opening PR..."
+
+ & git -C $repoRoot fetch origin dev --quiet
+ # Carry working-tree fixes onto a fresh branch from origin/dev.
+ & git -C $repoRoot stash push -u -m 'vuln-fix-wip' *> $null
+ $stashed = ($LASTEXITCODE -eq 0)
+ & git -C $repoRoot switch -C $branch origin/dev
+ if($LASTEXITCODE -ne 0){ Write-Err "Failed to create branch $branch."; if($stashed){ & git -C $repoRoot stash pop *> $null }; return }
+ if($stashed){
+ & git -C $repoRoot stash pop
+ if($LASTEXITCODE -ne 0){ Write-Err 'Stash pop conflicted; resolve manually. Aborting PR.'; return }
+ }
+
+ & git -C $repoRoot add -- 'Directory.Packages.props' '**/package.json' '**/package-lock.json'
+ & git -C $repoRoot commit -m @'
+fix(deps): remediate moderate+ npm & NuGet vulnerabilities
+
+Automated by scripts/update-vulnerable-deps.ps1.
+
+Co-Authored-By: Claude Opus 4.8 (1M context)
+'@
+ if($LASTEXITCODE -ne 0){ Write-Warn 'Nothing to commit (no changes staged). Skipping PR.'; return }
+
+ & git -C $repoRoot push -u origin $branch
+ if($LASTEXITCODE -ne 0){ Write-Err 'git push failed.'; return }
+
+ $fixedLines = ($NuGetFixed | ForEach-Object { "- NuGet $($_.Id): $($_.From) -> $($_.To) ($($_.Severity))" }) -join "`n"
+ $npmLines = ($NpmResults | Where-Object { $_.Fixed -gt 0 } | ForEach-Object { "- npm $($_.Project): fixed $($_.Fixed)" }) -join "`n"
+ $unfixed = ($NuGetUnfixed | ForEach-Object { "- $($_.Id) ($($_.Severity)): $($_.Reason)" }) -join "`n"
+ $body = @"
+Automated remediation of moderate-and-above npm & NuGet vulnerabilities.
+
+## Fixed
+$fixedLines
+$npmLines
+
+## Needs manual review
+$unfixed
+
+See the attached report ($([System.IO.Path]::GetFileName($ReportPath))) for full detail.
+
+🤖 Generated with [Claude Code](https://claude.com/claude-code)
+"@
+ & gh pr create --base dev --head $branch --title 'fix(deps): remediate moderate+ npm & NuGet vulnerabilities' --body $body
+ if($LASTEXITCODE -ne 0){ Write-Err 'gh pr create failed.' } else { Write-Info 'PR opened against dev.' }
+}
+
+# ---------------------------------------------------------------------------
+# Main
+# ---------------------------------------------------------------------------
+$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss')
+Write-Info "update-vulnerable-deps (minSeverity=$MinSeverity, dryRun=$DryRun, npm=$doNpm, nuget=$doNuget)"
+
+if($doNuget){ Invoke-NuGetScan }
+if($doNpm){ Invoke-NpmScan }
+
+$reportPath = Write-Report -Stamp $stamp
+
+# Determine unfixed count for exit code.
+$npmRemaining = ($NpmResults | Measure-Object -Property After -Sum).Sum
+if($null -eq $npmRemaining){ $npmRemaining = 0 }
+$unfixedCount = $NuGetUnfixed.Count + [int]$npmRemaining
+
+Write-Host ''
+Write-Host '================ SUMMARY ================' -ForegroundColor Cyan
+Write-Host (" NuGet fixed : {0}" -f $NuGetFixed.Count)
+Write-Host (" NuGet skipped : {0}" -f $NuGetSkipped.Count)
+Write-Host (" NuGet unfixed : {0}" -f $NuGetUnfixed.Count)
+Write-Host (" npm projects : {0}" -f $NpmResults.Count)
+Write-Host (" npm remaining : {0}" -f $npmRemaining)
+Write-Host (" scan errors : {0}" -f $ScanErrors.Count)
+Write-Host '========================================' -ForegroundColor Cyan
+
+if($CreatePR -and -not $DryRun){
+ if($NuGetFixed.Count -gt 0 -or ($NpmResults | Where-Object { $_.Fixed -gt 0 })){
+ Invoke-CreatePR -ReportPath $reportPath
+ } else {
+ Write-Warn 'No fixes applied; skipping PR creation.'
+ }
+}
+
+if($ScanErrors.Count -gt 0){ Write-Warn "$($ScanErrors.Count) scan error(s) - see report." }
+
+if($unfixedCount -gt 0){
+ Write-Warn "$unfixedCount vulnerability/vulnerabilities remain unfixed."
+ exit 1
+}
+Write-Info 'No outstanding vulnerabilities at/above threshold.'
+exit 0
diff --git a/src/traversals/apax/apax.yml b/src/traversals/apax/apax.yml
new file mode 100644
index 000000000..53140784a
--- /dev/null
+++ b/src/traversals/apax/apax.yml
@@ -0,0 +1,51 @@
+name: "apax.traversal"
+version: "0.0.0-dev.0"
+type: "app"
+targets:
+- "1500"
+registries:
+ '@inxton': "https://npm.pkg.github.com/"
+devDependencies:
+ '@inxton/ax-sdk': "0.0.0-dev.0"
+dependencies:
+ "@inxton/axopen.abstractions": "0.0.0-dev.0"
+ "@inxton/ax.axopen.app": "0.0.0-dev.0"
+ "@inxton/ax.axopen.hwlibrary": "0.0.0-dev.0"
+ "@inxton/ax.axopen.min": "0.0.0-dev.0"
+ "@inxton/ax.catalog": "0.0.51"
+ "@inxton/axopen.components.abb.robotics": "0.0.0-dev.0"
+ "@inxton/axopen.components.abstractions": "0.0.0-dev.0"
+ "@inxton/axopen.components.balluff.identification": "0.0.0-dev.0"
+ "@inxton/axopen.components.cognex.vision": "0.0.0-dev.0"
+ "@inxton/axopen.components.desoutter.tightening": "0.0.0-dev.0"
+ "@inxton/axopen.components.drives": "0.0.0-dev.0"
+ "@inxton/axopen.components.dukane.welders": "0.0.0-dev.0"
+ "@inxton/axopen.components.elements": "0.0.0-dev.0"
+ "@inxton/axopen.components.festo.drives": "0.0.0-dev.0"
+ "@inxton/axopen.components.keyence.vision": "0.0.0-dev.0"
+ "@inxton/axopen.components.kuka.robotics": "0.0.0-dev.0"
+ "@inxton/axopen.components.mitsubishi.robotics": "0.0.0-dev.0"
+ "@inxton/axopen.components.pneumatics": "0.0.0-dev.0"
+ "@inxton/axopen.components.rexroth.drives": "0.0.0-dev.0"
+ "@inxton/axopen.components.rexroth.press": "0.0.0-dev.0"
+ "@inxton/axopen.components.rexroth.tightening": "0.0.0-dev.0"
+ "@inxton/axopen.components.robotics": "0.0.0-dev.0"
+ "@inxton/axopen.components.siem.communication": "0.0.0-dev.0"
+ "@inxton/axopen.components.siem.identification": "0.0.0-dev.0"
+ "@inxton/axopen.components.ur.robotics": "0.0.0-dev.0"
+ "@inxton/axopen.components.zebra.vision": "0.0.0-dev.0"
+ "@inxton/axopen.core": "0.0.0-dev.0"
+ "@inxton/axopen.data": "0.0.0-dev.0"
+ "axopen_data_distributed_tests_l4": "0.0.0-dev.0"
+ "axopen.data.tests_l1": "0.0.0-dev.0"
+ "axopen.integration.tests_l4": "0.0.0-dev.0"
+ "@inxton/axopen.inspectors": "0.0.0-dev.0"
+ "@inxton/axopen.io": "0.0.0-dev.0"
+ "@inxton/axopen.probers": "0.0.0-dev.0"
+ "showcase": "0.0.0-dev.0"
+ "@inxton/axopen.simatic1500": "0.0.0-dev.0"
+ "@inxton/apaxlibname": "0.0.0-dev.0"
+ "@inxton/axopen.timers": "0.0.0-dev.0"
+ "@inxton/axopen.utils": "0.0.0-dev.0"
+installStrategy: "overridable"
+...
From ae16242b754046bbbe4ad9ed3466a07a330ccf46 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 17:29:21 +0200
Subject: [PATCH 06/13] Refactor code structure for improved readability and
maintainability
---
src/styling/src/package-lock.json | 218 +++++++++--------------
src/styling/src/package.json | 8 +-
src/styling/src/wwwroot/css/momentum.css | 4 +-
3 files changed, 88 insertions(+), 142 deletions(-)
diff --git a/src/styling/src/package-lock.json b/src/styling/src/package-lock.json
index 498ed0899..41135c11f 100644
--- a/src/styling/src/package-lock.json
+++ b/src/styling/src/package-lock.json
@@ -5,8 +5,8 @@
"packages": {
"": {
"dependencies": {
- "@tailwindcss/cli": "^4.2.2",
- "tailwindcss": "^4.2.2"
+ "@tailwindcss/cli": "^4.3.0",
+ "tailwindcss": "^4.3.0"
}
},
"node_modules/@jridgewell/gen-mapping": {
@@ -350,65 +350,65 @@
}
},
"node_modules/@tailwindcss/cli": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.2.2.tgz",
- "integrity": "sha512-iJS+8kAFZ8HPqnh0O5DHCLjo4L6dD97DBQEkrhfSO4V96xeefUus2jqsBs1dUMt3OU9Ks4qIkiY0mpL5UW+4LQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.3.0.tgz",
+ "integrity": "sha512-X9kdlqyMopO9fewbgHsEeuy31YzMHbdZ9VsKt004tB+mxSg1CNbyhZYCzvhciN0AM4R4b5lvIprPjtNq7iQxpQ==",
"license": "MIT",
"dependencies": {
"@parcel/watcher": "^2.5.1",
- "@tailwindcss/node": "4.2.2",
- "@tailwindcss/oxide": "4.2.2",
- "enhanced-resolve": "^5.19.0",
+ "@tailwindcss/node": "4.3.0",
+ "@tailwindcss/oxide": "4.3.0",
+ "enhanced-resolve": "^5.21.0",
"mri": "^1.2.0",
"picocolors": "^1.1.1",
- "tailwindcss": "4.2.2"
+ "tailwindcss": "4.3.0"
},
"bin": {
"tailwindcss": "dist/index.mjs"
}
},
"node_modules/@tailwindcss/node": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",
- "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.0.tgz",
+ "integrity": "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==",
"license": "MIT",
"dependencies": {
"@jridgewell/remapping": "^2.3.5",
- "enhanced-resolve": "^5.19.0",
+ "enhanced-resolve": "^5.21.0",
"jiti": "^2.6.1",
"lightningcss": "1.32.0",
"magic-string": "^0.30.21",
"source-map-js": "^1.2.1",
- "tailwindcss": "4.2.2"
+ "tailwindcss": "4.3.0"
}
},
"node_modules/@tailwindcss/oxide": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz",
- "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.0.tgz",
+ "integrity": "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==",
"license": "MIT",
"engines": {
"node": ">= 20"
},
"optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.2.2",
- "@tailwindcss/oxide-darwin-arm64": "4.2.2",
- "@tailwindcss/oxide-darwin-x64": "4.2.2",
- "@tailwindcss/oxide-freebsd-x64": "4.2.2",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2",
- "@tailwindcss/oxide-linux-arm64-musl": "4.2.2",
- "@tailwindcss/oxide-linux-x64-gnu": "4.2.2",
- "@tailwindcss/oxide-linux-x64-musl": "4.2.2",
- "@tailwindcss/oxide-wasm32-wasi": "4.2.2",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2",
- "@tailwindcss/oxide-win32-x64-msvc": "4.2.2"
+ "@tailwindcss/oxide-android-arm64": "4.3.0",
+ "@tailwindcss/oxide-darwin-arm64": "4.3.0",
+ "@tailwindcss/oxide-darwin-x64": "4.3.0",
+ "@tailwindcss/oxide-freebsd-x64": "4.3.0",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.3.0",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.3.0",
+ "@tailwindcss/oxide-linux-x64-musl": "4.3.0",
+ "@tailwindcss/oxide-wasm32-wasi": "4.3.0",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.3.0"
}
},
"node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz",
- "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.0.tgz",
+ "integrity": "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==",
"cpu": [
"arm64"
],
@@ -422,9 +422,9 @@
}
},
"node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz",
- "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.0.tgz",
+ "integrity": "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==",
"cpu": [
"arm64"
],
@@ -438,9 +438,9 @@
}
},
"node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz",
- "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.0.tgz",
+ "integrity": "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==",
"cpu": [
"x64"
],
@@ -454,9 +454,9 @@
}
},
"node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz",
- "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.0.tgz",
+ "integrity": "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==",
"cpu": [
"x64"
],
@@ -470,9 +470,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz",
- "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.0.tgz",
+ "integrity": "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==",
"cpu": [
"arm"
],
@@ -486,9 +486,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz",
- "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.0.tgz",
+ "integrity": "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==",
"cpu": [
"arm64"
],
@@ -502,9 +502,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz",
- "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.0.tgz",
+ "integrity": "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==",
"cpu": [
"arm64"
],
@@ -518,9 +518,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz",
- "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.0.tgz",
+ "integrity": "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==",
"cpu": [
"x64"
],
@@ -534,9 +534,9 @@
}
},
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz",
- "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.0.tgz",
+ "integrity": "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==",
"cpu": [
"x64"
],
@@ -550,9 +550,9 @@
}
},
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz",
- "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.0.tgz",
+ "integrity": "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==",
"bundleDependencies": [
"@napi-rs/wasm-runtime",
"@emnapi/core",
@@ -567,10 +567,10 @@
"license": "MIT",
"optional": true,
"dependencies": {
- "@emnapi/core": "^1.8.1",
- "@emnapi/runtime": "^1.8.1",
- "@emnapi/wasi-threads": "^1.1.0",
- "@napi-rs/wasm-runtime": "^1.1.1",
+ "@emnapi/core": "^1.10.0",
+ "@emnapi/runtime": "^1.10.0",
+ "@emnapi/wasi-threads": "^1.2.1",
+ "@napi-rs/wasm-runtime": "^1.1.4",
"@tybys/wasm-util": "^0.10.1",
"tslib": "^2.8.1"
},
@@ -578,64 +578,10 @@
"node": ">=14.0.0"
}
},
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.7.1",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.1.0",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.7.1",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.1.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1",
- "@tybys/wasm-util": "^0.10.1"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.10.1",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.1",
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz",
- "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.0.tgz",
+ "integrity": "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==",
"cpu": [
"arm64"
],
@@ -649,9 +595,9 @@
}
},
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz",
- "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.0.tgz",
+ "integrity": "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==",
"cpu": [
"x64"
],
@@ -674,13 +620,13 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.20.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
- "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==",
+ "version": "5.22.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.22.1.tgz",
+ "integrity": "sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
- "tapable": "^2.3.0"
+ "tapable": "^2.3.3"
},
"engines": {
"node": ">=10.13.0"
@@ -714,9 +660,9 @@
}
},
"node_modules/jiti": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
- "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
+ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
"license": "MIT",
"bin": {
"jiti": "lib/jiti-cli.mjs"
@@ -1023,15 +969,15 @@
}
},
"node_modules/tailwindcss": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
- "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.0.tgz",
+ "integrity": "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==",
"license": "MIT"
},
"node_modules/tapable": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz",
- "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
+ "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
"license": "MIT",
"engines": {
"node": ">=6"
diff --git a/src/styling/src/package.json b/src/styling/src/package.json
index 5acf123ef..7a25bdcf0 100644
--- a/src/styling/src/package.json
+++ b/src/styling/src/package.json
@@ -1,10 +1,10 @@
{
"scripts": {
- "build:css": "npx @tailwindcss/cli -i ./wwwroot/tailwindroot.css -o ./wwwroot/css/axopenstyling.css --minify",
- "watch:css": "npx @tailwindcss/cli -i ./wwwroot/tailwindroot.css -o ./wwwroot/css/axopenstyling.css --watch"
+ "build:css": "npx @tailwindcss/cli -i ./wwwroot/css/tailwind.css -o ./wwwroot/css/momentum.css --minify --content \"..\\..\\..\\**\\*.{html,js,jsx,ts,tsx,vue,razor}\"",
+ "watch:css": "npx @tailwindcss/cli -i ./wwwroot/css/tailwind.css -o ./wwwroot/css/momentum.css --watch --content \"..\\..\\..\\**\\*.{html,js,jsx,ts,tsx,vue,razor}\""
},
"dependencies": {
- "@tailwindcss/cli": "^4.2.2",
- "tailwindcss": "^4.2.2"
+ "@tailwindcss/cli": "^4.3.0",
+ "tailwindcss": "^4.3.0"
}
}
diff --git a/src/styling/src/wwwroot/css/momentum.css b/src/styling/src/wwwroot/css/momentum.css
index 1ca14ac2b..4ac1215be 100644
--- a/src/styling/src/wwwroot/css/momentum.css
+++ b/src/styling/src/wwwroot/css/momentum.css
@@ -1,2 +1,2 @@
-/*! tailwindcss v4.2.2 | 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)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.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)}.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
+/*! 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)}.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
From 334cd2625608b059c3103481326c6050af3fdd16 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 18:02:26 +0200
Subject: [PATCH 07/13] feat(deps): add script to update all non-AXSharp
dependencies to latest stable versions
---
scripts/update-latest-deps.ps1 | 682 +++++++++++++++++++++++++++++++++
1 file changed, 682 insertions(+)
create mode 100644 scripts/update-latest-deps.ps1
diff --git a/scripts/update-latest-deps.ps1 b/scripts/update-latest-deps.ps1
new file mode 100644
index 000000000..8ba494dde
--- /dev/null
+++ b/scripts/update-latest-deps.ps1
@@ -0,0 +1,682 @@
+#!/usr/bin/env pwsh
+<#
+.SYNOPSIS
+Updates all (non-AXSharp) dependencies to their latest STABLE versions across NuGet, npm and dotnet tools.
+
+.DESCRIPTION
+One command to bring the repo up to the latest stable third-party versions. It complements - and never
+overlaps with - the two narrower updaters:
+
+ * scripts/update_axsharp_versions.ps1 - owns AXSharp.*/Inxton.Operon.* (always skipped here)
+ * scripts/update-vulnerable-deps.ps1 - owns the "Security pins" ItemGroup (always skipped here)
+
+Scope:
+
+ NuGet - rewrites entries (and the GitVersion.MsBuild ) in
+ Directory.Packages.props to the latest STABLE version from nuget.org. AXSharp/Operon/AXOpen
+ packages, the security-pin entries, and framework-tied packages (Microsoft.AspNetCore.*,
+ Microsoft.EntityFrameworkCore.*, Microsoft.Extensions.*, System.*, Microsoft.NET.ILLink.Tasks,
+ Microsoft.VisualStudio.Web.CodeGeneration.Design) are FROZEN to stay aligned with net10.0.
+
+ npm - for the source package.json projects, rewrites declared ranges (preserving the ^/~ prefix) to
+ the latest stable from `npm outdated`, then runs `npm install` to refresh package-lock.json.
+
+ tools - rewrites .config/dotnet-tools.json tool versions to latest stable (AXSharp.ix* skipped).
+
+GitVersion.MsBuild and gitversion.tool are resolved together and pinned to the SAME latest stable.
+
+"Latest" means latest STABLE: alpha/beta/rc are skipped. Major-version bumps ARE applied but flagged
+prominently in the report (use -SkipMajor to exclude them).
+
+Default action is a DRY RUN - pass -Apply to write changes. With -Apply (and unless -SkipBuild) the full
+cake build runs as verification; on failure the offending bump(s) are bisected out and only the green
+remainder is kept. A timestamped Markdown + JSON report is written to scripts/reports/. With -CreatePR the
+changes are committed to branch 'chore/update-latest-deps' off origin/dev and a PR is opened against dev.
+
+.PARAMETER Apply
+Write changes. Without it the script previews only (dry run) and touches nothing.
+
+.PARAMETER NuGetOnly
+Process NuGet (Directory.Packages.props) only.
+
+.PARAMETER NpmOnly
+Process npm only.
+
+.PARAMETER ToolsOnly
+Process dotnet tools only.
+
+.PARAMETER SkipMajor
+Exclude major-version bumps (default: apply them and flag them in the report).
+
+.PARAMETER SkipBuild
+Skip the cake build verification step (fast path; relies on manual review).
+
+.PARAMETER RollbackAllOnFailure
+On build failure, revert every change instead of bisecting for a green subset.
+
+.PARAMETER MaxBisectBuilds
+Cap on the number of full cake builds spent bisecting after an initial failure. Default 6.
+
+.PARAMETER CreatePR
+Commit changes to branch 'chore/update-latest-deps' off origin/dev and open a PR against dev. Implies -Apply.
+
+.PARAMETER Source
+NuGet v3 feed used to look up available versions. Default nuget.org.
+
+.PARAMETER Token
+Token for the NuGet feed (private feeds). Falls back to NUGET_TOKEN / GITHUB_PACKAGES_TOKEN /
+GITHUB_TOKEN / GH_TOKEN.
+
+.PARAMETER Detailed
+Verbose logging.
+
+.EXAMPLE
+./update-latest-deps.ps1 # dry run, all ecosystems
+
+.EXAMPLE
+./update-latest-deps.ps1 -NuGetOnly # dry run, NuGet only
+
+.EXAMPLE
+./update-latest-deps.ps1 -Apply -SkipBuild # write changes, skip the (slow) cake build
+
+.EXAMPLE
+./update-latest-deps.ps1 -CreatePR # apply, build-verify, open PR against dev
+#>
+
+[CmdletBinding()]
+param(
+ [switch]$Apply,
+ [switch]$NuGetOnly,
+ [switch]$NpmOnly,
+ [switch]$ToolsOnly,
+ [switch]$SkipMajor,
+ [switch]$SkipBuild,
+ [switch]$RollbackAllOnFailure,
+ [int]$MaxBisectBuilds = 6,
+ [switch]$CreatePR,
+ [string]$Source = 'https://api.nuget.org/v3/index.json',
+ [string]$Token,
+ [switch]$Detailed
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
+. "$scriptRoot/_deps-common.ps1"
+
+$repoRoot = Split-Path -Parent $scriptRoot
+$propsPath = Join-Path $repoRoot 'Directory.Packages.props'
+$toolsPath = Join-Path $repoRoot '.config/dotnet-tools.json'
+$cakeProj = Join-Path $repoRoot 'cake/Build.csproj'
+
+# ---------------------------------------------------------------------------
+# Validation & constants
+# ---------------------------------------------------------------------------
+if($CreatePR){ $Apply = $true } # -CreatePR implies writing changes
+$DryRun = -not $Apply
+
+$onlyCount = @($NuGetOnly,$NpmOnly,$ToolsOnly | Where-Object { $_ }).Count
+if($onlyCount -gt 1){ Write-Err '-NuGetOnly / -NpmOnly / -ToolsOnly are mutually exclusive.'; exit 1 }
+
+$doNuget = (-not $NpmOnly) -and (-not $ToolsOnly)
+$doNpm = (-not $NuGetOnly) -and (-not $ToolsOnly)
+$doTools = (-not $NuGetOnly) -and (-not $NpmOnly)
+
+# Feed auth: never send a token to the public nuget.org CDN (it 403s on authed cached responses).
+# Resolve a token only for an explicitly-provided private -Source (or explicit -Token).
+$IsPublicNuGet = ($Source -match 'api\.nuget\.org')
+$feedToken = if($Token){ $Token } elseif(-not $IsPublicNuGet){ Resolve-FeedToken -Token $Token -Detailed:$Detailed } else { $null }
+
+# Owned by update_axsharp_versions.ps1 - never touched.
+$AxSharpSkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b'
+# Owned by update-vulnerable-deps.ps1 ("Security pins" ItemGroup) - never touched.
+$SecurityPinIds = @('Snappier','System.Security.Cryptography.Xml')
+# Frozen to stay aligned with net10.0 (see plan / interview).
+$FrameworkFreezeExact = @('Microsoft.NET.ILLink.Tasks','Microsoft.VisualStudio.Web.CodeGeneration.Design')
+$FrameworkFreezePrefixes = @('Microsoft.AspNetCore.','Microsoft.EntityFrameworkCore.','Microsoft.Extensions.','System.')
+# GitVersion packages/tool are kept in sync with one another.
+$GitVersionNuGetId = 'GitVersion.MsBuild'
+$GitVersionToolId = 'gitversion.tool'
+
+# Source npm projects (explicit list - avoids bin/obj/ctrl/.apax generated copies).
+$NpmProjects = @(
+ 'src/components.abb.robotics/package.json'
+ 'src/components.abstractions/package.json'
+ 'src/data/package.json'
+ 'src/inspectors/package.json'
+ 'src/showcase/app/ix-blazor/showcase.blazor/package.json'
+ 'src/styling/src/package.json'
+) | ForEach-Object { Join-Path $repoRoot $_ }
+
+# Accumulators for the report.
+$Changes = New-Object System.Collections.ArrayList # applied/previewed bumps
+$Frozen = New-Object System.Collections.ArrayList # id + reason
+$Reverted = New-Object System.Collections.ArrayList # bumps removed by bisection
+$ScanErrors = New-Object System.Collections.ArrayList
+$BuildResult = 'not-run'
+
+# Captured original file contents (for bisection replay). file path -> original raw text.
+$OriginalContent = @{}
+
+# ---------------------------------------------------------------------------
+# Helpers
+# ---------------------------------------------------------------------------
+function Test-CommandAvailable { param([string]$Name) $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) }
+
+function Test-IsMajorBump {
+ param([string]$From,[string]$To)
+ $f = ConvertTo-VersionRecord $From
+ $t = ConvertTo-VersionRecord $To
+ return ($t.Major -gt $f.Major)
+}
+
+function Get-LatestStableVersion {
+ # Highest non-prerelease version of $PackageId on the feed, or $null.
+ param([string]$PackageId,$FeedCtx)
+ $versions = @()
+ try { $versions = Get-PackageVersionsFromFeed -PkgBase $FeedCtx.PkgBase -Headers $FeedCtx.Headers -PackageId $PackageId }
+ catch { if($Detailed){ Write-Warn "feed lookup failed for ${PackageId}: $($_.Exception.Message)" }; return $null }
+ if(-not $versions -or @($versions).Count -eq 0){ return $null }
+ $stable = @($versions | Where-Object { -not (Test-IsPrerelease $_) })
+ if($stable.Count -eq 0){ return $null }
+ $best = $stable[0]
+ foreach($v in $stable){ if(Test-VersionGreater $v $best){ $best = $v } }
+ return $best
+}
+
+function Get-NuGetDisposition {
+ # Returns 'update' or a 'freeze-*' / 'skip-*' reason for a package id.
+ param([string]$Id)
+ if($Id -match $AxSharpSkipPattern){ return 'skip-axsharp (owned by update_axsharp_versions.ps1)' }
+ if($SecurityPinIds -contains $Id){ return 'skip-security-pin (owned by update-vulnerable-deps.ps1)' }
+ if($FrameworkFreezeExact -contains $Id){ return 'freeze-framework (net10.0-tied)' }
+ foreach($p in $FrameworkFreezePrefixes){ if($Id.StartsWith($p)){ return 'freeze-framework (net10.0-tied)' } }
+ return 'update'
+}
+
+# ---------------------------------------------------------------------------
+# Change application (replayable from captured original content)
+# ---------------------------------------------------------------------------
+function Apply-ChangeToContent {
+ # Applies a single change to the supplied file content and returns the new content.
+ param([string]$Content,$Change)
+ $idEsc = [regex]::Escape($Change.Id)
+ switch($Change.Kind){
+ 'props-packageversion' {
+ $rx = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")"
+ return [regex]::Replace($Content,$rx,"`${1}$($Change.To)`${2}",1)
+ }
+ 'props-globalref' {
+ $rx = "(]*\bInclude=`"$idEsc`"[^>]*\bVersion=`")[^`"]*(`")"
+ return [regex]::Replace($Content,$rx,"`${1}$($Change.To)`${2}",1)
+ }
+ 'tool' {
+ $rx = "(`"$idEsc`"\s*:\s*\{[^{}]*?`"version`"\s*:\s*`")[^`"]+(`")"
+ return [System.Text.RegularExpressions.Regex]::Replace(
+ $Content,$rx,"`${1}$($Change.To)`${2}",
+ [System.Text.RegularExpressions.RegexOptions]::Singleline)
+ }
+ 'npm' {
+ # Preserve any leading range operator (^, ~, >=, etc.) on the declared range.
+ $rx = "(`"$idEsc`"\s*:\s*`")([^`"]*)(`")"
+ return [regex]::Replace($Content,$rx,{
+ param($m)
+ $old = $m.Groups[2].Value
+ $prefix = ''
+ if($old -match '^([\^~>=<\s]*)'){ $prefix = $Matches[1] }
+ $m.Groups[1].Value + $prefix + $Change.To + $m.Groups[3].Value
+ },1)
+ }
+ default { return $Content }
+ }
+}
+
+function Write-FileSet {
+ # Rebuilds every affected file from its captured ORIGINAL content, applying only $ActiveChanges.
+ # Returns the list of npm directories whose package.json changed (caller refreshes their lock).
+ param($ActiveChanges)
+ $byFile = $ActiveChanges | Group-Object -Property File
+ $npmDirs = New-Object System.Collections.ArrayList
+ foreach($g in $byFile){
+ $file = $g.Name
+ if(-not $OriginalContent.ContainsKey($file)){ continue }
+ $content = $OriginalContent[$file]
+ foreach($c in $g.Group){
+ $content = Apply-ChangeToContent -Content $content -Change $c
+ if($c.Ecosystem -eq 'npm'){ $dir = Split-Path -Parent $file; if(-not $npmDirs.Contains($dir)){ [void]$npmDirs.Add($dir) } }
+ }
+ Write-Utf8NoBom-LF -Path $file -Content $content
+ }
+ # Files that had ALL their changes removed must be restored to original too.
+ foreach($file in $OriginalContent.Keys){
+ if(-not ($byFile | Where-Object { $_.Name -eq $file })){
+ Write-Utf8NoBom-LF -Path $file -Content $OriginalContent[$file]
+ }
+ }
+ return $npmDirs
+}
+
+function Update-NpmLockfiles {
+ param($NpmDirs)
+ foreach($dir in $NpmDirs){
+ if($Detailed){ Write-Info " npm install (refresh lockfile): $dir" }
+ Push-Location $dir
+ try { & npm install --no-audit --no-fund *> $null }
+ catch { [void]$ScanErrors.Add("npm install failed in ${dir}: $($_.Exception.Message)") }
+ finally { Pop-Location }
+ }
+}
+
+# ---------------------------------------------------------------------------
+# Scanners (populate $Changes / $Frozen; capture originals)
+# ---------------------------------------------------------------------------
+function Invoke-NuGetScan {
+ param($FeedCtx)
+ Write-Info 'Scanning NuGet (Directory.Packages.props)...'
+ if(-not (Test-Path $propsPath)){ [void]$ScanErrors.Add('Directory.Packages.props not found'); return }
+ $content = Get-Content -LiteralPath $propsPath -Raw
+ $OriginalContent[$propsPath] = $content
+
+ $pvMatches = [regex]::Matches($content,']*\bInclude="([^"]+)"[^>]*\bVersion="([^"]+)"')
+ $grMatches = [regex]::Matches($content,']*\bInclude="([^"]+)"[^>]*\bVersion="([^"]+)"')
+
+ foreach($m in @($pvMatches) + @($grMatches)){
+ $id = $m.Groups[1].Value
+ $cur = $m.Groups[2].Value
+ $kind = if($m.Value -like '*GlobalPackageReference*'){ 'props-globalref' } else { 'props-packageversion' }
+
+ # GitVersion handled together below.
+ if($id -eq $GitVersionNuGetId){ continue }
+
+ $disp = Get-NuGetDisposition $id
+ if($disp -ne 'update'){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason=$disp }); continue }
+
+ $latest = Get-LatestStableVersion -PackageId $id -FeedCtx $FeedCtx
+ if(-not $latest){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason='no stable version on feed' }); continue }
+ if(-not (Test-VersionGreater $latest $cur)){ if($Detailed){ Write-Info " $id already latest ($cur)" }; continue }
+
+ $isMajor = Test-IsMajorBump $cur $latest
+ if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue }
+
+ [void]$Changes.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$id; From=$cur; To=$latest; IsMajor=$isMajor; Kind=$kind; File=$propsPath })
+ Write-Info (" {0}: {1} -> {2}{3}" -f $id,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''}))
+ }
+}
+
+function Resolve-GitVersionSync {
+ # Resolves one latest-stable GitVersion across MsBuild pkg + dotnet tool and queues both bumps.
+ param($FeedCtx)
+ if(-not (Test-Path $propsPath)){ return }
+ $propsRaw = $OriginalContent[$propsPath]
+ if(-not $propsRaw){ $propsRaw = Get-Content -LiteralPath $propsPath -Raw; $OriginalContent[$propsPath] = $propsRaw }
+
+ $curMsb = $null
+ $m = [regex]::Match($propsRaw,"]*\bInclude=`"$([regex]::Escape($GitVersionNuGetId))`"[^>]*\bVersion=`"([^`"]+)`"")
+ if($m.Success){ $curMsb = $m.Groups[1].Value }
+
+ $curTool = $null
+ if(Test-Path $toolsPath){
+ $toolsRaw = $OriginalContent[$toolsPath]
+ if(-not $toolsRaw){ $toolsRaw = Get-Content -LiteralPath $toolsPath -Raw; $OriginalContent[$toolsPath] = $toolsRaw }
+ $tm = [regex]::Match($toolsRaw,"`"$([regex]::Escape($GitVersionToolId))`"\s*:\s*\{[^{}]*?`"version`"\s*:\s*`"([^`"]+)`"",[System.Text.RegularExpressions.RegexOptions]::Singleline)
+ if($tm.Success){ $curTool = $tm.Groups[1].Value }
+ }
+
+ $latestMsb = Get-LatestStableVersion -PackageId $GitVersionNuGetId -FeedCtx $FeedCtx
+ $latestTool = Get-LatestStableVersion -PackageId $GitVersionToolId -FeedCtx $FeedCtx
+ $synced = $latestMsb
+ if($latestTool -and (Test-VersionGreater $latestTool $synced)){ $synced = $latestTool }
+ if(-not $synced){ Write-Warn 'Could not resolve a latest stable GitVersion; leaving as-is.'; return }
+
+ if($doNuget -and $curMsb -and (Test-VersionGreater $synced $curMsb)){
+ $isMajor = Test-IsMajorBump $curMsb $synced
+ if(-not ($isMajor -and $SkipMajor)){
+ [void]$Changes.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$GitVersionNuGetId; From=$curMsb; To=$synced; IsMajor=$isMajor; Kind='props-globalref'; File=$propsPath })
+ Write-Info (" {0}: {1} -> {2} (GitVersion sync){3}" -f $GitVersionNuGetId,$curMsb,$synced,$(if($isMajor){' [MAJOR]'}else{''}))
+ } else { [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='nuget'; Id=$GitVersionNuGetId; Current=$curMsb; Reason="major bump to $synced skipped (-SkipMajor)" }) }
+ }
+ if($doTools -and $curTool -and (Test-VersionGreater $synced $curTool)){
+ $isMajor = Test-IsMajorBump $curTool $synced
+ if(-not ($isMajor -and $SkipMajor)){
+ [void]$Changes.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$GitVersionToolId; From=$curTool; To=$synced; IsMajor=$isMajor; Kind='tool'; File=$toolsPath })
+ Write-Info (" {0}: {1} -> {2} (GitVersion sync){3}" -f $GitVersionToolId,$curTool,$synced,$(if($isMajor){' [MAJOR]'}else{''}))
+ } else { [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$GitVersionToolId; Current=$curTool; Reason="major bump to $synced skipped (-SkipMajor)" }) }
+ }
+}
+
+function Invoke-ToolsScan {
+ param($FeedCtx)
+ Write-Info 'Scanning dotnet tools (.config/dotnet-tools.json)...'
+ if(-not (Test-Path $toolsPath)){ [void]$ScanErrors.Add('.config/dotnet-tools.json not found'); return }
+ $raw = $OriginalContent[$toolsPath]
+ if(-not $raw){ $raw = Get-Content -LiteralPath $toolsPath -Raw; $OriginalContent[$toolsPath] = $raw }
+ try { $obj = $raw | ConvertFrom-Json -ErrorAction Stop } catch { [void]$ScanErrors.Add('tools JSON parse failed'); return }
+ if(-not $obj.tools){ [void]$ScanErrors.Add("tools JSON missing 'tools'"); return }
+
+ foreach($name in $obj.tools.PSObject.Properties.Name){
+ if($name -like 'AXSharp.*' -or $name -like 'Inxton.Operon.*'){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$obj.tools.$name.version; Reason='skip-axsharp (owned by update_axsharp_versions.ps1)' }); continue }
+ if($name -eq $GitVersionToolId){ continue } # handled by Resolve-GitVersionSync
+ $cur = $obj.tools.$name.version
+ $latest = Get-LatestStableVersion -PackageId $name -FeedCtx $FeedCtx
+ if(-not $latest){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$cur; Reason='no stable version on feed' }); continue }
+ if(-not (Test-VersionGreater $latest $cur)){ if($Detailed){ Write-Info " $name already latest ($cur)" }; continue }
+ $isMajor = Test-IsMajorBump $cur $latest
+ if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue }
+ [void]$Changes.Add([PSCustomObject]@{ Ecosystem='tool'; Id=$name; From=$cur; To=$latest; IsMajor=$isMajor; Kind='tool'; File=$toolsPath })
+ Write-Info (" {0}: {1} -> {2}{3}" -f $name,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''}))
+ }
+}
+
+function Invoke-NpmScan {
+ Write-Info 'Scanning npm projects...'
+ if(-not (Test-CommandAvailable 'npm')){ Write-Err 'npm not found on PATH.'; [void]$ScanErrors.Add('npm not found'); return }
+ foreach($pkgJson in $NpmProjects){
+ if(-not (Test-Path -LiteralPath $pkgJson)){ if($Detailed){ Write-Warn "missing: $pkgJson" }; continue }
+ $dir = Split-Path -Parent $pkgJson
+ $name = (Resolve-Path -LiteralPath $dir).Path.Replace((Resolve-Path $repoRoot).Path,'').TrimStart('\','/')
+ Write-Info " $name"
+ $OriginalContent[$pkgJson] = Get-Content -LiteralPath $pkgJson -Raw
+ Push-Location $dir
+ try {
+ if(-not (Test-Path 'node_modules')){
+ if($Detailed){ Write-Info " npm install (no node_modules)" }
+ & npm install --no-audit --no-fund *> $null
+ }
+ $raw = & npm outdated --json 2>$null | Out-String
+ if(-not $raw.Trim()){ if($Detailed){ Write-Info " up to date" }; Pop-Location; continue }
+ $parsed = $null; try { $parsed = $raw | ConvertFrom-Json } catch { [void]$ScanErrors.Add("npm outdated unparseable: $name"); Pop-Location; continue }
+ if(-not $parsed){ Pop-Location; continue }
+ foreach($p in $parsed.PSObject.Properties){
+ $pkgName = $p.Name
+ $info = $p.Value
+ if($info -is [System.Object[]]){ $info = $info[0] } # multiple entries -> take first
+ $cur = if($info.PSObject.Properties.Name -contains 'current'){ $info.current } else { $null }
+ $latest = if($info.PSObject.Properties.Name -contains 'latest'){ $info.latest } else { $null }
+ if(-not $cur -or -not $latest){ continue } # not installed / no candidate
+ if(Test-IsPrerelease $latest){ continue } # stable only
+ if(-not (Test-VersionGreater $latest $cur)){ continue }
+ $isMajor = Test-IsMajorBump $cur $latest
+ if($isMajor -and $SkipMajor){ [void]$Frozen.Add([PSCustomObject]@{ Ecosystem='npm'; Id="$name/$pkgName"; Current=$cur; Reason="major bump to $latest skipped (-SkipMajor)" }); continue }
+ [void]$Changes.Add([PSCustomObject]@{ Ecosystem='npm'; Id=$pkgName; Project=$name; From=$cur; To=$latest; IsMajor=$isMajor; Kind='npm'; File=$pkgJson })
+ Write-Info (" {0}: {1} -> {2}{3}" -f $pkgName,$cur,$latest,$(if($isMajor){' [MAJOR]'}else{''}))
+ }
+ } catch { [void]$ScanErrors.Add("npm scan error in ${name}: $($_.Exception.Message)") }
+ finally { Pop-Location }
+ }
+}
+
+# ---------------------------------------------------------------------------
+# Build verification + bisection
+# ---------------------------------------------------------------------------
+function Invoke-CakeBuild {
+ if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet CLI not found; cannot build.'; return $false }
+ Write-Info 'Running full cake build (dotnet run --project cake/Build.csproj) ...'
+ & dotnet run --project $cakeProj
+ return ($LASTEXITCODE -eq 0)
+}
+
+function Invoke-BisectGreenSubset {
+ # ddmin-style: remove minimal change subsets until the build is green, bounded by $MaxBisectBuilds.
+ # Mutates the working tree to the green subset; records removed changes in $script:Reverted.
+ $builds = 0
+ $active = @($Changes)
+ $n = 2
+ Write-Warn "Build failed with all $($active.Count) change(s). Bisecting for a green subset (max $MaxBisectBuilds builds)..."
+ while($builds -lt $MaxBisectBuilds -and $active.Count -gt 1){
+ $chunkSize = [Math]::Ceiling($active.Count / $n)
+ $removedSomething = $false
+ for($i=0; $i -lt $active.Count; $i += $chunkSize){
+ $chunk = $active[$i..([Math]::Min($i+$chunkSize-1,$active.Count-1))]
+ $trial = $active | Where-Object { $chunk -notcontains $_ }
+ if(@($trial).Count -eq 0){ continue }
+ $dirs = Write-FileSet -ActiveChanges $trial
+ Update-NpmLockfiles -NpmDirs $dirs
+ $builds++
+ Write-Info " bisect build $builds/$MaxBisectBuilds : trying $((@($trial)).Count) of $($active.Count) changes"
+ if(Invoke-CakeBuild){ $active = @($trial); $n = [Math]::Max($n-1,2); $removedSomething = $true; break }
+ if($builds -ge $MaxBisectBuilds){ break }
+ }
+ if(-not $removedSomething){
+ if($n -ge $active.Count){ break }
+ $n = [Math]::Min($n*2,$active.Count)
+ }
+ }
+ # Record what got dropped and lock in the surviving subset.
+ $kept = @($active)
+ foreach($c in $Changes){ if($kept -notcontains $c){ [void]$Reverted.Add($c) } }
+ $dirs = Write-FileSet -ActiveChanges $kept
+ Update-NpmLockfiles -NpmDirs $dirs
+ if($kept.Count -gt 0 -and $builds -lt $MaxBisectBuilds){
+ $builds++
+ Write-Info " bisect build $builds : confirming surviving subset ($($kept.Count) change(s))"
+ $script:BuildResult = if(Invoke-CakeBuild){ 'pass (after bisection)' } else { 'FAIL (bisection exhausted - manual review)' }
+ } else {
+ $script:BuildResult = "indeterminate (bisection hit -MaxBisectBuilds=$MaxBisectBuilds)"
+ }
+}
+
+# ---------------------------------------------------------------------------
+# Report
+# ---------------------------------------------------------------------------
+function Write-Report {
+ param([string]$Stamp)
+ $reportsDir = Join-Path $scriptRoot 'reports'
+ if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null }
+ $mdPath = Join-Path $reportsDir "latest-deps-report-$Stamp.md"
+ $jsonPath = Join-Path $reportsDir "latest-deps-report-$Stamp.json"
+
+ $applied = @($Changes | Where-Object { $Reverted -notcontains $_ })
+ $majors = @($applied | Where-Object { $_.IsMajor })
+
+ $payload = [PSCustomObject]@{
+ timestamp = $Stamp
+ dryRun = [bool]$DryRun
+ skipMajor = [bool]$SkipMajor
+ ecosystems = @{ nuget=[bool]$doNuget; npm=[bool]$doNpm; tools=[bool]$doTools }
+ build = $BuildResult
+ applied = $applied
+ reverted = $Reverted
+ frozen = $Frozen
+ majors = $majors
+ scanErrors = $ScanErrors
+ }
+ Write-Utf8NoBom-LF -Path $jsonPath -Content ($payload | ConvertTo-Json -Depth 8)
+
+ $sb = New-Object System.Text.StringBuilder
+ [void]$sb.AppendLine('# Latest-dependency update report')
+ [void]$sb.AppendLine('')
+ [void]$sb.AppendLine("- Generated: $Stamp")
+ [void]$sb.AppendLine("- Dry run: $([bool]$DryRun)")
+ [void]$sb.AppendLine("- Skip major: $([bool]$SkipMajor)")
+ [void]$sb.AppendLine("- Ecosystems: NuGet=$doNuget, npm=$doNpm, tools=$doTools")
+ [void]$sb.AppendLine("- Build result: **$BuildResult**")
+ [void]$sb.AppendLine('')
+
+ if($majors.Count -gt 0){
+ [void]$sb.AppendLine("## [!] Major-version bumps ($($majors.Count)) - review carefully")
+ [void]$sb.AppendLine('| Ecosystem | Package | From | To |')
+ [void]$sb.AppendLine('|---|---|---|---|')
+ foreach($c in $majors){ [void]$sb.AppendLine("| $($c.Ecosystem) | $($c.Id) | $($c.From) | $($c.To) |") }
+ [void]$sb.AppendLine('')
+ }
+
+ [void]$sb.AppendLine("## NuGet bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'nuget' }).Count))")
+ [void]$sb.AppendLine('| Package | From | To | Major? |')
+ [void]$sb.AppendLine('|---|---|---|---|')
+ foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'nuget' })){ [void]$sb.AppendLine("| $($c.Id) | $($c.From) | $($c.To) | $(if($c.IsMajor){'YES'}else{''}) |") }
+ [void]$sb.AppendLine('')
+
+ [void]$sb.AppendLine("## npm bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'npm' }).Count))")
+ [void]$sb.AppendLine('| Project | Package | From | To | Major? |')
+ [void]$sb.AppendLine('|---|---|---|---|---|')
+ foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'npm' })){ [void]$sb.AppendLine("| $($c.Project) | $($c.Id) | $($c.From) | $($c.To) | $(if($c.IsMajor){'YES'}else{''}) |") }
+ [void]$sb.AppendLine('')
+
+ [void]$sb.AppendLine("## Tools bumped ($(@($applied | Where-Object { $_.Ecosystem -eq 'tool' }).Count))")
+ [void]$sb.AppendLine('| Tool | From | To |')
+ [void]$sb.AppendLine('|---|---|---|')
+ foreach($c in ($applied | Where-Object { $_.Ecosystem -eq 'tool' })){ [void]$sb.AppendLine("| $($c.Id) | $($c.From) | $($c.To) |") }
+ [void]$sb.AppendLine('')
+
+ if($Reverted.Count -gt 0){
+ [void]$sb.AppendLine("## Reverted by build bisection ($($Reverted.Count))")
+ [void]$sb.AppendLine('| Ecosystem | Package | From | To |')
+ [void]$sb.AppendLine('|---|---|---|---|')
+ foreach($c in $Reverted){ [void]$sb.AppendLine("| $($c.Ecosystem) | $($c.Id) | $($c.From) | $($c.To) |") }
+ [void]$sb.AppendLine('')
+ }
+
+ [void]$sb.AppendLine("## Frozen / skipped ($($Frozen.Count))")
+ [void]$sb.AppendLine('| Ecosystem | Package | Current | Reason |')
+ [void]$sb.AppendLine('|---|---|---|---|')
+ foreach($f in $Frozen){ [void]$sb.AppendLine("| $($f.Ecosystem) | $($f.Id) | $($f.Current) | $($f.Reason) |") }
+ [void]$sb.AppendLine('')
+
+ if($ScanErrors.Count -gt 0){
+ [void]$sb.AppendLine('## Scan errors')
+ foreach($e in $ScanErrors){ [void]$sb.AppendLine("- $e") }
+ }
+ Write-Utf8NoBom-LF -Path $mdPath -Content $sb.ToString()
+ Write-Info "Report: $mdPath"
+ return $mdPath
+}
+
+# ---------------------------------------------------------------------------
+# Commit + PR
+# ---------------------------------------------------------------------------
+function Invoke-CreatePR {
+ param([string]$ReportPath)
+ if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot create PR.'; return }
+ if(-not (Test-CommandAvailable 'gh')){ Write-Err 'gh CLI not found; cannot open PR.'; return }
+
+ $branch = 'chore/update-latest-deps'
+ Write-Info "Creating branch '$branch' off origin/dev and opening PR..."
+
+ & git -C $repoRoot fetch origin dev --quiet
+ & git -C $repoRoot stash push -u -m 'latest-deps-wip' *> $null
+ $stashed = ($LASTEXITCODE -eq 0)
+ & git -C $repoRoot switch -C $branch origin/dev
+ if($LASTEXITCODE -ne 0){ Write-Err "Failed to create branch $branch."; if($stashed){ & git -C $repoRoot stash pop *> $null }; return }
+ if($stashed){
+ & git -C $repoRoot stash pop
+ if($LASTEXITCODE -ne 0){ Write-Err 'Stash pop conflicted; resolve manually. Aborting PR.'; return }
+ }
+
+ & git -C $repoRoot add -- 'Directory.Packages.props' '.config/dotnet-tools.json' '**/package.json' '**/package-lock.json'
+ & git -C $repoRoot commit -m @'
+chore(deps): update dependencies to latest stable
+
+Automated by scripts/update-latest-deps.ps1.
+
+Co-Authored-By: Claude Opus 4.8 (1M context)
+'@
+ if($LASTEXITCODE -ne 0){ Write-Warn 'Nothing to commit (no changes staged). Skipping PR.'; return }
+
+ & git -C $repoRoot push -u origin $branch
+ if($LASTEXITCODE -ne 0){ Write-Err 'git push failed.'; return }
+
+ $applied = @($Changes | Where-Object { $Reverted -notcontains $_ })
+ $bumpLines = ($applied | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)$(if($_.IsMajor){' (MAJOR)'}else{''})" }) -join "`n"
+ $majorList = ($applied | Where-Object { $_.IsMajor } | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)" }) -join "`n"
+ $revLines = ($Reverted | ForEach-Object { "- $($_.Ecosystem) $($_.Id): $($_.From) -> $($_.To)" }) -join "`n"
+ $body = @"
+Automated update of (non-AXSharp) dependencies to their latest stable versions.
+
+Build verification: $BuildResult
+
+## Bumped ($($applied.Count))
+$bumpLines
+
+## [!] Major-version bumps
+$(if($majorList){ $majorList } else { '_none_' })
+
+## Reverted by build bisection
+$(if($revLines){ $revLines } else { '_none_' })
+
+See the attached report ($([System.IO.Path]::GetFileName($ReportPath))) for frozen/skipped detail.
+
+🤖 Generated with [Claude Code](https://claude.com/claude-code)
+"@
+ & gh pr create --base dev --head $branch --title 'chore(deps): update dependencies to latest stable' --body $body
+ if($LASTEXITCODE -ne 0){ Write-Err 'gh pr create failed.' } else { Write-Info 'PR opened against dev.' }
+}
+
+# ---------------------------------------------------------------------------
+# Main
+# ---------------------------------------------------------------------------
+$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss')
+Write-Info "update-latest-deps (apply=$Apply, dryRun=$DryRun, nuget=$doNuget, npm=$doNpm, tools=$doTools, skipMajor=$SkipMajor)"
+if($DryRun){ Write-Warn 'DRY RUN - no files will be changed. Pass -Apply to write.' }
+
+$feedCtx = $null
+if($doNuget -or $doTools){
+ try { $feedCtx = Get-FeedContext -Feed $Source -User $null -Tok $feedToken } catch { Write-Err "Could not initialise NuGet feed: $($_.Exception.Message)"; exit 2 }
+}
+
+if($doNuget){ Invoke-NuGetScan -FeedCtx $feedCtx }
+if($doTools){ Invoke-ToolsScan -FeedCtx $feedCtx }
+if($doNuget -or $doTools){ Resolve-GitVersionSync -FeedCtx $feedCtx }
+if($doNpm){ Invoke-NpmScan }
+
+Write-Host ''
+Write-Host '================ PLAN ================' -ForegroundColor Cyan
+Write-Host (" Changes : {0}" -f $Changes.Count)
+Write-Host (" Major : {0}" -f @($Changes | Where-Object { $_.IsMajor }).Count)
+Write-Host (" Frozen : {0}" -f $Frozen.Count)
+Write-Host (" Errors : {0}" -f $ScanErrors.Count)
+Write-Host '=====================================' -ForegroundColor Cyan
+
+if($DryRun){
+ Write-Warn '[DRY RUN] No changes written. Review the report below.'
+ $reportPath = Write-Report -Stamp $stamp
+ if($ScanErrors.Count -gt 0){ Write-Warn "$($ScanErrors.Count) scan error(s) - see report." }
+ exit 0
+}
+
+if($Changes.Count -eq 0){
+ Write-Info 'Nothing to update; everything already at latest stable.'
+ Write-Report -Stamp $stamp | Out-Null
+ exit 0
+}
+
+# Apply everything, then verify.
+$dirs = Write-FileSet -ActiveChanges @($Changes)
+Update-NpmLockfiles -NpmDirs $dirs
+Write-Info "Applied $($Changes.Count) change(s) to the working tree."
+
+if(-not $SkipBuild){
+ if(Invoke-CakeBuild){
+ $BuildResult = 'pass'
+ Write-Info 'Build passed with all changes.'
+ } elseif($RollbackAllOnFailure){
+ Write-Warn 'Build failed; -RollbackAllOnFailure set, reverting everything.'
+ foreach($c in $Changes){ [void]$Reverted.Add($c) }
+ Write-FileSet -ActiveChanges @() | Out-Null
+ $BuildResult = 'FAIL (all changes rolled back)'
+ } else {
+ Invoke-BisectGreenSubset
+ }
+} else {
+ $BuildResult = 'skipped (-SkipBuild)'
+ Write-Warn 'Build verification skipped (-SkipBuild).'
+}
+
+$reportPath = Write-Report -Stamp $stamp
+
+Write-Host ''
+Write-Host '================ SUMMARY ================' -ForegroundColor Cyan
+Write-Host (" Applied : {0}" -f @($Changes | Where-Object { $Reverted -notcontains $_ }).Count)
+Write-Host (" Reverted : {0}" -f $Reverted.Count)
+Write-Host (" Frozen : {0}" -f $Frozen.Count)
+Write-Host (" Build : {0}" -f $BuildResult)
+Write-Host (" Errors : {0}" -f $ScanErrors.Count)
+Write-Host '========================================' -ForegroundColor Cyan
+
+if($CreatePR){
+ if(@($Changes | Where-Object { $Reverted -notcontains $_ }).Count -gt 0){ Invoke-CreatePR -ReportPath $reportPath }
+ else { Write-Warn 'No surviving changes; skipping PR creation.' }
+}
+
+if($BuildResult -like 'FAIL*'){ exit 1 }
+exit 0
From caf3e4ba7941649e9f4238dd11bfd244b24044d0 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 18:02:37 +0200
Subject: [PATCH 08/13] Remove unused package.json and apax.yml files to clean
up the project structure.
---
src/components.abb.robotics/package-lock.json | 1174 -----------------
src/components.abb.robotics/package.json | 6 -
src/components.abstractions/package-lock.json | 1174 -----------------
src/components.abstractions/package.json | 6 -
src/data/package-lock.json | 1174 -----------------
src/data/package.json | 6 -
src/inspectors/package-lock.json | 1174 -----------------
src/inspectors/package.json | 6 -
src/traversals/apax/apax.yml | 51 -
9 files changed, 4771 deletions(-)
delete mode 100644 src/components.abb.robotics/package-lock.json
delete mode 100644 src/components.abb.robotics/package.json
delete mode 100644 src/components.abstractions/package-lock.json
delete mode 100644 src/components.abstractions/package.json
delete mode 100644 src/data/package-lock.json
delete mode 100644 src/data/package.json
delete mode 100644 src/inspectors/package-lock.json
delete mode 100644 src/inspectors/package.json
delete mode 100644 src/traversals/apax/apax.yml
diff --git a/src/components.abb.robotics/package-lock.json b/src/components.abb.robotics/package-lock.json
deleted file mode 100644
index 13ea2dbbc..000000000
--- a/src/components.abb.robotics/package-lock.json
+++ /dev/null
@@ -1,1174 +0,0 @@
-{
- "name": "components.abb.robotics",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
- "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^1.0.3",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.5",
- "node-addon-api": "^7.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.1",
- "@parcel/watcher-darwin-arm64": "2.5.1",
- "@parcel/watcher-darwin-x64": "2.5.1",
- "@parcel/watcher-freebsd-x64": "2.5.1",
- "@parcel/watcher-linux-arm-glibc": "2.5.1",
- "@parcel/watcher-linux-arm-musl": "2.5.1",
- "@parcel/watcher-linux-arm64-glibc": "2.5.1",
- "@parcel/watcher-linux-arm64-musl": "2.5.1",
- "@parcel/watcher-linux-x64-glibc": "2.5.1",
- "@parcel/watcher-linux-x64-musl": "2.5.1",
- "@parcel/watcher-win32-arm64": "2.5.1",
- "@parcel/watcher-win32-ia32": "2.5.1",
- "@parcel/watcher-win32-x64": "2.5.1"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
- "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
- "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
- "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
- "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
- "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
- "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
- "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
- "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
- "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
- "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
- "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
- "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
- "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@tailwindcss/cli": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz",
- "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==",
- "license": "MIT",
- "dependencies": {
- "@parcel/watcher": "^2.5.1",
- "@tailwindcss/node": "4.1.11",
- "@tailwindcss/oxide": "4.1.11",
- "enhanced-resolve": "^5.18.1",
- "mri": "^1.2.0",
- "picocolors": "^1.1.1",
- "tailwindcss": "4.1.11"
- },
- "bin": {
- "tailwindcss": "dist/index.mjs"
- }
- },
- "node_modules/@tailwindcss/node": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
- "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "enhanced-resolve": "^5.18.1",
- "jiti": "^2.4.2",
- "lightningcss": "1.30.1",
- "magic-string": "^0.30.17",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
- "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.4",
- "tar": "^7.4.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-x64": "4.1.11",
- "@tailwindcss/oxide-freebsd-x64": "4.1.11",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.11",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.11",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
- "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
- "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
- "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
- "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
- "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
- "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
- "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
- "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
- "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
- "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@emnapi/wasi-threads": "^1.0.2",
- "@napi-rs/wasm-runtime": "^0.2.11",
- "@tybys/wasm-util": "^0.9.0",
- "tslib": "^2.8.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.0.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.11",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@tybys/wasm-util": "^0.9.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.0",
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
- "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
- "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/detect-libc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "license": "Apache-2.0",
- "bin": {
- "detect-libc": "bin/detect-libc.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.18.2",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
- "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/jiti": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
- "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
- "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.30.1",
- "lightningcss-darwin-x64": "1.30.1",
- "lightningcss-freebsd-x64": "1.30.1",
- "lightningcss-linux-arm-gnueabihf": "1.30.1",
- "lightningcss-linux-arm64-gnu": "1.30.1",
- "lightningcss-linux-arm64-musl": "1.30.1",
- "lightningcss-linux-x64-gnu": "1.30.1",
- "lightningcss-linux-x64-musl": "1.30.1",
- "lightningcss-win32-arm64-msvc": "1.30.1",
- "lightningcss-win32-x64-msvc": "1.30.1"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
- "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
- "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
- "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
- "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
- "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
- "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
- "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
- "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
- "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
- "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/minizlib": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
- "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tailwindcss": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
- "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==",
- "license": "MIT"
- },
- "node_modules/tapable": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
- "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "7.5.13",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz",
- "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.1.0",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- }
- }
-}
diff --git a/src/components.abb.robotics/package.json b/src/components.abb.robotics/package.json
deleted file mode 100644
index 59aeb296f..000000000
--- a/src/components.abb.robotics/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
-}
diff --git a/src/components.abstractions/package-lock.json b/src/components.abstractions/package-lock.json
deleted file mode 100644
index c180f8e4c..000000000
--- a/src/components.abstractions/package-lock.json
+++ /dev/null
@@ -1,1174 +0,0 @@
-{
- "name": "components.abstractions",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
- "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^1.0.3",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.5",
- "node-addon-api": "^7.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.1",
- "@parcel/watcher-darwin-arm64": "2.5.1",
- "@parcel/watcher-darwin-x64": "2.5.1",
- "@parcel/watcher-freebsd-x64": "2.5.1",
- "@parcel/watcher-linux-arm-glibc": "2.5.1",
- "@parcel/watcher-linux-arm-musl": "2.5.1",
- "@parcel/watcher-linux-arm64-glibc": "2.5.1",
- "@parcel/watcher-linux-arm64-musl": "2.5.1",
- "@parcel/watcher-linux-x64-glibc": "2.5.1",
- "@parcel/watcher-linux-x64-musl": "2.5.1",
- "@parcel/watcher-win32-arm64": "2.5.1",
- "@parcel/watcher-win32-ia32": "2.5.1",
- "@parcel/watcher-win32-x64": "2.5.1"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
- "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
- "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
- "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
- "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
- "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
- "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
- "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
- "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
- "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
- "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
- "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
- "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
- "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@tailwindcss/cli": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz",
- "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==",
- "license": "MIT",
- "dependencies": {
- "@parcel/watcher": "^2.5.1",
- "@tailwindcss/node": "4.1.11",
- "@tailwindcss/oxide": "4.1.11",
- "enhanced-resolve": "^5.18.1",
- "mri": "^1.2.0",
- "picocolors": "^1.1.1",
- "tailwindcss": "4.1.11"
- },
- "bin": {
- "tailwindcss": "dist/index.mjs"
- }
- },
- "node_modules/@tailwindcss/node": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
- "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "enhanced-resolve": "^5.18.1",
- "jiti": "^2.4.2",
- "lightningcss": "1.30.1",
- "magic-string": "^0.30.17",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
- "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.4",
- "tar": "^7.4.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-x64": "4.1.11",
- "@tailwindcss/oxide-freebsd-x64": "4.1.11",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.11",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.11",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
- "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
- "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
- "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
- "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
- "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
- "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
- "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
- "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
- "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
- "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@emnapi/wasi-threads": "^1.0.2",
- "@napi-rs/wasm-runtime": "^0.2.11",
- "@tybys/wasm-util": "^0.9.0",
- "tslib": "^2.8.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.0.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.11",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@tybys/wasm-util": "^0.9.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.0",
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
- "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
- "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/detect-libc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "license": "Apache-2.0",
- "bin": {
- "detect-libc": "bin/detect-libc.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.18.2",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
- "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/jiti": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
- "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
- "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.30.1",
- "lightningcss-darwin-x64": "1.30.1",
- "lightningcss-freebsd-x64": "1.30.1",
- "lightningcss-linux-arm-gnueabihf": "1.30.1",
- "lightningcss-linux-arm64-gnu": "1.30.1",
- "lightningcss-linux-arm64-musl": "1.30.1",
- "lightningcss-linux-x64-gnu": "1.30.1",
- "lightningcss-linux-x64-musl": "1.30.1",
- "lightningcss-win32-arm64-msvc": "1.30.1",
- "lightningcss-win32-x64-msvc": "1.30.1"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
- "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
- "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
- "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
- "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
- "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
- "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
- "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
- "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
- "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
- "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/minizlib": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
- "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tailwindcss": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
- "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==",
- "license": "MIT"
- },
- "node_modules/tapable": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
- "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "7.5.13",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz",
- "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.1.0",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- }
- }
-}
diff --git a/src/components.abstractions/package.json b/src/components.abstractions/package.json
deleted file mode 100644
index 59aeb296f..000000000
--- a/src/components.abstractions/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
-}
diff --git a/src/data/package-lock.json b/src/data/package-lock.json
deleted file mode 100644
index a4f78bc8b..000000000
--- a/src/data/package-lock.json
+++ /dev/null
@@ -1,1174 +0,0 @@
-{
- "name": "data",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
- "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^1.0.3",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.5",
- "node-addon-api": "^7.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.1",
- "@parcel/watcher-darwin-arm64": "2.5.1",
- "@parcel/watcher-darwin-x64": "2.5.1",
- "@parcel/watcher-freebsd-x64": "2.5.1",
- "@parcel/watcher-linux-arm-glibc": "2.5.1",
- "@parcel/watcher-linux-arm-musl": "2.5.1",
- "@parcel/watcher-linux-arm64-glibc": "2.5.1",
- "@parcel/watcher-linux-arm64-musl": "2.5.1",
- "@parcel/watcher-linux-x64-glibc": "2.5.1",
- "@parcel/watcher-linux-x64-musl": "2.5.1",
- "@parcel/watcher-win32-arm64": "2.5.1",
- "@parcel/watcher-win32-ia32": "2.5.1",
- "@parcel/watcher-win32-x64": "2.5.1"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
- "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
- "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
- "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
- "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
- "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
- "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
- "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
- "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
- "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
- "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
- "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
- "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
- "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@tailwindcss/cli": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz",
- "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==",
- "license": "MIT",
- "dependencies": {
- "@parcel/watcher": "^2.5.1",
- "@tailwindcss/node": "4.1.11",
- "@tailwindcss/oxide": "4.1.11",
- "enhanced-resolve": "^5.18.1",
- "mri": "^1.2.0",
- "picocolors": "^1.1.1",
- "tailwindcss": "4.1.11"
- },
- "bin": {
- "tailwindcss": "dist/index.mjs"
- }
- },
- "node_modules/@tailwindcss/node": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
- "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "enhanced-resolve": "^5.18.1",
- "jiti": "^2.4.2",
- "lightningcss": "1.30.1",
- "magic-string": "^0.30.17",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
- "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.4",
- "tar": "^7.4.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-x64": "4.1.11",
- "@tailwindcss/oxide-freebsd-x64": "4.1.11",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.11",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.11",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
- "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
- "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
- "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
- "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
- "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
- "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
- "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
- "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
- "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
- "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@emnapi/wasi-threads": "^1.0.2",
- "@napi-rs/wasm-runtime": "^0.2.11",
- "@tybys/wasm-util": "^0.9.0",
- "tslib": "^2.8.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.0.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.11",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@tybys/wasm-util": "^0.9.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.0",
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
- "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
- "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/detect-libc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "license": "Apache-2.0",
- "bin": {
- "detect-libc": "bin/detect-libc.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.18.2",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
- "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/jiti": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
- "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
- "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.30.1",
- "lightningcss-darwin-x64": "1.30.1",
- "lightningcss-freebsd-x64": "1.30.1",
- "lightningcss-linux-arm-gnueabihf": "1.30.1",
- "lightningcss-linux-arm64-gnu": "1.30.1",
- "lightningcss-linux-arm64-musl": "1.30.1",
- "lightningcss-linux-x64-gnu": "1.30.1",
- "lightningcss-linux-x64-musl": "1.30.1",
- "lightningcss-win32-arm64-msvc": "1.30.1",
- "lightningcss-win32-x64-msvc": "1.30.1"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
- "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
- "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
- "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
- "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
- "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
- "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
- "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
- "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
- "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
- "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/minizlib": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
- "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tailwindcss": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
- "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==",
- "license": "MIT"
- },
- "node_modules/tapable": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
- "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "7.5.13",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz",
- "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.1.0",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- }
- }
-}
diff --git a/src/data/package.json b/src/data/package.json
deleted file mode 100644
index 59aeb296f..000000000
--- a/src/data/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
-}
diff --git a/src/inspectors/package-lock.json b/src/inspectors/package-lock.json
deleted file mode 100644
index 75f8225f6..000000000
--- a/src/inspectors/package-lock.json
+++ /dev/null
@@ -1,1174 +0,0 @@
-{
- "name": "inspectors",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@isaacs/fs-minipass": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
- "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
- "license": "ISC",
- "dependencies": {
- "minipass": "^7.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.12",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz",
- "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
- "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.29",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
- "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz",
- "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^1.0.3",
- "is-glob": "^4.0.3",
- "micromatch": "^4.0.5",
- "node-addon-api": "^7.0.0"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.1",
- "@parcel/watcher-darwin-arm64": "2.5.1",
- "@parcel/watcher-darwin-x64": "2.5.1",
- "@parcel/watcher-freebsd-x64": "2.5.1",
- "@parcel/watcher-linux-arm-glibc": "2.5.1",
- "@parcel/watcher-linux-arm-musl": "2.5.1",
- "@parcel/watcher-linux-arm64-glibc": "2.5.1",
- "@parcel/watcher-linux-arm64-musl": "2.5.1",
- "@parcel/watcher-linux-x64-glibc": "2.5.1",
- "@parcel/watcher-linux-x64-musl": "2.5.1",
- "@parcel/watcher-win32-arm64": "2.5.1",
- "@parcel/watcher-win32-ia32": "2.5.1",
- "@parcel/watcher-win32-x64": "2.5.1"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
- "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
- "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
- "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
- "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
- "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
- "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
- "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
- "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
- "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
- "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
- "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
- "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
- "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@tailwindcss/cli": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.11.tgz",
- "integrity": "sha512-7RAFOrVaXCFz5ooEG36Kbh+sMJiI2j4+Ozp71smgjnLfBRu7DTfoq8DsTvzse2/6nDeo2M3vS/FGaxfDgr3rtQ==",
- "license": "MIT",
- "dependencies": {
- "@parcel/watcher": "^2.5.1",
- "@tailwindcss/node": "4.1.11",
- "@tailwindcss/oxide": "4.1.11",
- "enhanced-resolve": "^5.18.1",
- "mri": "^1.2.0",
- "picocolors": "^1.1.1",
- "tailwindcss": "4.1.11"
- },
- "bin": {
- "tailwindcss": "dist/index.mjs"
- }
- },
- "node_modules/@tailwindcss/node": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz",
- "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==",
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "enhanced-resolve": "^5.18.1",
- "jiti": "^2.4.2",
- "lightningcss": "1.30.1",
- "magic-string": "^0.30.17",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz",
- "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "detect-libc": "^2.0.4",
- "tar": "^7.4.3"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-arm64": "4.1.11",
- "@tailwindcss/oxide-darwin-x64": "4.1.11",
- "@tailwindcss/oxide-freebsd-x64": "4.1.11",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-arm64-musl": "4.1.11",
- "@tailwindcss/oxide-linux-x64-gnu": "4.1.11",
- "@tailwindcss/oxide-linux-x64-musl": "4.1.11",
- "@tailwindcss/oxide-wasm32-wasi": "4.1.11",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11",
- "@tailwindcss/oxide-win32-x64-msvc": "4.1.11"
- }
- },
- "node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz",
- "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz",
- "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz",
- "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz",
- "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz",
- "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz",
- "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz",
- "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz",
- "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz",
- "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz",
- "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@emnapi/wasi-threads": "^1.0.2",
- "@napi-rs/wasm-runtime": "^0.2.11",
- "@tybys/wasm-util": "^0.9.0",
- "tslib": "^2.8.0"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.0.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.4.3",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.0.2",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "0.2.11",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.4.3",
- "@emnapi/runtime": "^1.4.3",
- "@tybys/wasm-util": "^0.9.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.9.0",
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.0",
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
- "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
- "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz",
- "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@tailwindcss/oxide/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chownr": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
- "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/detect-libc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "license": "Apache-2.0",
- "bin": {
- "detect-libc": "bin/detect-libc.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.18.2",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz",
- "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==",
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/jiti": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
- "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz",
- "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-darwin-arm64": "1.30.1",
- "lightningcss-darwin-x64": "1.30.1",
- "lightningcss-freebsd-x64": "1.30.1",
- "lightningcss-linux-arm-gnueabihf": "1.30.1",
- "lightningcss-linux-arm64-gnu": "1.30.1",
- "lightningcss-linux-arm64-musl": "1.30.1",
- "lightningcss-linux-x64-gnu": "1.30.1",
- "lightningcss-linux-x64-musl": "1.30.1",
- "lightningcss-win32-arm64-msvc": "1.30.1",
- "lightningcss-win32-x64-msvc": "1.30.1"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz",
- "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz",
- "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz",
- "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz",
- "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz",
- "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz",
- "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz",
- "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz",
- "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz",
- "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz",
- "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss/node_modules/detect-libc": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
- "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.17",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
- "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/minizlib": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz",
- "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==",
- "license": "MIT",
- "dependencies": {
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/node-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/tailwindcss": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz",
- "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==",
- "license": "MIT"
- },
- "node_modules/tapable": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz",
- "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar": {
- "version": "7.5.13",
- "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.13.tgz",
- "integrity": "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/fs-minipass": "^4.0.0",
- "chownr": "^3.0.0",
- "minipass": "^7.1.2",
- "minizlib": "^3.1.0",
- "yallist": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/yallist": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
- "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=18"
- }
- }
- }
-}
diff --git a/src/inspectors/package.json b/src/inspectors/package.json
deleted file mode 100644
index 59aeb296f..000000000
--- a/src/inspectors/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "dependencies": {
- "@tailwindcss/cli": "^4.1.11",
- "tailwindcss": "^4.1.11"
- }
-}
diff --git a/src/traversals/apax/apax.yml b/src/traversals/apax/apax.yml
deleted file mode 100644
index 53140784a..000000000
--- a/src/traversals/apax/apax.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: "apax.traversal"
-version: "0.0.0-dev.0"
-type: "app"
-targets:
-- "1500"
-registries:
- '@inxton': "https://npm.pkg.github.com/"
-devDependencies:
- '@inxton/ax-sdk': "0.0.0-dev.0"
-dependencies:
- "@inxton/axopen.abstractions": "0.0.0-dev.0"
- "@inxton/ax.axopen.app": "0.0.0-dev.0"
- "@inxton/ax.axopen.hwlibrary": "0.0.0-dev.0"
- "@inxton/ax.axopen.min": "0.0.0-dev.0"
- "@inxton/ax.catalog": "0.0.51"
- "@inxton/axopen.components.abb.robotics": "0.0.0-dev.0"
- "@inxton/axopen.components.abstractions": "0.0.0-dev.0"
- "@inxton/axopen.components.balluff.identification": "0.0.0-dev.0"
- "@inxton/axopen.components.cognex.vision": "0.0.0-dev.0"
- "@inxton/axopen.components.desoutter.tightening": "0.0.0-dev.0"
- "@inxton/axopen.components.drives": "0.0.0-dev.0"
- "@inxton/axopen.components.dukane.welders": "0.0.0-dev.0"
- "@inxton/axopen.components.elements": "0.0.0-dev.0"
- "@inxton/axopen.components.festo.drives": "0.0.0-dev.0"
- "@inxton/axopen.components.keyence.vision": "0.0.0-dev.0"
- "@inxton/axopen.components.kuka.robotics": "0.0.0-dev.0"
- "@inxton/axopen.components.mitsubishi.robotics": "0.0.0-dev.0"
- "@inxton/axopen.components.pneumatics": "0.0.0-dev.0"
- "@inxton/axopen.components.rexroth.drives": "0.0.0-dev.0"
- "@inxton/axopen.components.rexroth.press": "0.0.0-dev.0"
- "@inxton/axopen.components.rexroth.tightening": "0.0.0-dev.0"
- "@inxton/axopen.components.robotics": "0.0.0-dev.0"
- "@inxton/axopen.components.siem.communication": "0.0.0-dev.0"
- "@inxton/axopen.components.siem.identification": "0.0.0-dev.0"
- "@inxton/axopen.components.ur.robotics": "0.0.0-dev.0"
- "@inxton/axopen.components.zebra.vision": "0.0.0-dev.0"
- "@inxton/axopen.core": "0.0.0-dev.0"
- "@inxton/axopen.data": "0.0.0-dev.0"
- "axopen_data_distributed_tests_l4": "0.0.0-dev.0"
- "axopen.data.tests_l1": "0.0.0-dev.0"
- "axopen.integration.tests_l4": "0.0.0-dev.0"
- "@inxton/axopen.inspectors": "0.0.0-dev.0"
- "@inxton/axopen.io": "0.0.0-dev.0"
- "@inxton/axopen.probers": "0.0.0-dev.0"
- "showcase": "0.0.0-dev.0"
- "@inxton/axopen.simatic1500": "0.0.0-dev.0"
- "@inxton/apaxlibname": "0.0.0-dev.0"
- "@inxton/axopen.timers": "0.0.0-dev.0"
- "@inxton/axopen.utils": "0.0.0-dev.0"
-installStrategy: "overridable"
-...
From 59fc0c12636cec48ecad85e2df809d1066130c0f Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Fri, 29 May 2026 18:15:38 +0200
Subject: [PATCH 09/13] docs(changelog): add deps-update entry; bump
next-version 0.56.3 -> 0.56.4
Co-Authored-By: Claude Opus 4.8 (1M context)
---
CHANGELOG.md | 24 ++++++++++++++++++++++++
GitVersion.yml | 2 +-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b8654c355..ea863b69f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,27 @@
+### [BUILD] Dependency-maintenance tooling + AXSharp `0.47.0-alpha.484` bump
+
+**Note:** Build/CI tooling and dependency maintenance. No public-API change, no PLC source change. Branch: `deps-update`.
+
+- feat: `scripts/update-latest-deps.ps1` — bumps all non-AXSharp dependencies (NuGet + npm) to their latest stable versions, sharing common helpers via `scripts/_deps-common.ps1`.
+- feat: `scripts/update-vulnerable-deps.ps1` — scans npm and NuGet dependencies for known vulnerabilities and emits a report.
+- chore: AXSharp packages bumped to `0.47.0-alpha.484` in `Directory.Packages.props`, with transitive dependencies reconciled. `.config/dotnet-tools.json` updated to match.
+- chore: Added `.claude/skills/update-axsharp-version/SKILL.md` — skill for updating AXSharp and Inxton.Operon package versions.
+- chore: Removed obsolete `package.json` / `package-lock.json` files across `src/components.abb.robotics`, `src/components.abstractions`, `src/data`, `src/data/src/AXOpen.Data.Blazor`, `src/inspectors`, and a stray `apax.yml`, to clean up the project structure.
+- chore: `develop` branch GitVersion mode changed to `ContinuousDeployment`.
+- chore: Styling dependencies refreshed (`src/styling/src/package.json` / lock; `momentum.css` regenerated).
+
+**Impact:**
+- Routine dependency bumps and vulnerability scanning are now scriptable and reproducible.
+- AXSharp consumers build against `0.47.0-alpha.484`.
+- Dead npm lockfiles no longer pollute the tree or trigger spurious tooling.
+
+**Risks/Review:**
+- Dependency version bumps can introduce behavioural drift; verify a full `dotnet build` and the styling render after pulling.
+
+**Testing:**
+- Run `scripts/update-latest-deps.ps1` and `scripts/update-vulnerable-deps.ps1` end-to-end (exit code 0).
+- `dotnet build` from solution root succeeds against the bumped package set.
+
### [CORE] AxoSequencer step-timeout alarm — does not fall after timeout clears
**Note:** PLC bug fix in `src/core/ctrl/src/AxoCoordination/AxoSequencer/AxoSequencer.st` (`AxoStepTimedOutMessenger.Activate`). No public-API change. Branch: `fix-issue-when-timeout-sequencer-alarm-doesnot-fall`.
diff --git a/GitVersion.yml b/GitVersion.yml
index c4aeb37fd..458569c2d 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -1,5 +1,5 @@
mode: ContinuousDeployment
-next-version: 0.56.3
+next-version: 0.56.4
branches:
main:
regex: ^master$|^main$
From 1c93135ccfa84513d057d09fadd282392c8f506f Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Sat, 30 May 2026 08:10:48 +0200
Subject: [PATCH 10/13] feat(deps): update NuGet.Packaging to 6.14.3 and add
NuGet.Protocol dependency; enhance npm project discovery in update scripts
---
Directory.Packages.props | 3 +-
scripts/update-latest-deps.ps1 | 30 +++--
scripts/update-vulnerable-deps-npm-app.ps1 | 140 ---------------------
scripts/update-vulnerable-deps.ps1 | 17 ++-
4 files changed, 30 insertions(+), 160 deletions(-)
delete mode 100644 scripts/update-vulnerable-deps-npm-app.ps1
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 6ccee4040..73c8c8c39 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -24,7 +24,7 @@
-
+
@@ -90,6 +90,7 @@
+
diff --git a/scripts/update-latest-deps.ps1 b/scripts/update-latest-deps.ps1
index 8ba494dde..191802890 100644
--- a/scripts/update-latest-deps.ps1
+++ b/scripts/update-latest-deps.ps1
@@ -60,6 +60,10 @@ Cap on the number of full cake builds spent bisecting after an initial failure.
.PARAMETER CreatePR
Commit changes to branch 'chore/update-latest-deps' off origin/dev and open a PR against dev. Implies -Apply.
+.PARAMETER NpmProjects
+Explicit list of package.json paths to process (relative to repo root or absolute). When omitted,
+projects are discovered automatically under src/ (skipping bin/obj/ctrl/.apax/node_modules/wwwroot/dist).
+
.PARAMETER Source
NuGet v3 feed used to look up available versions. Default nuget.org.
@@ -94,6 +98,7 @@ param(
[switch]$RollbackAllOnFailure,
[int]$MaxBisectBuilds = 6,
[switch]$CreatePR,
+ [string[]]$NpmProjects,
[string]$Source = 'https://api.nuget.org/v3/index.json',
[string]$Token,
[switch]$Detailed
@@ -131,7 +136,7 @@ $feedToken = if($Token){ $Token } elseif(-not $IsPublicNuGet){ Resolve-FeedToken
# Owned by update_axsharp_versions.ps1 - never touched.
$AxSharpSkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b'
# Owned by update-vulnerable-deps.ps1 ("Security pins" ItemGroup) - never touched.
-$SecurityPinIds = @('Snappier','System.Security.Cryptography.Xml')
+$SecurityPinIds = @('') #@('Snappier','System.Security.Cryptography.Xml')
# Frozen to stay aligned with net10.0 (see plan / interview).
$FrameworkFreezeExact = @('Microsoft.NET.ILLink.Tasks','Microsoft.VisualStudio.Web.CodeGeneration.Design')
$FrameworkFreezePrefixes = @('Microsoft.AspNetCore.','Microsoft.EntityFrameworkCore.','Microsoft.Extensions.','System.')
@@ -139,15 +144,20 @@ $FrameworkFreezePrefixes = @('Microsoft.AspNetCore.','Microsoft.EntityFrameworkC
$GitVersionNuGetId = 'GitVersion.MsBuild'
$GitVersionToolId = 'gitversion.tool'
-# Source npm projects (explicit list - avoids bin/obj/ctrl/.apax generated copies).
-$NpmProjects = @(
- 'src/components.abb.robotics/package.json'
- 'src/components.abstractions/package.json'
- 'src/data/package.json'
- 'src/inspectors/package.json'
- 'src/showcase/app/ix-blazor/showcase.blazor/package.json'
- 'src/styling/src/package.json'
-) | ForEach-Object { Join-Path $repoRoot $_ }
+# Source npm projects - discovered dynamically under src/, skipping generated/dependency
+# copies (bin/obj/ctrl/.apax/node_modules/wwwroot). Override with -NpmProjects to be explicit.
+function Get-NpmProjects {
+ $srcRoot = Join-Path $repoRoot 'src'
+ if(-not (Test-Path -LiteralPath $srcRoot)){ return @() }
+ $excludeRx = '[\\/](bin|obj|ctrl|\.apax|node_modules|wwwroot|dist|\.git)[\\/]'
+ Get-ChildItem -LiteralPath $srcRoot -Recurse -File -Filter 'package.json' -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notmatch $excludeRx } |
+ Select-Object -ExpandProperty FullName |
+ Sort-Object
+}
+
+$NpmProjects = if($NpmProjects){ $NpmProjects | ForEach-Object { if([System.IO.Path]::IsPathRooted($_)){ $_ } else { Join-Path $repoRoot $_ } } }
+ else { Get-NpmProjects }
# Accumulators for the report.
$Changes = New-Object System.Collections.ArrayList # applied/previewed bumps
diff --git a/scripts/update-vulnerable-deps-npm-app.ps1 b/scripts/update-vulnerable-deps-npm-app.ps1
deleted file mode 100644
index b2ee3c31f..000000000
--- a/scripts/update-vulnerable-deps-npm-app.ps1
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env pwsh
-<#
-.SYNOPSIS
-Updates vulnerable npm dependencies in all directories matching the pattern **/app/ix-blazor/
-
-.DESCRIPTION
-This script finds all directories matching the pattern **/app/ix-blazor/ and runs npm audit fix
-to automatically fix identified vulnerabilities.
-
-.PARAMETER DryRun
-If specified, only shows what would be done without making actual changes.
-
-.PARAMETER Force
-If specified, bypasses confirmation prompts.
-
-.EXAMPLE
-./update-vulnerable-deps.ps1
-./update-vulnerable-deps.ps1 -DryRun
-./update-vulnerable-deps.ps1 -Force
-#>
-
-param(
- [switch]$DryRun,
- [switch]$Force
-)
-
-$ErrorActionPreference = "Stop"
-
-# Get the script's directory
-$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
-
-# Find all directories matching **/app/ix-blazor/
-Write-Host "Searching for directories matching pattern '**/app/ix-blazor/'..." -ForegroundColor Cyan
-
-$targetDirs = @()
-$appDirs = Get-ChildItem -Path $scriptRoot -Recurse -Filter "app" -Directory -ErrorAction SilentlyContinue
-
-foreach ($appDir in $appDirs) {
- $ixBlazerPath = Join-Path -Path $appDir.FullName -ChildPath "ix-blazor"
-
- if (Test-Path -Path $ixBlazerPath -PathType Container) {
- $packageJsonPath = Join-Path -Path $ixBlazerPath -ChildPath "package.json"
-
- if (Test-Path -Path $packageJsonPath -PathType Leaf) {
- $targetDirs += @{
- Path = $ixBlazerPath
- PackageJson = $packageJsonPath
- }
- }
- }
-}
-
-if ($targetDirs.Count -eq 0) {
- Write-Host "No directories matching '**/app/ix-blazor/' with package.json found." -ForegroundColor Yellow
- exit 0
-}
-
-Write-Host "Found $($targetDirs.Count) directory/directories to process:" -ForegroundColor Green
-foreach ($dir in $targetDirs) {
- Write-Host " - $($dir.Path)" -ForegroundColor Gray
-}
-
-if (-not $Force) {
- Write-Host ""
- $confirmation = Read-Host "Continue with npm audit fix? (Y/n)"
- if ($confirmation -and $confirmation.ToLower() -ne 'y') {
- Write-Host "Operation cancelled." -ForegroundColor Yellow
- exit 0
- }
-}
-
-# Process each directory
-$successCount = 0
-$failureCount = 0
-
-foreach ($dir in $targetDirs) {
- $dirPath = $dir.Path
- Write-Host ""
- Write-Host "Processing: $dirPath" -ForegroundColor Cyan
-
- try {
- Push-Location -Path $dirPath
-
- # Check if node_modules exists, install if not
- if (-not (Test-Path -Path "node_modules" -PathType Container)) {
- Write-Host " Installing dependencies..." -ForegroundColor Gray
- if ($DryRun) {
- Write-Host " [DRY RUN] Would run: npm install" -ForegroundColor Yellow
- }
- else {
- npm install
- if ($LASTEXITCODE -ne 0) {
- Write-Host " Failed to install dependencies" -ForegroundColor Red
- $failureCount++
- Pop-Location
- continue
- }
- }
- }
-
- # Run npm audit to show vulnerabilities
- Write-Host " Running npm audit..." -ForegroundColor Gray
- if ($DryRun) {
- Write-Host " [DRY RUN] Would run: npm audit fix" -ForegroundColor Yellow
- npm audit
- }
- else {
- npm audit fix
- if ($LASTEXITCODE -ne 0) {
- Write-Host " Warning: npm audit fix completed with exit code $($LASTEXITCODE)" -ForegroundColor Yellow
- }
- else {
- Write-Host " Successfully updated vulnerable dependencies" -ForegroundColor Green
- $successCount++
- }
- }
-
- Pop-Location
- }
- catch {
- Write-Host " Error processing directory: $_" -ForegroundColor Red
- $failureCount++
- Pop-Location
- }
-}
-
-# Summary
-Write-Host ""
-Write-Host "================================" -ForegroundColor Cyan
-Write-Host "Summary:" -ForegroundColor Cyan
-Write-Host " Processed: $($targetDirs.Count)" -ForegroundColor Gray
-Write-Host " Successful: $successCount" -ForegroundColor Green
-Write-Host " Failed: $failureCount" -ForegroundColor $(if ($failureCount -gt 0) { "Red" } else { "Green" })
-Write-Host "================================" -ForegroundColor Cyan
-
-if ($DryRun) {
- Write-Host "[DRY RUN] No changes were made." -ForegroundColor Yellow
-}
-
-exit $(if ($failureCount -gt 0) { 1 } else { 0 })
diff --git a/scripts/update-vulnerable-deps.ps1 b/scripts/update-vulnerable-deps.ps1
index c2d68c6a3..477b28330 100644
--- a/scripts/update-vulnerable-deps.ps1
+++ b/scripts/update-vulnerable-deps.ps1
@@ -65,7 +65,7 @@ param(
[switch]$NuGetOnly,
[switch]$CreatePR,
[ValidateSet('low','moderate','high','critical')]
- [string]$MinSeverity = 'moderate',
+ [string]$MinSeverity = 'low',
[string]$Source = 'https://api.nuget.org/v3/index.json',
[string]$Token,
[switch]$Detailed
@@ -97,15 +97,14 @@ $SkipPattern = '^(AXSharp|Inxton\.Operon|AXOpen)\b'
$Token = Resolve-FeedToken -Token $Token -Detailed:$Detailed
-# Source npm projects (explicit list - avoids bin/obj/ctrl generated copies).
+# Source npm projects - discovered dynamically under src/ (skips node_modules and
+# bin/obj/ctrl generated copies so only first-party source manifests are audited).
$NpmProjects = @(
- 'src/components.abb.robotics/package.json'
- 'src/components.abstractions/package.json'
- 'src/data/package.json'
- 'src/inspectors/package.json'
- 'src/showcase/app/ix-blazor/showcase.blazor/package.json'
- 'src/styling/src/package.json'
-) | ForEach-Object { Join-Path $repoRoot $_ }
+ Get-ChildItem -Path (Join-Path $repoRoot 'src') -Recurse -File -Filter 'package.json' -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notmatch '[\\/](node_modules|bin|obj|ctrl)[\\/]' } |
+ ForEach-Object { $_.FullName } |
+ Sort-Object
+)
# Accumulators for the report.
$NuGetFixed = New-Object System.Collections.ArrayList
From 7dc678a32def97187805ba1df4a6c45a7dc6f514 Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Sat, 30 May 2026 10:31:59 +0200
Subject: [PATCH 11/13] chore(catalog): update @ax deps + bump ax.catalog
Automated by scripts/update-ax-catalog.ps1.
Co-Authored-By: Claude Opus 4.8 (1M context)
---
src/ax.axopen.app/ctrl/apax.yml | 6 ++--
src/ax.axopen.hwlibrary/ctrl/apax.yml | 2 +-
src/ax.axopen.min/ctrl/apax.yml | 2 +-
src/ax.catalog/apax.yml | 36 +++++++++----------
.../ctrl/apax.yml | 2 +-
src/sdk-ax/ctrl/apax.yml | 28 +++++++--------
6 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/src/ax.axopen.app/ctrl/apax.yml b/src/ax.axopen.app/ctrl/apax.yml
index c222e84a2..948050959 100644
--- a/src/ax.axopen.app/ctrl/apax.yml
+++ b/src/ax.axopen.app/ctrl/apax.yml
@@ -6,7 +6,7 @@ files:
registries:
"@inxton": "https://npm.pkg.github.com/"
catalogs:
- "@inxton/ax.catalog": '0.0.51'
+ "@inxton/ax.catalog": '0.0.52'
devDependencies:
"@inxton/ax-sdk": '0.0.0-dev.0'
dependencies:
@@ -14,8 +14,8 @@ dependencies:
"@ax/system-bitaccess": 10.4.16
"@ax/system-math": 10.4.16
"@ax/system-serde": 10.4.16
- "@ax/dcp-utility": 1.2.0
- "@ax/hardware-diagnostics": 1.1.1
+ "@ax/dcp-utility": 1.2.1
+ "@ax/hardware-diagnostics": 1.2.0
"@ax/simatic-tasks": 11.0.2
installStrategy: strict
apaxVersion: 3.5.0
diff --git a/src/ax.axopen.hwlibrary/ctrl/apax.yml b/src/ax.axopen.hwlibrary/ctrl/apax.yml
index 17d822ac4..5e3b2a176 100644
--- a/src/ax.axopen.hwlibrary/ctrl/apax.yml
+++ b/src/ax.axopen.hwlibrary/ctrl/apax.yml
@@ -6,7 +6,7 @@ files:
registries:
"@inxton": "https://npm.pkg.github.com/"
catalogs:
- "@inxton/ax.catalog": '0.0.51'
+ "@inxton/ax.catalog": '0.0.52'
devDependencies:
"@inxton/ax-sdk": '0.0.0-dev.0'
dependencies:
diff --git a/src/ax.axopen.min/ctrl/apax.yml b/src/ax.axopen.min/ctrl/apax.yml
index 7d48cec69..1fd659fd6 100644
--- a/src/ax.axopen.min/ctrl/apax.yml
+++ b/src/ax.axopen.min/ctrl/apax.yml
@@ -6,7 +6,7 @@ files:
registries:
"@inxton": "https://npm.pkg.github.com/"
catalogs:
- "@inxton/ax.catalog": '0.0.51'
+ "@inxton/ax.catalog": '0.0.52'
devDependencies:
"@inxton/ax-sdk": '0.0.0-dev.0'
dependencies:
diff --git a/src/ax.catalog/apax.yml b/src/ax.catalog/apax.yml
index 5da316ada..5d03afb50 100644
--- a/src/ax.catalog/apax.yml
+++ b/src/ax.catalog/apax.yml
@@ -1,5 +1,5 @@
name: "@inxton/ax.catalog"
-version: '0.0.51'
+version: '0.0.52'
registries:
"@inxton": "https://npm.pkg.github.com/"
type: catalog
@@ -12,21 +12,21 @@ catalogDependencies:
"@ax/axunitst": 9.4.8 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 9.4.8
"@ax/axunitst-library": 9.4.8 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 9.4.8
"@ax/build-native": 16.1.51 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 16.1.51
- "@ax/certificate-management": 2.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0
- "@ax/dcp-utility": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0
+ "@ax/certificate-management": 2.0.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0
+ "@ax/dcp-utility": 1.2.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0
"@ax/debug-st-ls-plugin": 1.0.10 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.10
- "@ax/diagnostic-buffer": 2.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.1.1
- "@ax/hardware-diagnostics": 1.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.1.1
+ "@ax/diagnostic-buffer": 2.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.1.1
+ "@ax/hardware-diagnostics": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.1.1
"@ax/hw-et200sp": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1
"@ax/hw-s7-1500": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1
"@ax/hwc": 4.4.1 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 4.4.1
- "@ax/hwld": 3.4.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.4.0
- "@ax/mod": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
- "@ax/mon": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
- "@ax/plc-control": 1.6.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.6.3
- "@ax/plc-info": 4.1.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.1.1
+ "@ax/hwld": 3.5.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.4.0
+ "@ax/mod": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
+ "@ax/mon": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
+ "@ax/plc-control": 1.7.22 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.6.3
+ "@ax/plc-info": 4.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.1.1
"@ax/plc-web-app-manager": 1.2.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.2.0
- "@ax/sdb": 1.13.21 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
+ "@ax/sdb": 1.14.13 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.13.21
"@ax/sdk": 2510.12.0 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 2510.12.0
"@ax/simatic-alarming": 5.1.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 5.1.0
"@ax/simatic-clocks": 11.0.116 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.0.116
@@ -58,12 +58,12 @@ catalogDependencies:
"@ax/simatic-pointtopoint": 4.0.54 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.54
"@ax/simatic-tasks": 11.0.2 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.0.2
"@ax/simatic-technology-objects": 4.0.43 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.43
- "@ax/sld": 3.6.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.6.3
- "@ax/st-lang-contrib-xlad": 1.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.0
- "@ax/st-ls": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
+ "@ax/sld": 3.8.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.6.3
+ "@ax/st-lang-contrib-xlad": 1.1.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 1.0.0
+ "@ax/st-ls": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
"@ax/st-opcua.stc-plugin": 2.0.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 2.0.0
"@ax/st-resources.stc-plugin": 4.0.3 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.0.3
- "@ax/stc": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
+ "@ax/stc": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
"@ax/system": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
"@ax/system-bistable": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
"@ax/system-bitaccess": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
@@ -78,8 +78,8 @@ catalogDependencies:
"@ax/system-serde": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
"@ax/system-strings": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
"@ax/system-timer": 10.4.16 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 10.4.16
- "@ax/target-llvm": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
- "@ax/target-mc7plus": 11.4.57 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
+ "@ax/target-llvm": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
+ "@ax/target-mc7plus": 11.5.53 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 11.4.57
"@ax/tia2st": 4.3.5 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 4.3.5
- "@ax/trace": 3.3.1 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.3.1
+ "@ax/trace": 3.4.0 # @ax/simatic-ax@2510.11.0 contained at the time of creation this catalog (16.5.2026) version 3.3.1
"@ax/xlad-service": 1.1.0 # @ax/simatic-ax@2510.12.0 contained at the time of creation this catalog (25.5.2026) version 1.1.0
diff --git a/src/components.siem.communication/ctrl/apax.yml b/src/components.siem.communication/ctrl/apax.yml
index 2d44d0a1b..391b1e229 100644
--- a/src/components.siem.communication/ctrl/apax.yml
+++ b/src/components.siem.communication/ctrl/apax.yml
@@ -9,7 +9,7 @@ files:
registries:
"@inxton": "https://npm.pkg.github.com/"
catalogs:
- "@inxton/ax.catalog": '0.0.51'
+ "@inxton/ax.catalog": '0.0.52'
devDependencies:
"@inxton/ax-sdk": '0.0.0-dev.0'
dependencies:
diff --git a/src/sdk-ax/ctrl/apax.yml b/src/sdk-ax/ctrl/apax.yml
index a4eb51863..bb2646427 100644
--- a/src/sdk-ax/ctrl/apax.yml
+++ b/src/sdk-ax/ctrl/apax.yml
@@ -6,27 +6,27 @@ files:
registries:
"@inxton": "https://npm.pkg.github.com/"
catalogs:
- "@inxton/ax.catalog": '0.0.51'
+ "@inxton/ax.catalog": '0.0.52'
dependencies:
'@ax/apax-build': 2.2.60
'@ax/axunitst': 9.4.8
- '@ax/certificate-management': 2.0.0
- '@ax/diagnostic-buffer': 2.1.1
+ '@ax/certificate-management': 2.0.1
+ '@ax/diagnostic-buffer': 2.2.0
'@ax/hw-s7-1500': 4.4.1
'@ax/hwc': 4.4.1
- '@ax/hwld': 3.4.0
- '@ax/mod': 1.13.21
- '@ax/mon': 1.13.21
- '@ax/plc-info': 4.1.1
- '@ax/sdb': 1.13.21
+ '@ax/hwld': 3.5.0
+ '@ax/mod': 1.14.13
+ '@ax/mon': 1.14.13
+ '@ax/plc-info': 4.2.0
+ '@ax/sdb': 1.14.13
'@ax/simatic-package-tool': 2.0.17
- '@ax/sld': 3.6.3
- '@ax/st-ls': 11.4.57
+ '@ax/sld': 3.8.3
+ '@ax/st-ls': 11.5.53
'@ax/st-resources.stc-plugin': 4.0.3
- '@ax/stc': 11.4.57
- '@ax/target-llvm': 11.4.57
- '@ax/target-mc7plus': 11.4.57
- '@ax/trace': 3.3.1
+ '@ax/stc': 11.5.53
+ '@ax/target-llvm': 11.5.53
+ '@ax/target-mc7plus': 11.5.53
+ '@ax/trace': 3.4.0
installStrategy: strict
apaxVersion: 3.5.0
scripts:
From a889c87a974f9d58326c2bb8bdbf51676d9914fa Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Sat, 30 May 2026 10:32:10 +0200
Subject: [PATCH 12/13] feat: add update-ax-catalog.ps1 script for managing
@ax/* dependencies
- Implemented a PowerShell script to update @ax/* dependencies in the local apax catalog.
- The script includes two phases: Phase 1 for updating and publishing the catalog, and Phase 2 for verifying the build.
- Added parameters for controlling behavior such as -AfterPublish, -Prerelease, -CatalogVersion, -NoPublish, -DryRun, and -Detailed.
- Introduced functions for dependency resolution, consumer synchronization, and report generation.
- Ensured safe handling of git operations to maintain a clean working directory during updates.
---
scripts/update-ax-catalog.ps1 | 731 ++++++++++++++++++++++++++++++++++
1 file changed, 731 insertions(+)
create mode 100644 scripts/update-ax-catalog.ps1
diff --git a/scripts/update-ax-catalog.ps1 b/scripts/update-ax-catalog.ps1
new file mode 100644
index 000000000..a920c2fd2
--- /dev/null
+++ b/scripts/update-ax-catalog.ps1
@@ -0,0 +1,731 @@
+#!/usr/bin/env pwsh
+<#
+.SYNOPSIS
+Updates the @ax/* dependencies of the local apax catalog (@inxton/ax.catalog) to the latest versions,
+bumps the catalog version, syncs every catalog consumer, and publishes the catalog (Phase 1); then
+verifies the build (Phase 2, -AfterPublish).
+
+.DESCRIPTION
+The repo pins all Simatic AX (@ax/*) package versions centrally in the apax catalog at
+src/ax.catalog/apax.yml (package @inxton/ax.catalog). The catalog CONSUMERS are the per-library
+manifests src//ctrl/apax.yml that declare a `catalogs:` block referencing @inxton/ax.catalog and
+re-pin a subset of @ax/* packages in their own `dependencies:`. Consumers are discovered dynamically.
+
+NOTE on ctrl/ and build noise: the consumer manifest lives at src//ctrl/apax.yml (git-tracked) and
+is the file apax install reads, so this script edits it directly. During `apax pack`, cake stamps the
+GitVersion SemVer into each manifest's `version` and @inxton/* deps (it leaves @ax/* and the .catalog
+reference alone - see cake BuildContext.UpdateApaxVersion/UpdateApaxDependencies). Those stamps are
+unwanted build noise, so Phase 2 commits our edits, runs the build, then restores every build-touched
+tracked file back to that commit and un-commits - leaving ONLY our @ax/catalog edits staged.
+
+Editing files needs no published catalog - only the cake VERIFY build (which runs apax install) does.
+So all editing + publishing happens in Phase 1, and verification is the separate Phase 2 (because a
+published catalog version cannot be cleanly un-published, the build verification is deliberately AFTER
+the publish - run it and inspect before relying on the new catalog):
+
+ PHASE 1 (default) - refresh catalog + sync consumers + publish:
+ 1. Capture the current @ax/* versions.
+ 2. Resolve each @ax/* dep's highest non-deprecated version from the AX registry via
+ `apax list -p ` (stable; -Prerelease widens to prereleases) and rewrite the catalog's
+ catalogDependencies. (`apax update` is NOT used - it ignores a catalog's catalogDependencies.)
+ 3. If (and only if) at least one @ax/* dep changed: auto-bump the catalog `version` (patch, or
+ -CatalogVersion), and sync every discovered consumer (src//ctrl/apax.yml) - their explicit
+ @ax/* pins to the new catalog versions and their `catalogs: "@inxton/ax.catalog"` reference.
+ 4. Write a report under scripts/reports/.
+ 5. Publish the catalog by invoking scripts/_pack_and_publish_catalog.ps1 (unless -NoPublish, or a
+ -DryRun, or nothing changed). Then STOP - run -AfterPublish to verify.
+
+ PHASE 2 (-AfterPublish) - verify:
+ 1. Re-assert consumer sync as an idempotent guard (normally a no-op).
+ 2. Pre-build commit ONLY our edited manifests (catalog + consumers).
+ 3. Verify with cake TESTS at level 2: `dotnet run --project cake/Build.csproj --do-test
+ --test-level 2 -n` (cake runs apax install --catalog --strict + build per consumer, then the L2
+ .NET test suite). Not pack - so cake does not stamp SemVer into the manifests.
+ 4. Discard build-produced changes WITHOUT touching your other uncommitted work: restore build-changed
+ tracked files (excluding files that were already dirty before this run) back to the commit, then
+ `git reset --soft HEAD~1` so our edits remain STAGED. No `git clean` (protects untracked files).
+
+Phase 1 publishes automatically when there are changes; pass -NoPublish to keep the old manual gate.
+
+.PARAMETER AfterPublish
+Run Phase 2 (cake verify, with an idempotent consumer-sync guard). Use after Phase 1 has published.
+
+.PARAMETER Prerelease
+Include prerelease versions when resolving "latest" (otherwise the highest non-deprecated stable version
+is used). Default: stable only.
+
+.PARAMETER CatalogVersion
+Explicit new catalog version (overrides the automatic patch bump). Phase 1 only.
+
+.PARAMETER NoPublish
+Phase 1 only: update + sync but do NOT auto-publish; print the manual publish/verify steps instead.
+
+.PARAMETER DryRun
+Preview everything; write no files, make no git changes, publish nothing, run no cake build.
+
+.PARAMETER Detailed
+Verbose logging.
+
+.EXAMPLE
+./update-ax-catalog.ps1 -DryRun -Detailed # Phase 1 preview: @ax old->new, version, consumer edits
+
+.EXAMPLE
+./update-ax-catalog.ps1 # Phase 1: refresh + bump + sync + auto-publish
+
+.EXAMPLE
+./update-ax-catalog.ps1 -NoPublish # Phase 1: refresh + bump + sync, but DON'T publish
+
+.EXAMPLE
+./update-ax-catalog.ps1 -AfterPublish # Phase 2: cake-verify, discard build noise
+#>
+
+[CmdletBinding()]
+param(
+ [switch]$AfterPublish,
+ [switch]$Prerelease,
+ [string]$CatalogVersion,
+ [switch]$NoPublish,
+ [switch]$DryRun,
+ [switch]$Detailed
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = 'Stop'
+
+$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
+. "$scriptRoot/_deps-common.ps1"
+
+$repoRoot = Split-Path -Parent $scriptRoot
+$catalogDir = Join-Path $repoRoot 'src/ax.catalog'
+$catalogYml = Join-Path $catalogDir 'apax.yml'
+$cakeProj = Join-Path $repoRoot 'cake/Build.csproj'
+$catalogPkg = '@inxton/ax.catalog'
+$publishScript = Join-Path $scriptRoot '_pack_and_publish_catalog.ps1'
+
+# Catalog consumers are DISCOVERED dynamically (see Get-CatalogConsumers): any apax.yml whose
+# `catalogs:` block references @inxton/ax.catalog. This is the same marker cake's ApaxCatalogInstall
+# keys on, so new libraries that adopt the catalog are picked up automatically.
+
+# ---------------------------------------------------------------------------
+# Small helpers
+# ---------------------------------------------------------------------------
+function Test-CommandAvailable { param([string]$Name) $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) }
+
+# Repo-root-relative, forward-slash path (matches `git status --porcelain` output).
+function ConvertTo-RepoRelative {
+ param([string]$Path)
+ $full = [System.IO.Path]::GetFullPath($Path)
+ $root = [System.IO.Path]::GetFullPath($repoRoot)
+ if($full.StartsWith($root, [StringComparison]::OrdinalIgnoreCase)){
+ $full = $full.Substring($root.Length).TrimStart('\','/')
+ }
+ return ($full -replace '\\','/')
+}
+
+# Dependency-line regexes. Tolerant of single/double quoting, any indentation, and an optional
+# trailing comment (the catalog pins carry `# ...` provenance notes). Group layout for the dep
+# regexes: 1=indent+openquote 2=key 3=closequote+colon+space 4=value-openquote 5=version
+# 6=value-closequote 7=trailing (whitespace + optional #comment), preserved on rewrite.
+$AxDepRx = '^(\s+[''"]?)(@ax/[^''":\s]+)([''"]?\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$'
+$CatalogRefRx = '^(\s+[''"]?)(@inxton/ax\.catalog)([''"]?\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$'
+$VersionRx = '^(version\s*:\s*)([''"]?)([^''"\s#]+)([''"]?)(\s*(?:#.*)?)$'
+
+# Parse a top-level section of `key: value` deps and return @ax/* entries as an ordered map.
+function Get-AxDepsInSection {
+ param([string[]]$Lines, [string]$Section)
+ $map = [ordered]@{}
+ $cur = $null
+ foreach($ln in $Lines){
+ if($ln -match '^[A-Za-z]'){ # zero-indent => a top-level key
+ if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] }
+ continue
+ }
+ if($cur -ne $Section){ continue }
+ if($ln -match $AxDepRx){ $map[$Matches[2]] = $Matches[5] }
+ }
+ return $map
+}
+
+# True when these apax.yml lines declare a `catalogs:` block that references the catalog package.
+function Test-IsCatalogConsumer {
+ param([string[]]$Lines)
+ $cur = $null
+ foreach($ln in $Lines){
+ if($ln -match '^[A-Za-z]'){
+ if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] }
+ continue
+ }
+ if($cur -eq 'catalogs' -and $ln -match $CatalogRefRx){ return $true }
+ }
+ return $false
+}
+
+# Discover every catalog consumer under src/: an apax.yml whose `catalogs:` block references
+# @inxton/ax.catalog. In this repo the per-library manifest lives at src//ctrl/apax.yml (tracked
+# in git) - that IS the file we edit and that apax install reads. We exclude only the dependency-copy
+# / build-output dirs (.apax cache, bin, obj, node_modules), NOT ctrl. Sorted, absolute.
+function Get-CatalogConsumers {
+ $srcRoot = Join-Path $repoRoot 'src'
+ if(-not (Test-Path -LiteralPath $srcRoot)){ return @() }
+ $excludeRx = '[\\/](bin|obj|\.apax|node_modules|wwwroot|dist|\.git|\.vs)[\\/]'
+ $catalogFull = [System.IO.Path]::GetFullPath($catalogYml)
+ Get-ChildItem -LiteralPath $srcRoot -Recurse -File -Filter 'apax.yml' -ErrorAction SilentlyContinue |
+ Where-Object { $_.FullName -notmatch $excludeRx } |
+ Where-Object { [System.IO.Path]::GetFullPath($_.FullName) -ne $catalogFull } |
+ Where-Object { Test-IsCatalogConsumer -Lines (Get-Content -LiteralPath $_.FullName) } |
+ Select-Object -ExpandProperty FullName |
+ Sort-Object
+}
+
+# Read the top-level `version:` value from catalog content.
+function Get-CatalogVersion {
+ param([string[]]$Lines)
+ foreach($ln in $Lines){ if($ln -match $VersionRx){ return $Matches[3] } }
+ return $null
+}
+
+# Patch-bump a semver string (x.y.z -> x.y.(z+1)).
+function Get-NextPatchVersion {
+ param([string]$Version)
+ $rec = ConvertTo-VersionRecord $Version
+ return ('{0}.{1}.{2}' -f $rec.Major, $rec.Minor, ($rec.Patch + 1))
+}
+
+# Strip ANSI/VT escape sequences from apax's coloured output so it can be parsed.
+function Remove-Ansi { param([string]$Text) return ([regex]::Replace($Text, "\x1B\[[0-9;]*[A-Za-z]", '')) }
+
+# Query the AX registry for one package via `apax list -p ` and return its latest dist-tag plus the
+# full version list (each flagged deprecated/prerelease). apax has no JSON mode and writes to stderr, so
+# we merge streams, strip ANSI, and parse the "Versions" / "Tags(latest:)" sections. $LASTEXITCODE is
+# unreliable here (apax emits info banners on stderr), so success is judged by whether we parsed a tag
+# or any versions. Returns $null when the package can't be read.
+function Get-AxPackageInfo {
+ param([string]$Package, [int]$Retries = 2)
+ # apax list can occasionally return an empty/partial response (registry warmup). Retry a couple of
+ # times until we get output that contains a Versions/Tags section before giving up.
+ $prevEap = $ErrorActionPreference
+ $ErrorActionPreference = 'Continue'
+ $clean = ''
+ try {
+ for($attempt = 0; $attempt -le $Retries; $attempt++){
+ $raw = ''
+ try { $raw = (& apax list -p $Package 2>&1 | Out-String) } catch { $raw = '' }
+ $clean = Remove-Ansi $raw
+ if($clean -match '(?m)^\s*(Versions|Tags)\s*$'){ break }
+ }
+ } finally { $ErrorActionPreference = $prevEap }
+ $latest = $null
+ $versions = New-Object System.Collections.ArrayList
+ $inVersions = $false; $inTags = $false
+ foreach($ln in ($clean -split "`r?`n")){
+ $t = $ln.Trim()
+ if($t -eq 'Versions'){ $inVersions = $true; $inTags = $false; continue }
+ if($t -eq 'Tags'){ $inTags = $true; $inVersions = $false; continue }
+ # A non-list, non-section header line ends the current section.
+ if($t -match '^[A-Za-z]' -and $t -notmatch '^-\s'){ $inVersions = $false; $inTags = $false }
+ if($inVersions -and $t -match '^-\s*([0-9][^\s]*)'){
+ $v = $Matches[1]
+ [void]$versions.Add([PSCustomObject]@{ Version=$v; Deprecated=($t -match 'deprecated'); Prerelease=(Test-IsPrerelease $v) })
+ }
+ if($inTags -and $t -match 'latest:\s*([^\s]+)'){ $latest = $Matches[1] }
+ }
+ if(-not $latest -and $versions.Count -eq 0){ return $null }
+ return [PSCustomObject]@{ Package=$Package; Latest=$latest; Versions=@($versions) }
+}
+
+# Pick the version to move a package to: the HIGHEST non-deprecated published version. We deliberately
+# do NOT use the registry 'latest' dist-tag, because on the AX registry it can point below the highest
+# published version (e.g. @ax/ax2tia latest=11.1.25 while 12.2.8 is published) - taking it would
+# downgrade a pin. Stable mode excludes prereleases; -Prerelease includes them. Returns $null if none.
+function Select-TargetVersion {
+ param($Info)
+ if(-not $Info){ return $null }
+ # Wrap the whole if-expression in @() - assigning a one-element array via `if` would unwrap it to a
+ # scalar, breaking the .Count check under StrictMode.
+ $cand = @(if($Prerelease){ $Info.Versions | Where-Object { -not $_.Deprecated } }
+ else { $Info.Versions | Where-Object { -not $_.Deprecated -and -not $_.Prerelease } })
+ if($cand.Count -eq 0){ return $null }
+ $best = $cand[0].Version
+ foreach($c in $cand){ if(Test-VersionGreater $c.Version $best){ $best = $c.Version } }
+ return $best
+}
+
+# True when moving From -> To crosses a major-version boundary (used to flag, not block).
+function Test-IsMajorBump {
+ param([string]$From,[string]$To)
+ if([string]::IsNullOrWhiteSpace($From) -or [string]::IsNullOrWhiteSpace($To)){ return $false }
+ return ((ConvertTo-VersionRecord $To).Major -gt (ConvertTo-VersionRecord $From).Major)
+}
+
+# Resolve the latest target version for every @ax/* key in $OldMap by querying the registry. Returns an
+# ordered map (same key order as $OldMap). NEVER downgrades: if the resolved highest version is not
+# strictly greater than the current pin, the current pin is kept (covers a lagging 'latest', a yanked
+# higher version, or an already-current pin). Unresolvable keys keep their current version with a
+# warning. Pure read - touches no file.
+function Resolve-LatestAxVersions {
+ param($OldMap)
+ $newMap = [ordered]@{}
+ $i = 0; $total = $OldMap.Count
+ $updated = 0; $kept = 0; $failed = 0
+ foreach($pkg in $OldMap.Keys){
+ $i++
+ $cur = $OldMap[$pkg]
+ # Live progress: a progress bar plus a single rewriting status line, so 77 sequential registry
+ # queries don't look frozen. (Write-Progress is suppressed in non-interactive hosts; the inline
+ # counter still shows. -Detailed additionally logs the per-package outcome below.)
+ $pct = [int](($i-1) * 100 / [Math]::Max($total,1))
+ Write-Progress -Activity 'Resolving @ax/* latest versions' -Status ("[{0}/{1}] {2}" -f $i,$total,$pkg) -PercentComplete $pct
+ Write-Host ("`r [{0,2}/{1}] querying {2,-45}" -f $i,$total,$pkg) -NoNewline -ForegroundColor DarkGray
+
+ $info = Get-AxPackageInfo -Package $pkg
+ $target = Select-TargetVersion -Info $info
+ if(-not $target){
+ $failed++; $newMap[$pkg] = $cur
+ Write-Host "`r" -NoNewline
+ Write-Warn (" [{0}/{1}] {2}: could not resolve latest - keeping {3}" -f $i,$total,$pkg,$cur)
+ continue
+ }
+ if(Test-VersionGreater $target $cur){
+ $updated++; $newMap[$pkg] = $target
+ if($Detailed){ Write-Host "`r" -NoNewline; Write-Info (" [{0}/{1}] {2}: {3} -> {4}" -f $i,$total,$pkg,$cur,$target) }
+ } else {
+ # Resolved version is <= current pin: keep current (no downgrade). Note when the registry's
+ # highest is actually lower than what we have pinned.
+ $kept++; $newMap[$pkg] = $cur
+ if($Detailed){
+ Write-Host "`r" -NoNewline
+ if(Test-VersionGreater $cur $target){ Write-Info (" [{0}/{1}] {2}: {3} (registry highest {4} is lower - kept)" -f $i,$total,$pkg,$cur,$target) }
+ else { Write-Info (" [{0}/{1}] {2}: {3} (already latest)" -f $i,$total,$pkg,$cur) }
+ }
+ }
+ }
+ Write-Host ("`r{0,-72}" -f '') -NoNewline; Write-Host "`r" -NoNewline # clear the status line
+ Write-Progress -Activity 'Resolving @ax/* latest versions' -Completed
+ Write-Info ("Resolved {0} package(s): {1} to update, {2} already current, {3} unresolved." -f $total,$updated,$kept,$failed)
+ return $newMap
+}
+
+# Rewrite the catalogDependencies section of the catalog file in place from $NewMap, preserving line
+# formatting and trailing comments. Only @ax/* lines whose version changed are touched.
+function Update-CatalogDepsFile {
+ param([string]$Path, $NewMap)
+ $lines = Get-Content -LiteralPath $Path
+ $cur = $null
+ $out = foreach($ln in $lines){
+ if($ln -match '^[A-Za-z]'){
+ if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] }
+ $ln; continue
+ }
+ if($cur -eq 'catalogDependencies' -and $ln -match $AxDepRx){
+ $pkg = $Matches[2]; $oldv = $Matches[5]
+ if($NewMap.Contains($pkg) -and $NewMap[$pkg] -ne $oldv){
+ "$($Matches[1])$pkg$($Matches[3])$($Matches[4])$($NewMap[$pkg])$($Matches[6])$($Matches[7])".TrimEnd(); continue
+ }
+ $ln; continue
+ }
+ $ln
+ }
+ Write-Utf8NoBom-LF -Path $Path -Content (($out -join "`n") + "`n")
+}
+
+# Pack + publish the catalog to the @inxton registry by invoking the existing pack/publish script.
+# Returns $true on success. Requires APAX_KEY (and GH_USER/GH_TOKEN if the registry login isn't cached).
+function Invoke-CatalogPublish {
+ if(-not (Test-Path -LiteralPath $publishScript)){ Write-Err "Publish script not found: $publishScript"; return $false }
+ if(-not $env:APAX_KEY){ Write-Err 'APAX_KEY is not set - cannot pack/publish the catalog. Set APAX_KEY (and GH_USER/GH_TOKEN) and re-run, or pass -NoPublish.'; return $false }
+ Write-Info "Publishing catalog: $publishScript"
+ $prevEap = $ErrorActionPreference
+ $ErrorActionPreference = 'Continue'
+ try { & $publishScript } finally { $ErrorActionPreference = $prevEap }
+ if($LASTEXITCODE -and $LASTEXITCODE -ne 0){ Write-Err "Publish script exited with code $LASTEXITCODE."; return $false }
+ return $true
+}
+
+# ---------------------------------------------------------------------------
+# Report
+# ---------------------------------------------------------------------------
+function Write-Report {
+ param([string]$Stamp, [string]$Phase, $Payload, [string]$MarkdownBody)
+ $reportsDir = Join-Path $scriptRoot 'reports'
+ if(-not (Test-Path $reportsDir)){ New-Item -ItemType Directory -Path $reportsDir -Force | Out-Null }
+ $base = "ax-catalog-$Phase-$Stamp"
+ $mdPath = Join-Path $reportsDir "$base.md"
+ $jsonPath = Join-Path $reportsDir "$base.json"
+ Write-Utf8NoBom-LF -Path $jsonPath -Content ($Payload | ConvertTo-Json -Depth 8)
+ Write-Utf8NoBom-LF -Path $mdPath -Content $MarkdownBody
+ Write-Info "Report: $mdPath"
+ return $mdPath
+}
+
+function Format-DiffTable {
+ # Builds a markdown table of @ax old->new from two ordered maps.
+ param($OldMap, $NewMap)
+ $sb = New-Object System.Text.StringBuilder
+ [void]$sb.AppendLine('| Package | From | To |')
+ [void]$sb.AppendLine('|---|---|---|')
+ $keys = @($OldMap.Keys) + @($NewMap.Keys) | Select-Object -Unique | Sort-Object
+ foreach($k in $keys){
+ $from = if($OldMap.Contains($k)){ $OldMap[$k] } else { '(new)' }
+ $to = if($NewMap.Contains($k)){ $NewMap[$k] } else { '(removed)' }
+ if($from -ne $to){ [void]$sb.AppendLine("| $k | $from | $to |") }
+ }
+ return $sb.ToString()
+}
+
+# ===========================================================================
+# PHASE 1 - refresh catalog
+# ===========================================================================
+function Invoke-Phase1 {
+ param([string]$Stamp)
+ Write-Info '== PHASE 1: refresh @inxton/ax.catalog =='
+ if(-not (Test-CommandAvailable 'apax')){ Write-Err 'apax CLI not found on PATH.'; exit 2 }
+ if(-not (Test-Path -LiteralPath $catalogYml)){ Write-Err "Catalog not found: $catalogYml"; exit 2 }
+
+ $origLines = Get-Content -LiteralPath $catalogYml
+ $oldMap = Get-AxDepsInSection -Lines $origLines -Section 'catalogDependencies'
+ $oldVersion = Get-CatalogVersion -Lines $origLines
+ if(-not $oldVersion){ Write-Err 'Could not read catalog version field.'; exit 2 }
+ Write-Info "Catalog at $oldVersion ($($oldMap.Count) @ax/* deps). Resolving latest versions..."
+
+ # Resolve the latest version of every @ax/* dep by querying the AX registry directly with
+ # `apax list -p `. NOTE: `apax update` only touches dependencies/devDependencies "from the
+ # apax.yml" - it does NOT update a catalog's catalogDependencies (verified: it reports "No updates
+ # available" on this catalog), which is why we resolve each pin ourselves. This is a pure read; the
+ # file is rewritten below only when something actually changed.
+ $newMap = Resolve-LatestAxVersions -OldMap $oldMap
+
+ # Diff summary (version-changed @ax/* deps; the set of keys is fixed by the catalog). Major bumps are
+ # flagged for review but still applied.
+ $changed = @()
+ foreach($k in $newMap.Keys){
+ if($oldMap[$k] -ne $newMap[$k]){ $changed += [PSCustomObject]@{ Package=$k; From=$oldMap[$k]; To=$newMap[$k]; IsMajor=(Test-IsMajorBump $oldMap[$k] $newMap[$k]) } }
+ }
+ $majors = @($changed | Where-Object { $_.IsMajor })
+
+ # Bump the catalog version ONLY when something changed - no dependency change means no new version
+ # to publish. On a real run we rewrite the catalogDependencies and the version in place; dry run
+ # reports what WOULD change and writes nothing.
+ $hasChanges = ($changed.Count -gt 0)
+ $newVersion = if($hasChanges){ if($CatalogVersion){ $CatalogVersion } else { Get-NextPatchVersion $oldVersion } } else { $oldVersion }
+ if($hasChanges -and -not $DryRun){
+ Update-CatalogDepsFile -Path $catalogYml -NewMap $newMap
+ $afterLines = Get-Content -LiteralPath $catalogYml
+ $bumped = $afterLines | ForEach-Object {
+ if($_ -match $VersionRx){ "$($Matches[1])$($Matches[2])$newVersion$($Matches[4])$($Matches[5])".TrimEnd() } else { $_ }
+ }
+ Write-Utf8NoBom-LF -Path $catalogYml -Content (($bumped -join "`n") + "`n")
+ Write-Info "Updated $($changed.Count) @ax/* dep(s); bumped catalog version $oldVersion -> $newVersion."
+ } elseif(-not $hasChanges){
+ Write-Info 'No @ax/* dependency changes - catalog left unchanged (version NOT bumped).'
+ }
+
+ Write-Host ''
+ Write-Host '================ CATALOG PLAN ================' -ForegroundColor Cyan
+ Write-Host (" @ax deps changed : {0} / {1}" -f $changed.Count, $newMap.Count)
+ Write-Host (" Major bumps : {0}" -f $majors.Count)
+ if($hasChanges){ Write-Host (" Catalog version : {0} -> {1}" -f $oldVersion, $newVersion) }
+ else { Write-Host (" Catalog version : {0} (unchanged - no dep updates)" -f $oldVersion) }
+ Write-Host '=============================================' -ForegroundColor Cyan
+ foreach($c in $changed){ Write-Info (" {0}: {1} -> {2}{3}" -f $c.Package, $c.From, $c.To, $(if($c.IsMajor){' [MAJOR]'}else{''})) }
+ if($majors.Count -gt 0){ Write-Warn "$($majors.Count) MAJOR-version bump(s) included - review before publishing." }
+
+ # Sync consumers in the SAME phase - editing files needs no published catalog (only the cake verify
+ # build in Phase 2 does), so the catalog + all consumer edits land as one reviewable diff before
+ # publish. We pass the freshly-resolved map/version so dry-run preview is accurate even though the
+ # catalog file isn't written yet. Skipped entirely when nothing changed.
+ $sync = $null
+ if($hasChanges){
+ Write-Host ''
+ $sync = Invoke-ConsumerSync -CatMap $newMap -CatVersion $newVersion
+ }
+
+ # Report.
+ $md = New-Object System.Text.StringBuilder
+ [void]$md.AppendLine('# @ax catalog update - Phase 1 (refresh + sync)')
+ [void]$md.AppendLine('')
+ [void]$md.AppendLine("- Generated: $Stamp")
+ [void]$md.AppendLine("- Dry run: $([bool]$DryRun)")
+ [void]$md.AppendLine("- Prerelease: $([bool]$Prerelease)")
+ [void]$md.AppendLine("- Catalog version: $oldVersion -> $newVersion")
+ [void]$md.AppendLine("- @ax deps changed: $($changed.Count) of $($newMap.Count)")
+ [void]$md.AppendLine("- Major-version bumps: $($majors.Count)")
+ [void]$md.AppendLine("- Consumer edits: $(if($sync){$sync.TotalEdits}else{0})")
+ [void]$md.AppendLine('')
+ if($majors.Count -gt 0){
+ [void]$md.AppendLine("## [!] Major-version bumps ($($majors.Count)) - review carefully")
+ [void]$md.AppendLine('| Package | From | To |')
+ [void]$md.AppendLine('|---|---|---|')
+ foreach($c in $majors){ [void]$md.AppendLine("| $($c.Package) | $($c.From) | $($c.To) |") }
+ [void]$md.AppendLine('')
+ }
+ [void]$md.AppendLine('## Changed @ax dependencies')
+ [void]$md.Append((Format-DiffTable -OldMap $oldMap -NewMap $newMap))
+ if($sync -and $sync.TotalEdits -gt 0){
+ [void]$md.AppendLine('')
+ [void]$md.AppendLine('## Consumer edits')
+ Add-ConsumerDiffMarkdown -Sb $md -Results $sync.Results
+ }
+ $payload = [PSCustomObject]@{
+ phase='1-refresh-sync'; timestamp=$Stamp; dryRun=[bool]$DryRun; prerelease=[bool]$Prerelease
+ catalogVersionFrom=$oldVersion; catalogVersionTo=$newVersion; changed=$changed
+ consumerEdits=$(if($sync){$sync.TotalEdits}else{0})
+ consumers=@(if($sync){ $sync.Results | ForEach-Object { [PSCustomObject]@{ file=(ConvertTo-RepoRelative $_.File); edits=$_.Edits } } })
+ }
+ Write-Report -Stamp $Stamp -Phase 'phase1' -Payload $payload -MarkdownBody $md.ToString() | Out-Null
+
+ Write-Host ''
+ if(-not $hasChanges){
+ Write-Info 'All @ax/* dependencies already at their latest. Nothing to publish; no Phase 2 needed.'
+ return
+ }
+ if($DryRun){
+ Write-Warn "[DRY RUN] $($changed.Count) @ax/* dep(s) would change; catalog would bump $oldVersion -> $newVersion; $($sync.TotalEdits) consumer edit(s)."
+ Write-Warn "[DRY RUN] Would then publish the catalog$(if($NoPublish){' (SKIPPED: -NoPublish)'}else{''}) and stop for build verification. Re-run without -DryRun to apply."
+ return
+ }
+
+ # Real run with changes: publish the catalog automatically (per user request), unless -NoPublish.
+ if($NoPublish){
+ Write-Info 'Catalog + consumers updated. Publish skipped (-NoPublish). NEXT STEPS:'
+ Write-Info " 1. Review the diff: git diff -- src/ax.catalog/apax.yml 'src/**/ctrl/apax.yml'"
+ Write-Info " 2. Publish the catalog: pwsh scripts/_pack_and_publish_catalog.ps1 (needs APAX_KEY, GH_USER, GH_TOKEN)"
+ Write-Info " 3. Verify the build: pwsh scripts/update-ax-catalog.ps1 -AfterPublish"
+ return
+ }
+
+ Write-Host ''
+ if(Invoke-CatalogPublish){
+ Write-Info "Catalog @inxton/ax.catalog $newVersion published."
+ Write-Info 'NEXT STEP - verify the build: pwsh scripts/update-ax-catalog.ps1 -AfterPublish'
+ } else {
+ Write-Err 'Automatic publish FAILED. The catalog + consumer edits are on disk but NOT published.'
+ Write-Err "Fix the cause (e.g. set APAX_KEY/GH_USER/GH_TOKEN), then run: pwsh scripts/_pack_and_publish_catalog.ps1"
+ Write-Err 'After a successful publish, run: pwsh scripts/update-ax-catalog.ps1 -AfterPublish'
+ exit 4
+ }
+}
+
+# ===========================================================================
+# PHASE 2 - sync consumers + verify
+# ===========================================================================
+
+# Rewrite one consumer file in place (or preview): sync @ax/* pins + catalog ref to $CatVersion/$CatMap.
+# Returns a PSCustomObject with the file's applied edits.
+function Update-ConsumerFile {
+ param([string]$Path, $CatMap, [string]$CatVersion)
+ $lines = Get-Content -LiteralPath $Path
+ $edits = New-Object System.Collections.ArrayList
+ $cur = $null
+ $out = for($i=0; $i -lt $lines.Count; $i++){
+ $ln = $lines[$i]
+ if($ln -match '^[A-Za-z]'){
+ if($ln -match '^([A-Za-z][\w\.]*)\s*:'){ $cur = $Matches[1] }
+ $ln; continue
+ }
+ if($cur -eq 'dependencies' -and $ln -match $AxDepRx){
+ $pkg = $Matches[2]; $oldv = $Matches[5]
+ if($CatMap.Contains($pkg) -and $CatMap[$pkg] -ne $oldv){
+ [void]$edits.Add([PSCustomObject]@{ Package=$pkg; From=$oldv; To=$CatMap[$pkg] })
+ "$($Matches[1])$pkg$($Matches[3])$($Matches[4])$($CatMap[$pkg])$($Matches[6])$($Matches[7])".TrimEnd(); continue
+ }
+ $ln; continue
+ }
+ if($cur -eq 'catalogs' -and $ln -match $CatalogRefRx){
+ $oldv = $Matches[5]
+ if($oldv -ne $CatVersion){
+ [void]$edits.Add([PSCustomObject]@{ Package=$catalogPkg; From=$oldv; To=$CatVersion })
+ "$($Matches[1])$($Matches[2])$($Matches[3])$($Matches[4])$CatVersion$($Matches[6])$($Matches[7])".TrimEnd(); continue
+ }
+ $ln; continue
+ }
+ $ln
+ }
+ if($edits.Count -gt 0 -and -not $DryRun){
+ Write-Utf8NoBom-LF -Path $Path -Content (($out -join "`n") + "`n")
+ }
+ return [PSCustomObject]@{ File=$Path; Edits=@($edits) }
+}
+
+# Discover catalog consumers and sync each one's @ax/* pins + `catalogs:` ref to the catalog. Applies
+# edits in place (preview only when -DryRun). $CatMap/$CatVersion may be supplied explicitly (Phase 1
+# passes the freshly-resolved values so dry-run preview is accurate even though the catalog file is not
+# written yet); when omitted they are read from the catalog file (Phase 2, post-publish). Returns the
+# discovered consumers, per-file edit results, and the totals.
+function Invoke-ConsumerSync {
+ param($CatMap, [string]$CatVersion)
+ if(-not $CatMap -or -not $CatVersion){
+ $catLines = Get-Content -LiteralPath $catalogYml
+ if(-not $CatMap){ $CatMap = Get-AxDepsInSection -Lines $catLines -Section 'catalogDependencies' }
+ if(-not $CatVersion){ $CatVersion = Get-CatalogVersion -Lines $catLines }
+ }
+ if(-not $CatVersion){ Write-Err 'Could not determine catalog version for consumer sync.'; exit 2 }
+
+ $consumerYmls = @(Get-CatalogConsumers)
+ if($consumerYmls.Count -eq 0){ Write-Err 'No catalog consumers discovered (no apax.yml references @inxton/ax.catalog).'; exit 2 }
+ Write-Info "Syncing $($consumerYmls.Count) consumer(s) to catalog @ $CatVersion ($($CatMap.Count) @ax/* deps):"
+ $results = foreach($c in $consumerYmls){
+ $r = Update-ConsumerFile -Path $c -CatMap $CatMap -CatVersion $CatVersion
+ $rel = ConvertTo-RepoRelative $c
+ if($r.Edits.Count -gt 0){
+ Write-Info " $rel : $($r.Edits.Count) edit(s)"
+ foreach($e in $r.Edits){ if($Detailed){ Write-Info (" {0}: {1} -> {2}" -f $e.Package,$e.From,$e.To) } }
+ } elseif($Detailed){ Write-Info " $rel : already in sync" }
+ $r
+ }
+ $totalEdits = (@($results) | ForEach-Object { $_.Edits.Count } | Measure-Object -Sum).Sum
+ return [PSCustomObject]@{ Consumers=$consumerYmls; Results=@($results); CatVersion=$CatVersion; TotalEdits=$totalEdits }
+}
+
+# Append a per-consumer edit table section to a markdown StringBuilder.
+function Add-ConsumerDiffMarkdown {
+ param([System.Text.StringBuilder]$Sb, $Results)
+ foreach($r in @($Results)){
+ if($r.Edits.Count -eq 0){ continue }
+ [void]$Sb.AppendLine("### $(ConvertTo-RepoRelative $r.File) ($($r.Edits.Count))")
+ [void]$Sb.AppendLine('| Package | From | To |')
+ [void]$Sb.AppendLine('|---|---|---|')
+ foreach($e in $r.Edits){ [void]$Sb.AppendLine("| $($e.Package) | $($e.From) | $($e.To) |") }
+ [void]$Sb.AppendLine('')
+ }
+}
+
+function Invoke-Phase2 {
+ param([string]$Stamp)
+ Write-Info '== PHASE 2: verify (consumers synced in Phase 1) =='
+ if(-not (Test-Path -LiteralPath $catalogYml)){ Write-Err "Catalog not found: $catalogYml"; exit 2 }
+
+ # Re-assert consumer sync as an idempotent guard: Phase 1 already synced them, but the catalog may
+ # have moved (e.g. a re-publish) or a new consumer may have appeared. Reads map/version from the
+ # (now-published) catalog file. Normally a no-op.
+ $sync = Invoke-ConsumerSync
+ if($sync.TotalEdits -gt 0){ Write-Warn "$($sync.TotalEdits) consumer edit(s) applied in Phase 2 (Phase 1 sync was incomplete or stale)." }
+ else { Write-Info 'Consumers already in sync with the catalog.' }
+
+ $buildResult = if($DryRun){ 'not-run (dry run)' } else { Invoke-VerifyAndDiscardBuildNoise -Consumers $sync.Consumers }
+
+ # Report.
+ $md = New-Object System.Text.StringBuilder
+ [void]$md.AppendLine('# @ax catalog update - Phase 2 (verify)')
+ [void]$md.AppendLine('')
+ [void]$md.AppendLine("- Generated: $Stamp")
+ [void]$md.AppendLine("- Dry run: $([bool]$DryRun)")
+ [void]$md.AppendLine("- Catalog version: $($sync.CatVersion)")
+ [void]$md.AppendLine("- Consumer edits (this phase): $($sync.TotalEdits)")
+ [void]$md.AppendLine("- Build result: **$buildResult**")
+ [void]$md.AppendLine('')
+ if($sync.TotalEdits -gt 0){
+ [void]$md.AppendLine('## Consumer edits (Phase 2 guard)')
+ Add-ConsumerDiffMarkdown -Sb $md -Results $sync.Results
+ }
+ $payload = [PSCustomObject]@{
+ phase='2-verify'; timestamp=$Stamp; dryRun=[bool]$DryRun; catalogVersion=$sync.CatVersion
+ build=$buildResult; consumerEditsThisPhase=$sync.TotalEdits
+ consumers=@($sync.Results | ForEach-Object { [PSCustomObject]@{ file=(ConvertTo-RepoRelative $_.File); edits=$_.Edits } })
+ }
+ Write-Report -Stamp $Stamp -Phase 'phase2' -Payload $payload -MarkdownBody $md.ToString() | Out-Null
+
+ Write-Host ''
+ Write-Host '================ PHASE 2 SUMMARY ================' -ForegroundColor Cyan
+ Write-Host (" Consumer edits : {0}" -f $sync.TotalEdits)
+ Write-Host (" Build : {0}" -f $buildResult)
+ Write-Host '=================================================' -ForegroundColor Cyan
+
+ if($DryRun){ Write-Warn '[DRY RUN] Nothing written, no build run.'; return }
+ if($buildResult -like 'FAIL*'){ Write-Err 'Build verification FAILED - edits left staged for inspection.'; exit 1 }
+}
+
+# Pre-build commit our files, run cake, then surgically discard build-produced changes and un-commit
+# so our edits remain staged. Returns a build-result string. Never touches files that were already
+# dirty before this run, and never runs `git clean`.
+function Invoke-VerifyAndDiscardBuildNoise {
+ param([string[]]$Consumers)
+ if(-not (Test-CommandAvailable 'git')){ Write-Err 'git not found; cannot safely verify.'; return 'FAIL (git unavailable)' }
+ if(-not (Test-CommandAvailable 'dotnet')){ Write-Err 'dotnet not found; cannot build.'; return 'FAIL (dotnet unavailable)' }
+
+ # Refuse to run mid-merge / detached HEAD.
+ $headRef = (& git -C $repoRoot symbolic-ref --quiet HEAD 2>$null)
+ if($LASTEXITCODE -ne 0){ Write-Err 'Detached HEAD or no branch; aborting Phase 2 git steps.'; return 'FAIL (detached HEAD)' }
+ if(Test-Path (Join-Path $repoRoot '.git/MERGE_HEAD')){ Write-Err 'Merge in progress; aborting.'; return 'FAIL (merge in progress)' }
+
+ # Files that were already dirty BEFORE this run (excluding our own allowlist) must never be restored.
+ # Our edits are the source manifests only; ctrl/apax.yml and apax-lock.json are gitignored generated
+ # output and never appear in git status, so they need no special handling.
+ $allowlist = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::OrdinalIgnoreCase)
+ foreach($f in (@($catalogYml) + $Consumers)){ [void]$allowlist.Add((ConvertTo-RepoRelative $f)) }
+
+ $preExistingDirty = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::OrdinalIgnoreCase)
+ foreach($line in (& git -C $repoRoot status --porcelain)){
+ if($line.Length -lt 4){ continue }
+ $p = $line.Substring(3).Trim('"')
+ if($p -match ' -> '){ $p = ($p -split ' -> ')[-1].Trim('"') } # rename: keep destination
+ if(-not $allowlist.Contains($p)){ [void]$preExistingDirty.Add($p) }
+ }
+ if($Detailed -and $preExistingDirty.Count -gt 0){
+ Write-Info "Protecting $($preExistingDirty.Count) pre-existing dirty path(s) from discard:"
+ foreach($p in $preExistingDirty){ Write-Info " $p" }
+ }
+
+ # Pre-build commit of ONLY our files.
+ $addPaths = @($catalogYml) + $Consumers | ForEach-Object { ConvertTo-RepoRelative $_ }
+ & git -C $repoRoot add -- $addPaths
+ & git -C $repoRoot diff --cached --quiet
+ $committed = ($LASTEXITCODE -ne 0) # non-zero => there ARE staged changes
+ if($committed){
+ & git -C $repoRoot commit -q -m @"
+chore(catalog): update @ax deps + bump ax.catalog
+
+Automated by scripts/update-ax-catalog.ps1.
+
+Co-Authored-By: Claude Opus 4.8 (1M context)
+"@
+ if($LASTEXITCODE -ne 0){ Write-Err 'Pre-build commit failed.'; return 'FAIL (pre-build commit)' }
+ Write-Info 'Committed catalog + consumer edits (temporary; un-committed after verification).'
+ } else {
+ Write-Warn 'No catalog/consumer changes to commit; running build verification anyway.'
+ }
+
+ # Verify with cake TESTS at level 2 (NOT pack). Level-2 runs apax install --catalog --strict +
+ # build per consumer and the L2 .NET test suite, which is what we want to prove the new catalog
+ # resolves and builds. We deliberately do NOT pack (--do-pack), so cake also won't stamp GitVersion
+ # SemVer into the manifests - the only remaining noise is apax install churn, handled below.
+ Write-Info 'Verifying: dotnet run --project cake/Build.csproj --do-test --test-level 2 -n'
+ & dotnet run --project $cakeProj -- --do-test --test-level 2 -n
+ $buildOk = ($LASTEXITCODE -eq 0)
+
+ # Discard build/test-produced changes to TRACKED files (everything dirty vs HEAD that we did not
+ # already flag as pre-existing) - e.g. apax install churn during the test run. We never `git clean`
+ # (untracked files - incl. yours - are left alone).
+ $toRestore = New-Object System.Collections.ArrayList
+ foreach($p in (& git -C $repoRoot diff --name-only HEAD)){
+ $pp = $p.Trim('"')
+ if(-not $preExistingDirty.Contains($pp)){ [void]$toRestore.Add($pp) }
+ }
+ if($toRestore.Count -gt 0){
+ Write-Info "Discarding $($toRestore.Count) build-produced change(s) to tracked files."
+ & git -C $repoRoot checkout -- $toRestore
+ }
+ $newUntracked = @(& git -C $repoRoot ls-files --others --exclude-standard) | Where-Object { -not $preExistingDirty.Contains($_.Trim('"')) }
+ if($newUntracked.Count -gt 0){
+ Write-Warn "$($newUntracked.Count) new untracked file(s) left by the build (NOT removed - clean manually if unwanted):"
+ foreach($u in ($newUntracked | Select-Object -First 20)){ Write-Warn " $u" }
+ }
+
+ # Un-commit so our edits remain STAGED (build noise already discarded).
+ if($committed){
+ & git -C $repoRoot reset --soft HEAD~1
+ if($LASTEXITCODE -ne 0){ Write-Warn 'Could not soft-reset; the pre-build commit remains in history.' }
+ else { Write-Info 'Un-committed: catalog + consumer edits are now staged.' }
+ }
+
+ if($buildOk){ return 'pass (test-level 2)' } else { return 'FAIL (cake test-level 2 - edits left staged)' }
+}
+
+# ===========================================================================
+# Main
+# ===========================================================================
+$stamp = (Get-Date).ToString('yyyy-MM-dd-HHmmss')
+Write-Info "update-ax-catalog (afterPublish=$AfterPublish, dryRun=$DryRun, prerelease=$Prerelease)"
+if($DryRun){ Write-Warn 'DRY RUN - no files, no git, no build.' }
+
+if($AfterPublish){ Invoke-Phase2 -Stamp $stamp } else { Invoke-Phase1 -Stamp $stamp }
+exit 0
From 2d820d1366471285eb81d0ca67c775999d9127eb Mon Sep 17 00:00:00 2001
From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com>
Date: Sat, 30 May 2026 11:30:38 +0200
Subject: [PATCH 13/13] feat: enhance testing capabilities with level 4
integration and cleanup of unused workflows
---
.github/workflows/nightly.yml | 2 +-
.github/workflows/single_app_run.yml | 127 -----------
cake/AppsRunTaskHelpers.cs | 324 +++++++--------------------
cake/BuildParameters.cs | 8 +-
cake/DotNetCmd.cs | 128 +++++++++++
cake/Program.cs | 137 +----------
cake/Properties/launchSettings.json | 122 +---------
scripts/test_L4.ps1 | 4 +
8 files changed, 226 insertions(+), 626 deletions(-)
delete mode 100644 .github/workflows/single_app_run.yml
create mode 100644 scripts/test_L4.ps1
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index cee3d166c..6cd271afe 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -91,7 +91,7 @@ jobs:
GH_TOKEN : ${{ secrets.GH_TOKEN }}
GH_USER : ${{ secrets.GH_USER }}
run: |
- dotnet run --project cake/Build.csproj --apps-run
+ dotnet run --project cake/Build.csproj --do-test --test-level 4
"TEST_EXIT_CODE=$LASTEXITCODE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
shell: pwsh
diff --git a/.github/workflows/single_app_run.yml b/.github/workflows/single_app_run.yml
deleted file mode 100644
index dd2d2fb88..000000000
--- a/.github/workflows/single_app_run.yml
+++ /dev/null
@@ -1,127 +0,0 @@
-name: single_app_run
-permissions:
- contents: read
-on:
- workflow_dispatch:
- inputs:
- folder:
- description: "Select library folder"
- required: true
- default: "template.axolibrary"
- type: choice
- options:
- - abstractions
- - components.abb.robotics
- - components.abstractions
- - components.balluff.identification
- - components.cognex.vision
- - components.desoutter.tightening
- - components.drives
- - components.elements
- - components.festo.drives
- - components.kuka.robotics
- - components.keyence.vision
- - components.mitsubishi.robotics
- - components.pneumatics
- - components.rexroth.drives
- - components.rexroth.press
- - components.robotics
- - components.siem.identification
- - components.ur.robotics
- - core
- - data
- - inspectors
- - integrations
- - io
- - probers
- - simatic1500
- - template.axolibrary
- - timers
- - utils
-
-jobs:
- app-run-manual-with-selected-folder:
- runs-on: [self-hosted, Windows, X64, L3, AX, APP]
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- with:
- fetch-depth: '0'
-
- - name: Get Branch Name
- run: |
- if ($env:GITHUB_REF -like "refs/pull/*") {
- $BRANCH_NAME = "${{ github.event.pull_request.head.ref }}"
- } else {
- $BRANCH_NAME = $env:GITHUB_REF -replace 'refs/heads/', ''
- }
- Write-Host "Triggered on branch: $BRANCH_NAME"
- "BRANCH_NAME=$BRANCH_NAME" | Out-File -FilePath $env:GITHUB_ENV -Append
- shell: pwsh
-
- - name: Get Short Commit SHA
- run: |
- $currentSHA = git rev-parse --short HEAD
- "CURRENT_SHA=$currentSHA" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
- shell: pwsh
-
- - name: Setup
- run: |
- "TEST_EXIT_CODE=123" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
- shell: pwsh
-
- - name: Print and store library folder
- run: |
- $APP_FOLDER = "${{ inputs.folder }}"
- Write-Host "Selected folder: $APP_FOLDER"
- "APP_FOLDER=$APP_FOLDER" | Out-File -FilePath $env:GITHUB_ENV -Append
- shell: pwsh
-
- - name: "Build cake"
- run: dotnet build cake/Build.csproj
- shell: pwsh
-
- - name: "Run cake with single app"
- continue-on-error: true
- env:
- GH_TOKEN : ${{ secrets.GH_TOKEN }}
- GH_USER : ${{ secrets.GH_USER }}
- run: |
- dotnet run --project cake/Build.csproj --skip-build --apps-run --single-app-run-folder-name $env:APP_FOLDER
- "TEST_EXIT_CODE=$LASTEXITCODE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
- shell: pwsh
-
- - name: Display workflow details in Summary
- run: |
- if($env:TEST_EXIT_CODE -eq "123")
- {
- $TEST_RESULT = "SKIPPED"
- }
- elseif($env:TEST_EXIT_CODE -eq "0")
- {
- $TEST_RESULT = "PASSED"
- }
- else
- {
- $TEST_RESULT = "FAILED"
- }
- "### Runner name: $env:RUNNER_NAME ::: Branch name: $env:BRANCH_NAME ::: Library folder: $env:APP_FOLDER ::: Commit SHA: $env:CURRENT_SHA ::: Test result: $TEST_RESULT" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Append -Encoding utf8
- shell: pwsh
-
- - name: Evaluate final result
- run: |
- if($env:TEST_EXIT_CODE -eq "123")
- {
- echo "Tests skipped."
- }
- elseif($env:TEST_EXIT_CODE -eq "0")
- {
- echo "Tests passed."
- }
- else
- {
- echo "Tests failed."
- Exit 1
- }
- shell: pwsh
-
diff --git a/cake/AppsRunTaskHelpers.cs b/cake/AppsRunTaskHelpers.cs
index c1a9bd7cd..cb9a0ae81 100644
--- a/cake/AppsRunTaskHelpers.cs
+++ b/cake/AppsRunTaskHelpers.cs
@@ -1,4 +1,4 @@
-using Cake.Common.Diagnostics;
+using Cake.Common.Diagnostics;
using Cake.Common.IO;
using Cake.Core.Diagnostics;
using System;
@@ -17,276 +17,110 @@
internal static class AppsRunTaskHelpers
{
-
- public static void BuildAndLoadPlc(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult)
+ ///
+ /// Test level 4 integration step: loads the entire showcase PLC (incl. hardware configuration) onto
+ /// PLCSIM Advanced, starts the Blazor server and asserts it serves traffic over HTTPS.
+ /// Fails the build (non-zero exit) on any error and always cleans up the spawned processes.
+ ///
+ public static void RunShowcaseIntegration(BuildContext context, string appYamlFile)
{
- string plcName = context.PlcName;
- string plcIpAddress = context.PlcIpAddress;
-
- // Validate application YAML file
- if (string.IsNullOrWhiteSpace(appYamlFile))
- {
- context.Log.Error("The provided YAML of the application is empty.");
- return;
- }
-
- if (!File.Exists(appYamlFile))
- {
- context.Log.Error($"The provided application file does not exist: {appYamlFile}");
- return;
- }
-
- if (string.IsNullOrWhiteSpace(appName))
- {
- context.Log.Error("The provided application name is empty.");
- return;
- }
-
- string appFolder = Path.GetDirectoryName(appYamlFile);
- if (string.IsNullOrWhiteSpace(appFolder) || !Directory.Exists(appFolder))
- {
- context.Log.Error($"The provided path for the application does not exist: {appFolder}");
- return;
- }
-
- // Run "apax install"
- ApaxCmd.ApaxInstall(context, appFolder);
-
- // Run "apax plcsim"
- string plcSimResult = ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult);
- WriteResult(context, plcSimResult, logFilePath, appendToSameLine: true);
-
- // Run "apax hwu"
- string hwuResult = ApaxCmd.ApaxHwu(context, appFolder, ref summaryResult);
- WriteResult(context, hwuResult, logFilePath, appendToSameLine: true);
-
- // Run "apax swfd"
- string swfdResult = ApaxCmd.ApaxSwfd(context, appFolder, ref summaryResult);
- WriteResult(context, swfdResult, logFilePath, appendToSameLine: true);
- }
- public static void AppRunDetailed(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult)
- {
- string plcName = context.PlcName;
- string plcIpAddress = context.PlcIpAddress;
-
- // Validate application YAML file
- if (string.IsNullOrWhiteSpace(appYamlFile))
- {
- context.Log.Error("The provided YAML of the application is empty.");
- return;
- }
+ bool summaryResult = true;
- if (!File.Exists(appYamlFile))
+ if (string.IsNullOrWhiteSpace(appYamlFile) || !File.Exists(appYamlFile))
{
- context.Log.Error($"The provided application file does not exist: {appYamlFile}");
+ context.Log.Error($"Showcase application file does not exist: {appYamlFile}");
+ Environment.Exit(1);
return;
}
- if (string.IsNullOrWhiteSpace(appName))
- {
- context.Log.Error("The provided application name is empty.");
- return;
- }
-
- string appFolder = Path.GetDirectoryName(appYamlFile);
- if (string.IsNullOrWhiteSpace(appFolder) || !Directory.Exists(appFolder))
- {
- context.Log.Error($"The provided path for the application does not exist: {appFolder}");
- return;
- }
-
- // Run "apax install"
- string result = ApaxCmd.ApaxCommand(context, appFolder, "install", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax plcsim"
- result = ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax gsd" # copy and install all gsdml files from libraries
- result = ApaxCmd.ApaxCommand(context, appFolder, "gsd", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax hwl" # copy all templates from libraries
- result = ApaxCmd.ApaxCommand(context, appFolder, "hwl", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax hwcc" # compile hardware configuration
- result = ApaxCmd.ApaxCommand(context, appFolder, "hwcc", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax hwid" # copy the generated HwIds from global constants into the type definition, matching the format as the TIA2AX tool creates
- result = ApaxCmd.ApaxCommand(context, appFolder, "hwid", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax hwadr" # copy the generated IoAddresses
- result = ApaxCmd.ApaxCommand(context, appFolder, "hwadr", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax hwdo" # download HW only using certificate
- result = ApaxCmd.ApaxCommand(context, appFolder, "hwdo", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax build "
- result = ApaxCmd.ApaxCommand(context, appFolder, "build", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "dotnet ixc"
- result = DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- // Run "apax swfdo" # software full download only
- result = ApaxCmd.ApaxCommand(context, appFolder, "swfdo", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
+ string appFolder = Path.GetFullPath(Path.GetDirectoryName(appYamlFile));
+ string appName = context.GetApplicationName(appYamlFile);
- // Recreate solution file by running the slngen script
- string slnGenPath = Path.GetFullPath(Path.GetFullPath(Path.Combine(appFolder, "..", "./slngen.ps1")));
- result = DotNetCmd.RunPowershellScript(context, slnGenPath, "", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
+ context.Log.Information("###################################################");
+ context.Log.Information($"Test level 4 showcase integration: {appName}");
+ context.Log.Information($"Application file: {appYamlFile}");
+ context.Log.Information("###################################################");
- // Clean solution
- string solutionFile = Path.GetFullPath(Path.Combine(appFolder, "../this.sln"));
- result = DotNetCmd.DotNetClean(context, solutionFile, "-c Debug", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
+ // Make sure no stale simulator UI is running before we start.
+ KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface");
- //########################## template.axolibrary => ######################//
- if (appFolder.Contains("template.axolibrary"))
+ try
{
- string dot_g_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.g"));
- context.CleanDirectory(dot_g_folder, new CleanDirectorySettings() { Force = true });
-
- string dot_meta_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.meta"));
- context.CleanDirectory(dot_meta_folder, new CleanDirectorySettings() { Force = true });
-
- // Run "dotnet ixc"
- result = DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult);
- }
-
- //########################## <= template.axolibrary ######################//
+ // Clean state from previous runs.
+ DeleteJsonReposFolder(context, appFolder);
- //// Build solution
- //result = DotNetCmd.DotNetBuildWithResult(context, solutionFile, "-c Debug", ref summaryResult);
- //WriteResult(context, result, logFilePath, appendToSameLine: true);
+ // Prepare a fresh PLCSIM Advanced virtual memory card instance.
+ InitializePlcSimInstance(context, appName);
- //// Get blazor projects
- //var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList();
+ // Provide the certificate / security configuration used by the secure download.
+ OverwriteSecurityFiles(context, appYamlFile, context.PlcName);
- // Get blazor projects
- var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList();
+ // Full first-download of hardware + software onto the simulator.
+ LoadShowcasePlc(context, appFolder, ref summaryResult);
- if (blazorFiles.Any())
- {
- foreach (var blazorFile in blazorFiles)
+ if (!summaryResult)
{
- // Build solution
- result = DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
-
- context.Log.Information($"Application 'blazor' file: {blazorFile}");
+ context.Log.Error("Showcase PLC load failed.");
+ }
+ else
+ {
+ // Build and run the Blazor server, then probe it over HTTPS.
+ var blazorFile = Directory
+ .GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories)
+ .FirstOrDefault(file => file.Contains("blazor") && !File.ReadAllText(file).Contains(""));
- // Filter out libraries by checking for in the project file
- string csprojContent = File.ReadAllText(blazorFile);
- if (!csprojContent.Contains(""))
+ if (string.IsNullOrEmpty(blazorFile))
{
- result = DotNetCmd.DotNetRunWithResult(context, blazorFile, "-c Debug --framework net9.0", 60, ref summaryResult);
- WriteResult(context, result, logFilePath, appendToSameLine: true);
+ context.Log.Error("No runnable Blazor project (*blazor*.csproj without ) was found.");
+ summaryResult = false;
+ }
+ else
+ {
+ DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult);
+
+ DotNetCmd.DotNetRunWithHealthCheck(
+ context,
+ blazorFile,
+ "-c Debug --launch-profile https",
+ "https://localhost:7290",
+ 120,
+ ref summaryResult);
}
}
}
- else
- {
- context.Log.Information("No files containing 'blazor' in the filename and ending with '.csproj' were found.");
- }
- }
-
- public static void BuildAndStartHmi(BuildContext context, string appYamlFile, string appName, string logFilePath, ref bool summaryResult)
- {
- // Validate application YAML file
- if (string.IsNullOrWhiteSpace(appYamlFile))
- {
- context.Log.Error("The provided YAML of the application is empty.");
- return;
- }
-
- if (!context.FileExists(appYamlFile))
- {
- context.Log.Error($"The provided application file does not exist: {appYamlFile}");
- return;
- }
-
- if (string.IsNullOrWhiteSpace(appName))
- {
- context.Log.Error("The provided application name is empty.");
- return;
- }
-
- string appFolder = Path.GetFullPath(Path.GetDirectoryName(appYamlFile));
- if (string.IsNullOrWhiteSpace(appFolder) || !context.DirectoryExists(appFolder))
+ finally
{
- context.Log.Error($"The provided path for the application does not exist: {appFolder}");
- return;
+ // Always tear down the Blazor server and the simulator, even on success.
+ KillProcess(context, "dotnet");
+ KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface");
}
- // Recreate solution file by running the slngen script
- string slnGenPath = Path.GetFullPath(Path.GetFullPath(Path.Combine(appFolder, "..", "./slngen.ps1")));
- DotNetCmd.RunPowershellScript(context, slnGenPath, "");
-
- // Clean solution
- string solutionFile = Path.GetFullPath(Path.Combine(appFolder, "../this.sln"));
- DotNetCmd.DotNetClean(context, solutionFile, "-c Debug");
-
-
- //########################## template.axolibrary => ######################//
- if (appFolder.Contains("template.axolibrary"))
+ if (!summaryResult)
{
- string dot_g_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.g"));
- context.CleanDirectory(dot_g_folder, new CleanDirectorySettings() { Force = true });
-
- string dot_meta_folder = Path.GetFullPath(Path.Combine(appFolder, "ix//.meta"));
- context.CleanDirectory(dot_meta_folder, new CleanDirectorySettings() { Force = true });
-
- // Run "dotnet ixc"
- DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult);
+ context.Log.Error("Showcase integration (test level 4) failed.");
+ Environment.Exit(1);
}
- //########################## <= template.axolibrary ######################//
-
- //// Build solution
- //string buildResult = DotNetCmd.DotNetBuildWithResult(context, solutionFile, "-c Debug", ref summaryResult);
- //WriteResult(context, buildResult, logFilePath, appendToSameLine: true);
-
- //// Get blazor projects
- //var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList();
-
- // Get blazor projects
- var blazorFiles = Directory.GetFiles(appFolder, "*.csproj", SearchOption.AllDirectories).Where(file => file.Contains("blazor")).ToList();
-
-
-
- if (blazorFiles.Any())
- {
- foreach (var blazorFile in blazorFiles)
- {
- // Build solution
- string buildResult = DotNetCmd.DotNetBuildWithResult(context, blazorFile, "-c Debug", ref summaryResult);
- WriteResult(context, buildResult, logFilePath, appendToSameLine: true);
-
- context.Log.Information($"Application 'blazor' file: {blazorFile}");
+ context.Log.Information("Showcase integration (test level 4) done.");
+ }
- // Filter out libraries by checking for in the project file
- string csprojContent = File.ReadAllText(blazorFile);
- if (!csprojContent.Contains(""))
- {
- string runResult = DotNetCmd.DotNetRunWithResult(context, blazorFile, "-c Debug --framework net9.0", 60, ref summaryResult);
- WriteResult(context, runResult, logFilePath, appendToSameLine: true);
- }
- }
- }
- else
- {
- context.Log.Information("No files containing 'blazor' in the filename and ending with '.csproj' were found.");
- }
+ ///
+ /// Performs the full first-download apax sequence for the showcase application onto PLCSIM Advanced:
+ /// install -> plcsim -> gsd -> hwl -> hwcc -> hwid -> hwadr -> hwdo -> build -> dotnet ixc -> swfdo.
+ ///
+ public static void LoadShowcasePlc(BuildContext context, string appFolder, ref bool summaryResult)
+ {
+ ApaxCmd.ApaxCommand(context, appFolder, "install", ref summaryResult); // install dependencies
+ ApaxCmd.ApaxPlcSim(context, appFolder, ref summaryResult); // start PLCSIM Advanced instance
+ ApaxCmd.ApaxCommand(context, appFolder, "gsd", ref summaryResult); // copy & install GSDML files
+ ApaxCmd.ApaxCommand(context, appFolder, "hwl", ref summaryResult); // copy hardware templates
+ ApaxCmd.ApaxCommand(context, appFolder, "hwcc", ref summaryResult); // compile hardware configuration
+ ApaxCmd.ApaxCommand(context, appFolder, "hwid", ref summaryResult); // copy generated HwIds
+ ApaxCmd.ApaxCommand(context, appFolder, "hwadr", ref summaryResult); // copy generated IO addresses
+ ApaxCmd.ApaxCommand(context, appFolder, "hwdo", ref summaryResult); // download hardware only
+ ApaxCmd.ApaxCommand(context, appFolder, "build", ref summaryResult); // compile SIMATIC AX code
+ DotNetCmd.DotNetIxc(context, appFolder, ref summaryResult); // generate IXC twin controller
+ ApaxCmd.ApaxCommand(context, appFolder, "swfdo", ref summaryResult); // software full download only
}
public static (bool Success, string FilePath) CreateLogFile(BuildContext context, string fileNamePrefix = "app_test_result")
@@ -646,4 +480,4 @@ public static void WriteResult(BuildContext context, string textToWrite, string
context.Log.Error($"An error occurred while writing to the file: {ex.Message}");
}
}
-}
\ No newline at end of file
+}
diff --git a/cake/BuildParameters.cs b/cake/BuildParameters.cs
index ad7f1b675..250de1689 100644
--- a/cake/BuildParameters.cs
+++ b/cake/BuildParameters.cs
@@ -28,7 +28,7 @@ public class BuildParameters
[Option('v', "verbosity", Required = false, Default = DotNetVerbosity.Minimal, HelpText = "Verbosity (default Quiet)")]
public DotNetVerbosity Verbosity { get; set; }
- [Option('l', "test-level", Required = false, Default = 1, HelpText = "Test level 1 - 3")]
+ [Option('l', "test-level", Required = false, Default = 1, HelpText = "Test level 1 - 4")]
public int TestLevel { get; set; }
[Option('r', "do-publish-release", Required = false, Default = false, HelpText = "Publishes release on GH")]
@@ -49,12 +49,6 @@ public class BuildParameters
[Option('b', "skip-build", Required = false, Default = false, HelpText = "Does not run build steps")]
public bool NoBuild { get; set; }
- [Option('a', "apps-run", Required = false, Default = false, HelpText = "Download to PLC and run apps ")]
- public bool AppsRun{ get; set; }
-
[Option('o', "do-publish-only", Required = false, Default = false, HelpText = "Skips all steps and publishes from pre-build artefacts.")]
public bool PublishOnly { get; set; }
-
- [Option('s', "single-app-run-folder-name", Required = false, Default = "", HelpText = "Download to PLC and run just app from folder")]
- public string AppRunOnlyFolderName { get; set; }
}
\ No newline at end of file
diff --git a/cake/DotNetCmd.cs b/cake/DotNetCmd.cs
index fc2d29e8c..2af679783 100644
--- a/cake/DotNetCmd.cs
+++ b/cake/DotNetCmd.cs
@@ -13,6 +13,7 @@
using System.IO;
using System.Linq;
using System.Management.Automation;
+using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Cake.Common.IO;
@@ -487,4 +488,131 @@ public static string DotNetRunWithResult(this BuildContext context, string proje
return retVal;
}
}
+
+ ///
+ /// Runs a project via "dotnet run" and probes until it returns a
+ /// success status code or elapses. The probe accepts self-signed
+ /// development certificates. The spawned process is always terminated before returning.
+ /// Returns ",OK" on a healthy response, ",NOK" otherwise (and sets to false).
+ ///
+ public static string DotNetRunWithHealthCheck(this BuildContext context, string projectPath, string arguments, string healthUrl, int maxWaitSeconds, ref bool summaryResult)
+ {
+ string workDir = Path.GetFullPath(Path.Combine(projectPath, ".."));
+ string args = $"run --project \"{projectPath}\" {arguments}";
+ context.Log.Information($"Dotnet run (health check) started with project: {projectPath}");
+
+ string retVal = ",NOK";
+
+ var processStartInfo = new ProcessStartInfo
+ {
+ FileName = "dotnet",
+ Arguments = args,
+ WorkingDirectory = workDir,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ using (var process = Process.Start(processStartInfo))
+ {
+ if (process == null)
+ {
+ summaryResult = false;
+ throw new Exception("Failed to start the process.");
+ }
+
+ // Asynchronously drain the output and error streams.
+ Task outputTask = Task.Run(() =>
+ {
+ while (!process.StandardOutput.EndOfStream)
+ {
+ var line = process.StandardOutput.ReadLine();
+ if (!string.IsNullOrEmpty(line))
+ {
+ context.Log.Information($"[Output] {line}");
+ }
+ }
+ });
+
+ Task errorTask = Task.Run(() =>
+ {
+ while (!process.StandardError.EndOfStream)
+ {
+ var line = process.StandardError.ReadLine();
+ if (!string.IsNullOrEmpty(line))
+ {
+ context.Log.Error($"[Error] {line}");
+ }
+ }
+ });
+
+ try
+ {
+ // Probe the server, accepting the self-signed development certificate.
+ using (var handler = new HttpClientHandler
+ {
+ ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
+ })
+ using (var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(5) })
+ {
+ bool healthy = false;
+ int waited = 0;
+
+ while (waited < maxWaitSeconds)
+ {
+ if (process.HasExited)
+ {
+ context.Log.Error($"The application '{projectPath}' exited before serving (exit code {process.ExitCode}).");
+ break;
+ }
+
+ try
+ {
+ var response = client.GetAsync(healthUrl).GetAwaiter().GetResult();
+ if (response.IsSuccessStatusCode)
+ {
+ context.Log.Information($"Health check OK: {healthUrl} returned {(int)response.StatusCode}.");
+ healthy = true;
+ break;
+ }
+
+ context.Log.Information($"Health check: {healthUrl} returned {(int)response.StatusCode}, retrying...");
+ }
+ catch (Exception ex)
+ {
+ context.Log.Information($"Health check: {healthUrl} not ready yet ({ex.Message}), retrying...");
+ }
+
+ Task.Delay(2000).Wait();
+ waited += 2;
+ }
+
+ if (healthy)
+ {
+ retVal = ",OK";
+ }
+ else
+ {
+ summaryResult = false;
+ context.Log.Error($"Health check FAILED: no success response from {healthUrl} within {maxWaitSeconds}s.");
+ }
+ }
+ }
+ finally
+ {
+ // Always stop the server.
+ if (!process.HasExited)
+ {
+ context.Log.Information($"Terminating the application '{projectPath}'...");
+ process.Kill(true);
+ }
+
+ Task.WhenAll(outputTask, errorTask);
+ context.Log.Information($"Process exited with code: {process.ExitCode}");
+ }
+
+ return retVal;
+ }
+ }
}
\ No newline at end of file
diff --git a/cake/Program.cs b/cake/Program.cs
index 0e00dc628..a069a94cd 100644
--- a/cake/Program.cs
+++ b/cake/Program.cs
@@ -399,142 +399,21 @@ public override void Run(BuildContext context)
context.DotNetTest(Path.Combine(context.RootDir, package.folder, "tmp_L3_.proj"), context.DotNetTestSettings);
}
}
-
- context.Log.Information("Tests done.");
- }
-}
-
-[TaskName("AppsRun")]
-[IsDependentOn(typeof(TestsTask))]
-public sealed class AppsRunTask : FrostingTask
-{
- // Tasks can be asynchronous
- public override void Run(BuildContext context)
- {
- if (!context.BuildParameters.AppsRun)
+ if (context.BuildParameters.TestLevel >= 4)
{
- context.Log.Warning($"Skipping apps run");
- return;
+ // Full end-to-end smoke test of the consolidated showcase app: load the entire PLC
+ // (incl. hardware configuration) onto PLCSIM Advanced, then run the Blazor server and
+ // assert it serves traffic. Fails the build on any error.
+ var showcaseApp = Path.Combine(context.RootDir, "showcase", "app", "apax.yml");
+ AppsRunTaskHelpers.RunShowcaseIntegration(context, showcaseApp);
}
- AppsRunTaskHelpers.KillProcess(context,"Siemens.Simatic.PlcSim.Advanced.UserInterface");
-
- bool summaryResult = true;
-
- if (string.IsNullOrEmpty(context.BuildParameters.AppRunOnlyFolderName))
- {
- var createResult = AppsRunTaskHelpers.CreateLogFile(context, "app_test_result");
-
- if (createResult.Success)
- {
- string logFilePath = createResult.FilePath;
- AppsRunTaskHelpers.WriteResult(context, "AppName,PlcSim,PlcHw,PlcSw,DotnetBuild,DotnetRun", logFilePath);
-
- foreach (var library in context.Libraries)
- {
- if (library.app_run)
- {
- string appFolder = context.GetAppFolder(library);
- string appFile = context.GetApaxFile(appFolder);
- string appName = context.GetApplicationName(appFile);
-
- if (!string.IsNullOrEmpty(appFolder) && context.DirectoryExists(appFolder) && !string.IsNullOrEmpty(appFile) && context.FileExists(appFile) && !string.IsNullOrEmpty(appName))
- {
- // Display the file details
- context.Log.Information($"###################################################");
- context.Log.Information($"Starting the application: {appName}");
- context.Log.Information($"File of the application: {appFile}");
- context.Log.Information($"###################################################");
- AppsRunTaskHelpers.WriteResult(context, " ", logFilePath);
- AppsRunTaskHelpers.WriteResult(context, appName, logFilePath, appendToSameLine: true);
-
- // Cleanup JSONREPOS
- AppsRunTaskHelpers.DeleteJsonReposFolder(context, appFolder);
-
- // Initialize PLC Sim instance
- AppsRunTaskHelpers.InitializePlcSimInstance(context, appName);
-
- // Overwrite security files
- AppsRunTaskHelpers.OverwriteSecurityFiles(context, appFile, context.PlcName);
-
- // Build and load PLC
- AppsRunTaskHelpers.BuildAndLoadPlc(context, appFile, appName, logFilePath, ref summaryResult);
-
- // Build and start HMI
- AppsRunTaskHelpers.BuildAndStartHmi(context, appFile, appName, logFilePath, ref summaryResult);
-
-
- }
- }
- }
-
- if (!summaryResult)
- {
- context.Log.Error($"App run failed for some of the applications.");
- context.Log.Error($"Good luck with finding out the reason :-).");
- Environment.Exit(1);
- }
- }
- else
- {
- Console.Error.WriteLine("Failed to create the log file.");
- }
- }
- else
- {
- var createResult = AppsRunTaskHelpers.CreateLogFile(context, "single_app_test_result");
-
- if (createResult.Success)
- {
- string logFilePath = createResult.FilePath;
- AppsRunTaskHelpers.WriteResult(context, "AppName,ApaxInstall,ApaxPlcSim,ApaxGsd,ApaxHwl,ApaxHwcc,ApaxHwid,ApaxHwadr,ApaxHwdo,ApaxBuild,DotnetIxc,ApaxSlfdo,Slngen,DotnetClean,DotnetBuild,DotnetRun", logFilePath);
-
- string appFolder = Path.Combine(context.RootDir, context.BuildParameters.AppRunOnlyFolderName);
- string appFile = context.GetApaxFile(appFolder);
- string appName = context.GetApplicationName(appFile);
-
- if (!string.IsNullOrEmpty(appFolder) && context.DirectoryExists(appFolder) && !string.IsNullOrEmpty(appFile) && context.FileExists(appFile) && !string.IsNullOrEmpty(appName))
- {
- // Display the file details
- context.Log.Information($"###################################################");
- context.Log.Information($"Starting the application: {appName}");
- context.Log.Information($"File of the application: {appFile}");
- context.Log.Information($"###################################################");
- AppsRunTaskHelpers.WriteResult(context, " ", logFilePath);
- AppsRunTaskHelpers.WriteResult(context, appName, logFilePath, appendToSameLine: true);
-
- // Cleanup JSONREPOS
- AppsRunTaskHelpers.DeleteJsonReposFolder(context, appFolder);
-
- // Initialize PLC Sim instance
- AppsRunTaskHelpers.InitializePlcSimInstance(context, appName);
-
- // Overwrite security files
- AppsRunTaskHelpers.OverwriteSecurityFiles(context, appFile, context.PlcName);
-
- // Build and load PLC, build and start HMI with more grannular evaluation
- AppsRunTaskHelpers.AppRunDetailed(context, appFile, appName, logFilePath, ref summaryResult);
-
- if (!summaryResult)
- {
- context.Log.Error($"App run failed for the application name: '{appName}', application file: '{appFile}' in folder: '{appFolder}'");
- Environment.Exit(1);
- }
- }
- }
- else
- {
- Console.Error.WriteLine("Failed to create the log file.");
- }
- }
-
- AppsRunTaskHelpers.KillProcess(context, "Siemens.Simatic.PlcSim.Advanced.UserInterface");
- context.Log.Information("Apps run done.");
+ context.Log.Information("Tests done.");
}
}
[TaskName("CreateArtifacts")]
-[IsDependentOn(typeof(AppsRunTask))]
+[IsDependentOn(typeof(TestsTask))]
public sealed class CreateArtifactsTask : FrostingTask
{
public override void Run(BuildContext context)
diff --git a/cake/Properties/launchSettings.json b/cake/Properties/launchSettings.json
index 53666dfa1..131b89751 100644
--- a/cake/Properties/launchSettings.json
+++ b/cake/Properties/launchSettings.json
@@ -20,6 +20,10 @@
"commandName": "Project",
"commandLineArgs": "--do-test --test-level 10"
},
+ "test-L4": {
+ "commandName": "Project",
+ "commandLineArgs": "--do-test --test-level 4"
+ },
"no-build": {
"commandName": "Project",
"commandLineArgs": "--skip-build"
@@ -31,122 +35,6 @@
"build": {
"commandName": "Project",
"commandLineArgs": ""
- },
- "test-L3-apps_run": {
- "commandName": "Project",
- "commandLineArgs": "--do-test --test-level 10 --apps-run"
- },
- "apps_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run"
- },
- "abstractions_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name abstractions"
- },
- "components.abb.robotics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.abb.robotics"
- },
- "components.abstractions_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.abstractions"
- },
- "components.balluff.identification_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.balluff.identification"
- },
- "components.cognex.vision_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.cognex.vision"
- },
- "components.desoutter.tightening_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.desoutter.tightening"
- },
- "components.drives_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.drives"
- },
- "components.elements_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.elements"
- },
- "components.festo.drives_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.festo.drives"
- },
- "components.kuka.robotics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.kuka.robotics"
- },
- "components.keyence.vision_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.keyence.vision"
- },
- "components.mitsubishi.robotics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.mitsubishi.robotics"
- },
- "components.pneumatics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.pneumatics"
- },
- "components.rexroth.drives_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.rexroth.drives"
- },
- "components.rexroth.press_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.rexroth.press"
- },
- "components.robotics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.robotics"
- },
- "components.siem.identification_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.siem.identification"
- },
- "components.ur.robotics_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name components.ur.robotics"
- },
- "core_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name core"
- },
- "data_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name data"
- },
- "inspectors_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name inspectors"
- },
- "io_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name io"
- },
- "probers_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name probers"
- },
- "simatic1500_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name simatic1500"
- },
- "template.axolibrary_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name template.axolibrary"
- },
- "timers_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name timers"
- },
- "utils_app_run_only": {
- "commandName": "Project",
- "commandLineArgs": "--skip-build --apps-run --single-app-run-folder-name utils"
}
}
-}
\ No newline at end of file
+}
diff --git a/scripts/test_L4.ps1 b/scripts/test_L4.ps1
new file mode 100644
index 000000000..f76ea7585
--- /dev/null
+++ b/scripts/test_L4.ps1
@@ -0,0 +1,4 @@
+# run build
+
+dotnet run --project cake/Build.csproj --do-test --test-level 4 -n
+exit $LASTEXITCODE;
\ No newline at end of file