$ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot $asset = Join-Path $root 'static/assets/modules/auth/opaque/a02-login-panel.png' if (-not (Test-Path -LiteralPath $asset)) { throw 'Missing A02 login-panel asset' } Add-Type -AssemblyName System.Drawing $bitmap = [System.Drawing.Bitmap]::FromFile($asset) $width = [int]$bitmap.Width $height = [int]$bitmap.Height $corners = @( $bitmap.GetPixel(0, 0).A, $bitmap.GetPixel(($width - 1), 0).A, $bitmap.GetPixel(0, ($height - 1)).A, $bitmap.GetPixel(($width - 1), ($height - 1)).A ) $bitmap.Dispose() $ratio = [double]$width / $height if ($width -ne 940 -or $height -ne 1672) { throw 'A02 login-panel asset must remain 940 x 1672px.' } if ([Math]::Abs($ratio - 0.5622) -gt 0.001) { throw 'A02 login-panel asset must retain its approved panel ratio.' } if (($corners | Where-Object { $_ -ne 255 }).Count -ne 0) { throw 'A02 login-panel asset must have opaque outer corners.' } $agreementAssets = @( 'static/assets/modules/auth/transparent/a02-agreement-unchecked.png', 'static/assets/modules/auth/transparent/a02-agreement-checked.png' ) foreach ($agreementAssetRelativePath in $agreementAssets) { $agreementAsset = Join-Path $root $agreementAssetRelativePath if (-not (Test-Path -LiteralPath $agreementAsset)) { throw "Missing A02 agreement asset: $agreementAssetRelativePath" } $agreementBitmap = [System.Drawing.Bitmap]::FromFile($agreementAsset) try { if ($agreementBitmap.Width -ne 96 -or $agreementBitmap.Height -ne 96) { throw "A02 agreement asset must be 96 x 96px: $agreementAssetRelativePath" } if (-not [System.Drawing.Image]::IsAlphaPixelFormat($agreementBitmap.PixelFormat)) { throw "A02 agreement asset must retain an alpha channel: $agreementAssetRelativePath" } $agreementCorners = @( $agreementBitmap.GetPixel(0, 0).A, $agreementBitmap.GetPixel(95, 0).A, $agreementBitmap.GetPixel(0, 95).A, $agreementBitmap.GetPixel(95, 95).A ) if (($agreementCorners | Where-Object { $_ -ne 0 }).Count -ne 0) { throw "A02 agreement asset must have transparent outer corners: $agreementAssetRelativePath" } $hasOpaquePixel = $false for ($y = 0; $y -lt 96 -and -not $hasOpaquePixel; $y += 1) { for ($x = 0; $x -lt 96; $x += 1) { if ($agreementBitmap.GetPixel($x, $y).A -eq 255) { $hasOpaquePixel = $true break } } } if (-not $hasOpaquePixel) { throw "A02 agreement asset must contain an opaque icon: $agreementAssetRelativePath" } } finally { $agreementBitmap.Dispose() } } Write-Output 'A02-ASSET-ALPHA-AUDIT PASS'